1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-14 03:03:58 +02:00

Make onChange prop optional, update examples and docs to treat slate as uncontrolled (#4922)

* Make onChange prop optional, update examples and docs to treat slate as uncontrolled

* Add changeset
This commit is contained in:
Eric Meier
2022-04-03 16:52:32 +01:00
committed by GitHub
parent 08d5a12c91
commit 9892cf0ffb
29 changed files with 207 additions and 246 deletions

View File

@@ -0,0 +1,5 @@
---
'slate-react': patch
---
Make Slate component onChange optional

View File

@@ -66,53 +66,23 @@ declare module 'slate' {
} }
``` ```
```typescript
// Also you must annotate `useState<Descendant[]>` and the editor's initial value.
const App = () => {
const initialValue: CustomElement[] = []
const [value, setValue] = useState<Descendant[]>(initialValue)
return (
<Slate value={value} onChange={setValue}>
...
</Slate>
)
}
```
Next we want to create state for `value`:
```jsx
const App = () => {
const [editor] = useState(() => withReact(createEditor()))
// Keep track of state for the value of the editor.
const [value, setValue] = useState([])
return null
}
```
Next up is to render a `<Slate>` context provider. Next up is to render a `<Slate>` context provider.
The provider component keeps track of your Slate editor, its plugins, its value, its selection, and any changes that occur. It **must** be rendered above any `<Editable>` components. But it can also provide the editor state to other components like toolbars, menus, etc. using the `useSlate` hook. The provider component keeps track of your Slate editor, its plugins, its value, its selection, and any changes that occur. It **must** be rendered above any `<Editable>` components. But it can also provide the editor state to other components like toolbars, menus, etc. using the `useSlate` hook.
```jsx ```jsx
const initialValue = []
const App = () => { const App = () => {
const [editor] = useState(() => withReact(createEditor())) const [editor] = useState(() => withReact(createEditor()))
const [value, setValue] = useState([])
// Render the Slate context. // Render the Slate context.
return ( return <Slate editor={editor} value={initialValue} />
<Slate
editor={editor}
value={value}
onChange={newValue => setValue(newValue)}
/>
)
} }
``` ```
You can think of the `<Slate>` component as providing a context to every component underneath it. You can think of the `<Slate>` component as providing a context to every component underneath it.
> As of v0.67 the Slate Provider's "value" prop is now only used as initial state for editor.children. If your code relies on replacing editor.children you should do so by replacing it directly instead of relying on the "value" prop to do this for you. See [Slate PR 4540](https://github.com/ianstormtaylor/slate/pull/4540) for a more in-depth discussion. > Slate Provider's "value" prop is only used as initial state for editor.children. If your code relies on replacing editor.children you should do so by replacing it directly instead of relying on the "value" prop to do this for you. See [Slate PR 4540](https://github.com/ianstormtaylor/slate/pull/4540) for a more in-depth discussion.
This is a slightly different mental model than things like `<input>` or `<textarea>`, because richtext documents are more complex. You'll often want to include toolbars, or live previews, or other complex components next to your editable content. This is a slightly different mental model than things like `<input>` or `<textarea>`, because richtext documents are more complex. You'll often want to include toolbars, or live previews, or other complex components next to your editable content.
@@ -121,16 +91,14 @@ By having a shared context, those other components can execute commands, query t
Okay, so the next step is to render the `<Editable>` component itself: Okay, so the next step is to render the `<Editable>` component itself:
```jsx ```jsx
const initialValue = []
const App = () => { const App = () => {
const [editor] = useState(() => withReact(createEditor())) const [editor] = useState(() => withReact(createEditor()))
const [value, setValue] = useState([]) const [value, setValue] = useState([])
return ( return (
// Add the editable component inside the context. // Add the editable component inside the context.
<Slate <Slate editor={editor} value={initialValue}>
editor={editor}
value={value}
onChange={newValue => setValue(newValue)}
>
<Editable /> <Editable />
</Slate> </Slate>
) )
@@ -144,22 +112,20 @@ There's only one last step. So far we've been using an empty `[]` array as the i
The value is just plain JSON. Here's one containing a single paragraph block with some text in it: The value is just plain JSON. Here's one containing a single paragraph block with some text in it:
```jsx ```jsx
// Add the initial value.
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const [editor] = useState(() => withReact(createEditor())) const [editor] = useState(() => withReact(createEditor())
// Add the initial value when setting up our state. const [value, setValue] = useState()
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
return ( return (
<Slate <Slate editor={editor} value={initialValue}>
editor={editor}
value={value}
onChange={newValue => setValue(newValue)}
>
<Editable /> <Editable />
</Slate> </Slate>
) )

View File

@@ -9,17 +9,18 @@ Let's use the `onKeyDown` handler to change the editor's content when we press a
Here's our app from earlier: Here's our app from earlier:
```jsx ```jsx
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable /> <Editable />
</Slate> </Slate>
) )
@@ -29,17 +30,18 @@ const App = () => {
Now we add an `onKeyDown` handler: Now we add an `onKeyDown` handler:
```jsx ```jsx
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
// Define a new handler which prints the key that was pressed. // Define a new handler which prints the key that was pressed.
onKeyDown={event => { onKeyDown={event => {
@@ -58,17 +60,18 @@ Now we want to make it actually change the content. For the purposes of our exam
Our `onKeyDown` handler might look like this: Our `onKeyDown` handler might look like this:
```jsx ```jsx
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
onKeyDown={event => { onKeyDown={event => {
if (event.key === '&') { if (event.key === '&') {

View File

@@ -7,17 +7,18 @@ But that's not all you can do. Slate lets you define any type of custom blocks y
We'll show you how. Let's start with our app from earlier: We'll show you how. Let's start with our app from earlier:
```jsx ```jsx
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
onKeyDown={event => { onKeyDown={event => {
if (event.key === '&') { if (event.key === '&') {
@@ -65,14 +66,15 @@ const DefaultElement = props => {
Now, let's add that renderer to our `Editor`: Now, let's add that renderer to our `Editor`:
```jsx ```jsx
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
// Define a rendering function based on the element passed to `props`. We use // Define a rendering function based on the element passed to `props`. We use
// `useCallback` here to memoize the function for subsequent renders. // `useCallback` here to memoize the function for subsequent renders.
@@ -86,7 +88,7 @@ const App = () => {
}, []) }, [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
// Pass in the `renderElement` function. // Pass in the `renderElement` function.
renderElement={renderElement} renderElement={renderElement}
@@ -120,14 +122,15 @@ Okay, but now we'll need a way for the user to actually turn a block into a code
// Import the `Editor` and `Transforms` helpers from Slate. // Import the `Editor` and `Transforms` helpers from Slate.
import { Editor, Transforms } from 'slate' import { Editor, Transforms } from 'slate'
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
const renderElement = useCallback(props => { const renderElement = useCallback(props => {
switch (props.element.type) { switch (props.element.type) {
@@ -139,7 +142,7 @@ const App = () => {
}, []) }, [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
renderElement={renderElement} renderElement={renderElement}
onKeyDown={event => { onKeyDown={event => {
@@ -177,14 +180,15 @@ Now, if you press ``Ctrl-``` the block your cursor is in should turn into a code
But we forgot one thing. When you hit ``Ctrl-``` again, it should change the code block back into a paragraph. To do that, we'll need to add a bit of logic to change the type we set based on whether any of the currently selected blocks are already a code block: But we forgot one thing. When you hit ``Ctrl-``` again, it should change the code block back into a paragraph. To do that, we'll need to add a bit of logic to change the type we set based on whether any of the currently selected blocks are already a code block:
```jsx ```jsx
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
const renderElement = useCallback(props => { const renderElement = useCallback(props => {
switch (props.element.type) { switch (props.element.type) {
@@ -196,7 +200,7 @@ const App = () => {
}, []) }, [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
renderElement={renderElement} renderElement={renderElement}
onKeyDown={event => { onKeyDown={event => {

View File

@@ -7,26 +7,27 @@ In this guide, we'll show you how to add custom formatting options, like **bold*
So we start with our app from earlier: So we start with our app from earlier:
```jsx ```jsx
const renderElement = (props) => { const renderElement = props => {
switch (props.element.type) { switch (props.element.type) {
case 'code': case 'code':
return <CodeElement {...props} /> return <CodeElement {...props} />
default: default:
return <DefaultElement {...props} /> return <DefaultElement {...props} />
} }
}) }
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
renderElement={renderElement} renderElement={renderElement}
onKeyDown={event => { onKeyDown={event => {
@@ -52,14 +53,15 @@ const App = () => {
And now, we'll edit the `onKeyDown` handler to make it so that when you press `control-B`, it will add a `bold` format to the currently selected text: And now, we'll edit the `onKeyDown` handler to make it so that when you press `control-B`, it will add a `bold` format to the currently selected text:
```jsx ```jsx
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
const renderElement = useCallback(props => { const renderElement = useCallback(props => {
switch (props.element.type) { switch (props.element.type) {
@@ -71,7 +73,7 @@ const App = () => {
}, []) }, [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={value}>
<Editable <Editable
renderElement={renderElement} renderElement={renderElement}
onKeyDown={event => { onKeyDown={event => {
@@ -137,14 +139,15 @@ Pretty familiar, right?
And now, let's tell Slate about that leaf. To do that, we'll pass in the `renderLeaf` prop to our editor. And now, let's tell Slate about that leaf. To do that, we'll pass in the `renderLeaf` prop to our editor.
```jsx ```jsx
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
const renderElement = useCallback(props => { const renderElement = useCallback(props => {
switch (props.element.type) { switch (props.element.type) {
@@ -161,7 +164,7 @@ const App = () => {
}, []) }, [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
renderElement={renderElement} renderElement={renderElement}
// Pass in the `renderLeaf` function. // Pass in the `renderLeaf` function.

View File

@@ -11,14 +11,15 @@ Let's see how this works.
We'll start with our app from earlier: We'll start with our app from earlier:
```jsx ```jsx
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
const renderElement = useCallback(props => { const renderElement = useCallback(props => {
switch (props.element.type) { switch (props.element.type) {
@@ -34,7 +35,7 @@ const App = () => {
}, []) }, [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
renderElement={renderElement} renderElement={renderElement}
renderLeaf={renderLeaf} renderLeaf={renderLeaf}
@@ -117,14 +118,15 @@ const CustomEditor = {
}, },
} }
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
const renderElement = useCallback(props => { const renderElement = useCallback(props => {
switch (props.element.type) { switch (props.element.type) {
@@ -140,7 +142,7 @@ const App = () => {
}, []) }, [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
renderElement={renderElement} renderElement={renderElement}
renderLeaf={renderLeaf} renderLeaf={renderLeaf}
@@ -173,14 +175,15 @@ const App = () => {
Now our commands are clearly defined and you can invoke them from anywhere we have access to our `editor` object. For example, from hypothetical toolbar buttons: Now our commands are clearly defined and you can invoke them from anywhere we have access to our `editor` object. For example, from hypothetical toolbar buttons:
```jsx ```jsx
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
const renderElement = useCallback(props => { const renderElement = useCallback(props => {
switch (props.element.type) { switch (props.element.type) {
@@ -197,7 +200,7 @@ const App = () => {
return ( return (
// Add a toolbar with buttons that call the same methods. // Add a toolbar with buttons that call the same methods.
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<div> <div>
<button <button
onMouseDown={event => { onMouseDown={event => {

View File

@@ -7,17 +7,18 @@ In this guide, we'll show you how to add logic to save your Slate content to a d
Let's start with a basic editor: Let's start with a basic editor:
```jsx ```jsx
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable /> <Editable />
</Slate> </Slate>
) )
@@ -31,22 +32,21 @@ What we need to do is save the changes you make somewhere. For this example, we'
So, in our `onChange` handler, we need to save the `value` if anything besides the selection was changed: So, in our `onChange` handler, we need to save the `value` if anything besides the selection was changed:
```jsx ```jsx
const initialValue = [
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
return ( return (
<Slate <Slate
editor={editor} editor={editor}
value={value} value={initialValue}
onChange={value => { onChange={value => {
setValue(value)
const isAstChange = editor.operations.some( const isAstChange = editor.operations.some(
op => 'set_selection' !== op.type op => 'set_selection' !== op.type
) )
@@ -71,21 +71,21 @@ But... if you refresh the page, everything is still reset. That's because we nee
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
// Update the initial content to be pulled from Local Storage if it exists. // Update the initial content to be pulled from Local Storage if it exists.
const [value, setValue] = useState( const initialValue = useMemo(
JSON.parse(localStorage.getItem('content')) || [ JSON.parse(localStorage.getItem('content')) || [
{ {
type: 'paragraph', type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }], children: [{ text: 'A line of text in a paragraph.' }],
}, },
] ],
[]
) )
return ( return (
<Slate <Slate
editor={editor} editor={editor}
value={value} value={initialValue}
onChange={value => { onChange={value => {
setValue(value)
const isAstChange = editor.operations.some( const isAstChange = editor.operations.some(
op => 'set_selection' !== op.type op => 'set_selection' !== op.type
) )
@@ -136,16 +136,16 @@ const deserialize = string => {
const App = () => { const App = () => {
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
// Use our deserializing function to read the data from Local Storage. // Use our deserializing function to read the data from Local Storage.
const [value, setValue] = useState( const initialValue = useMemo(
deserialize(localStorage.getItem('content')) || '' deserialize(localStorage.getItem('content')) || '',
[]
) )
return ( return (
<Slate <Slate
editor={editor} editor={editor}
value={value} value={initialValue}
onChange={value => { onChange={value => {
setValue(value)
const isAstChange = editor.operations.some( const isAstChange = editor.operations.some(
op => 'set_selection' !== op.type op => 'set_selection' !== op.type
) )
@@ -167,7 +167,7 @@ You can emulate this strategy for any format you like. You can serialize to HTML
> 🤖 Note that even though you _can_ serialize your content however you like, there are tradeoffs. The serialization process has a cost itself, and certain formats may be harder to work with than others. In general we recommend writing your own format only if your use case has a specific need for it. Otherwise, you're often better leaving the data in the format Slate uses. > 🤖 Note that even though you _can_ serialize your content however you like, there are tradeoffs. The serialization process has a cost itself, and certain formats may be harder to work with than others. In general we recommend writing your own format only if your use case has a specific need for it. Otherwise, you're often better leaving the data in the format Slate uses.
If you want to update the editor's content in response to events from outside of slate, you need to change the children property directly. The simplest way is to replace the value of editor.children `editor.children = newValue` and trigger a re-rendering (e.g. by calling `setValue(newValue)` in the example above). Alternatively, you can use slate's internal operations to transform the value, for example: If you want to update the editor's content in response to events from outside of slate, you need to change the children property directly. The simplest way is to replace the value of editor.children `editor.children = newValue` and trigger a re-rendering (e.g. by calling `editor.onChange()` in the example above). Alternatively, you can use slate's internal operations to transform the value, for example:
```javascript ```javascript
/** /**

View File

@@ -20,7 +20,7 @@ export const Slate = (props: {
editor: ReactEditor editor: ReactEditor
value: Descendant[] value: Descendant[]
children: React.ReactNode children: React.ReactNode
onChange: (value: Descendant[]) => void onChange?: (value: Descendant[]) => void
}) => { }) => {
const { editor, children, onChange, value, ...rest } = props const { editor, children, onChange, value, ...rest } = props
const unmountRef = useRef(false) const unmountRef = useRef(false)
@@ -48,7 +48,10 @@ export const Slate = (props: {
} = getSelectorContext(editor) } = getSelectorContext(editor)
const onContextChange = useCallback(() => { const onContextChange = useCallback(() => {
onChange(editor.children) if (onChange) {
onChange(editor.children)
}
setContext([editor]) setContext([editor])
handleSelectorChange(editor) handleSelectorChange(editor)
}, [onChange]) }, [onChange])

View File

@@ -1,4 +1,4 @@
import React, { useState, useMemo, useCallback } from 'react' import React, { useMemo, useCallback } from 'react'
import { import {
Slate, Slate,
Editable, Editable,
@@ -66,7 +66,6 @@ const initialValue: Descendant[] = [
] ]
const CheckListsExample = () => { const CheckListsExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const renderElement = useCallback(props => <Element {...props} />, []) const renderElement = useCallback(props => <Element {...props} />, [])
const editor = useMemo( const editor = useMemo(
() => withChecklists(withHistory(withReact(createEditor()))), () => withChecklists(withHistory(withReact(createEditor()))),
@@ -74,7 +73,7 @@ const CheckListsExample = () => {
) )
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
renderElement={renderElement} renderElement={renderElement}
placeholder="Get to work…" placeholder="Get to work…"

View File

@@ -10,7 +10,6 @@ import { withHistory } from 'slate-history'
import { css } from '@emotion/css' import { css } from '@emotion/css'
const CodeHighlightingExample = () => { const CodeHighlightingExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const [language, setLanguage] = useState('html') const [language, setLanguage] = useState('html')
const renderLeaf = useCallback(props => <Leaf {...props} />, []) const renderLeaf = useCallback(props => <Leaf {...props} />, [])
const editor = useMemo(() => withHistory(withReact(createEditor())), []) const editor = useMemo(() => withHistory(withReact(createEditor())), [])
@@ -46,7 +45,7 @@ const CodeHighlightingExample = () => {
) )
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<div <div
contentEditable={false} contentEditable={false}
style={{ position: 'relative', top: '5px', right: '5px' }} style={{ position: 'relative', top: '5px', right: '5px' }}

View File

@@ -1,13 +1,19 @@
import React, { useState, useMemo } from 'react' import React, { useMemo } from 'react'
import { createEditor, Descendant } from 'slate' import { createEditor, Descendant } from 'slate'
import { Slate, Editable, withReact } from 'slate-react' import { Slate, Editable, withReact } from 'slate-react'
import { withHistory } from 'slate-history' import { withHistory } from 'slate-history'
const initialValue: Descendant[] = [
{
type: 'paragraph',
children: [{ text: '' }],
},
]
const PlainTextExample = () => { const PlainTextExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const editor = useMemo(() => withHistory(withReact(createEditor())), []) const editor = useMemo(() => withHistory(withReact(createEditor())), [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
placeholder="Type something" placeholder="Type something"
renderPlaceholder={({ children, attributes }) => ( renderPlaceholder={({ children, attributes }) => (
@@ -24,11 +30,4 @@ const PlainTextExample = () => {
) )
} }
const initialValue: Descendant[] = [
{
type: 'paragraph',
children: [{ text: '' }],
},
]
export default PlainTextExample export default PlainTextExample

View File

@@ -1,4 +1,4 @@
import React, { useState, useMemo } from 'react' import React, { useMemo } from 'react'
import { import {
Transforms, Transforms,
createEditor, createEditor,
@@ -14,10 +14,9 @@ import {
} from 'slate-react' } from 'slate-react'
const EmbedsExample = () => { const EmbedsExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const editor = useMemo(() => withEmbeds(withReact(createEditor())), []) const editor = useMemo(() => withEmbeds(withReact(createEditor())), [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
renderElement={props => <Element {...props} />} renderElement={props => <Element {...props} />}
placeholder="Enter some text..." placeholder="Enter some text..."

View File

@@ -1,4 +1,4 @@
import React, { useState, useCallback, useMemo } from 'react' import React, { useCallback, useMemo } from 'react'
import { Slate, Editable, withReact } from 'slate-react' import { Slate, Editable, withReact } from 'slate-react'
import { import {
Transforms, Transforms,
@@ -64,14 +64,13 @@ const withLayout = editor => {
} }
const ForcedLayoutExample = () => { const ForcedLayoutExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const renderElement = useCallback(props => <Element {...props} />, []) const renderElement = useCallback(props => <Element {...props} />, [])
const editor = useMemo( const editor = useMemo(
() => withLayout(withHistory(withReact(createEditor()))), () => withLayout(withHistory(withReact(createEditor()))),
[] []
) )
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
renderElement={renderElement} renderElement={renderElement}
placeholder="Enter a title…" placeholder="Enter a title…"

View File

@@ -1,4 +1,4 @@
import React, { useState, useMemo, useRef, useEffect } from 'react' import React, { useMemo, useRef, useEffect } from 'react'
import { Slate, Editable, withReact, useSlate, useFocused } from 'slate-react' import { Slate, Editable, withReact, useSlate, useFocused } from 'slate-react'
import { import {
Editor, Editor,
@@ -14,11 +14,10 @@ import { withHistory } from 'slate-history'
import { Button, Icon, Menu, Portal } from '../components' import { Button, Icon, Menu, Portal } from '../components'
const HoveringMenuExample = () => { const HoveringMenuExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const editor = useMemo(() => withHistory(withReact(createEditor())), []) const editor = useMemo(() => withHistory(withReact(createEditor())), [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<HoveringToolbar /> <HoveringToolbar />
<Editable <Editable
renderLeaf={props => <Leaf {...props} />} renderLeaf={props => <Leaf {...props} />}

View File

@@ -1,4 +1,4 @@
import React, { useState, useMemo, useCallback } from 'react' import React, { useMemo, useCallback } from 'react'
import faker from 'faker' import faker from 'faker'
import { createEditor, Descendant } from 'slate' import { createEditor, Descendant } from 'slate'
import { Slate, Editable, withReact } from 'slate-react' import { Slate, Editable, withReact } from 'slate-react'
@@ -22,11 +22,10 @@ for (let h = 0; h < HEADINGS; h++) {
} }
const HugeDocumentExample = () => { const HugeDocumentExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const renderElement = useCallback(props => <Element {...props} />, []) const renderElement = useCallback(props => <Element {...props} />, [])
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable renderElement={renderElement} spellCheck autoFocus /> <Editable renderElement={renderElement} spellCheck autoFocus />
</Slate> </Slate>
) )

View File

@@ -15,7 +15,6 @@ const HOTKEYS = {
} }
const IFrameExample = () => { const IFrameExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const renderElement = useCallback( const renderElement = useCallback(
({ attributes, children }) => <p {...attributes}>{children}</p>, ({ attributes, children }) => <p {...attributes}>{children}</p>,
[] []
@@ -26,7 +25,7 @@ const IFrameExample = () => {
const handleBlur = useCallback(() => ReactEditor.deselect(editor), [editor]) const handleBlur = useCallback(() => ReactEditor.deselect(editor), [editor])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Toolbar> <Toolbar>
<MarkButton format="bold" icon="format_bold" /> <MarkButton format="bold" icon="format_bold" />
<MarkButton format="italic" icon="format_italic" /> <MarkButton format="italic" icon="format_italic" />

View File

@@ -1,4 +1,4 @@
import React, { useState, useMemo } from 'react' import React, { useMemo } from 'react'
import imageExtensions from 'image-extensions' import imageExtensions from 'image-extensions'
import isUrl from 'is-url' import isUrl from 'is-url'
import { Transforms, createEditor, Descendant } from 'slate' import { Transforms, createEditor, Descendant } from 'slate'
@@ -18,14 +18,13 @@ import { Button, Icon, Toolbar } from '../components'
import { ImageElement } from './custom-types' import { ImageElement } from './custom-types'
const ImagesExample = () => { const ImagesExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const editor = useMemo( const editor = useMemo(
() => withImages(withHistory(withReact(createEditor()))), () => withImages(withHistory(withReact(createEditor()))),
[] []
) )
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Toolbar> <Toolbar>
<InsertImageButton /> <InsertImageButton />
</Toolbar> </Toolbar>

View File

@@ -1,4 +1,4 @@
import React, { useState, useMemo } from 'react' import React, { useMemo } from 'react'
import isUrl from 'is-url' import isUrl from 'is-url'
import { isKeyHotkey } from 'is-hotkey' import { isKeyHotkey } from 'is-hotkey'
import { css } from '@emotion/css' import { css } from '@emotion/css'
@@ -61,7 +61,6 @@ const initialValue: Descendant[] = [
}, },
] ]
const InlinesExample = () => { const InlinesExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const editor = useMemo( const editor = useMemo(
() => withInlines(withHistory(withReact(createEditor()))), () => withInlines(withHistory(withReact(createEditor()))),
[] []
@@ -92,11 +91,7 @@ const InlinesExample = () => {
} }
return ( return (
<SlateReact.Slate <SlateReact.Slate editor={editor} value={initialValue}>
editor={editor}
value={value}
onChange={value => setValue(value)}
>
<Toolbar> <Toolbar>
<AddLinkButton /> <AddLinkButton />
<RemoveLinkButton /> <RemoveLinkButton />

View File

@@ -1,7 +1,7 @@
import Prism from 'prismjs' import Prism from 'prismjs'
import React, { useState, useCallback, useMemo } from 'react' import React, { useCallback, useMemo } from 'react'
import { Slate, Editable, withReact } from 'slate-react' import { Slate, Editable, withReact } from 'slate-react'
import { Text, createEditor, Element, Descendant } from 'slate' import { Text, createEditor, Descendant } from 'slate'
import { withHistory } from 'slate-history' import { withHistory } from 'slate-history'
import { css } from '@emotion/css' import { css } from '@emotion/css'
@@ -9,7 +9,6 @@ import { css } from '@emotion/css'
;Prism.languages.markdown=Prism.languages.extend("markup",{}),Prism.languages.insertBefore("markdown","prolog",{blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},code:[{pattern:/^(?: {4}|\t).+/m,alias:"keyword"},{pattern:/``.+?``|`[^`\n]+`/,alias:"keyword"}],title:[{pattern:/\w+.*(?:\r?\n|\r)(?:==+|--+)/,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#+.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])([\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:/(^|[^\\])(\*\*|__)(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^\*\*|^__|\*\*$|__$/}},italic:{pattern:/(^|[^\\])([*_])(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^[*_]|[*_]$/}},url:{pattern:/!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[[^\]\n]*\])/,inside:{variable:{pattern:/(!?\[)[^\]]+(?=\]$)/,lookbehind:!0},string:{pattern:/"(?:\\.|[^"\\])*"(?=\)$)/}}}}),Prism.languages.markdown.bold.inside.url=Prism.util.clone(Prism.languages.markdown.url),Prism.languages.markdown.italic.inside.url=Prism.util.clone(Prism.languages.markdown.url),Prism.languages.markdown.bold.inside.italic=Prism.util.clone(Prism.languages.markdown.italic),Prism.languages.markdown.italic.inside.bold=Prism.util.clone(Prism.languages.markdown.bold); // prettier-ignore ;Prism.languages.markdown=Prism.languages.extend("markup",{}),Prism.languages.insertBefore("markdown","prolog",{blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},code:[{pattern:/^(?: {4}|\t).+/m,alias:"keyword"},{pattern:/``.+?``|`[^`\n]+`/,alias:"keyword"}],title:[{pattern:/\w+.*(?:\r?\n|\r)(?:==+|--+)/,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#+.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])([\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:/(^|[^\\])(\*\*|__)(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^\*\*|^__|\*\*$|__$/}},italic:{pattern:/(^|[^\\])([*_])(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^[*_]|[*_]$/}},url:{pattern:/!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[[^\]\n]*\])/,inside:{variable:{pattern:/(!?\[)[^\]]+(?=\]$)/,lookbehind:!0},string:{pattern:/"(?:\\.|[^"\\])*"(?=\)$)/}}}}),Prism.languages.markdown.bold.inside.url=Prism.util.clone(Prism.languages.markdown.url),Prism.languages.markdown.italic.inside.url=Prism.util.clone(Prism.languages.markdown.url),Prism.languages.markdown.bold.inside.italic=Prism.util.clone(Prism.languages.markdown.italic),Prism.languages.markdown.italic.inside.bold=Prism.util.clone(Prism.languages.markdown.bold); // prettier-ignore
const MarkdownPreviewExample = () => { const MarkdownPreviewExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const renderLeaf = useCallback(props => <Leaf {...props} />, []) const renderLeaf = useCallback(props => <Leaf {...props} />, [])
const editor = useMemo(() => withHistory(withReact(createEditor())), []) const editor = useMemo(() => withHistory(withReact(createEditor())), [])
const decorate = useCallback(([node, path]) => { const decorate = useCallback(([node, path]) => {
@@ -51,7 +50,7 @@ const MarkdownPreviewExample = () => {
}, []) }, [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
decorate={decorate} decorate={decorate}
renderLeaf={renderLeaf} renderLeaf={renderLeaf}

View File

@@ -1,4 +1,4 @@
import React, { useState, useCallback, useMemo } from 'react' import React, { useCallback, useMemo } from 'react'
import { Slate, Editable, withReact } from 'slate-react' import { Slate, Editable, withReact } from 'slate-react'
import { import {
Editor, Editor,
@@ -26,14 +26,13 @@ const SHORTCUTS = {
} }
const MarkdownShortcutsExample = () => { const MarkdownShortcutsExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const renderElement = useCallback(props => <Element {...props} />, []) const renderElement = useCallback(props => <Element {...props} />, [])
const editor = useMemo( const editor = useMemo(
() => withShortcuts(withReact(withHistory(createEditor()))), () => withShortcuts(withReact(withHistory(createEditor()))),
[] []
) )
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
renderElement={renderElement} renderElement={renderElement}
placeholder="Write some markdown..." placeholder="Write some markdown..."

View File

@@ -15,7 +15,6 @@ import { MentionElement } from './custom-types'
const MentionExample = () => { const MentionExample = () => {
const ref = useRef<HTMLDivElement | null>() const ref = useRef<HTMLDivElement | null>()
const [value, setValue] = useState<Descendant[]>(initialValue)
const [target, setTarget] = useState<Range | undefined>() const [target, setTarget] = useState<Range | undefined>()
const [index, setIndex] = useState(0) const [index, setIndex] = useState(0)
const [search, setSearch] = useState('') const [search, setSearch] = useState('')
@@ -73,9 +72,8 @@ const MentionExample = () => {
return ( return (
<Slate <Slate
editor={editor} editor={editor}
value={value} value={initialValue}
onChange={value => { onChange={() => {
setValue(value)
const { selection } = editor const { selection } = editor
if (selection && Range.isCollapsed(selection)) { if (selection && Range.isCollapsed(selection)) {

View File

@@ -1,4 +1,4 @@
import React, { useState, useCallback, useMemo } from 'react' import React, { useCallback, useMemo } from 'react'
import { jsx } from 'slate-hyperscript' import { jsx } from 'slate-hyperscript'
import { Transforms, createEditor, Descendant } from 'slate' import { Transforms, createEditor, Descendant } from 'slate'
import { withHistory } from 'slate-history' import { withHistory } from 'slate-history'
@@ -84,7 +84,6 @@ export const deserialize = el => {
} }
const PasteHtmlExample = () => { const PasteHtmlExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const renderElement = useCallback(props => <Element {...props} />, []) const renderElement = useCallback(props => <Element {...props} />, [])
const renderLeaf = useCallback(props => <Leaf {...props} />, []) const renderLeaf = useCallback(props => <Leaf {...props} />, [])
const editor = useMemo( const editor = useMemo(
@@ -92,7 +91,7 @@ const PasteHtmlExample = () => {
[] []
) )
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable <Editable
renderElement={renderElement} renderElement={renderElement}
renderLeaf={renderLeaf} renderLeaf={renderLeaf}

View File

@@ -1,13 +1,12 @@
import React, { useState, useMemo } from 'react' import React, { useMemo } from 'react'
import { createEditor, Descendant } from 'slate' import { createEditor, Descendant } from 'slate'
import { Slate, Editable, withReact } from 'slate-react' import { Slate, Editable, withReact } from 'slate-react'
import { withHistory } from 'slate-history' import { withHistory } from 'slate-history'
const PlainTextExample = () => { const PlainTextExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const editor = useMemo(() => withHistory(withReact(createEditor())), []) const editor = useMemo(() => withHistory(withReact(createEditor())), [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable placeholder="Enter some plain text..." /> <Editable placeholder="Enter some plain text..." />
</Slate> </Slate>
) )

View File

@@ -1,12 +1,11 @@
import React, { useState, useMemo } from 'react' import React, { useMemo } from 'react'
import { createEditor, Descendant, Element } from 'slate' import { createEditor, Descendant } from 'slate'
import { Slate, Editable, withReact } from 'slate-react' import { Slate, Editable, withReact } from 'slate-react'
const ReadOnlyExample = () => { const ReadOnlyExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const editor = useMemo(() => withReact(createEditor()), []) const editor = useMemo(() => withReact(createEditor()), [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable readOnly placeholder="Enter some plain text..." /> <Editable readOnly placeholder="Enter some plain text..." />
</Slate> </Slate>
) )

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useMemo, useState } from 'react' import React, { useCallback, useMemo } from 'react'
import isHotkey from 'is-hotkey' import isHotkey from 'is-hotkey'
import { Editable, withReact, useSlate, Slate } from 'slate-react' import { Editable, withReact, useSlate, Slate } from 'slate-react'
import { import {
@@ -23,13 +23,12 @@ const LIST_TYPES = ['numbered-list', 'bulleted-list']
const TEXT_ALIGN_TYPES = ['left', 'center', 'right', 'justify'] const TEXT_ALIGN_TYPES = ['left', 'center', 'right', 'justify']
const RichTextExample = () => { const RichTextExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const renderElement = useCallback(props => <Element {...props} />, []) const renderElement = useCallback(props => <Element {...props} />, [])
const renderLeaf = useCallback(props => <Leaf {...props} />, []) const renderLeaf = useCallback(props => <Leaf {...props} />, [])
const editor = useMemo(() => withHistory(withReact(createEditor())), []) const editor = useMemo(() => withHistory(withReact(createEditor())), [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Toolbar> <Toolbar>
<MarkButton format="bold" icon="format_bold" /> <MarkButton format="bold" icon="format_bold" />
<MarkButton format="italic" icon="format_italic" /> <MarkButton format="italic" icon="format_italic" />

View File

@@ -1,4 +1,4 @@
import React, { useState, useMemo } from 'react' import React, { useMemo } from 'react'
import { createEditor, Descendant } from 'slate' import { createEditor, Descendant } from 'slate'
import { Slate, Editable, withReact } from 'slate-react' import { Slate, Editable, withReact } from 'slate-react'
import { withHistory } from 'slate-history' import { withHistory } from 'slate-history'
@@ -49,10 +49,9 @@ const ScrollIntoViewExample = () => {
} }
const PlainTextEditor = () => { const PlainTextEditor = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const editor = useMemo(() => withHistory(withReact(createEditor())), []) const editor = useMemo(() => withHistory(withReact(createEditor())), [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable placeholder="Enter some plain text..." /> <Editable placeholder="Enter some plain text..." />
</Slate> </Slate>
) )

View File

@@ -7,7 +7,6 @@ import { withHistory } from 'slate-history'
import { Icon, Toolbar } from '../components' import { Icon, Toolbar } from '../components'
const SearchHighlightingExample = () => { const SearchHighlightingExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const [search, setSearch] = useState<string | undefined>() const [search, setSearch] = useState<string | undefined>()
const editor = useMemo(() => withHistory(withReact(createEditor())), []) const editor = useMemo(() => withHistory(withReact(createEditor())), [])
const decorate = useCallback( const decorate = useCallback(
@@ -38,7 +37,7 @@ const SearchHighlightingExample = () => {
) )
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Toolbar> <Toolbar>
<div <div
className={css` className={css`

View File

@@ -1,5 +1,5 @@
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import React, { useState, useMemo, useRef, useEffect } from 'react' import React, { useMemo, useRef, useEffect } from 'react'
import { createEditor, Descendant } from 'slate' import { createEditor, Descendant } from 'slate'
import { Slate, Editable, withReact } from 'slate-react' import { Slate, Editable, withReact } from 'slate-react'
import { withHistory } from 'slate-history' import { withHistory } from 'slate-history'
@@ -28,11 +28,10 @@ const ShadowDOM = () => {
} }
const ShadowEditor = () => { const ShadowEditor = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const editor = useMemo(() => withHistory(withReact(createEditor())), []) const editor = useMemo(() => withHistory(withReact(createEditor())), [])
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable placeholder="Enter some plain text..." /> <Editable placeholder="Enter some plain text..." />
</Slate> </Slate>
) )

View File

@@ -1,4 +1,4 @@
import React, { useState, useCallback, useMemo } from 'react' import React, { useCallback, useMemo } from 'react'
import { Slate, Editable, withReact } from 'slate-react' import { Slate, Editable, withReact } from 'slate-react'
import { import {
Editor, Editor,
@@ -11,7 +11,6 @@ import {
import { withHistory } from 'slate-history' import { withHistory } from 'slate-history'
const TablesExample = () => { const TablesExample = () => {
const [value, setValue] = useState<Descendant[]>(initialValue)
const renderElement = useCallback(props => <Element {...props} />, []) const renderElement = useCallback(props => <Element {...props} />, [])
const renderLeaf = useCallback(props => <Leaf {...props} />, []) const renderLeaf = useCallback(props => <Leaf {...props} />, [])
const editor = useMemo( const editor = useMemo(
@@ -19,7 +18,7 @@ const TablesExample = () => {
[] []
) )
return ( return (
<Slate editor={editor} value={value} onChange={value => setValue(value)}> <Slate editor={editor} value={initialValue}>
<Editable renderElement={renderElement} renderLeaf={renderLeaf} /> <Editable renderElement={renderElement} renderLeaf={renderLeaf} />
</Slate> </Slate>
) )