1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-17 20:51:20 +02:00

update walkthroughs, docs and changelog

This commit is contained in:
Ian Storm Taylor
2017-10-16 21:13:07 -07:00
parent a9e037a6a7
commit 54ec11e199
8 changed files with 66 additions and 110 deletions

View File

@@ -1,7 +1,7 @@
# Core Plugin # 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 ## 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: A noop `onBeforeInput` handler looks like:
```js ```js
function onBeforeInput(event, data, state) { function onBeforeInput(event, state) {
event.preventDefault() event.preventDefault()
return state return state
} }

View File

@@ -38,126 +38,66 @@ 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` ### `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. 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` ### `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` ### `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` ### `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. 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` ### `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` ### `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. 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` ### `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. 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` ### `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. This handler is called when any key is released in the `contenteditable` element.
### `onPaste` ### `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. 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` ### `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. 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).
_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 `<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`](../slate-react/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._

View File

@@ -25,7 +25,7 @@ simulator
.beforeInput({ data: 'l' }) .beforeInput({ data: 'l' })
.beforeInput({ data: 'o' }) .beforeInput({ data: 'o' })
.beforeInput({ data: '!' }) .beforeInput({ data: '!' })
.keyDown({}, { key: 'enter' }) .keyDown({ key: 'Enter' })
const nextState = simulator.state const nextState = simulator.state
``` ```
@@ -34,42 +34,42 @@ const nextState = simulator.state
## Methods ## Methods
### `beforeInput` ### `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`
`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`
`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`
`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`
`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`
`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`
`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`
`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.

View File

@@ -50,7 +50,7 @@ class App extends React.Component {
} }
// Define a new handler which prints the key that was pressed. // Define a new handler which prints the key that was pressed.
onKeyDown = (event, data, change) => { onKeyDown = (event, change) => {
console.log(event.key) console.log(event.key)
} }
@@ -84,7 +84,7 @@ class App extends React.Component {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, change) => { onKeyDown = (event, change) => {
// Return with no changes if it's not the "&" key. // Return with no changes if it's not the "&" key.
if (event.key != '&') return if (event.key != '&') return

View File

@@ -27,7 +27,7 @@ class App extends React.Component {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, change) => { onKeyDown = (event, change) => {
if (event.key != '`' || !event.metaKey) return if (event.key != '`' || !event.metaKey) return
event.preventDefault() event.preventDefault()
const isCode = change.state.blocks.some(block => block.type == 'code') const isCode = change.state.blocks.some(block => block.type == 'code')
@@ -68,7 +68,7 @@ class App extends React.Component {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, change) => { onKeyDown = (event, 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...
@@ -144,7 +144,7 @@ class App extends React.Component {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, change) => { onKeyDown = (event, change) => {
if (!event.metaKey) return if (!event.metaKey) return
switch (event.key) { switch (event.key) {

View File

@@ -22,7 +22,7 @@ class App extends React.Component {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, change) => { onKeyDown = (event, change) => {
if (event.key != '&') return if (event.key != '&') return
event.preventDefault() event.preventDefault()
change.insertText('and'); change.insertText('and');
@@ -84,7 +84,7 @@ class App extends React.Component {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, change) => { onKeyDown = (event, change) => {
if (event.key != '&') return if (event.key != '&') return
event.preventDefault() event.preventDefault()
change.insertText('and') change.insertText('and')
@@ -128,7 +128,7 @@ class App extends React.Component {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, change) => { onKeyDown = (event, 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.key != '`' || !event.metaKey) return if (event.key != '`' || !event.metaKey) return
@@ -178,7 +178,7 @@ class App extends React.Component {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, change) => { onKeyDown = (event, change) => {
if (event.key != '`' || !event.metaKey) return if (event.key != '`' || !event.metaKey) return
event.preventDefault() event.preventDefault()

View File

@@ -29,7 +29,7 @@ class App extends React.Component {
this.setState({ state }) this.setState({ state })
} }
onKeyDown = (event, data, change) => { onKeyDown = (event, change) => {
if (event.key != 'b' || !event.metaKey) return if (event.key != 'b' || !event.metaKey) return
event.preventDefault() event.preventDefault()
change.toggleMark('bold') change.toggleMark('bold')
@@ -71,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, change) { onKeyDown(event, change) {
// Check that the key pressed matches our `key` option. // Check that the key pressed matches our `key` option.
if (!event.metaKey || event.key != key) return if (!event.metaKey || event.key != key) return

View File

@@ -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 ### `0.5.0` — October 15, 2017
###### DEPRECATED ###### DEPRECATED