From 6552da940ad734faf2dfdf470ba61907d51258bd Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Thu, 12 Dec 2019 15:37:55 -0500 Subject: [PATCH] Add `format_text` command, and `editor.marks` state (#3308) * add format_text command, refactor command extensions * update onChange to not receive selection * update docs * fix tests --- docs/concepts/06-editor.md | 7 +- docs/walkthroughs/01-installing-slate.md | 38 +---- docs/walkthroughs/02-adding-event-handlers.md | 33 +---- .../03-defining-custom-elements.md | 43 +----- .../04-applying-custom-formatting.md | 33 +---- docs/walkthroughs/05-executing-commands.md | 44 +----- docs/walkthroughs/06-saving-to-a-database.md | 25 +--- packages/slate-history/src/history-command.ts | 26 ++-- packages/slate-history/src/with-history.ts | 9 +- packages/slate-react/src/components/slate.tsx | 19 ++- .../slate-react/src/plugin/react-command.ts | 21 ++- packages/slate-react/src/plugin/with-react.ts | 12 +- packages/slate-react/src/utils/weak-maps.ts | 7 +- packages/slate/src/create-editor.ts | 79 ++++++++++- packages/slate/src/interfaces/command.ts | 132 ++++++------------ packages/slate/src/interfaces/editor/index.ts | 7 +- .../src/interfaces/editor/queries/general.ts | 55 ++++++++ packages/slate/src/interfaces/operation.ts | 102 +++++--------- .../interfaces/Element/isElement/editor.js | 3 +- .../Element/isElementList/full-editor.js | 3 +- .../Operation/isOperation/set_value.js | 13 -- site/examples/check-lists.js | 11 +- site/examples/embeds.js | 11 +- site/examples/forced-layout.js | 11 +- site/examples/hovering-toolbar.js | 11 +- site/examples/huge-document.js | 11 +- site/examples/images.js | 11 +- site/examples/links.js | 11 +- site/examples/markdown-preview.js | 11 +- site/examples/markdown-shortcuts.js | 11 +- site/examples/mentions.js | 5 +- site/examples/paste-html.js | 11 +- site/examples/plaintext.js | 11 +- site/examples/read-only.js | 11 +- site/examples/richtext.js | 127 ++++++++--------- site/examples/search-highlighting.js | 11 +- site/examples/tables.js | 11 +- 37 files changed, 350 insertions(+), 647 deletions(-) delete mode 100644 packages/slate/test/interfaces/Operation/isOperation/set_value.js diff --git a/docs/concepts/06-editor.md b/docs/concepts/06-editor.md index 746d950f1..1b8e45ec8 100644 --- a/docs/concepts/06-editor.md +++ b/docs/concepts/06-editor.md @@ -4,15 +4,16 @@ All of the behaviors, content and state of a Slate editor is rollup up into a si ```ts interface Editor { + children: Node[] + operations: Operation[] + selection: Range | null + marks: Record | null apply: (operation: Operation) => void exec: (command: Command) => void isInline: (element: Element) => boolean isVoid: (element: Element) => boolean normalizeNode: (entry: NodeEntry) => void onChange: () => void - children: Node[] - operations: Operation[] - selection: Range | null [key: string]: any } ``` diff --git a/docs/walkthroughs/01-installing-slate.md b/docs/walkthroughs/01-installing-slate.md index ef455a840..e7345e13e 100644 --- a/docs/walkthroughs/01-installing-slate.md +++ b/docs/walkthroughs/01-installing-slate.md @@ -45,15 +45,14 @@ const App = () => { Of course we haven't rendered anything, so you won't see any changes. -Next we want to create state for `value` and `selection`: +Next we want to create state for `value`: ```jsx const App = () => { const editor = useMemo(() => withReact(createEditor()), []) - // Keep track of state for the value and selection of the editor. + // Keep track of state for the value of the editor. const [value, setValue] = useState([]) - const [selection, setSelection] = useState(null) return null } ``` @@ -66,18 +65,9 @@ The provider component keeps track of your Slate editor, its plugins, its value, const App = () => { const editor = useMemo(() => withReact(createEditor()), []) const [value, setValue] = useState([]) - const [selection, setSelection] = useState(null) // Render the Slate context. return ( - { - setValue(value) - setSelection(selection) - }} - /> + setValue(value)} /> ) } ``` @@ -94,18 +84,9 @@ Okay, so the next step is to render the `` component itself: const App = () => { const editor = useMemo(() => withReact(createEditor()), []) const [value, setValue] = useState([]) - const [selection, setSelection] = useState(null) return ( // Add the editable component inside the context. - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> ) @@ -121,7 +102,6 @@ The value is just plain JSON. Here's one containing a single paragraph block wit ```js const App = () => { const editor = useMemo(() => withReact(createEditor()), []) - const [selection, setSelection] = useState(null) // Add the initial value when setting up our state. const [value, setValue] = useState([ { @@ -131,15 +111,7 @@ const App = () => { ]) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> ) diff --git a/docs/walkthroughs/02-adding-event-handlers.md b/docs/walkthroughs/02-adding-event-handlers.md index 274a21b0d..f735debcc 100644 --- a/docs/walkthroughs/02-adding-event-handlers.md +++ b/docs/walkthroughs/02-adding-event-handlers.md @@ -11,7 +11,6 @@ Here's our app from earlier: ```js const App = () => { const editor = useMemo(() => withReact(createEditor()), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -20,15 +19,7 @@ const App = () => { ]) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> ) @@ -40,7 +31,6 @@ Now we add an `onKeyDown` handler: ```js const App = () => { const editor = useMemo(() => withReact(createEditor()), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -49,15 +39,7 @@ const App = () => { ]) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> { @@ -78,7 +60,6 @@ Our `onKeyDown` handler might look like this: ```js const App = () => { const editor = useMemo(() => withReact(createEditor()), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -87,15 +68,7 @@ const App = () => { ]) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> { if (event.key === '&') { diff --git a/docs/walkthroughs/03-defining-custom-elements.md b/docs/walkthroughs/03-defining-custom-elements.md index 60ac14840..6f8b520b2 100644 --- a/docs/walkthroughs/03-defining-custom-elements.md +++ b/docs/walkthroughs/03-defining-custom-elements.md @@ -9,7 +9,6 @@ We'll show you how. Let's start with our app from earlier: ```js const App = () => { const editor = useMemo(() => withReact(createEditor()), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -18,15 +17,7 @@ const App = () => { ]) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> { if (event.key === '&') { @@ -76,7 +67,6 @@ Now, let's add that renderer to our `Editor`: ```js const App = () => { const editor = useMemo(() => withReact(createEditor()), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -96,15 +86,7 @@ const App = () => { }, []) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> { const editor = useMemo(() => withReact(createEditor()), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -158,15 +139,7 @@ const App = () => { }, []) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> { @@ -220,15 +193,7 @@ const App = () => { }, []) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> { diff --git a/docs/walkthroughs/04-applying-custom-formatting.md b/docs/walkthroughs/04-applying-custom-formatting.md index 89f39df4f..1371082ac 100644 --- a/docs/walkthroughs/04-applying-custom-formatting.md +++ b/docs/walkthroughs/04-applying-custom-formatting.md @@ -9,7 +9,6 @@ So we start with our app from earlier: ```js const App = () => { const editor = useMemo(() => withReact(createEditor()), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -27,15 +26,7 @@ const App = () => { }, []) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> { @@ -61,7 +52,6 @@ And now, we'll edit the `onKeyDown` handler to make it so that when you press `c ```js const App = () => { const editor = useMemo(() => withReact(createEditor()), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -79,15 +69,7 @@ const App = () => { }, []) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> { @@ -153,7 +135,6 @@ And now, let's tell Slate about that leaf. To do that, we'll pass in the `render ```js const App = () => { const editor = useMemo(() => withReact(createEditor()), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -176,15 +157,7 @@ const App = () => { }, []) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> { const editor = useMemo(() => withReact(createEditor()), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -35,15 +34,7 @@ const App = () => { }, []) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> { const App = () => { // Wrap the editor with our new `withCustom` plugin. const editor = useMemo(() => withCustom(withReact(createEditor())), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -116,15 +106,7 @@ const App = () => { }, []) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> { const editor = useMemo(() => withCustom(withReact(createEditor())), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -246,15 +227,7 @@ const App = () => { }, []) return ( - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}> { const editor = useMemo(() => withCustom(withReact(createEditor())), []) - const [selection, setSelection] = useState(null) const [value, setValue] = useState([ { type: 'paragraph', @@ -312,15 +284,7 @@ const App = () => { return ( // Add a toolbar with buttons that call the same methods. - { - setValue(value) - setSelection(selection) - }} - > + setValue(value)}>
+ ) +} + +const MarkButton = ({ format, icon }) => { + const editor = useSlate() + return ( +