mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-09-02 11:42:53 +02:00
@@ -12,8 +12,6 @@ The top-level React component that renders the Slate editor itself.
|
|||||||
- [`autoFocus`](#autofocus)
|
- [`autoFocus`](#autofocus)
|
||||||
- [`className`](#classname)
|
- [`className`](#classname)
|
||||||
- [`onChange`](#onchange)
|
- [`onChange`](#onchange)
|
||||||
- [`onDocumentChange`](#ondocumentchange)
|
|
||||||
- [`onSelectionChange`](#onselectionchange)
|
|
||||||
- [`plugins`](#plugins)
|
- [`plugins`](#plugins)
|
||||||
- [`readOnly`](#readonly)
|
- [`readOnly`](#readonly)
|
||||||
- [`role`](#role)
|
- [`role`](#role)
|
||||||
@@ -53,8 +51,6 @@ The top-level React component that renders the Slate editor itself.
|
|||||||
autoFocus={Boolean}
|
autoFocus={Boolean}
|
||||||
className={String}
|
className={String}
|
||||||
onChange={Function}
|
onChange={Function}
|
||||||
onDocumentChange={Function}
|
|
||||||
onSelectionChange={Function}
|
|
||||||
plugins={Array}
|
plugins={Array}
|
||||||
readOnly={Boolean}
|
readOnly={Boolean}
|
||||||
role={String}
|
role={String}
|
||||||
@@ -85,16 +81,6 @@ An optional class name to apply to the content editable element.
|
|||||||
|
|
||||||
A change handler that will be called with the `change` that applied the change. You should usually pass the newly changed `change.state` back into the editor through its `state` property. This hook allows you to add persistence logic to your editor.
|
A change handler that will be called with the `change` that applied the change. You should usually pass the newly changed `change.state` back into the editor through its `state` property. This hook allows you to add persistence logic to your editor.
|
||||||
|
|
||||||
### `onDocumentChange`
|
|
||||||
`Function onDocumentChange(document: Document, change: Change)`
|
|
||||||
|
|
||||||
A convenience handler property that will only be called for changes in state where the document has changed. It is called with the changed `document` and `change`.
|
|
||||||
|
|
||||||
### `onSelectionChange`
|
|
||||||
`Function onSelectionChange(selection: Selection, change: Change)`
|
|
||||||
|
|
||||||
A convenience handler property that will only be called for changes in state where the selection has changed. It is called with the changed `selection` and `change`.
|
|
||||||
|
|
||||||
### `plugins`
|
### `plugins`
|
||||||
`Array`
|
`Array`
|
||||||
|
|
||||||
|
@@ -202,7 +202,7 @@ The `data` object contains a State [`Selection`](../models/selection.md) object
|
|||||||
|
|
||||||
If no other plugin handles this event, it will be handled by the [Core plugin](./core.md).
|
If no other plugin handles this event, it will be handled by the [Core plugin](./core.md).
|
||||||
|
|
||||||
_Note: This is **not** Slate's internal selection representation (although it mirrors it). If you want to get notified when Slate's selection changes, use the [`onSelectionChange`](../components/editor.md#onselectionchange) property of the `<Editor>`. This handler is instead meant to give you lower-level access to the DOM selection handling, which **is not always triggered** as you'd expect._
|
_Note: This is **not** Slate's internal selection representation (although it mirrors it). If you want to get notified when Slate's selection changes, use the [`onChange`](../components/editor.md#onchange) property of the `<Editor>`. This handler is instead meant to give you lower-level access to the DOM selection handling, which **is not always triggered** as you'd expect._
|
||||||
|
|
||||||
|
|
||||||
## Other Properties
|
## Other Properties
|
||||||
|
@@ -239,23 +239,21 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onChange = ({ state }) => {
|
onChange = ({ state }) => {
|
||||||
|
// When the document changes, save the serialized HTML to Local Storage.
|
||||||
|
if (state.document != this.state.state.document) {
|
||||||
|
const string = html.serialize(state)
|
||||||
|
localStorage.setItem('content', string)
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({ state })
|
this.setState({ state })
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the document changes, save the serialized HTML to Local Storage.
|
|
||||||
onDocumentChange = (document, { state }) => {
|
|
||||||
const string = html.serialize(state)
|
|
||||||
localStorage.setItem('content', string)
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// Add the `onDocumentChange` handler.
|
|
||||||
return (
|
return (
|
||||||
<Editor
|
<Editor
|
||||||
schema={this.state.schema}
|
schema={this.state.schema}
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
onChange={this.onChange}
|
onChange={this.onChange}
|
||||||
onDocumentChange={this.onDocumentChange}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -56,11 +56,11 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onChange = ({ state }) => {
|
onChange = ({ state }) => {
|
||||||
this.setState({ state })
|
|
||||||
|
|
||||||
// Save the state to Local Storage.
|
// Save the state to Local Storage.
|
||||||
const content = Plain.serialize(state)
|
const content = Plain.serialize(state)
|
||||||
localStorage.setItem('content', content)
|
localStorage.setItem('content', content)
|
||||||
|
|
||||||
|
this.setState({ state })
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -93,10 +93,10 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onChange = ({ state }) => {
|
onChange = ({ state }) => {
|
||||||
this.setState({ state })
|
|
||||||
|
|
||||||
const content = Plain.serialize(state)
|
const content = Plain.serialize(state)
|
||||||
localStorage.setItem('content', content)
|
localStorage.setItem('content', content)
|
||||||
|
|
||||||
|
this.setState({ state })
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -113,9 +113,7 @@ class App extends React.Component {
|
|||||||
|
|
||||||
Now you should be able to save changes across refreshes!
|
Now you should be able to save changes across refreshes!
|
||||||
|
|
||||||
However, if you inspect the change handler, you'll notice that it's actually saving the Local Storage value on _every_ change to the editor, even when only the selection changes! This is because `onChange` is called for _every_ change. For Local Storage this doesn't really matter, but if you're saving things to a database via HTTP request this would result in a lot of unnecessary requests.
|
However, if you inspect the change handler, you'll notice that it's actually saving the Local Storage value on _every_ change to the editor, even when only the selection changes! This is because `onChange` is called for _every_ change. For Local Storage this doesn't really matter, but if you're saving things to a database via HTTP request this would result in a lot of unnecessary requests. You can fix this by checking against the previous `document` value.
|
||||||
|
|
||||||
Instead of using `onChange`, Slate's editor also accepts an `onDocumentChange` convenience handler that you can use to isolate saving logic to only happen when the document itself has changed, like so:
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const initialContent = (
|
const initialContent = (
|
||||||
@@ -129,22 +127,20 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onChange = ({ state }) => {
|
onChange = ({ state }) => {
|
||||||
|
// Check to see if the document has changed before saving.
|
||||||
|
if (state.document != this.state.state.document) {
|
||||||
|
const content = Plain.serialize(state)
|
||||||
|
localStorage.setItem('content', content)
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({ state })
|
this.setState({ state })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull the saving logic out into the `onDocumentChange` handler.
|
|
||||||
onDocumentChange = (document, { state }) => {
|
|
||||||
const content = Plain.serialize(state)
|
|
||||||
localStorage.setItem('content', content)
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// Add the `onDocumentChange` handler to the editor.
|
|
||||||
return (
|
return (
|
||||||
<Editor
|
<Editor
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
onChange={this.onChange}
|
onChange={this.onChange}
|
||||||
onDocumentChange={this.onDocumentChange}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -177,13 +173,13 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onChange = ({ state }) => {
|
onChange = ({ state }) => {
|
||||||
this.setState({ state })
|
if (state.document != this.state.state.document) {
|
||||||
}
|
// Switch to using the Raw serializer.
|
||||||
|
const content = JSON.stringify(Raw.serialize(state))
|
||||||
|
localStorage.setItem('content', content)
|
||||||
|
}
|
||||||
|
|
||||||
onDocumentChange = (document, { state }) => {
|
this.setState({ state })
|
||||||
// Switch to using the Raw serializer.
|
|
||||||
const content = JSON.stringify(Raw.serialize(state))
|
|
||||||
localStorage.setItem('content', content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -191,7 +187,6 @@ class App extends React.Component {
|
|||||||
<Editor
|
<Editor
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
onChange={this.onChange}
|
onChange={this.onChange}
|
||||||
onDocumentChange={this.onDocumentChange}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@ import Types from 'prop-types'
|
|||||||
import Stack from '../models/stack'
|
import Stack from '../models/stack'
|
||||||
import State from '../models/state'
|
import State from '../models/state'
|
||||||
import SlateTypes from '../utils/prop-types'
|
import SlateTypes from '../utils/prop-types'
|
||||||
|
import logger from '../utils/logger'
|
||||||
import noop from '../utils/noop'
|
import noop from '../utils/noop'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,8 +72,6 @@ class Editor extends React.Component {
|
|||||||
className: Types.string,
|
className: Types.string,
|
||||||
onBeforeChange: Types.func,
|
onBeforeChange: Types.func,
|
||||||
onChange: Types.func,
|
onChange: Types.func,
|
||||||
onDocumentChange: Types.func,
|
|
||||||
onSelectionChange: Types.func,
|
|
||||||
placeholder: Types.any,
|
placeholder: Types.any,
|
||||||
placeholderClassName: Types.string,
|
placeholderClassName: Types.string,
|
||||||
placeholderStyle: Types.object,
|
placeholderStyle: Types.object,
|
||||||
@@ -96,8 +95,6 @@ class Editor extends React.Component {
|
|||||||
autoFocus: false,
|
autoFocus: false,
|
||||||
autoCorrect: true,
|
autoCorrect: true,
|
||||||
onChange: noop,
|
onChange: noop,
|
||||||
onDocumentChange: noop,
|
|
||||||
onSelectionChange: noop,
|
|
||||||
plugins: [],
|
plugins: [],
|
||||||
readOnly: false,
|
readOnly: false,
|
||||||
schema: {},
|
schema: {},
|
||||||
@@ -137,6 +134,14 @@ class Editor extends React.Component {
|
|||||||
this.onChange(change)
|
this.onChange(change)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (props.onDocumentChange) {
|
||||||
|
logger.deprecate('0.22.10', 'The `onDocumentChange` prop is deprecated because it led to confusing UX issues, see https://github.com/ianstormtaylor/slate/issues/614#issuecomment-327868679')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.onSelectionChange) {
|
||||||
|
logger.deprecate('0.22.10', 'The `onSelectionChange` prop is deprecated because it led to confusing UX issues, see https://github.com/ianstormtaylor/slate/issues/614#issuecomment-327868679')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -239,8 +244,8 @@ class Editor extends React.Component {
|
|||||||
if (state == this.state.state) return
|
if (state == this.state.state) return
|
||||||
|
|
||||||
onChange(change)
|
onChange(change)
|
||||||
if (state.document != document) onDocumentChange(state.document, change)
|
if (onDocumentChange && state.document != document) onDocumentChange(state.document, change)
|
||||||
if (state.selection != selection) onSelectionChange(state.selection, change)
|
if (onSelectionChange && state.selection != selection) onSelectionChange(state.selection, change)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user