Company events, blog posts. Some time ago it happened that the project needed a rich text editor. Draft.js used by my colleagues is troublesome to use. Google looked for an alternative solution and found Slate.js, which was also used to customize the underlying language.

1. The website https://docs.slatejs.org/

Slate.js, like draft.js, Prosemirror, and Quill, is based on structured objects that render rich text editing content. Simply put, the value of a rich text editor is no longer HTML, but a State Object.

If you are not good at e, you can look at the Chinese document github.com/loveloki/sl…

Originally also want to copy paste translation of a wave of official website, you have Chinese to see their own learning next bar.

After looking at the Walktaxation taxation, it really feels simple and useful, the code is still in use in React Hook, so buy it. Of course I am patient to read Concepts, apis

API chapter does not have Chinese translation, you can exercise yourself, looking at such a detailed API, it is not more should support a wave

  1. Transforms are auxiliary functions that manipulate documents (Node, Selection, Text)

  2. Nodes Several methods of Editor are more commonly used and need to be extended through function rewriting in the code

  3. Locations specific APIS

  4. Refs don’t understand

  5. Miscellaneous createEditor()

2. Getting started – Editor DEMO instance

I did a search on GitHub and found this project github.com/Canner/cann… “, but this project was two years ago (or am I too 9 to have heard Slate.js before).

Looking at the examples on the official website, I feel that it is not difficult to write a simple one, just want to learn carefully, but also convenient to customize the editor. Write a simple example, github.com/legu2009/sl… , the company component library used the Braft Editor, so the UI borrowed from the next (we all understand), is really icon thrashed about for a long time, did not find out of the box. The react Hook component is written.



Summing up the pothole

  1. Click on the Toolbar Button and the Editor loses focus via onKeyDownevent.preventDefault()To deal with
  2. To determine the state of Selection, Button selects the state. For Text, passmarks = Editor.marks(editor)Gets the current state judgment. For Element, passEditor.nodes(editor, { match: (n) => n.type === 'xxx' })Iterate to find

  3. The Link DropDown has an input. OnKeyDown event.preventDefault() can’t handle it, so use the tmpSelection cache, which Transforms it beforeTransforms.select(editor, tmpSelection.current);Restore Selection, even when DropDown is closed, andHTMLElement.focus() 

    const onDropDownHide = (a)= > {
        if (isNewLink.current) {
            Transforms.select(editor, tmpSelection.current);
            unwrapLink(editor);
            isNewLink.current = false;
        }  
        getContainerNode().querySelector(".slate-content").focus();
    };
    // Line-level elements and text can only be in the same children, so need to be overridden
    isInlineeditor.isInline = (element) = > {
        return element.type === "link" ? true : isInline(element);
    };Copy the code

  4. When DropDown displays a section of text, an empty Link is added by default. When editing the URL, the user can see the set text. If the selected content overlaps with a link, setting a new link removes the original link
  5. The horizontal line HR determines if it is the end of the article, insert one more line. And the selection area moved to insert hr after a position, easy to delete. I’m not familiar with the API, so maybe there’s an easier way to write it

    const insertLine = (editor) = > {
        let editorEnd = Editor.end(editor, []);
        let selection = editor.selection;
        let [selectionStart, selectionEnd] = Range.edges(selection);
        let isEditorEnd = false;
        if (selection) {
            if (Point.equals(editorEnd, selectionEnd)) {
                isEditorEnd = true; }}if (Point.equals(selectionStart, selectionEnd) && isEditorEnd) {
            // The last line
            if (editorEnd.offset === 0 && editorEnd.path.length === 2 && editorEnd.path[1= = =0) {
                Transforms.removeNodes(editor, {
                    at: selection
                });
            }
        }
        Transforms.insertNodes(editor, {
            type: 'hr'.children: [{ text: ' '}}]);if (isEditorEnd) {
            Transforms.insertNodes(editor, {
                type: 'paragraph'.children: [{ text: ' '}}]); }else {
            let anchor = editor.selection.anchor;
            let path = anchor.path.map((item) = > item);
            path[path.length - 2] + +; Transforms.select(editor, { path,offset: 0
            });
        }};
    // The HR component has no content to edit, so it is overwritten
    isVoideditor.isVoid = (element) = > {
        return element.type === 'hr' ? true : isVoid(element);
    };
    //Element contentEditable={false} Controls cannot be edited. Image,video,mention are all supported by supporting Settings
    const HR = React.memo(({ attributes, children, element }) = > {
        const selected = useSelected();
        const editor = useSlate();
        const fn = (a)= > {
            Transforms.removeNodes(editor);
        };
        return (
            <div contentEditable={false} {. attributes} >
                <div className={'slate-hr'+ (selected ? ' active' :"')} >
                    <div className="slate-content-toolbar" onClick={fn}>
                        <a>&#xe9ac;</a>
                    </div>
                </div>
                {children}
            </div>
        );
    });Copy the code
  6. Online Chinese input method problems (forget firstIssuesSearch in). The React VDom and THE Dom are not the same because the Chinese input method inserts the content that is rendered by State. My solution is to set a Key to the Text at onCompositionEnd so that the edited Text triggers re-rendering

    <Editable
        className="slate-content"
        renderElement={renderElement}
        renderLeaf={renderLeaf} 
        placeholder="Enter some rich text..."
        spellCheck={false}
        autoFocus
        onCompositionEnd={(e) => {
            Transforms.setNodes(
                editor,
                {
                    key: +new Date()}, {match: Text.isText } ); }} / >Copy the code

  7. The image function is not implemented. This interface is used to upload pictures.
  8. The expression function is not implemented. I just wrote a simple insert at sign aaa, and let’s see what happens. A function in a project that is supposed to replace text as a placeholder.
  9. Table functionality is not implemented. It’s too complicated, and the problems are too difficult to achieve. This includes table select-edit state interaction, table nesting, table merge columns, table merge rows, and more. I just tried the table nesting effect.

3. To give up

It’s fun to use in every way, but github can’t find a great project, which is really embarrassing

  1. Due to my limited time and ability, it was really difficult to develop such a complex interaction as Table component.
  2. Slate.js doesn’t support IE very well, I made a stupid mistake when I used It too much on MAC, I forgot to look at IE compatibility when I selected it. Slate-react uses a lot of APIS that IE doesn’t support. While I think it makes sense for users to install Chrome, you know, it’s a lot harder to convince product managers than it is to convince yourself.
  3. The dom structure of the editor is very complex. There are so many nodes in one text that slate-React needs to be customized
  4. I don’t know if the problem of Chinese input method has been solved completely

4. Other

Now that front-end Low Code, No Code, AI Code is popular, I feel that WYSIWYG editing interaction is more friendly. Big factory Ali language sparrow editor do not know there is no open source plan, look forward to.

I hereby express my condolences to The United States University. Every time, I feel the technology, efforts and luck of the grand God. Behind each grand god, I must pay more. Life is only once, want to go to the peak of life through technology friends, also pay attention to rest, exercise.