UNPKG

marshall-y-slate

Version:
94 lines (82 loc) 3.53 kB
import { useCallback, useEffect, useState } from 'react'; import { NodeEntry, Path, Range, Text } from 'slate'; import { Cursor, CursorInfo } from '../model'; import { relativePositionToAbsolutePosition } from '../cursor/utils'; import { CursorEditor } from './cursor-editor'; export const useCursors = ( editor: CursorEditor ): { decorate: (entry: NodeEntry) => Range[]; cursors: Cursor[]; } => { const [cursors, setCursorData] = useState<Cursor[]>([]); useEffect(() => { editor.awareness.on('update', () => { const newCursorData = Array.from(editor.awareness.getStates()) .filter(([clientId]) => clientId !== editor.sharedType.doc?.clientID) .map(([, awareness]) => { let anchor = null; let focus = null; if (awareness.anchor) { anchor = relativePositionToAbsolutePosition( editor.sharedType, awareness.anchor ); } if (awareness.focus) { focus = relativePositionToAbsolutePosition( editor.sharedType, awareness.focus ); } return { anchor, focus, data: awareness }; }) .filter((cursor) => cursor.anchor && cursor.focus); setCursorData(newCursorData as unknown as Cursor[]); }); }, [editor]); const decorate = useCallback( ([node, path]: NodeEntry) => { const ranges: (Range & CursorInfo)[] = []; if (Text.isText(node) && cursors?.length) { cursors.forEach((cursor) => { if (Range.includes(cursor, path)) { const { focus, anchor, data } = cursor; const isFocusNode = Path.equals(focus.path, path); const isAnchorNode = Path.equals(anchor.path, path); const isForward = Range.isForward({ anchor, focus }); ranges.push({ data, isForward, originAnchorPath: anchor.path, originFocusPath: focus.path, isCaret: isFocusNode, anchor: { path, // eslint-disable-next-line no-nested-ternary offset: isAnchorNode ? anchor.offset : isForward ? 0 : node.text.length, }, focus: { path, // eslint-disable-next-line no-nested-ternary offset: isFocusNode ? focus.offset : isForward ? node.text.length : 0, }, }); } }); } return ranges; }, [cursors] ); return { decorate, cursors }; }; export default useCursors;