UNPKG

@eventcatalogtest/studio

Version:

A drag and drop UI for distributed systems that keeps your diagrams where they belong – in your repo

90 lines (71 loc) 2.4 kB
import { Editor, Range, Transforms, Element, Point, Text } from 'slate' import { ReactEditor } from 'slate-react' export interface MentionElement { type: 'mention' nodeId: string nodeType: string children: { text: string }[] } // Helper to check if a node is a mention export const isMentionElement = (element: any): element is MentionElement => { return element.type === 'mention' } // Find mentions in text export const withMentions = (editor: Editor) => { const { isInline, isVoid, markableVoid } = editor editor.isInline = element => { return element.type === 'mention' ? true : isInline(element) } editor.isVoid = element => { return element.type === 'mention' ? true : isVoid(element) } editor.markableVoid = element => { return element.type === 'mention' || markableVoid(element) } return editor } // Get current mention search export const getMentionSearch = (editor: Editor): { range: Range; search: string } | null => { const { selection } = editor if (!selection || !Range.isCollapsed(selection)) { return null } const [start] = Range.edges(selection) // Get text before cursor (up to 20 characters to find @) const beforeRange = { anchor: Editor.before(editor, start, { distance: 20, unit: 'character' }) || Editor.start(editor, []), focus: start, } const beforeText = Editor.string(editor, beforeRange) // Look for @ followed by word characters at the end of the text const match = beforeText.match(/@(\w*)$/) if (match) { const matchStart = beforeText.lastIndexOf(match[0]) const matchRange = { anchor: Editor.before(editor, start, { distance: beforeText.length - matchStart, unit: 'character' }) || start, focus: start, } return { range: matchRange, search: match[1] || '' } } return null } // Insert mention export const insertMention = (editor: Editor, nodeId: string, nodeType: string, nodeName: string) => { const mention: MentionElement = { type: 'mention', nodeId, nodeType, children: [{ text: '' }] } const mentionSearch = getMentionSearch(editor) if (mentionSearch) { // Replace the @ and search text with the mention Transforms.select(editor, mentionSearch.range) Transforms.insertNodes(editor, mention) Transforms.insertText(editor, ` ${nodeName} `) Transforms.move(editor) } }