mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-18 13:11:17 +02:00
add plugin gocs
This commit is contained in:
52
docs/reference/plugins/core.md
Normal file
52
docs/reference/plugins/core.md
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
# 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.
|
||||
|
||||
- [Default Behavior](#behavior)
|
||||
- [Overriding Defaults](#overriding-defaults)
|
||||
|
||||
|
||||
## Default Behavior
|
||||
|
||||
The default behavior of the core plugin performs the following logic:
|
||||
|
||||
#### `onBeforeInput`
|
||||
|
||||
When `onBeforeInput` is triggered, the core plugin simply inserts the text from `event.data` into the editor.
|
||||
|
||||
#### `onKeyDown`
|
||||
|
||||
When `onKeyDown` is triggered, the core plugin handles performing some of the "native" behavior that `contenteditable` elements must do. For example it splits blocks on `enter`, removes characters `backspace`, triggers an undo state from the history on `cmd-z`, etc.
|
||||
|
||||
#### `onPaste`
|
||||
|
||||
When `onPaste` is triggered, the core plugin handles all pastes of type `text` and `html` as plain text, and does nothing for those of type `files`.
|
||||
|
||||
#### `renderNode`
|
||||
|
||||
The core plugin renders a default block and inline node, wrapping in a `<div>` and `<span>`, respectively. Each of these nodes contains `shouldComponentUpdate` logic prevents unnecessary re-renders.
|
||||
|
||||
The default block node also controls its own placeholder logic, which is controlled via the [`<Editor>`](../components/editor.md)'s placeholder options.
|
||||
|
||||
#### `renderMark`
|
||||
|
||||
The core plugin adds no default styles to marks.
|
||||
|
||||
|
||||
## Overriding Defaults
|
||||
|
||||
Any plugin you add to the editor will override the default behavior of the core plugin simply because it is always resolved last.
|
||||
|
||||
However, sometimes you might want to disable the logic of the core plugin without actually adding any logic yourself. For example, you might want to prevent the `enter` key from performing any action. In those cases, you'll need to define a "noop" handler.
|
||||
|
||||
A noop `onBeforeInput` handler looks like:
|
||||
|
||||
```js
|
||||
function onBeforeInput(event, state, editor) {
|
||||
event.preventDefault()
|
||||
return state
|
||||
}
|
||||
```
|
||||
|
||||
Notice that is calls `event.preventDefault()` to prevent the default browser behavior, and it returns the current `state` to prevent the editor from continuing to resolve its plugins stack.
|
169
docs/reference/plugins/plugin.md
Normal file
169
docs/reference/plugins/plugin.md
Normal file
@@ -0,0 +1,169 @@
|
||||
|
||||
# Plugin
|
||||
|
||||
Plugins can be attached to an editor to alter its behavior in different ways. Plugins are just simple Javascript objects, containing a set of properties that control different behaviors—event handling, change handling, rendering, etc.
|
||||
|
||||
Each editor has a "middleware stack" of plugins, which has a specific order.
|
||||
|
||||
When the editor needs to resolve a plugin-related handler, it will loop through its plugin stack, searching for the first plugin that successfully returns a value. After receiving that value, the editor will **not** continue to search the remaining plugins; it returns early.
|
||||
|
||||
- [Conventions](#conventions)
|
||||
- [Event Handler Properties](#event-handler-properties)
|
||||
- [`onBeforeInput`](#onbeforeinput-event-state-editor-state-void)
|
||||
- [`onKeyDown`](#onkeydown-event-state-editor-state-void)
|
||||
- [`onPaste`](#onpaste-event-paste-state-editor-state-void)
|
||||
- [Renderer Properties](#renderer-properties)
|
||||
- [`renderDecorations`](#renderdecorations-text-characters-void)
|
||||
- [`renderMark`](#rendermark-mark-object-void)
|
||||
- [`renderNode`](#rendernode-node-component-void)
|
||||
- [Other Properties](#other-properties)
|
||||
- [`onChange`](#onchange-state-state-void)
|
||||
|
||||
|
||||
## Conventions
|
||||
|
||||
A plugin should always export a function that takes options. This way even if it doesn't take any options now, it won't be a breaking API change to take more options in the future. So a basic plugin might look like this:
|
||||
|
||||
```js
|
||||
export default MySlatePlugin(options) {
|
||||
return {
|
||||
// Return properties that describe your logic here...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Event Handler Properties
|
||||
|
||||
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 the current `state` of the editor, and the `editor` instance itself.
|
||||
|
||||
Each event handler can choose to return a new `state` object, in which case the editor's state will be updated. If nothing is returned, the editor will simply continue resolving the plugin stack.
|
||||
|
||||
```js
|
||||
{
|
||||
onBeforeInput: Function,
|
||||
onKeyDown: Function,
|
||||
onPaste: Function
|
||||
}
|
||||
```
|
||||
|
||||
#### `onBeforeInput(event, state, editor) => State || Void`
|
||||
|
||||
This handler is called right before a string of text is inserted into the `contenteditable` element. The `event.data` property will be the string of text that is being inserted.
|
||||
|
||||
_Make sure to `event.preventDefault()` if you do not want the default insertion behavior to occur!_
|
||||
|
||||
By default, if no other plugin resolves this event, the editor's core plugin will resolve it by insert the text from `event.data` into the editor. If you do not want this, or anything else to happen, you can "noop" this event:
|
||||
|
||||
#### `onKeyDown(event, state, editor) => State || Void`
|
||||
|
||||
This handler is called when any key is pressed in the `contenteditable` element, before any action is taken. Use the `event.which` property to determine which key was pressed.
|
||||
|
||||
_Make sure to `event.preventDefault()` if you do not want the default insertion behavior to occur!_
|
||||
|
||||
#### `onPaste(event, paste, state, editor) => State || 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 `paste` object is a convenience object created to standardize the paste metadata across browsers. Every paste 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
|
||||
}
|
||||
```
|
||||
|
||||
By default, the editor will handle all `text` and `html` pastes as plain text.
|
||||
|
||||
|
||||
## Renderer Properties
|
||||
|
||||
```js
|
||||
{
|
||||
renderDecorations: Function,
|
||||
renderMark: Function,
|
||||
renderNode: Function
|
||||
}
|
||||
```
|
||||
|
||||
#### `renderDecorations(text) => Characters || Void`
|
||||
|
||||
The `renderDecorations` handler allows you to add dynamic, content-aware [`Marks`](../models/mark.md) to ranges of text, without having them show up in the serialized state of the editor. This is useful for things like code highlighting, where the marks will change as the user types.
|
||||
|
||||
`renderDecorations` is called for every `text` node in the document, and should return a set of updated [`Characters`](../models/character.md) for the text node in question. Every plugin's decoration logic is called, and the resulting characters are unioned, such that multiple plugins can apply decorations to the same pieces of text.
|
||||
|
||||
#### `renderMark(mark) => Object || Void`
|
||||
|
||||
The `renderMark` handler allows you to define the styles that each mark should be rendered with. It takes a [`Mark`](../models/mark.md) object, and should return a dictionary of styles that will be applied via React's `style=` property. For example:
|
||||
|
||||
```js
|
||||
{
|
||||
fontWeight: 'bold',
|
||||
fontStyle: 'italic'
|
||||
}
|
||||
```
|
||||
|
||||
#### `renderNode(node) => Component || Void`
|
||||
|
||||
The `renderNode` handler allows you to define the component that will be used to render a node—both blocks and inlines. It takes a [`Node`](../models/node.md) object, and should return a React component.
|
||||
|
||||
The component will be called with a set of properties:
|
||||
|
||||
```js
|
||||
<Component
|
||||
attributes={Object}
|
||||
children={Any}
|
||||
node={Node}
|
||||
state={State}
|
||||
/>
|
||||
```
|
||||
|
||||
- `attributes: Object` — a dictionary of attributes that **you must** add to the top-level element of the rendered component. Using the [Object Spread Syntax (Stage 2)](https://github.com/sebmarkbage/ecmascript-rest-spread) this is as easy as `...props.attributes`.
|
||||
- `children: Any` — a set of React element children that **you must** render as the leaf element in your component.
|
||||
- `node: Node` the node being rendered.
|
||||
- `state: State` the current state of the editor.
|
||||
|
||||
Such that a simple code block renderer might look like this:
|
||||
|
||||
```js
|
||||
const CodeBlockRenderer = (props) => {
|
||||
return (
|
||||
<pre {...props.attributes}>
|
||||
<code>
|
||||
{children}
|
||||
</code>
|
||||
</pre>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
The `node` itself is passed in, such that you can access any custom data associated with it from its `data` property.
|
||||
|
||||
|
||||
## Other Properties
|
||||
|
||||
```js
|
||||
{
|
||||
onChange: Function
|
||||
}
|
||||
```
|
||||
|
||||
#### `onChange(state) => State || Void`
|
||||
|
||||
The `onChange` handler isn't a native browser event handler. Instead, it is invoked whenever the editor state changes. Returning a new state will update the editor's state, continuing down the plugin stack.
|
||||
|
||||
Unlike the native event handlers, results from the `onChange` handler **are cummulative**! This means that every plugin in the stack that defines an `onChange` handler will have its handler resolved for every change the editor makes; the editor will not return early after the first plugin's handler is called.
|
||||
|
||||
This allows you to stack up changes across the entire plugin stack.
|
Reference in New Issue
Block a user