All Versions
Latest Version
Avg Release Cycle
8 days
Latest Release
1478 days ago

Changelog History
Page 1

  • v0.58.3

    June 04, 2020
  • v0.58.2

    May 27, 2020
  • v0.58.1

    May 11, 2020
  • v0.58.0 Changes

    May 05, 2020

    👉 User properties on Elements and Texts now have an unknown type instead of any. Previously, the arbitrary user defined keys on the Text and Element interface had a type of any which effectively removed any potential type checking on those properties. Now these have a type of unknown so that type checking can be done by consumers of the API when they are applying their own custom properties to the Texts and Elements.

  • v0.57.3

    May 05, 2020
  • v0.57.2

    April 24, 2020
  • v0.57.1

    December 20, 2019
  • v0.57.0 Changes

    December 18, 2019

    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:

    const withPlugin = editor => {
      const { exec } = editor
      editor.exec = command => {
        if (command.type === 'insert_text') {
          const { text } = command
          if (myCustomLogic) {
            // ...
      return editor

    Now, you'd override the specific function directly:

    const withPlugin = editor => {
      const { insertText } = editor
      editor.insertText = text => {
        if (myCustomLogic) {
          // ...
      return editor

    🔌 You shouldn't ever need to call these functions directly! They are there for plugins to tap into, but there are higher level helpers for you to call whenever you actually need to invoke them. Read on…

    Transforms now live in a separate namespace of helpers. Previously the document and selection transformation helpers were available directly on the Editor interface as Editor.*. But these helpers are fairly low level, and not something that you'd use in your own codebase all over the place, usually only inside specific custom helpers of your own. To make room for custom userland commands, these helpers have been moved to a new Transforms namespace.

    Previously you'd write:

    Editor.unwrapNodes(editor, ...)

    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 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.


    👉 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:

    Editor.insertText(editor, 'a string of text')
    Editor.deleteBackward(editor, { unit: 'word' })
    Editor.addMark(editor, 'bold', true)

    Every one of the old "core commands" has an equivalent Editor.* helper exposed now. However, you can easily define your own custom helpers and place them in a namespace as well:

    const MyEditor = {
      insertParagraph(editor) { ... },
      toggleBoldMark(editor) { ... },
      formatLink(editor, url) { ... },

    Whatever makes sense for your specific use case!

  • v0.56.1

    December 18, 2019
  • v0.56.0 Changes

    December 17, 2019

    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:

      type: 'format_text',
      properties: { bold: true },

    Now you would write:

    if (isActive) {
      editor.exec({ type: 'remove_mark', key: 'bold' })
    } else {
      editor.exec({ type: 'add_mark', key: 'bold', value: true })

    🤖 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.