1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-09-02 11:42:53 +02:00

update walkthroughs

This commit is contained in:
Ian Storm Taylor
2019-12-06 12:06:53 -05:00
parent 624c03339b
commit be8b7222ee
6 changed files with 370 additions and 99 deletions

View File

@@ -16,8 +16,6 @@ _Note, if you'd rather use a pre-bundled version of Slate, you can `yarn add sla
Once you've installed Slate, you'll need to import it.
Slate exposes a set of modules that you'll use to build your editor. The most important of which are the `Editor` class and the `<Editable>` component.
```js
// Import the Slate editor factory.
import { createEditor } from 'slate'
@@ -47,19 +45,44 @@ const App = () => {
Of course we haven't rendered anything, so you won't see any changes.
Next up is to render a `<Slate>` context provider.
The provider component keeps track of your Slate editor, its plugins, its default value, 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.
Next we want to create state for `value` and `selection`:
```jsx
const App = () => {
const editor = useMemo(() => withReact(createEditor()), [])
// Render the Slate editor context.
return <Slate editor={editor} />
// Keep track of state for the value and selection of the editor.
const [value, setValue] = useState([])
const [selection, setSelection] = useState(null)
return null
}
```
You can think of the `<Slate>` component as provided an "un-controlled" editor context to every component underneath it.
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.
```jsx
const App = () => {
const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([])
const [selection, setSelection] = useState(null)
// Render the Slate context.
return (
<Slate
editor={editor}
value={value}
selection={selection}
onChange={(value, selection) => {
setValue(value)
setSelection(selection)
}}
/>
)
}
```
You can think of the `<Slate>` component as providing a "controlled" context to every component underneath it.
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.
@@ -70,9 +93,19 @@ Okay, so the next step is to render the `<Editable>` component itself:
```jsx
const App = () => {
const editor = useMemo(() => withReact(createEditor()), [])
const [value, setValue] = useState([])
const [selection, setSelection] = useState(null)
return (
// Add the editable component inside the context.
<Slate editor={editor}>
<Slate
editor={editor}
value={value}
selection={selection}
onChange={(value, selection) => {
setValue(value)
setSelection(selection)
}}
>
<Editable />
</Slate>
)
@@ -81,28 +114,32 @@ const App = () => {
The `<Editable>` component acts like `contenteditable`. Anywhere you render it will render an editable richtext document for the nearest editor context.
There's only one last step. So far we haven't defined what the default value of the editor is, so it's empty. Let's fix that by defining an initial value.
There's only one last step. So far we've been using an empty `[]` array as the initial value of the editor, so it has no content. Let's fix that by defining an initial value.
The value is just plain JSON. Here's one containing a single paragraph block with some text in it:
```js
// Create our default value...
const defaultValue = [
{
type: 'paragraph',
children: [
{
text: 'A line of text in a paragraph.',
},
],
},
]
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([
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
])
return (
// Add the default value as a prop to the editor context.
<Slate editor={editor} defaultValue={defaultValue}>
<Slate
editor={editor}
value={value}
selection={selection}
onChange={(value, selection) => {
setValue(value)
setSelection(selection)
}}
>
<Editable />
</Slate>
)
@@ -112,5 +149,3 @@ const App = () => {
There you have it!
That's the most basic example of Slate. If you render that onto the page, you should see a paragraph with the text `A line of text in a paragraph.`. And when you type, you should see the text change!
You'll notice that there is no `onChange` handler defined. That's because the `<Slate>` context acts like an **un-controlled** component, with the changes automatically being propagated to any context consumers. However, just like with un-controlled components you can attach an `onChange` prop to listen for changes. We'll cover that later.