49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
import * as Y from 'yjs'
|
|
import React, {useMemo, useState} from "react";
|
|
import {Slate, withReact} from "slate-react";
|
|
import {createEditor, Descendant} from "slate";
|
|
import {withYHistory, withYjs} from "@slate-yjs/core";
|
|
import {FormatToolbar} from "./FormatToolbar/FormatToolbar.tsx";
|
|
|
|
|
|
function withNormalize(editor: Editor) {
|
|
const { normalizeNode } = editor;
|
|
|
|
// Ensure editor always has at least one child.
|
|
editor.normalizeNode = (entry) => {
|
|
const [node] = entry;
|
|
if (!Editor.isEditor(node) || node.children.length > 0) {
|
|
return normalizeNode(entry);
|
|
}
|
|
|
|
Transforms.insertNodes(
|
|
editor,
|
|
{
|
|
type: 'paragraph',
|
|
children: [{ text: '' }],
|
|
},
|
|
{ at: [0] }
|
|
);
|
|
};
|
|
|
|
return editor;
|
|
}
|
|
export const SlateSimple: React.FC = ()=>{
|
|
const [value, setValue] = useState<Descendant[]>([]);
|
|
const editor = useMemo(() => {
|
|
const sharedType = provider.document.get('content', Y.XmlText) as Y.XmlText;
|
|
|
|
return withNormalize(withReact(
|
|
withYHistory(
|
|
withYjs(createEditor(), sharedType, { autoConnect: false })
|
|
)
|
|
));
|
|
}, [provider.document]);
|
|
return (<div>
|
|
<Slate editor={editor} value={value}>
|
|
<FormatToolbar />
|
|
<CustomEditable className="max-w-4xl w-full flex-col break-words" />
|
|
</Slate>
|
|
</div>)
|
|
}
|