1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-28 09:29:49 +02:00

Update walkthrough docs to use change object instead of state (#1062)

This commit is contained in:
David Gertmenian-Wong
2017-09-06 17:51:40 -07:00
committed by Ian Storm Taylor
parent c0b4a30ce6
commit a75899f57a
6 changed files with 89 additions and 123 deletions

View File

@@ -20,7 +20,7 @@ class App extends React.Component {
state: initialState state: initialState
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
@@ -44,13 +44,13 @@ class App extends React.Component {
state = { state = {
state: initialState state: initialState
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
// Define a new handler which prints the key code that was pressed. // Define a new handler which prints the key code that was pressed.
onKeyDown = (event, data, state) => { onKeyDown = (event, data, change) => {
console.log(event.which) console.log(event.which)
} }
@@ -67,9 +67,9 @@ class App extends React.Component {
} }
``` ```
Okay cool, so now when you press a key in the editor, you'll see the key's code printed to the console. Not very useful, but at least we know it's working. Okay cool, so now when you press a key in the editor, you'll see the key's code printed to the console. Not very useful, but at least we know it's working.
Now we want to make it actually change the content. For the purposes of our example, let's say we want to make it so that whenever a user types `&` we actually add `and` to the content. Now we want to make it actually change the content. For the purposes of our example, let's say we want to make it so that whenever a user types `&` we actually add `and` to the content.
Our `onKeyDown` handler might look like this: Our `onKeyDown` handler might look like this:
@@ -79,26 +79,21 @@ class App extends React.Component {
state = { state = {
state: initialState state: initialState
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, state) => { onKeyDown = (event, data, change) => {
// Return with no changes if it's not the "7" key with shift pressed. // Return with no changes if it's not the "7" key with shift pressed.
if (event.which != 55 || !event.shiftKey) return if (event.which != 55 || !event.shiftKey) return
// Prevent the ampersand character from being inserted. // Prevent the ampersand character from being inserted.
event.preventDefault() event.preventDefault()
// Change the state by inserting "and" at the cursor's position. // Change the state by inserting "and" at the cursor's position.
const newState = state change.insertText('and')
.change() return true
.insertText('and')
.apply()
// Return the new state, which will cause the editor to update it.
return newState
} }
render() { render() {

View File

@@ -22,20 +22,18 @@ class App extends React.Component {
} }
} }
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, state) => { onKeyDown = (event, data, change) => {
if (event.which != 67 || !event.metaKey || !event.altKey) return if (event.which != 67 || !event.metaKey || !event.altKey) return
event.preventDefault() event.preventDefault()
const isCode = state.blocks.some(block => block.type == 'code') const isCode = change.state.blocks.some(block => block.type == 'code')
return state change.setBlock(isCode ? 'paragraph' : 'code')
.change() return true
.setBlock(isCode ? 'paragraph' : 'code')
.apply()
} }
render() { render() {
@@ -65,12 +63,12 @@ class App extends React.Component {
} }
} }
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, state) => { onKeyDown = (event, data, change) => {
if (!event.metaKey) return if (!event.metaKey) return
// Decide what to do based on the key code... // Decide what to do based on the key code...
@@ -78,20 +76,16 @@ class App extends React.Component {
// When "B" is pressed, add a "bold" mark to the text. // When "B" is pressed, add a "bold" mark to the text.
case 66: { case 66: {
event.preventDefault() event.preventDefault()
return state change.addMark('bold')
.change() return true
.addMark('bold')
.apply()
} }
// When "`" is pressed, keep our existing code block logic. // When "`" is pressed, keep our existing code block logic.
case 67: { case 67: {
if (!event.altKey) return if (!event.altKey) return
const isCode = state.blocks.some(block => block.type == 'code') const isCode = change.state.blocks.some(block => block.type == 'code')
event.preventDefault() event.preventDefault()
return state change.setBlock(isCode ? 'paragraph' : 'code')
.change() return true
.setBlock(isCode ? 'paragraph' : 'code')
.apply()
} }
} }
} }
@@ -146,30 +140,26 @@ class App extends React.Component {
} }
} }
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, state) => { onKeyDown = (event, data, change) => {
if (!event.metaKey) return if (!event.metaKey) return
switch (event.which) { switch (event.which) {
case 66: { case 66: {
event.preventDefault() event.preventDefault()
return state change.toggleMark('bold')
.change() return true
.toggleMark('bold')
.apply()
} }
case 67: { case 67: {
if (!event.altKey) return if (!event.altKey) return
const isCode = state.blocks.some(block => block.type == 'code') const isCode = change.state.blocks.some(block => block.type == 'code')
event.preventDefault() event.preventDefault()
return state state.setBlock(isCode ? 'paragraph' : 'code')
.change() return true
.setBlock(isCode ? 'paragraph' : 'code')
.apply()
} }
} }
} }

View File

@@ -7,7 +7,7 @@
In our previous example, we started with a paragraph, but we never actually told Slate anything about the `paragraph` block type. We just let it use its internal default renderer, which uses a plain old `<div>`. In our previous example, we started with a paragraph, but we never actually told Slate anything about the `paragraph` block type. We just let it use its internal default renderer, which uses a plain old `<div>`.
But that's not all you can do. Slate lets you define any type of custom blocks you want, like block quotes, code blocks, list items, etc. But that's not all you can do. Slate lets you define any type of custom blocks you want, like block quotes, code blocks, list items, etc.
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:
@@ -17,22 +17,18 @@ class App extends React.Component {
state = { state = {
state: initialState state: initialState
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, state) => { onKeyDown = (event, data, change) => {
if (event.which != 55 || !event.shiftKey) return if (event.which != 55 || !event.shiftKey) return
event.preventDefault() event.preventDefault()
const newState = state change.insertText('and');
.change() return true
.insertText('and')
.apply()
return newState
} }
render() { render() {
@@ -61,7 +57,7 @@ function CodeNode(props) {
} }
``` ```
Pretty simple. Pretty simple.
See the `props.attributes` reference? Slate passes attributes that should be rendered on the top-most element of your blocks, so that you don't have to build them up yourself. You **must** mix the attributes into your component. See the `props.attributes` reference? Slate passes attributes that should be rendered on the top-most element of your blocks, so that you don't have to build them up yourself. You **must** mix the attributes into your component.
@@ -85,22 +81,18 @@ class App extends React.Component {
} }
} }
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, state) => { onKeyDown = (event, data, change) => {
if (event.which != 55 || !event.shiftKey) return if (event.which != 55 || !event.shiftKey) return
event.preventDefault() event.preventDefault()
const newState = state change.insertText('and')
.change() return true
.insertText('and')
.apply()
return newState
} }
render() { render() {
@@ -135,23 +127,21 @@ class App extends React.Component {
} }
} }
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, state) => { onKeyDown = (event, data, change) => {
// Return with no changes if it's not the "`" key with cmd/ctrl pressed. // Return with no changes if it's not the "`" key with cmd/ctrl pressed.
if (event.which != 67 || !event.metaKey || !event.altKey) return if (event.which != 67 || !event.metaKey || !event.altKey) return
// Prevent the "`" from being inserted by default. // Prevent the "`" from being inserted by default.
event.preventDefault() event.preventDefault()
// Otherwise, set the currently selected blocks type to "code". // Otherwise, set the currently selected blocks type to "code".
return state change.setBlock('code')
.change() return true
.setBlock('code')
.apply()
} }
render() { render() {
@@ -187,25 +177,22 @@ class App extends React.Component {
} }
} }
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, state) => { onKeyDown = (event, data, change) => {
if (event.which != 67 || !event.metaKey || !event.altKey) return if (event.which != 67 || !event.metaKey || !event.altKey) return
event.preventDefault() event.preventDefault()
// Determine whether any of the currently selected blocks are code blocks. // Determine whether any of the currently selected blocks are code blocks.
const isCode = state.blocks.some(block => block.type == 'code') const isCode = change.state.blocks.some(block => block.type == 'code')
// Toggle the block type depending on `isCode`. // Toggle the block type depending on `isCode`.
return state change.setBlock(isCode ? 'paragraph' : 'code')
.change() return true
.setBlock(isCode ? 'paragraph' : 'code')
.apply()
} }
render() { render() {

View File

@@ -20,7 +20,7 @@ class App extends React.Component {
state: Plain.deserialize('') state: Plain.deserialize('')
} }
onChange(state) { onChange({ state }) {
this.setState({ state }) this.setState({ state })
} }
@@ -238,12 +238,12 @@ class App extends React.Component {
} }
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
// When the document changes, save the serialized HTML to Local Storage. // When the document changes, save the serialized HTML to Local Storage.
onDocumentChange = (document, state) => { onDocumentChange = (document, { state }) => {
const string = html.serialize(state) const string = html.serialize(state)
localStorage.setItem('content', string) localStorage.setItem('content', string)
} }

View File

@@ -21,8 +21,8 @@ class App extends React.Component {
state = { state = {
state: Plain.deserialize(initialContent) state: Plain.deserialize(initialContent)
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
@@ -55,7 +55,7 @@ class App extends React.Component {
state: Plain.deserialize(initialContent) state: Plain.deserialize(initialContent)
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
// Save the state to Local Storage. // Save the state to Local Storage.
@@ -92,7 +92,7 @@ class App extends React.Component {
state: Plain.deserialize(initialContent) state: Plain.deserialize(initialContent)
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
const content = Plain.serialize(state) const content = Plain.serialize(state)
@@ -128,12 +128,12 @@ class App extends React.Component {
state: Plain.deserialize(initialContent) state: Plain.deserialize(initialContent)
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
// Pull the saving logic out into the `onDocumentChange` handler. // Pull the saving logic out into the `onDocumentChange` handler.
onDocumentChange = (document, state) => { onDocumentChange = (document, { state }) => {
const content = Plain.serialize(state) const content = Plain.serialize(state)
localStorage.setItem('content', content) localStorage.setItem('content', content)
} }
@@ -176,11 +176,11 @@ class App extends React.Component {
state: Raw.deserialize(initialContent, {terse: true}) state: Raw.deserialize(initialContent, {terse: true})
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
onDocumentChange = (document, state) => { onDocumentChange = (document, { state }) => {
// Switch to using the Raw serializer. // Switch to using the Raw serializer.
const content = JSON.stringify(Raw.serialize(state)) const content = JSON.stringify(Raw.serialize(state))
localStorage.setItem('content', content) localStorage.setItem('content', content)

View File

@@ -25,17 +25,15 @@ class App extends React.Component {
} }
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, state) => { onKeyDown = (event, data, change) => {
if (!event.metaKey || event.which != 66) return if (!event.metaKey || event.which != 66) return
event.preventDefault() event.preventDefault()
return state change.toggleMark('bold')
.change() return true
.toggleMark('bold')
.apply()
} }
render() { render() {
@@ -73,7 +71,7 @@ function MarkHotkey(options) {
// Return our "plugin" object, containing the `onKeyDown` handler. // Return our "plugin" object, containing the `onKeyDown` handler.
return { return {
onKeyDown(event, data, state) { onKeyDown(event, data, change) {
// Check that the key pressed matches our `code` option. // Check that the key pressed matches our `code` option.
if (!event.metaKey || event.which != code || event.altKey != isAltKey) return if (!event.metaKey || event.which != code || event.altKey != isAltKey) return
@@ -81,10 +79,8 @@ function MarkHotkey(options) {
event.preventDefault() event.preventDefault()
// Toggle the mark `type`. // Toggle the mark `type`.
return state change.toggleMark(type)
.change() return true
.toggleMark(type)
.apply()
} }
} }
} }
@@ -101,7 +97,7 @@ function BoldMark(props) {
// Initialize our bold-mark-adding plugin. // Initialize our bold-mark-adding plugin.
const boldPlugin = MarkHotkey({ const boldPlugin = MarkHotkey({
type: 'bold', type: 'bold',
code: 66 code: 66
}) })
@@ -120,8 +116,8 @@ class App extends React.Component {
} }
} }
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
@@ -169,8 +165,8 @@ class App extends React.Component {
} }
} }
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }
@@ -215,14 +211,12 @@ function MarkHotkey(options) {
const { type, key, isAltKey = false } = options const { type, key, isAltKey = false } = options
return { return {
onKeyDown(event, data, state) { onKeyDown(event, data, change) {
// Change the comparison to use the key name. // Change the comparison to use the key name.
if (!event.metaKey || keycode(event.which) != key || event.altKey != isAltKey) return if (!event.metaKey || keycode(event.which) != key || event.altKey != isAltKey) return
event.preventDefault() event.preventDefault()
return state change.toggleMark(type)
.change() return true
.toggleMark(type)
.apply()
} }
} }
} }
@@ -254,8 +248,8 @@ class App extends React.Component {
} }
} }
} }
onChange = (state) => { onChange = ({ state }) => {
this.setState({ state }) this.setState({ state })
} }