diff --git a/docs/reference/slate-react/core-plugin.md b/docs/reference/slate-react/core-plugins.md similarity index 95% rename from docs/reference/slate-react/core-plugin.md rename to docs/reference/slate-react/core-plugins.md index 1f799b9aa..5eeb6850b 100644 --- a/docs/reference/slate-react/core-plugin.md +++ b/docs/reference/slate-react/core-plugins.md @@ -1,7 +1,7 @@ # Core Plugin -Slate's editor is very unopinionated. The only logic it handles by default is logic associated with the `contenteditable` functionality itself—managing text, selections, etc. That logic in contained in a single plugin, called the "core" plugin. +Slate's editor is very unopinionated. The only logic it handles by default is logic associated with the `contenteditable` functionality itself—managing text, selections, etc. That logic in contained in two plugin, called the "core" plugins. One runs before all other plugins, and one runs after. ## Default Behavior @@ -64,7 +64,7 @@ However, sometimes you might want to disable the logic of the core plugin withou A noop `onBeforeInput` handler looks like: ```js -function onBeforeInput(event, data, state) { +function onBeforeInput(event, state) { event.preventDefault() return state } diff --git a/docs/reference/slate-react/plugins.md b/docs/reference/slate-react/plugins.md index 8872db2c6..df25a7ec0 100644 --- a/docs/reference/slate-react/plugins.md +++ b/docs/reference/slate-react/plugins.md @@ -38,125 +38,65 @@ export default function MySlatePlugin(options) { } ``` -All of the event handler properties are passed the same React `event` object you are used to from React's event handlers. They are also passed a `data` object with Slate-specific information relating to the event, the current `change` of the editor, and the `editor` instance itself. +All of the event handler properties are passed the same React `event` object you are used to from React's event handlers. They are also passed a `change` object representing any changes that have resulted from the event, and the `editor` instance itself. -Each event handler can choose to return a new `change` object, in which case the editor's state will be updated. If nothing is returned, the editor will simply continue resolving the plugin stack. +Each event handler can choose to call methods on the `change` object, in which case the editor's state will be updated. + +If the return value of a plugin handler is `null`, the editor will simply continue resolving the plugin stack. However, if you return a non-null value, the editor will break out of the loop. ### `onBeforeInput` -`Function onBeforeInput(event: Event, data: Object, change: Change, editor: Editor) => Change || Void` +`Function onBeforeInput(event: Event, change: Change, editor: Editor) => Change || Void` This handler is called right before a string of text is inserted into the `contenteditable` element. -Make sure to `event.preventDefault()` if you do not want the default insertion behavior to occur! If no other plugin handles this event, it will be handled by the [Core plugin](./core.md). +Make sure to `event.preventDefault()` if you do not want the default insertion behavior to occur! ### `onBlur` -`Function onBlur(event: Event, data: Object, change: Change, editor: Editor) => Change || Void` +`Function onBlur(event: Event, change: Change, editor: Editor) => Change || Void` -This handler is called when the editor's `contenteditable` element is blurred. If no other plugin handles this event, it will be handled by the [Core plugin](./core.md). +This handler is called when the editor's `contenteditable` element is blurred. ### `onFocus` -`Function onFocus(event: Event, data: Object, change: Change, editor: Editor) => Change || Void` +`Function onFocus(event: Event, change: Change, editor: Editor) => Change || Void` -This handler is called when the editor's `contenteditable` element is focused. If no other plugin handles this event, it will be handled by the [Core plugin](./core.md). +This handler is called when the editor's `contenteditable` element is focused. ### `onCopy` -`Function onCopy(event: Event, data: Object, change: Change, editor: Editor) => Change || Void` +`Function onCopy(event: Event, change: Change, editor: Editor) => Change || Void` This handler is called when there is a copy event in the editor's `contenteditable` element. -The `data` object contains a `type` string and associated data for that type. Right now the only type supported is `"fragment"`: - -```js -{ - type: 'fragment', - fragment: Document -} -``` - -If no other plugin handles this event, it will be handled by the [Core plugin](./core.md). - ### `onCut` -`Function onCut(event: Event, data: Object, change: Change, editor: Editor) => Change || Void` +`Function onCut(event: Event, change: Change, editor: Editor) => Change || Void` -This handler is equivalent to the `onCopy` handler. If no other plugin handles this event, it will be handled by the [Core plugin](./core.md). +This handler is equivalent to the `onCopy` handler. ### `onDrop` -`Function onDrop(event: Event, data: Object, change: Change, editor: Editor) => Change || Void` +`Function onDrop(event: Event, change: Change, editor: Editor) => Change || Void` This handler is called when the user drops content into the `contenteditable` element. The event is already prevented by default, so you must define a state change to have any affect occur. -The `data` object is a convenience object created to standardize the drop metadata across browsers. Every data object has a `type` property, which can be one of `text`, `html` or `files`, and a `target` property which is a [`Range`](../slate/range.md) indicating where the drop occurred. Depending on the type, its structure will be: - -```js -{ - type: 'text', - target: Range, - text: String -} - -{ - type: 'html', - target: Range, - text: String, - html: String -} - -{ - type: 'files', - target: Range, - files: FileList -} -``` - -If no other plugin handles this event, it will be handled by the [Core plugin](./core.md). - ### `onKeyDown` -`Function onKeyDown(event: Event, data: Object, change: Change, editor: Editor) => Change || Void` +`Function onKeyDown(event: Event, change: Change, editor: Editor) => Change || Void` This handler is called when any key is pressed in the `contenteditable` element, before any action is taken. -Make sure to `event.preventDefault()` if you do not want the default insertion behavior to occur! If no other plugin handles this event, it will be handled by the [Core plugin](./core.md). +Make sure to `event.preventDefault()` if you do not want the default insertion behavior to occur! ### `onKeyUp` -`Function onKeyUp(event: Event, data: Object, change: Change, editor: Editor) => Change || Void` +`Function onKeyUp(event: Event, change: Change, editor: Editor) => Change || Void` This handler is called when any key is released in the `contenteditable` element. ### `onPaste` -`Function onPaste(event: Event, data: Object, change: Change, editor: Editor) => Change || Void` +`Function onPaste(event: Event, change: Change, editor: Editor) => Change || Void` This handler is called when the user pastes content into the `contenteditable` element. The event is already prevented by default, so you must define a state change to have any affect occur. -The `data` object is a convenience object created to standardize the paste metadata across browsers. Every data object has a `type` property, which can be one of `text`, `html` or `files`. Depending on the type, it's structure will be: - -```js -{ - type: 'text', - text: String -} - -{ - type: 'html', - text: String, - html: String -} - -{ - type: 'files', - files: FileList -} -``` - -If no other plugin handles this event, it will be handled by the [Core plugin](./core.md). - ### `onSelect` -`Function onSelect(event: Event, data: Object, change: Change, editor: Editor) => Change || Void` +`Function onSelect(event: Event, change: Change, editor: Editor) => Change || Void` -This handler is called whenever the native DOM selection changes. - -The `data` object contains a [`Range`](../slate/range.md) object representing the new selection. - -If no other plugin handles this event, it will be handled by the [Core plugin](./core.md). +This handler is called whenever the native DOM selection changes. _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`](../slate-react/editor.md#onchange) property of the ``. 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._ diff --git a/docs/reference/slate-simulator/index.md b/docs/reference/slate-simulator/index.md index c2b1a0673..3fdc4f2c6 100644 --- a/docs/reference/slate-simulator/index.md +++ b/docs/reference/slate-simulator/index.md @@ -25,7 +25,7 @@ simulator .beforeInput({ data: 'l' }) .beforeInput({ data: 'o' }) .beforeInput({ data: '!' }) - .keyDown({}, { key: 'enter' }) + .keyDown({ key: 'Enter' }) const nextState = simulator.state ``` @@ -34,42 +34,42 @@ const nextState = simulator.state ## Methods ### `beforeInput` -`beforeInput(event: Object, data: Object) => Simulator` +`beforeInput(event: Object) => Simulator` -Simulator a `beforeinput` event with an `event` object and `data` object. +Simulator a `beforeinput` event with an `event` object. ### `blur` -`blur(event: Object, data: Object) => Simulator` +`blur(event: Object) => Simulator` -Simulator a `blur` event with an `event` object and `data` object. +Simulator a `blur` event with an `event` object. ### `copy` -`copy(event: Object, data: Object) => Simulator` +`copy(event: Object) => Simulator` -Simulator a `copy` event with an `event` object and `data` object. +Simulator a `copy` event with an `event` object. ### `cut` -`cut(event: Object, data: Object) => Simulator` +`cut(event: Object) => Simulator` -Simulator a `cut` event with an `event` object and `data` object. +Simulator a `cut` event with an `event` object. ### `drop` -`drop(event: Object, data: Object) => Simulator` +`drop(event: Object) => Simulator` -Simulator a `drop` event with an `event` object and `data` object. +Simulator a `drop` event with an `event` object. ### `focus` -`focus(event: Object, data: Object) => Simulator` +`focus(event: Object) => Simulator` -Simulator a `focus` event with an `event` object and `data` object. +Simulator a `focus` event with an `event` object. ### `keyDown` -`keyDown(event: Object, data: Object) => Simulator` +`keyDown(event: Object) => Simulator` -Simulator a `keyDown` event with an `event` object and `data` object. +Simulator a `keyDown` event with an `event` object. ### `select` -`select(event: Object, data: Object) => Simulator` +`select(event: Object) => Simulator` -Simulator a `select` event with an `event` object and `data` object. +Simulator a `select` event with an `event` object. diff --git a/docs/walkthroughs/adding-event-handlers.md b/docs/walkthroughs/adding-event-handlers.md index f1e89cea1..94848e5ec 100644 --- a/docs/walkthroughs/adding-event-handlers.md +++ b/docs/walkthroughs/adding-event-handlers.md @@ -50,7 +50,7 @@ class App extends React.Component { } // Define a new handler which prints the key that was pressed. - onKeyDown = (event, data, change) => { + onKeyDown = (event, change) => { console.log(event.key) } @@ -84,7 +84,7 @@ class App extends React.Component { this.setState({ state }) } - onKeyDown = (event, data, change) => { + onKeyDown = (event, change) => { // Return with no changes if it's not the "&" key. if (event.key != '&') return diff --git a/docs/walkthroughs/applying-custom-formatting.md b/docs/walkthroughs/applying-custom-formatting.md index c70dc5255..7f5e7668d 100644 --- a/docs/walkthroughs/applying-custom-formatting.md +++ b/docs/walkthroughs/applying-custom-formatting.md @@ -27,7 +27,7 @@ class App extends React.Component { this.setState({ state }) } - onKeyDown = (event, data, change) => { + onKeyDown = (event, change) => { if (event.key != '`' || !event.metaKey) return event.preventDefault() const isCode = change.state.blocks.some(block => block.type == 'code') @@ -68,7 +68,7 @@ class App extends React.Component { this.setState({ state }) } - onKeyDown = (event, data, change) => { + onKeyDown = (event, change) => { if (!event.metaKey) return // Decide what to do based on the key code... @@ -144,7 +144,7 @@ class App extends React.Component { this.setState({ state }) } - onKeyDown = (event, data, change) => { + onKeyDown = (event, change) => { if (!event.metaKey) return switch (event.key) { diff --git a/docs/walkthroughs/defining-custom-block-nodes.md b/docs/walkthroughs/defining-custom-block-nodes.md index a1cd9aacd..4ac01092d 100644 --- a/docs/walkthroughs/defining-custom-block-nodes.md +++ b/docs/walkthroughs/defining-custom-block-nodes.md @@ -22,7 +22,7 @@ class App extends React.Component { this.setState({ state }) } - onKeyDown = (event, data, change) => { + onKeyDown = (event, change) => { if (event.key != '&') return event.preventDefault() change.insertText('and'); @@ -84,7 +84,7 @@ class App extends React.Component { this.setState({ state }) } - onKeyDown = (event, data, change) => { + onKeyDown = (event, change) => { if (event.key != '&') return event.preventDefault() change.insertText('and') @@ -128,7 +128,7 @@ class App extends React.Component { this.setState({ state }) } - onKeyDown = (event, data, change) => { + onKeyDown = (event, change) => { // Return with no changes if it's not the "`" key with cmd/ctrl pressed. if (event.key != '`' || !event.metaKey) return @@ -178,7 +178,7 @@ class App extends React.Component { this.setState({ state }) } - onKeyDown = (event, data, change) => { + onKeyDown = (event, change) => { if (event.key != '`' || !event.metaKey) return event.preventDefault() diff --git a/docs/walkthroughs/using-plugins.md b/docs/walkthroughs/using-plugins.md index 990d8bdac..3aae1825e 100644 --- a/docs/walkthroughs/using-plugins.md +++ b/docs/walkthroughs/using-plugins.md @@ -29,7 +29,7 @@ class App extends React.Component { this.setState({ state }) } - onKeyDown = (event, data, change) => { + onKeyDown = (event, change) => { if (event.key != 'b' || !event.metaKey) return event.preventDefault() change.toggleMark('bold') @@ -71,7 +71,7 @@ function MarkHotkey(options) { // Return our "plugin" object, containing the `onKeyDown` handler. return { - onKeyDown(event, data, change) { + onKeyDown(event, change) { // Check that the key pressed matches our `key` option. if (!event.metaKey || event.key != key) return diff --git a/packages/slate-react/Changelog.md b/packages/slate-react/Changelog.md index 3d7a0e88b..59f61719d 100644 --- a/packages/slate-react/Changelog.md +++ b/packages/slate-react/Changelog.md @@ -7,6 +7,22 @@ This document maintains a list of changes to the `slate-react` package with each --- +### `0.6.0` — October 16, 2017 + +###### BREAKING + +- **The `data` argument to event handlers has been removed.** Previously event handlers had a signature of `(event, data, change, editor)`, but now they have a signature of just `(event, change, editor)`. This leads to simpler internal Slate logic, and less complex relationship dependencies between plugins. All of the information inside the old `data` argument can be accessed via the similar properties on the `event` argument, or via the `getEventRange`, `getEventTransfer` and `setEventTransfer` helpers. + +###### NEW + +- **Added a new `setEventTransfer` helper.** This is useful if you're working with `onDrop` or `onPaste` event and you want to set custom data in the event, to retrieve later or for others to consume. It takes a data `type` and a `value` to set the type do. + +- **Event handlers now have access to new events.** The `onClick`, `onCompositionEnd`, `onCompositionStart`, `onDragEnd`, `onDragEnter`, `onDragExit`, `onDragLeave`, `onDragOver`, `onDragStart`, and `onInput` events are all now newly exposed. Your plugin logic can use them to solve some more advanced use cases, and even override the internal Slate logic when necessary. 99% of use cases won't require them still, but they can be useful to have when needed. + + +--- + + ### `0.5.0` — October 15, 2017 ###### DEPRECATED