1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-30 02:19:52 +02:00

Fix typos and other minor issues in docs (#3597)

Fixed typos and grammatical errors in the documentation
This commit is contained in:
Kirk Swenson
2020-04-10 09:05:03 -07:00
committed by GitHub
parent c9891a29e1
commit f6bfe034d7
16 changed files with 49 additions and 48 deletions

View File

@@ -8,7 +8,7 @@ This is a list of changes to Slate with each new release. Until `1.0.0` is relea
###### BREAKING
**Overrideble commands now live directly on the editor object.** Previously the `Command` concept was implemented as an interface that was passed into the `editor.exec` function, allowing the "core" commands to be overriden in one place. But this introduced a lot of Redux-like indirection when implementing custom commands that wasn't necessary because they are never overridden. Instead, now the core actions that can be overridden are implemented as individual functions on the editor (eg. `editor.insertText`) and they can be overridden just like any other function (eg. `isVoid`).
**Overridable commands now live directly on the editor object.** Previously the `Command` concept was implemented as an interface that was passed into the `editor.exec` function, allowing the "core" commands to be overridden in one place. But this introduced a lot of Redux-like indirection when implementing custom commands that wasn't necessary because they are never overridden. Instead, now the core actions that can be overridden are implemented as individual functions on the editor (eg. `editor.insertText`) and they can be overridden just like any other function (eg. `isVoid`).
Previously to override a command you'd do:
@@ -68,11 +68,11 @@ Now you'd write:
Transforms.unwrapNodes(editor, ...)
```
**The `Command` interfaces were removed.** As part of those changes, the existing `Command`, `CoreCommand`, `HistoryCommand`, and `ReactCommand` interfaces were all removed. You no longer need to define these "command objects", because you can just call the functions directly. Plugins can still define their own overridable commands by existing the `Editor` interface with new functions. The `slate-react` plugin does this with `insertData` and the `slate-history` plugin does this with `undo` and `redo`.
**The `Command` interfaces were removed.** As part of those changes, the existing `Command`, `CoreCommand`, `HistoryCommand`, and `ReactCommand` interfaces were all removed. You no longer need to define these "command objects", because you can just call the functions directly. Plugins can still define their own overridable commands by extending the `Editor` interface with new functions. The `slate-react` plugin does this with `insertData` and the `slate-history` plugin does this with `undo` and `redo`.
###### NEW
**User actions helpers now live directly on the `Editor.*` interface.** These are taking the place of the existing `Transforms.*` helpers that were moved. These helpers are equivalent to user actions, and they always operate on the existing selection. There are some defined by core, but you are likely to define your own custom helpers that are specific to your domain as well.
**User action helpers now live directly on the `Editor.*` interface.** These are taking the place of the existing `Transforms.*` helpers that were moved. These helpers are equivalent to user actions, and they always operate on the existing selection. There are some defined by core, but you are likely to define your own custom helpers that are specific to your domain as well.
For example, here are some of the built-in actions:
@@ -105,7 +105,7 @@ Whatever makes sense for your specific use case!
###### BREAKING
**The `format_text` command is split into `add_mark` and `remove_mark`.** Although the goal is to keep the number of commands in core to a minimum, having this as a combined command made it very hard to write logic that wanted to guarantee to only ever add or remove a mark from a text node. Now you can be guaranteed that the `add_mark` command will only ever add a custom property to text nodes, and the `remove_mark` command will only ever remove them.
**The `format_text` command is split into `add_mark` and `remove_mark`.** Although the goal is to keep the number of commands in core to a minimum, having this as a combined command made it very hard to write logic that wanted to guarantee to only ever add or remove a mark from a text node. Now you can be guaranteed that the `add_mark` command will only ever add custom properties to text nodes, and the `remove_mark` command will only ever remove them.
Previously you would write:
@@ -126,7 +126,7 @@ if (isActive) {
}
```
> 🤖 Note that the "mark" term does not mean what it meant in `0.47` and earlier. It simply means formatting that is applied at the text level—bold, italic, etc. We need a term for it because it's such a common pattern in richtext editor, and "mark" is often the term that is used. For example the `<mark>` tag in HTML.
> 🤖 Note that the "mark" term does not mean what it meant in `0.47` and earlier. It simply means formatting that is applied at the text level—bold, italic, etc. We need a term for it because it's such a common pattern in richtext editors, and "mark" is often the term that is used. For example the `<mark>` tag in HTML.
**The `Node.text` helper was renamed to `Node.string`.** This was simply to reduce the confusion between "the text string" and "text nodes". The helper still just returns the concatenated string content of a node.
@@ -224,7 +224,7 @@ Editor.nodes(editor, {
###### BREAKING
**The `slate-schema` package has been removed!** This decision was made because with the new helpers on the `Editor.*` interface, and with the changes to `normalizeNode` in the latest version of Slate, adding constraints using `normalizeNode` actually leads to more maintainable code that using `slate-schema`. Previously it was required to keep things from getting too unreadable, but that always came at a large cost of indirection and learning additional APIs. Everything you could do with `slate-schema` you can do with `normalizeNode`, and more.
**The `slate-schema` package has been removed!** This decision was made because with the new helpers on the `Editor.*` interface, and with the changes to `normalizeNode` in the latest version of Slate, adding constraints using `normalizeNode` actually leads to more maintainable code than using `slate-schema`. Previously it was required to keep things from getting too unreadable, but that always came at a large cost of indirection and learning additional APIs. Everything you could do with `slate-schema` you can do with `normalizeNode`, and more.
**Node matching functions now receive just a `Node`.** Previously they received a `NodeEntry` tuple, which consisted of `[node, path]`. However now they receive only a `node` argument, which makes it easier to write one-off node-checking helpers and pass them in directly as arguments. If you need to ensure a path, lookup the node first.

View File

@@ -52,7 +52,7 @@ yarn build
## Running Examples
To run the examples, start by building the mono repo as described in the [Repository Setup](#repository-setup) section.
To run the examples, start by building the monorepo as described in the [Repository Setup](#repository-setup) section.
Then you can start the examples server with:
@@ -62,7 +62,7 @@ yarn start
## Running Tests
To run the tests, start by building the mono repo as described in the [Repository Setup](#repository-setup) section.
To run the tests, start by building the monorepo as described in the [Repository Setup](#repository-setup) section.
Then you can rerun the tests with:

View File

@@ -6,7 +6,7 @@ Slate lets you build rich, intuitive editors like those in [Medium](https://medi
It can do this because all of its logic is implemented with a series of plugins, so you aren't ever constrained by what _is_ or _isn't_ in "core". You can think of it like a pluggable implementation of `contenteditable` built on top of [React](https://facebook.github.io/react/). It was inspired by libraries like [Draft.js](https://facebook.github.io/draft-js/), [Prosemirror](http://prosemirror.net/) and [Quill](http://quilljs.com/).
> 🤖 **Slate is currently in beta**. Its core API is useable now, but you might need to pull request fixes for advanced use cases. Some of its APIs are not "finalized" and will (breaking) change over time as we find better solutions.
> 🤖 **Slate is currently in beta**. Its core API is usable now, but you might need to pull request fixes for advanced use cases. Some of its APIs are not "finalized" and will (breaking) change over time as we find better solutions.
## Why?
@@ -20,15 +20,15 @@ Before creating Slate, I tried a lot of the other rich text libraries out there
- **Serializing to HTML, Markdown, etc. seemed like an afterthought.** Simple things like transforming a document to HTML or Markdown involved writing lots of boilerplate code, for what seemed like very common use cases.
- **Re-inventing the view layer seemed inefficient and limiting.** Most editors rolled their own views, instead of using existing technologies like React, so you have to learn a whole new system with new "gotchas".
- **Re-inventing the view layer seemed inefficient and limiting.** Most editors rolled their own views, instead of using existing technologies like React, so you had to learn a whole new system with new "gotchas".
- **Collaborative editing wasn't designed for in advance.** Often the editor's internal representation of data made it impossible to use to for a realtime, collaborative editing use case without basically rewriting the editor.
- **The repostories were monolithic, not small and reusable.** The code bases for many of the editors often didn't expose the internal tooling that could have been re-used by developers, leading to having to reinvent the wheel.
- **The repositories were monolithic, not small and reusable.** The code bases for many of the editors often didn't expose the internal tooling that could have been re-used by developers, leading to having to reinvent the wheel.
- **Building complex, nested documents was impossible.** Many editors were designed around simplistic "flat" documents, making things like tables, embeds and captions difficult to reason about and sometimes impossible.
Of course not every editor exhibits all of these issues, but if you've tried using another editor you might have run into similar problems. To get around the limitations of their API's and achieve the user experience you're after, you have to resort to very hacky things. And some experiences are just plain impossible to achieve.
Of course not every editor exhibits all of these issues, but if you've tried using another editor you might have run into similar problems. To get around the limitations of their APIs and achieve the user experience you're after, you have to resort to very hacky things. And some experiences are just plain impossible to achieve.
If that sounds familiar, you might like Slate.
@@ -63,7 +63,7 @@ To get a sense for how you might use Slate, check out a few of the examples:
- [**Plain text**](https://www.slatejs.org/examples/plaintext) — showing the most basic case: a glorified `<textarea>`.
- [**Rich text**](https://www.slatejs.org/examples/richtext) — showing the features you'd expect from a basic editor.
- [**Markdown preview**](https://www.slatejs.org/examples/markdown-preview) — showing how to add key handlers for Markdown-like shortcuts.
- [**Links**](https://www.slatejs.org/examples/links) — showing how wrap text in inline nodes with associated data.
- [**Links**](https://www.slatejs.org/examples/links) — showing how to wrap text in inline nodes with associated data.
- [**Images**](https://www.slatejs.org/examples/images) — showing how to use void (text-less) nodes to add images.
- [**Hovering toolbar**](https://www.slatejs.org/examples/hovering-toolbar) — showing how a contextual hovering menu can be implemented.
- [**Tables**](https://www.slatejs.org/examples/tables) — showing how to nest blocks to render more advanced components.

View File

@@ -22,7 +22,7 @@ type Path = number[]
## Point
`Point` objects refer to a specific location in a text node in a Slate document. Its `path` refers to the lcoation of the node in the tree, and its offset refers to distance into the node's string of text. Points may only refer to `Text` nodes.
`Point` objects refer to a specific location in a text node in a Slate document. Its `path` refers to the location of the node in the tree, and its offset refers to distance into the node's string of text. Points may only refer to `Text` nodes.
```typescript
interface Point {

View File

@@ -1,8 +1,8 @@
# Nodes: Editor, Elements and Texts
The most important type are the `Node` objects:
The most important types are the `Node` objects:
- A root-level `Editor` node that contains their entire document's content.
- A root-level `Editor` node that contains the entire document's content.
- Container `Element` nodes which have semantic meaning in your domain.
- And leaf-level `Text` nodes which contain the document's text.
@@ -33,7 +33,7 @@ Mirroring the DOM as much as possible is one of Slate's principles. People use t
> - [Inline elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements)
> - [Text elements](https://developer.mozilla.org/en-US/docs/Web/API/Text)
A Slate document is a nested and recursive structure. In a document, elements can have children nodes—all which may have children nodes without limit. The nested and recursive structure enables you to model simple behaviors such as user mentions and hashtags or complex behaviors such as tables and figures with captions.
A Slate document is a nested and recursive structure. In a document, elements can have children nodes—all of which may have children nodes without limit. The nested and recursive structure enables you to model simple behaviors such as user mentions and hashtags or complex behaviors such as tables and figures with captions.
## `Editor`
@@ -101,7 +101,7 @@ Depending on your use case, you might want to define another behavior for `Eleme
All elements default to being "block" elements. They each appear separated by vertical space, and they never run into each other.
But in certain cases, like for links, you might want to make as "inline" flowing elements instead. That way they live at the same level as text nodes, and flow.
But in certain cases, like for links, you might want to make them "inline" flowing elements instead. That way they live at the same level as text nodes, and flow.
> 🤖 This is a concept borrowed from the DOM's behavior, see [Block Elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements) and [Inline Elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements).
@@ -111,13 +111,13 @@ Elements can either contain block elements as children. Or they can contain inli
## Voids
Similarly to blocks and inlines, there is another element-specific behavior you can define depending on your use case: their "void"-ness.
Similar to blocks and inlines, there is another element-specific behavior you can define depending on your use case: their "void"-ness.
Elements default to being non-void, meaning that their children are fully editable as text. But in some cases, like for images, you want to ensure that Slate doesn't treat their content as editable text, but instead as a black box.
> 🤖 This is a concept borrowed from the HTML spec, see [Void Elements](https://www.w3.org/TR/2011/WD-html-markup-20110405/syntax.html#void-element).
You can do define which elements are treated as void by overriding the `editor.isVoid` function. (By default it always returns `false`.)
You can define which elements are treated as void by overriding the `editor.isVoid` function. (By default it always returns `false`.)
## `Text`

View File

@@ -4,7 +4,7 @@ Locations are how you refer to specific places in the document when inserting, d
## `Path`
Paths are the lowest-level way to refer to a location. Each path is a simple array of numbers that refers to a node in the document tree by its indexes in each of its ancestors nodes down the tree:
Paths are the lowest-level way to refer to a location. Each path is a simple array of numbers that refers to a node in the document tree by its indexes in each of its ancestor nodes down the tree:
```ts
type Path = number[]
@@ -92,7 +92,7 @@ One important distinction is that the anchor and focus points of ranges **always
Ranges are used in many places in Slate's API when you need to refer to a span of content between two points. One of the most common though is the user's current "selection".
The selection is a special range that is property of the top-level `Editor`. For example, say someone has the whole sentence currently selected:
The selection is a special range that is a property of the top-level `Editor`. For example, say someone has the whole sentence currently selected:
```js
const editor = {
@@ -115,4 +115,4 @@ const editor = {
> 🤖 The selection concept is also borrowed from the DOM, see [`Selection`, MDN](https://developer.mozilla.org/en-US/docs/Web/API/Selection), although in a greatly-simplified form because Slate doesn't allow for multiple ranges inside a single selection, which makes things a lot easier to work with.
There isn't a special `Selection` interface, it's just an object that happens to respect the more general-purpose `Range` interface instead.
There isn't a special `Selection` interface. It's just an object that happens to respect the more general-purpose `Range` interface instead.

View File

@@ -1,6 +1,6 @@
# Commands
While editing richtext content, your users will be doing things like inserting text, deleteing text, splitting paragraphs, adding formatting, etc. These edits are expressed using two concepts: commands and operations.
While editing richtext content, your users will be doing things like inserting text, deleting text, splitting paragraphs, adding formatting, etc. These edits are expressed using two concepts: commands and operations.
Commands are the high-level actions that represent a specific intent of the user. They are represented as helper functions on the `Editor` interface. A handful of helpers are included in core for common richtext behaviors, but you are encouraged to write your own that model your specific domain.
@@ -16,9 +16,9 @@ Editor.insertBreak(editor)
But you can (and will!) also define your own custom commands that model your domain. For example, you might want to define a `formatQuote` command, or an `insertImage` command, or a `toggleBold` command depending on what types of content you allow.
Commands always describe an action to be taken as if the **user** themselves was performing the action. For that reason, they never need to define a location to perform the command, because they always act on the user's current selection.
Commands always describe an action to be taken as if the **user** was performing the action. For that reason, they never need to define a location to perform the command, because they always act on the user's current selection.
> 🤖 The concept of commands are loosely based on the DOM's built-in [`execCommand`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) APIs. However Slate defines its own simpler (and extendable!) version of the API, because the DOM's version is too opinionated and inconsistent.
> 🤖 The concept of commands is loosely based on the DOM's built-in [`execCommand`](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) APIs. However Slate defines its own simpler (and extendable!) version of the API, because the DOM's version is too opinionated and inconsistent.
Under the covers, Slate takes care of converting each command into a set of low-level "operations" that are applied to produce a new value. This is what makes collaborative editing implementations possible. But you don't have to worry about that, because it happens automatically.

View File

@@ -33,4 +33,4 @@ editor.apply({
Under the covers Slate converts complex commands into the low-level operations and applies them to the editor automatically, so you rarely have to think about them.
> 🤖 Slate's editing behaviors being defined as operations is what makes things like collaborative editing possible, because each change is easily define-able, apply-able, compose-able and event undo-able!
> 🤖 Slate's editing behaviors being defined as operations is what makes things like collaborative editing possible, because each change is easily define-able, apply-able, compose-able and even undo-able!

View File

@@ -30,7 +30,7 @@ interface Editor {
}
```
Slightly more complex than the others, because it contains all of the top-level functions that define your custom, domain-specific behaviors.
It is slightly more complex than the others, because it contains all of the top-level functions that define your custom, domain-specific behaviors.
The `children` property contains the document tree of nodes that make up the editor's content.
@@ -42,9 +42,9 @@ The `marks` property stores formatting that is attached to the cursor, and that
## Overriding Behaviors
In previous guides we've already hinted at this, but you can override any of the behaviors of an editor by overriding it's function properties.
In previous guides we've already hinted at this, but you can override any of the behaviors of an editor by overriding its function properties.
For example, if you want define link elements that are inline nodes:
For example, if you want to define link elements that are inline nodes:
```js
const { isInline } = editor
@@ -86,7 +86,7 @@ editor.normalizeNode = entry => {
}
```
Whenever you override behaviors, be sure to call in to the existing functions as a fallback mechanism for the default behavior. Unless you really do want to completely remove the default behaviors (which is rarely a good idea).
Whenever you override behaviors, be sure to call the existing functions as a fallback mechanism for the default behavior. Unless you really do want to completely remove the default behaviors (which is rarely a good idea).
## Helper Functions

View File

@@ -1,6 +1,6 @@
# Plugins
You've already seen how the behaviors of Slate editors can be overriden. These overrides can also be packaged up into "plugins" to be reused, tested and shared. This is one of the most powerful aspects of Slate's architecture.
You've already seen how the behaviors of Slate editors can be overridden. These overrides can also be packaged up into "plugins" to be reused, tested and shared. This is one of the most powerful aspects of Slate's architecture.
A plugin is simply a function that takes an `Editor` object and returns it after it has augmented it in some way.

View File

@@ -76,7 +76,7 @@ const renderLeaf = useCallback(({ attributes, children, leaf }) => {
}, [])
```
Notice though how we've handled it slightly differently than `renderElement`. Since text formatting texts to be fairly simple, we've opted to ditch the `switch` statement and just toggle on/off a few styles instead. (But there's nothing preventing you from using custom components if you'd like!)
Notice though how we've handled it slightly differently than `renderElement`. Since text formatting tends to be fairly simple, we've opted to ditch the `switch` statement and just toggle on/off a few styles instead. (But there's nothing preventing you from using custom components if you'd like!)
One disadvantage of text-level formatting is that you cannot guarantee that any given format is "contiguous"—meaning that it stays as a single leaf. This limitation with respect to leaves is similar to the DOM, where this is invalid:

View File

@@ -119,7 +119,7 @@ It's really that easy!
## Deserializing
Another common use case in Slate is doing the reverse—deserializing. This is when you have some arbitrary input and want to convert it into a Slate-compabitable JSON structure. For example, when someone pastes HTML into your editor and you want to ensure it gets parsed with the proper formatting for your editor.
Another common use case in Slate is doing the reverse—deserializing. This is when you have some arbitrary input and want to convert it into a Slate-compatible JSON structure. For example, when someone pastes HTML into your editor and you want to ensure it gets parsed with the proper formatting for your editor.
Slate has a built-in helper for this: the `slate-hyperscript` package.

View File

@@ -1,6 +1,6 @@
# Normalizing
Slate editors can edit complex, nested data structures. And for the most part this is great, but in certain cases inconsistencies in the data structure can be introduced—most often when allowing a user to paste arbitrary richtext content.
Slate editors can edit complex, nested data structures. And for the most part this is great. But in certain cases inconsistencies in the data structure can be introduced—most often when allowing a user to paste arbitrary richtext content.
"Normalizing" is how you can ensure that your editor's content is always of a certain shape. It's similar to "validating", except instead of just determining whether the content is valid or invalid, its job is to fix the content to make it valid again.
@@ -37,7 +37,7 @@ const withParagraphs = editor => {
editor.normalizeNode = entry => {
const [node, path] = entry
// If the element is a paragraph, ensure it's children are valid.
// If the element is a paragraph, ensure its children are valid.
if (Element.isElement(node) && node.type === 'paragraph') {
for (const [child, childPath] of Node.children(editor, path)) {
if (Element.isElement(child) && !editor.isInline(child)) {
@@ -92,7 +92,7 @@ To see how this works in practice, let's start with this invalid document:
</editor>
```
The editor starts by running `normalizeNode` on `<paragraph c>`. And it is valid, because contains only text nodes as children.
The editor starts by running `normalizeNode` on `<paragraph c>`. And it is valid, because it contains only text nodes as children.
But then, it moves up the tree, and runs `normalizeNode` on `<paragraph b>`. This paragraph is invalid, since it contains a block element (`<paragraph c>`). So that child block gets unwrapped, resulting in a new document of:
@@ -118,7 +118,7 @@ And now when `normalizeNode` runs, no changes are made, so the document is valid
## Incorrect Fixes
The one pitfall to avoid however it creating an infinite normalization loop. This can happen if you check for a specific invalid structure, but then **don't** actually fix that structure with the change you make to the node. Resulting in an infinite loop because the node continues to be flagged as invalid, but never fixed properly.
The one pitfall to avoid however is creating an infinite normalization loop. This can happen if you check for a specific invalid structure, but then **don't** actually fix that structure with the change you make to the node. This results in an infinite loop because the node continues to be flagged as invalid, but it is never fixed properly.
For example, consider a normalization that ensured `link` elements have a valid `url` property:
@@ -135,6 +135,7 @@ const withLinks = editor => {
node.type === 'link' &&
typeof node.url !== 'string'
) {
// ERROR: null is not a valid value for a url
Transforms.setNodes(editor, { url: null }, { at: path })
return
}

View File

@@ -26,13 +26,13 @@ The codebase now uses TypeScript. Working with pure JSON as a data model, and us
### Fewer Concepts
The number of interfaces and commands has been reduced. Previously `Selection`, `Annotation`, `Decoration` used to all be separate classes. Now they are simply objects that implement the `Range` interface. Previously `Block` and `Inline` were separate, now they are objects that implement the `Element` interface. Previously there was a `Document` and `Value`, but now the top-level `Editor` contains the children nodes of the document itself.
The number of interfaces and commands has been reduced. Previously `Selection`, `Annotation`, and `Decoration` used to all be separate classes. Now they are simply objects that implement the `Range` interface. Previously `Block` and `Inline` were separate; now they are objects that implement the `Element` interface. Previously there was a `Document` and `Value`, but now the top-level `Editor` contains the children nodes of the document itself.
The number of commands has been reduced too. Previously we had commands for every type of input, like `insertText`, `insertTextAtRange`, `insertTextAtPath`. These have been merged into a smaller set of more customizable commands, eg. `insertText` which can take `at: Path | Range | Point`.
### Fewer Packages
In attempt to decrease the maintenance burden, and because the new abstraction and APIs in Slate's core packages make things much easier, the total number of packages has been reduced. Things like `slate-plain-serializer`, `slate-base64-serializer`, etc. have been removed and can be implemented in userland easily if needed. Even the `slate-html-deserializer` can now be implemented in userland (in ~10 LOC leveraging `slate-hyperscript`). And internal packages like `slate-dev-environment`, `slate-dev-test-utils`, etc. are no longer exposed because they are implementation details.
In an attempt to decrease the maintenance burden, and because the new abstraction and APIs in Slate's core packages make things much easier, the total number of packages has been reduced. Things like `slate-plain-serializer`, `slate-base64-serializer`, etc. have been removed and can be implemented in userland easily if needed. Even the `slate-html-deserializer` can now be implemented in userland (in ~10 LOC leveraging `slate-hyperscript`). And internal packages like `slate-dev-environment`, `slate-dev-test-utils`, etc. are no longer exposed because they are implementation details.
### Commands
@@ -42,7 +42,7 @@ Commands are triggered by calling the `editor.*` core functions. And they travel
### Plugins
Plugins are now plain functions that augment the `Editor` object they receive and return it again. For example can augment the command execution by composing the `editor.exec` function. Or listen to operations by composing `editor.apply`. Previously they relied on a custom middleware stack, and they were just bags of handlers that got merged onto an editor. Now we're using plain old function composition (aka wrapping) instead.
Plugins are now plain functions that augment the `Editor` object they receive and return it again. For example, they can augment the command execution by composing the `editor.exec` function or listen to operations by composing `editor.apply`. Previously they relied on a custom middleware stack, and they were just bags of handlers that got merged onto an editor. Now we're using plain old function composition (aka wrapping) instead.
### Elements
@@ -50,7 +50,7 @@ Block-ness and inline-ness is now a runtime choice. Previously it was baked into
### More React-ish
Rendering and event-handling is no longer a plugin's concern. Previously plugins had full control over the rendering logic, and event-handling logic in the editor. This creates a bad incentive to start putting **all** rendering logic in plugins, which puts Slate in a position of being a wrapper around all of React, which is very hard to do well. Instead, the new architecture has plugins focused purely on the richtext aspects, and leaves the rendering and event handling aspects to React.
Rendering and event-handling are no longer a plugin's concern. Previously plugins had full control over the rendering and event-handling logic in the editor. This creates a bad incentive to start putting **all** rendering logic in plugins, which puts Slate in a position of being a wrapper around all of React, which is very hard to do well. Instead, the new architecture has plugins focused purely on the richtext aspects, and leaves the rendering and event handling aspects to React.
### Context
@@ -62,7 +62,7 @@ In addition to the `useSlate` hook, there are a handful of other hooks. For exam
### `beforeinput`
We now use the `beforeinput` event almost exclusively. Instead of having relying on a series of shims and the quirks of React synthetic events, we're now using the standardized `beforeinput` event as our baseline. It is fully supported in Safari and Chrome, will soon be supported in the new Chromium-based Edge, and is currently being worked on in Firefox. In the meantime there are a few patches to make Firefox work. Internet Explorer is no longer supported in core out of the box.
We now use the `beforeinput` event almost exclusively. Instead of relying on a series of shims and the quirks of React synthetic events, we're now using the standardized `beforeinput` event as our baseline. It is fully supported in Safari and Chrome, will soon be supported in the new Chromium-based Edge, and is currently being worked on in Firefox. In the meantime there are a few patches to make Firefox work. Internet Explorer is no longer supported in core out of the box.
### History-less
@@ -70,11 +70,11 @@ The core history logic has now finally been extracted into a standalone plugin.
### Mark-less
Marks have been removed the Slate data model. Now that we have the ability to define custom properties right on the nodes themselves, you can model marks as custom properties of text nodes. For example bold can be modelled simply as a `bold: true` property.
Marks have been removed from the Slate data model. Now that we have the ability to define custom properties right on the nodes themselves, you can model marks as custom properties of text nodes. For example bold can be modelled simply as a `bold: true` property.
### Annotation-less
Similarly, annotations have been removed from Slate's core. They can be fully implemented now in userland by defining custom operations and rendering annotated ranges using decorations. But most cases should be using custom text node properties or decorations anyways. There were not that many use cases that benefitted from annotations.
Similarly, annotations have been removed from Slate's core. They can be fully implemented now in userland by defining custom operations and rendering annotated ranges using decorations. But most cases should be using custom text node properties or decorations anyways. There were not that many use cases that benefited from annotations.
## Reductions

View File

@@ -1,6 +1,6 @@
# Installing Slate
Slate is a monorepo divided up into multi npm packages, so to install it you do:
Slate is a monorepo divided up into multiple npm packages, so to install it you do:
```
yarn add slate slate-react
@@ -123,4 +123,4 @@ const App = () => {
There you have it!
That's the most basic example of Slate. If you render that onto the page, you should see a paragraph with the text `A line of text in a paragraph.`. And when you type, you should see the text change!
That's the most basic example of Slate. If you render that onto the page, you should see a paragraph with the text `A line of text in a paragraph.` And when you type, you should see the text change!

View File

@@ -30,7 +30,7 @@ Before you can add `slate.js` to your page, you need to bring your own copy of `
<script src="./vendor/react-dom-server.js"></script>
```
This ensures that Slate isn't bundling its own copy of Immutable and React, which would greatly increase the file size of your application.
This ensures that Slate isn't bundling its own copy of React, which would greatly increase the file size of your application.
Then you can add `slate.js` after those includes: