Slate Example

A simple example showing how to use Slate in a JSFiddle.

HTML

<script src="https://npmcdn.com/[email protected]/umd/react.development.js"></script>
<script src="https://npmcdn.com/[email protected]/umd/react-dom.development.js"></script>
<script src="https://npmcdn.com/immutable/dist/immutable.js"></script>
<script src="https://npmcdn.com/slate/dist/slate.js"></script>
<script src="https://npmcdn.com/slate-base64-serializer/dist/slate-base64-serializer.js"></script>
<script src="https://npmcdn.com/slate-html-serializer/dist/slate-html-serializer.js"></script>
<script src="https://npmcdn.com/slate-hyperscript/dist/slate-hyperscript.js"></script>
<script src="https://npmcdn.com/slate-plain-serializer/dist/slate-plain-serializer.js"></script>
<script src="https://npmcdn.com/slate-prop-types/dist/slate-prop-types.js"></script>
<script src="https://npmcdn.com/slate-react/dist/slate-react.js"></script>
<script src="https://npmcdn.com/slate-simulator/dist/slate-simulator.js"></script>
<div id="main"></div>

Babel + JSX

const { Value } = window.Slate.default
const { Editor } = window.SlateReact.default
const { useState, useEffect } = window.React

/*
 * Use-case: An editor with these requirements:
 * External format: some json compatible with back-end (`data`)
 * Internal format: whatever needed (`value`, expensive conversion)
 * The editor receives an initial`data` object, converts it to value.
 * The user can edit that value, triggering any change handlers.
 * The editor needs to be able to force-load a new value at any time.
 * It does this by providing a new `data` object.
 */

// First data
const data0 = {
  document: {
    nodes: [
      {
        kind: 'block',
        type: 'paragraph',
        nodes: [
          {
            kind: 'text',
            leaves: [{ text: 'First text, edit me.' }]
          }
        ]
      }
    ]
  }
}

// Second data
const data1 = {
  document: {
    nodes: [
      {
        kind: 'block',
        type: 'paragraph',
        nodes: [
          {
            kind: 'text',
            leaves: [{ text: 'New text overrides old.' }]
          }
        ]
      }
    ]
  }
}

const MyEditor = ({ data, onChange }) => {
  const [currentData, setCurrentData] = useState(null)
  const [value, setValue] = useState(null)

  const dataIsUpdating = currentData !== data

	// As soon as we have a new data object, we force a new value.
  useEffect(() => {
    setValue(Value.fromJSON(data))
  }, [data])

  // When the value has updated, new data comes in (re-)set the value from it.
  useEffect(() => {
    // Ignore effect before any data loaded.
    if (!value) {
      return
    }

	  // if data is updating, assume that the value has been updated by a node.
    // This is triggered by the previous effect.
    if (dataIsUpdating) {
      setCurrentData(data)
    	return
    }

	  // Assume this is an editor triggered change and inform the parent.
    onChange && onChange(value)

		// Finally, assume data is updating - 
  }, [value])

	// Load editor when...