@relevaince/mentions 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -0
- package/dist/index.d.mts +21 -2
- package/dist/index.d.ts +21 -2
- package/dist/index.js +134 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +132 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/MentionsInput.tsx","../src/hooks/useMentionsEditor.ts","../src/core/mentionExtension.ts","../src/core/suggestionPlugin.ts","../src/core/markdownSerializer.ts","../src/core/markdownParser.ts","../src/hooks/useSuggestion.ts","../src/utils/debounce.ts","../src/components/SuggestionList.tsx","../src/utils/ariaHelpers.ts"],"sourcesContent":["/* ------------------------------------------------------------------ */\n/* Components */\n/* ------------------------------------------------------------------ */\nexport { MentionsInput } from \"./components/MentionsInput\";\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\nexport type { MentionToken } from \"./types/MentionToken\";\nexport type {\n MentionProvider,\n MentionItem,\n} from \"./types/MentionProvider\";\nexport type { MentionsOutput } from \"./types/MentionsOutput\";\nexport type {\n MentionsInputProps,\n MentionsInputHandle,\n} from \"./types/MentionsInputProps\";\n\n/* ------------------------------------------------------------------ */\n/* Utilities */\n/* ------------------------------------------------------------------ */\nexport { serializeToMarkdown } from \"./core/markdownSerializer\";\nexport { parseFromMarkdown, extractFromMarkdown } from \"./core/markdownParser\";\n","import React, { forwardRef, useCallback, useId, useImperativeHandle } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { EditorContent } from \"@tiptap/react\";\nimport { useMentionsEditor } from \"../hooks/useMentionsEditor\";\nimport { useSuggestion } from \"../hooks/useSuggestion\";\nimport { SuggestionList } from \"./SuggestionList\";\nimport { comboboxAttrs } from \"../utils/ariaHelpers\";\nimport type {\n MentionsInputProps,\n MentionsInputHandle,\n} from \"../types/MentionsInputProps\";\n\n/**\n * `<MentionsInput>` — the single public component.\n *\n * A structured text editor with typed entity tokens.\n * Consumers register `providers` for each trigger character,\n * and receive structured output via `onChange` and `onSubmit`.\n */\nexport const MentionsInput = forwardRef<MentionsInputHandle, MentionsInputProps>(\n function MentionsInput(\n {\n value,\n providers,\n onChange,\n placeholder = \"Type a message...\",\n autoFocus = false,\n disabled = false,\n className,\n onSubmit,\n clearOnSubmit = true,\n maxLength,\n renderItem,\n renderChip,\n renderEmpty,\n renderLoading,\n renderGroupHeader,\n onFocus,\n onBlur,\n onMentionAdd,\n onMentionRemove,\n onMentionClick,\n onMentionHover,\n minHeight,\n maxHeight,\n submitKey = \"enter\",\n allowTrigger,\n validateMention,\n portalContainer,\n },\n ref,\n ) {\n const instanceId = useId();\n const listboxId = `mentions-listbox-${instanceId}`;\n\n const { uiState, actions, callbacksRef } = useSuggestion(providers, {\n onMentionAdd,\n });\n\n const { editor, getOutput, clear, setContent, focus } = useMentionsEditor({\n providers,\n value,\n onChange,\n onSubmit,\n clearOnSubmit,\n placeholder,\n autoFocus,\n editable: !disabled,\n callbacksRef,\n onFocus,\n onBlur,\n submitKey,\n onMentionRemove,\n onMentionClick,\n onMentionHover,\n allowTrigger,\n validateMention,\n });\n\n useImperativeHandle(\n ref,\n () => ({ clear, setContent, focus, getOutput }),\n [clear, setContent, focus, getOutput],\n );\n\n const isExpanded = uiState.state !== \"idle\";\n\n const handleHover = useCallback((index: number) => {\n void index;\n }, []);\n\n const handleFocusEditor = useCallback(() => {\n editor?.commands.focus();\n }, [editor]);\n\n const editorStyle: React.CSSProperties = {};\n if (minHeight != null) editorStyle.minHeight = `${minHeight}px`;\n if (maxHeight != null) {\n editorStyle.maxHeight = `${maxHeight}px`;\n editorStyle.overflowY = \"auto\";\n }\n\n const suggestionList = isExpanded ? (\n <SuggestionList\n items={uiState.items}\n activeIndex={uiState.activeIndex}\n breadcrumbs={uiState.breadcrumbs}\n loading={uiState.loading}\n trigger={uiState.trigger}\n query={uiState.query}\n clientRect={uiState.clientRect}\n onSelect={(item) => actions.select(item)}\n onHover={handleHover}\n onGoBack={actions.goBack}\n onSearchNested={actions.searchNested}\n onNavigateUp={actions.navigateUp}\n onNavigateDown={actions.navigateDown}\n onClose={actions.close}\n onFocusEditor={handleFocusEditor}\n renderItem={renderItem}\n renderEmpty={renderEmpty}\n renderLoading={renderLoading}\n renderGroupHeader={renderGroupHeader}\n listboxId={listboxId}\n />\n ) : null;\n\n return (\n <div\n className={className}\n data-mentions-input=\"\"\n data-disabled={disabled ? \"\" : undefined}\n {...comboboxAttrs(isExpanded, listboxId)}\n aria-activedescendant={\n isExpanded && uiState.items[uiState.activeIndex]\n ? `mention-option-${uiState.items[uiState.activeIndex].id}`\n : undefined\n }\n >\n <div style={editorStyle}>\n <EditorContent editor={editor} />\n </div>\n\n {portalContainer\n ? suggestionList && createPortal(suggestionList, portalContainer)\n : suggestionList}\n </div>\n );\n },\n);\n","import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { useEditor } from \"@tiptap/react\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\nimport { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { MentionNode } from \"../core/mentionExtension\";\nimport { createSuggestionExtension } from \"../core/suggestionPlugin\";\nimport {\n serializeToMarkdown,\n extractTokens,\n extractPlainText,\n} from \"../core/markdownSerializer\";\nimport { parseFromMarkdown } from \"../core/markdownParser\";\nimport type { MentionProvider } from \"../types/MentionProvider\";\nimport type { MentionToken } from \"../types/MentionToken\";\nimport type { MentionsOutput } from \"../types/MentionsOutput\";\nimport type { SuggestionCallbacksRef } from \"../core/suggestionPlugin\";\n\n/* ------------------------------------------------------------------ */\n/* Helper: build MentionsOutput from the current editor */\n/* ------------------------------------------------------------------ */\n\nfunction buildOutput(editor: { getJSON: () => any }): MentionsOutput {\n const json = editor.getJSON();\n return {\n markdown: serializeToMarkdown(json),\n tokens: extractTokens(json),\n plainText: extractPlainText(json),\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Collect all mention tokens from a doc JSON */\n/* ------------------------------------------------------------------ */\n\nfunction collectMentionTokens(doc: any): MentionToken[] {\n const tokens: MentionToken[] = [];\n function walk(node: any) {\n if (node.type === \"mention\" && node.attrs) {\n tokens.push({\n id: node.attrs.id,\n type: node.attrs.entityType ?? node.attrs.type,\n label: node.attrs.label,\n });\n }\n if (node.content) {\n for (const child of node.content) walk(child);\n }\n }\n walk(doc);\n return tokens;\n}\n\n/* ------------------------------------------------------------------ */\n/* Submit keyboard shortcut extension (Cmd/Ctrl+Enter) */\n/* ------------------------------------------------------------------ */\n\nfunction createSubmitExtension(\n onSubmitRef: React.RefObject<((output: MentionsOutput) => void) | undefined>,\n clearOnSubmitRef: React.RefObject<boolean>,\n submitKeyRef: React.RefObject<string>,\n) {\n return Extension.create({\n name: \"submitShortcut\",\n priority: 150,\n\n addKeyboardShortcuts() {\n return {\n \"Mod-Enter\": () => {\n const key = submitKeyRef.current;\n if (key === \"mod+enter\" || key === \"enter\") {\n if (onSubmitRef.current) {\n onSubmitRef.current(buildOutput(this.editor));\n if (clearOnSubmitRef.current) {\n this.editor.commands.clearContent(true);\n }\n }\n return true;\n }\n return false;\n },\n };\n },\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Enter key handling */\n/* ------------------------------------------------------------------ */\n\nconst enterSubmitPluginKey = new PluginKey(\"enterSubmit\");\n\nfunction createEnterExtension(\n onSubmitRef: React.RefObject<((output: MentionsOutput) => void) | undefined>,\n clearOnSubmitRef: React.RefObject<boolean>,\n submitKeyRef: React.RefObject<string>,\n) {\n return Extension.create({\n name: \"enterSubmit\",\n priority: 150,\n\n addProseMirrorPlugins() {\n const editor = this.editor;\n\n return [\n new Plugin({\n key: enterSubmitPluginKey,\n props: {\n handleKeyDown(_view, event) {\n if (event.key !== \"Enter\") return false;\n\n const key = submitKeyRef.current;\n\n if (key === \"none\") return false;\n\n if (key === \"mod+enter\") {\n // Enter = new line (default PM behavior handles it)\n // Shift+Enter also new line\n return false;\n }\n\n // key === \"enter\" (default)\n if (event.shiftKey) {\n editor.commands.splitBlock();\n return true;\n }\n\n if (event.metaKey || event.ctrlKey) return false;\n\n if (onSubmitRef.current) {\n onSubmitRef.current(buildOutput(editor));\n if (clearOnSubmitRef.current) {\n editor.commands.clearContent(true);\n }\n }\n return true;\n },\n },\n }),\n ];\n },\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Mention removal detection plugin */\n/* ------------------------------------------------------------------ */\n\nconst mentionRemovePluginKey = new PluginKey(\"mentionRemove\");\n\nfunction createMentionRemoveExtension(\n onMentionRemoveRef: React.RefObject<((token: MentionToken) => void) | undefined>,\n) {\n return Extension.create({\n name: \"mentionRemoveDetector\",\n priority: 100,\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: mentionRemovePluginKey,\n appendTransaction(transactions, oldState, newState) {\n if (!onMentionRemoveRef.current) return null;\n\n const oldMentions = collectMentionTokens(oldState.doc.toJSON());\n const newMentions = collectMentionTokens(newState.doc.toJSON());\n\n if (oldMentions.length <= newMentions.length) return null;\n\n const newIds = new Set(newMentions.map((m) => m.id));\n for (const m of oldMentions) {\n if (!newIds.has(m.id)) {\n onMentionRemoveRef.current(m);\n }\n }\n\n return null;\n },\n }),\n ];\n },\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Hook */\n/* ------------------------------------------------------------------ */\n\ntype UseMentionsEditorOptions = {\n providers: MentionProvider[];\n value?: string;\n onChange?: (output: MentionsOutput) => void;\n onSubmit?: (output: MentionsOutput) => void;\n clearOnSubmit?: boolean;\n placeholder?: string;\n autoFocus?: boolean;\n editable?: boolean;\n callbacksRef: SuggestionCallbacksRef;\n onFocus?: () => void;\n onBlur?: () => void;\n submitKey?: string;\n onMentionRemove?: (token: MentionToken) => void;\n onMentionClick?: (token: MentionToken, event: MouseEvent) => void;\n onMentionHover?: (token: MentionToken) => ReactNode;\n allowTrigger?: (trigger: string, context: { textBefore: string }) => boolean;\n validateMention?: (token: MentionToken) => boolean | Promise<boolean>;\n};\n\nexport function useMentionsEditor({\n providers,\n value,\n onChange,\n onSubmit,\n clearOnSubmit = true,\n placeholder,\n autoFocus = false,\n editable = true,\n callbacksRef,\n onFocus,\n onBlur,\n submitKey = \"enter\",\n onMentionRemove,\n onMentionClick,\n onMentionHover,\n allowTrigger,\n validateMention,\n}: UseMentionsEditorOptions) {\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n const onSubmitRef = useRef(onSubmit);\n onSubmitRef.current = onSubmit;\n\n const clearOnSubmitRef = useRef(clearOnSubmit);\n clearOnSubmitRef.current = clearOnSubmit;\n\n const onFocusRef = useRef(onFocus);\n onFocusRef.current = onFocus;\n\n const onBlurRef = useRef(onBlur);\n onBlurRef.current = onBlur;\n\n const submitKeyRef = useRef(submitKey);\n submitKeyRef.current = submitKey;\n\n const onMentionRemoveRef = useRef(onMentionRemove);\n onMentionRemoveRef.current = onMentionRemove;\n\n const onMentionClickRef = useRef(onMentionClick);\n onMentionClickRef.current = onMentionClick;\n\n const onMentionHoverRef = useRef(onMentionHover);\n onMentionHoverRef.current = onMentionHover;\n\n const allowTriggerRef = useRef(allowTrigger);\n allowTriggerRef.current = allowTrigger;\n\n const validateMentionRef = useRef(validateMention);\n validateMentionRef.current = validateMention;\n\n // Track internal value to avoid controlled-value infinite loops\n const internalMarkdownRef = useRef<string | null>(null);\n\n const initialContent = useMemo(() => {\n if (!value) return undefined;\n return parseFromMarkdown(value);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const triggersKey = providers.map((p) => p.trigger).join(\",\");\n const triggers = useMemo(\n () => providers.map((p) => p.trigger),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [triggersKey],\n );\n\n const suggestionExtension = useMemo(\n () => createSuggestionExtension(triggers, callbacksRef, allowTriggerRef),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [triggersKey],\n );\n\n const submitExt = useMemo(\n () => createSubmitExtension(onSubmitRef, clearOnSubmitRef, submitKeyRef),\n [],\n );\n const enterExt = useMemo(\n () => createEnterExtension(onSubmitRef, clearOnSubmitRef, submitKeyRef),\n [],\n );\n const mentionRemoveExt = useMemo(\n () => createMentionRemoveExtension(onMentionRemoveRef),\n [],\n );\n\n const mentionNodeExt = useMemo(\n () =>\n MentionNode.configure({\n onClickRef: onMentionClickRef,\n onHoverRef: onMentionHoverRef,\n }),\n [],\n );\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({\n heading: false,\n blockquote: false,\n codeBlock: false,\n bulletList: false,\n orderedList: false,\n listItem: false,\n horizontalRule: false,\n hardBreak: false,\n }),\n Placeholder.configure({\n placeholder: ({ editor }) =>\n editor.isEmpty ? (placeholder ?? \"Type a message...\") : \"\",\n showOnlyCurrent: true,\n }),\n mentionNodeExt,\n suggestionExtension,\n submitExt,\n enterExt,\n mentionRemoveExt,\n ],\n content: initialContent,\n autofocus: autoFocus ? \"end\" : false,\n editable,\n editorProps: {\n attributes: {\n class: \"mentions-editor\",\n },\n },\n onUpdate: ({ editor }) => {\n const output = buildOutput(editor);\n internalMarkdownRef.current = output.markdown;\n onChangeRef.current?.(output);\n },\n onFocus: () => {\n onFocusRef.current?.();\n },\n onBlur: () => {\n onBlurRef.current?.();\n },\n });\n\n // Sync editable state\n useEffect(() => {\n if (editor && editor.isEditable !== editable) {\n editor.setEditable(editable);\n }\n }, [editor, editable]);\n\n // Controlled value: update editor when external value changes\n useEffect(() => {\n if (!editor || value === undefined) return;\n if (value === internalMarkdownRef.current) return;\n const doc = parseFromMarkdown(value);\n editor.commands.setContent(doc);\n internalMarkdownRef.current = value;\n }, [editor, value]);\n\n // Mention validation\n useEffect(() => {\n if (!editor || !validateMention) return;\n\n const runValidation = async () => {\n const doc = editor.getJSON();\n const tokens = collectMentionTokens(doc);\n const invalidIds = new Set<string>();\n\n await Promise.all(\n tokens.map(async (token) => {\n const valid = await validateMention(token);\n if (!valid) invalidIds.add(token.id);\n }),\n );\n\n editor.view.dom.querySelectorAll(\"[data-mention]\").forEach((el) => {\n const id = el.getAttribute(\"data-id\");\n if (id && invalidIds.has(id)) {\n el.setAttribute(\"data-mention-invalid\", \"\");\n } else {\n el.removeAttribute(\"data-mention-invalid\");\n }\n });\n };\n\n runValidation();\n }, [editor, validateMention]);\n\n /* ---------------------------------------------------------------- */\n /* Imperative methods */\n /* ---------------------------------------------------------------- */\n\n const clear = useCallback(() => {\n editor?.commands.clearContent(true);\n }, [editor]);\n\n const setContent = useCallback(\n (markdown: string) => {\n if (!editor) return;\n const doc = parseFromMarkdown(markdown);\n editor.commands.setContent(doc);\n internalMarkdownRef.current = markdown;\n },\n [editor],\n );\n\n const focus = useCallback(() => {\n editor?.commands.focus(\"end\");\n }, [editor]);\n\n const getOutput = useCallback((): MentionsOutput | null => {\n if (!editor) return null;\n return buildOutput(editor);\n }, [editor]);\n\n return { editor, getOutput, clear, setContent, focus };\n}\n","import { mergeAttributes, Node } from \"@tiptap/core\";\nimport type { ReactNode } from \"react\";\nimport type { MentionToken } from \"../types/MentionToken\";\n\nexport interface MentionNodeAttrs {\n id: string;\n label: string;\n entityType: string;\n rootLabel?: string | null;\n}\n\nconst DEFAULT_PREFIXES: Record<string, string> = {\n workspace: \"@\",\n contract: \"@\",\n file: \"#\",\n web: \":\",\n};\n\nexport type MentionNodeOptions = {\n onClickRef?: React.RefObject<((token: MentionToken, event: MouseEvent) => void) | undefined>;\n onHoverRef?: React.RefObject<((token: MentionToken) => ReactNode) | undefined>;\n};\n\nexport const MentionNode = Node.create<MentionNodeOptions>({\n name: \"mention\",\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: true,\n draggable: false,\n\n addOptions() {\n return {\n onClickRef: undefined,\n onHoverRef: undefined,\n };\n },\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-id\"),\n renderHTML: (attributes) => ({ \"data-id\": attributes.id }),\n },\n label: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-label\"),\n renderHTML: (attributes) => ({ \"data-label\": attributes.label }),\n },\n entityType: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-type\"),\n renderHTML: (attributes) => ({ \"data-type\": attributes.entityType }),\n },\n rootLabel: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-root-label\"),\n renderHTML: (attributes) =>\n attributes.rootLabel\n ? { \"data-root-label\": attributes.rootLabel }\n : {},\n },\n };\n },\n\n parseHTML() {\n return [{ tag: 'span[data-mention]' }];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const entityType = node.attrs.entityType as string;\n const label = node.attrs.label as string;\n const prefix = DEFAULT_PREFIXES[entityType] ?? \"@\";\n const display = `${prefix}${label}`;\n\n const hasClick = !!this.options.onClickRef?.current;\n const extraAttrs: Record<string, string> = {};\n if (hasClick) {\n extraAttrs[\"data-mention-clickable\"] = \"\";\n }\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-mention\": \"\",\n class: \"mention-chip\",\n ...extraAttrs,\n }),\n display,\n ];\n },\n\n renderText({ node }) {\n const entityType = node.attrs.entityType as string;\n const label = node.attrs.label as string;\n const prefix = DEFAULT_PREFIXES[entityType] ?? \"@\";\n return `${prefix}${label}`;\n },\n\n addNodeView() {\n const options = this.options;\n\n return ({ node, HTMLAttributes }) => {\n const entityType = node.attrs.entityType as string;\n const label = node.attrs.label as string;\n const id = node.attrs.id as string;\n const prefix = DEFAULT_PREFIXES[entityType] ?? \"@\";\n\n const dom = document.createElement(\"span\");\n Object.entries(\n mergeAttributes(HTMLAttributes, {\n \"data-mention\": \"\",\n \"data-type\": entityType,\n \"data-id\": id,\n class: \"mention-chip\",\n }),\n ).forEach(([key, val]) => {\n if (val != null && val !== false) dom.setAttribute(key, String(val));\n });\n\n dom.textContent = `${prefix}${label}`;\n\n if (options.onClickRef?.current) {\n dom.setAttribute(\"data-mention-clickable\", \"\");\n dom.style.cursor = \"pointer\";\n }\n\n dom.addEventListener(\"click\", (event) => {\n const handler = options.onClickRef?.current;\n if (handler) {\n event.preventDefault();\n event.stopPropagation();\n handler({ id, type: entityType, label }, event);\n }\n });\n\n // Hover tooltip\n let tooltip: HTMLElement | null = null;\n\n dom.addEventListener(\"mouseenter\", () => {\n const hoverFn = options.onHoverRef?.current;\n if (!hoverFn) return;\n\n const content = hoverFn({ id, type: entityType, label });\n if (!content) return;\n\n tooltip = document.createElement(\"div\");\n tooltip.setAttribute(\"data-mention-tooltip\", \"\");\n tooltip.textContent = typeof content === \"string\" ? content : \"\";\n dom.style.position = \"relative\";\n dom.appendChild(tooltip);\n });\n\n dom.addEventListener(\"mouseleave\", () => {\n if (tooltip && tooltip.parentNode) {\n tooltip.parentNode.removeChild(tooltip);\n tooltip = null;\n }\n });\n\n return { dom };\n };\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () =>\n this.editor.commands.command(({ tr, state }) => {\n let isMention = false;\n const { selection } = state;\n const { empty, anchor } = selection;\n\n if (!empty) return false;\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true;\n tr.insertText(\"\", pos, pos + node.nodeSize);\n }\n });\n\n return isMention;\n }),\n };\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\n\n/* ------------------------------------------------------------------ */\n/* Suggestion state types */\n/* ------------------------------------------------------------------ */\n\nexport type SuggestionState =\n | \"idle\"\n | \"loading\"\n | \"showing\"\n | \"drilling\"\n | \"inserting\";\n\n/* ------------------------------------------------------------------ */\n/* Callbacks the React layer implements */\n/* ------------------------------------------------------------------ */\n\nexport type SuggestionCallbacks = {\n onStart: (props: SuggestionCallbackProps) => void;\n onUpdate: (props: SuggestionCallbackProps) => void;\n onExit: () => void;\n onKeyDown: (props: { event: KeyboardEvent }) => boolean;\n};\n\nexport type SuggestionCallbackProps = {\n query: string;\n trigger: string;\n clientRect: (() => DOMRect | null) | null;\n range: { from: number; to: number };\n command: (attrs: Record<string, unknown>) => void;\n};\n\n/* ------------------------------------------------------------------ */\n/* Trigger detection */\n/* ------------------------------------------------------------------ */\n\ntype TriggerMatch = {\n trigger: string;\n query: string;\n from: number;\n to: number;\n textBefore: string;\n};\n\nfunction detectTrigger(\n text: string,\n cursorPos: number,\n docStartPos: number,\n triggers: string[],\n): TriggerMatch | null {\n const relCursor = cursorPos - docStartPos;\n const before = text.slice(0, relCursor);\n\n for (let i = before.length - 1; i >= 0; i--) {\n const ch = before[i];\n if (ch === \"\\n\") return null;\n\n for (const trigger of triggers) {\n if (before.substring(i, i + trigger.length) === trigger) {\n if (i === 0 || /\\s/.test(before[i - 1])) {\n const query = before.slice(i + trigger.length);\n return {\n trigger,\n query,\n from: docStartPos + i,\n to: cursorPos,\n textBefore: before.slice(0, i),\n };\n }\n }\n }\n }\n\n return null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Plugin key */\n/* ------------------------------------------------------------------ */\n\nconst suggestionPluginKey = new PluginKey(\"mentionSuggestion\");\n\n/* ------------------------------------------------------------------ */\n/* Ref-based callback container (avoids stale closure issues) */\n/* ------------------------------------------------------------------ */\n\nexport type SuggestionCallbacksRef = { current: SuggestionCallbacks };\n\nexport type AllowTriggerRef = {\n current?: (trigger: string, context: { textBefore: string }) => boolean;\n};\n\n/* ------------------------------------------------------------------ */\n/* Build the single multi-trigger suggestion extension */\n/* ------------------------------------------------------------------ */\n\nexport function createSuggestionExtension(\n triggers: string[],\n callbacksRef: SuggestionCallbacksRef,\n allowTriggerRef?: AllowTriggerRef,\n) {\n return Extension.create({\n name: \"mentionSuggestion\",\n priority: 200,\n\n addProseMirrorPlugins() {\n const editor = this.editor;\n let active = false;\n let lastQuery: string | null = null;\n let lastTrigger: string | null = null;\n\n const getClientRect = (\n view: EditorView,\n from: number,\n ): (() => DOMRect | null) => {\n return () => {\n try {\n const coords = view.coordsAtPos(from);\n return new DOMRect(\n coords.left,\n coords.top,\n 0,\n coords.bottom - coords.top,\n );\n } catch {\n return null;\n }\n };\n };\n\n const makeCommand = (range: { from: number; to: number }) => {\n return (attrs: Record<string, unknown>) => {\n editor\n .chain()\n .focus()\n .insertContentAt(range, [\n {\n type: \"mention\",\n attrs: {\n id: attrs.id,\n label: attrs.label,\n entityType: attrs.entityType,\n rootLabel: attrs.rootLabel ?? null,\n },\n },\n { type: \"text\", text: \" \" },\n ])\n .run();\n };\n };\n\n const plugin = new Plugin({\n key: suggestionPluginKey,\n\n props: {\n handleKeyDown(_view, event) {\n if (!active) return false;\n return callbacksRef.current.onKeyDown({ event });\n },\n },\n\n view() {\n return {\n update(view, _prevState) {\n const { state } = view;\n const { selection } = state;\n\n if (!selection.empty) {\n if (active) {\n active = false;\n lastQuery = null;\n lastTrigger = null;\n callbacksRef.current.onExit();\n }\n return;\n }\n\n const $pos = selection.$from;\n const textBlock = $pos.parent;\n\n if (!textBlock.isTextblock) {\n if (active) {\n active = false;\n lastQuery = null;\n lastTrigger = null;\n callbacksRef.current.onExit();\n }\n return;\n }\n\n const blockStart = $pos.start();\n const blockText = textBlock.textContent;\n const cursorPos = $pos.pos;\n\n const match = detectTrigger(blockText, cursorPos, blockStart, triggers);\n\n if (match) {\n // Check allowTrigger gate\n if (allowTriggerRef?.current) {\n const allowed = allowTriggerRef.current(match.trigger, {\n textBefore: match.textBefore,\n });\n if (!allowed) {\n if (active) {\n active = false;\n lastQuery = null;\n lastTrigger = null;\n callbacksRef.current.onExit();\n }\n return;\n }\n }\n\n const range = { from: match.from, to: match.to };\n const props: SuggestionCallbackProps = {\n query: match.query,\n trigger: match.trigger,\n clientRect: getClientRect(view, match.from),\n range,\n command: makeCommand(range),\n };\n\n if (!active) {\n active = true;\n lastQuery = match.query;\n lastTrigger = match.trigger;\n callbacksRef.current.onStart(props);\n } else if (\n match.query !== lastQuery ||\n match.trigger !== lastTrigger\n ) {\n lastQuery = match.query;\n lastTrigger = match.trigger;\n callbacksRef.current.onUpdate(props);\n }\n } else {\n if (active) {\n active = false;\n lastQuery = null;\n lastTrigger = null;\n callbacksRef.current.onExit();\n }\n }\n },\n\n destroy() {\n if (active) {\n callbacksRef.current.onExit();\n }\n },\n };\n },\n });\n\n return [plugin];\n },\n });\n}\n","import type { JSONContent } from \"@tiptap/core\";\nimport type { MentionToken } from \"../types/MentionToken\";\n\n/**\n * Serialize a Tiptap JSON document to a markdown string.\n *\n * Mention nodes are encoded as `@[label](id)` or `@rootLabel[label](id)` when the mention has a root (e.g. file under workspace).\n * All other text passes through verbatim.\n */\nexport function serializeToMarkdown(doc: JSONContent): string {\n if (!doc.content) return \"\";\n\n const parts: string[] = [];\n\n for (const block of doc.content) {\n if (block.type === \"paragraph\") {\n parts.push(serializeParagraph(block));\n } else if (block.type === \"text\") {\n parts.push(block.text ?? \"\");\n }\n }\n\n return parts.join(\"\\n\");\n}\n\nfunction serializeParagraph(node: JSONContent): string {\n if (!node.content) return \"\";\n\n return node.content\n .map((child) => {\n if (child.type === \"mention\") {\n const { id, label, entityType, rootLabel } = child.attrs ?? {};\n const idPart =\n entityType && entityType !== \"unknown\"\n ? `${entityType}:${id}`\n : id;\n if (rootLabel != null && rootLabel !== \"\") {\n return `@${rootLabel}[${label}](${idPart})`;\n }\n return `@[${label}](${idPart})`;\n }\n return child.text ?? \"\";\n })\n .join(\"\");\n}\n\n/**\n * Extract all `MentionToken`s from a Tiptap JSON document, in document order.\n */\nexport function extractTokens(doc: JSONContent): MentionToken[] {\n const tokens: MentionToken[] = [];\n\n function walk(node: JSONContent) {\n if (node.type === \"mention\" && node.attrs) {\n tokens.push({\n id: node.attrs.id as string,\n type: node.attrs.entityType as string,\n label: node.attrs.label as string,\n });\n }\n if (node.content) {\n for (const child of node.content) {\n walk(child);\n }\n }\n }\n\n walk(doc);\n return tokens;\n}\n\n/**\n * Extract plain text from a Tiptap JSON document.\n * Mention nodes are replaced with their label (no trigger prefix in plain text).\n */\nexport function extractPlainText(doc: JSONContent): string {\n if (!doc.content) return \"\";\n\n const parts: string[] = [];\n\n for (const block of doc.content) {\n if (block.type === \"paragraph\") {\n parts.push(extractParagraphText(block));\n }\n }\n\n return parts.join(\"\\n\");\n}\n\nfunction extractParagraphText(node: JSONContent): string {\n if (!node.content) return \"\";\n\n return node.content\n .map((child) => {\n if (child.type === \"mention\") {\n return child.attrs?.label ?? \"\";\n }\n return child.text ?? \"\";\n })\n .join(\"\");\n}\n","import type { JSONContent } from \"@tiptap/core\";\nimport { extractTokens, extractPlainText } from \"./markdownSerializer\";\nimport type { MentionToken } from \"../types/MentionToken\";\n\n/**\n * Regex matching mention tokens:\n * - `@[label](id)` or `@[label](type:id)`\n * - `@rootLabel[label](type:id)` when the mention has a root (e.g. file under workspace).\n * Groups: (1) rootLabel (may be empty string), (2) label, (3) optional entityType, (4) id.\n *\n * `[^\\[@]` prevents the rootLabel from crossing `@` boundaries so that plain\n * `@word` in running text is never swallowed into a false rootLabel match.\n */\nconst MENTION_RE = /@([^\\[@]*)\\[([^\\]]+)\\]\\((?:([^:)]+):)?([^)]+)\\)/g;\n\n/**\n * Parse a markdown string (with `@[label](id)`, `@[label](type:id)`, or `@rootLabel[label](id)` tokens)\n * into a Tiptap-compatible JSON document.\n */\nexport function parseFromMarkdown(markdown: string): JSONContent {\n const lines = markdown.split(\"\\n\");\n\n const content: JSONContent[] = lines.map((line) => {\n const children = parseLine(line);\n return children.length > 0\n ? { type: \"paragraph\", content: children }\n : { type: \"paragraph\" };\n });\n\n return { type: \"doc\", content };\n}\n\nfunction parseLine(line: string): JSONContent[] {\n const nodes: JSONContent[] = [];\n let lastIndex = 0;\n\n // Reset regex state\n MENTION_RE.lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = MENTION_RE.exec(line)) !== null) {\n const fullMatch = match[0];\n const rootLabel = match[1] || null;\n const label = match[2];\n const entityType = match[3] ?? \"unknown\";\n const id = match[4];\n\n // Text before this mention\n if (match.index > lastIndex) {\n nodes.push({\n type: \"text\",\n text: line.slice(lastIndex, match.index),\n });\n }\n\n // Mention node\n nodes.push({\n type: \"mention\",\n attrs: {\n id,\n label,\n entityType,\n rootLabel,\n },\n });\n\n lastIndex = match.index + fullMatch.length;\n }\n\n // Trailing text\n if (lastIndex < line.length) {\n nodes.push({\n type: \"text\",\n text: line.slice(lastIndex),\n });\n }\n\n return nodes;\n}\n\n/* ------------------------------------------------------------------ */\n/* Convenience helper: markdown → tokens + plain text */\n/* ------------------------------------------------------------------ */\n\n/**\n * Parse a markdown string and extract structured data from it.\n *\n * This is a convenience wrapper that combines `parseFromMarkdown`,\n * `extractTokens`, and `extractPlainText` into a single call.\n *\n * @example\n * ```ts\n * const { tokens, plainText } = extractFromMarkdown(\n * \"Check @Marketing[Q4 Strategy.pdf](file_1) for details\"\n * );\n * // tokens → [{ id: \"file_1\", type: \"unknown\", label: \"Q4 Strategy.pdf\" }]\n * // plainText → \"Check Q4 Strategy.pdf for details\"\n * ```\n */\nexport function extractFromMarkdown(markdown: string): {\n tokens: MentionToken[];\n plainText: string;\n} {\n const doc = parseFromMarkdown(markdown);\n return {\n tokens: extractTokens(doc),\n plainText: extractPlainText(doc),\n };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { MentionItem, MentionProvider } from \"../types/MentionProvider\";\nimport type { MentionToken } from \"../types/MentionToken\";\nimport type {\n SuggestionCallbackProps,\n SuggestionCallbacks,\n SuggestionCallbacksRef,\n SuggestionState,\n} from \"../core/suggestionPlugin\";\nimport { debounce } from \"../utils/debounce\";\n\n/* ------------------------------------------------------------------ */\n/* Public state exposed to the UI layer */\n/* ------------------------------------------------------------------ */\n\nexport type SuggestionUIState = {\n state: SuggestionState;\n items: MentionItem[];\n breadcrumbs: MentionItem[];\n activeIndex: number;\n loading: boolean;\n clientRect: (() => DOMRect | null) | null;\n trigger: string | null;\n query: string;\n};\n\nexport type SuggestionActions = {\n navigateUp: () => void;\n navigateDown: () => void;\n select: (item?: MentionItem) => void;\n goBack: () => void;\n close: () => void;\n searchNested: (query: string) => void;\n};\n\nexport type SuggestionHookOptions = {\n onMentionAdd?: (token: MentionToken) => void;\n};\n\nconst IDLE_STATE: SuggestionUIState = {\n state: \"idle\",\n items: [],\n breadcrumbs: [],\n activeIndex: 0,\n loading: false,\n clientRect: null,\n trigger: null,\n query: \"\",\n};\n\n/* ------------------------------------------------------------------ */\n/* Hook */\n/* ------------------------------------------------------------------ */\n\nexport function useSuggestion(\n providers: MentionProvider[],\n options: SuggestionHookOptions = {},\n) {\n const [uiState, setUIState] = useState<SuggestionUIState>(IDLE_STATE);\n\n const stateRef = useRef(uiState);\n stateRef.current = uiState;\n\n const providersRef = useRef(providers);\n providersRef.current = providers;\n\n const onMentionAddRef = useRef(options.onMentionAdd);\n onMentionAddRef.current = options.onMentionAdd;\n\n const commandRef = useRef<((attrs: Record<string, unknown>) => void) | null>(\n null,\n );\n const providerRef = useRef<MentionProvider | null>(null);\n\n const debouncedFetchRef = useRef<ReturnType<typeof debounce> | null>(null);\n\n useEffect(() => {\n return () => {\n debouncedFetchRef.current?.cancel();\n };\n }, []);\n\n /* ---------------------------------------------------------------- */\n /* Fetch items from the provider */\n /* ---------------------------------------------------------------- */\n\n const fetchItems = useCallback(\n async (\n provider: MentionProvider,\n query: string,\n parent?: MentionItem,\n useSearchAll?: boolean,\n ) => {\n setUIState((prev) => ({ ...prev, loading: true, state: \"loading\" }));\n\n try {\n let items: MentionItem[];\n\n if (useSearchAll && provider.searchAll) {\n items = await provider.searchAll(query);\n } else if (parent && provider.getChildren) {\n items = await provider.getChildren(parent, query);\n } else {\n items = await provider.getRootItems(query);\n }\n\n setUIState((prev) => ({\n ...prev,\n items,\n loading: false,\n state: \"showing\",\n activeIndex: 0,\n }));\n } catch {\n setUIState((prev) => ({\n ...prev,\n items: [],\n loading: false,\n state: \"showing\",\n }));\n }\n },\n [],\n );\n\n const scheduleFetch = useCallback(\n (\n provider: MentionProvider,\n query: string,\n parent?: MentionItem,\n useSearchAll?: boolean,\n ) => {\n debouncedFetchRef.current?.cancel();\n\n const ms = provider.debounceMs;\n if (ms && ms > 0) {\n setUIState((prev) => ({ ...prev, loading: true }));\n const debouncedFn = debounce(() => {\n fetchItems(provider, query, parent, useSearchAll);\n }, ms);\n debouncedFetchRef.current = debouncedFn;\n debouncedFn();\n } else {\n fetchItems(provider, query, parent, useSearchAll);\n }\n },\n [fetchItems],\n );\n\n /* ---------------------------------------------------------------- */\n /* Suggestion plugin callbacks */\n /* ---------------------------------------------------------------- */\n\n const onStart = useCallback(\n (props: SuggestionCallbackProps) => {\n const provider = providersRef.current.find(\n (p) => p.trigger === props.trigger,\n );\n if (!provider) return;\n\n providerRef.current = provider;\n commandRef.current = props.command;\n\n setUIState({\n state: \"loading\",\n items: [],\n breadcrumbs: [],\n activeIndex: 0,\n loading: true,\n clientRect: props.clientRect,\n trigger: props.trigger,\n query: props.query,\n });\n\n if (!props.query.trim() && provider.getRecentItems) {\n provider.getRecentItems().then((recentItems) => {\n const tagged = recentItems.map((item) => ({\n ...item,\n group: item.group ?? \"Recent\",\n }));\n setUIState((prev) => ({\n ...prev,\n items: tagged,\n loading: false,\n state: \"showing\",\n activeIndex: 0,\n }));\n }).catch(() => {\n scheduleFetch(provider, props.query);\n });\n return;\n }\n\n if (props.query.trim() && provider.searchAll) {\n scheduleFetch(provider, props.query, undefined, true);\n } else {\n scheduleFetch(provider, props.query);\n }\n },\n [scheduleFetch],\n );\n\n const onUpdate = useCallback(\n (props: SuggestionCallbackProps) => {\n const provider = providerRef.current;\n if (!provider) return;\n\n commandRef.current = props.command;\n const current = stateRef.current;\n\n if (current.breadcrumbs.length > 0) {\n setUIState((prev) => ({\n ...prev,\n breadcrumbs: [],\n clientRect: props.clientRect,\n query: props.query,\n activeIndex: 0,\n }));\n } else {\n setUIState((prev) => ({\n ...prev,\n clientRect: props.clientRect,\n query: props.query,\n }));\n }\n\n if (props.query.trim() && provider.searchAll) {\n scheduleFetch(provider, props.query, undefined, true);\n } else if (!props.query.trim() && provider.getRecentItems) {\n provider.getRecentItems().then((recentItems) => {\n const tagged = recentItems.map((item) => ({\n ...item,\n group: item.group ?? \"Recent\",\n }));\n setUIState((prev) => ({\n ...prev,\n items: tagged,\n loading: false,\n state: \"showing\",\n activeIndex: 0,\n }));\n }).catch(() => {\n scheduleFetch(provider, props.query);\n });\n } else {\n scheduleFetch(provider, props.query);\n }\n },\n [scheduleFetch],\n );\n\n const onExit = useCallback(() => {\n debouncedFetchRef.current?.cancel();\n providerRef.current = null;\n commandRef.current = null;\n setUIState(IDLE_STATE);\n }, []);\n\n /* ---------------------------------------------------------------- */\n /* Navigation actions */\n /* ---------------------------------------------------------------- */\n\n const navigateUp = useCallback(() => {\n setUIState((prev) => ({\n ...prev,\n activeIndex: Math.max(0, prev.activeIndex - 1),\n }));\n }, []);\n\n const navigateDown = useCallback(() => {\n setUIState((prev) => ({\n ...prev,\n activeIndex: Math.min(prev.items.length - 1, prev.activeIndex + 1),\n }));\n }, []);\n\n const select = useCallback(\n (item?: MentionItem) => {\n const current = stateRef.current;\n const selected = item ?? current.items[current.activeIndex];\n if (!selected) return;\n\n const provider = providerRef.current;\n\n if (selected.hasChildren && provider?.getChildren) {\n setUIState((prev) => ({\n ...prev,\n state: \"drilling\",\n breadcrumbs: [...prev.breadcrumbs, selected],\n items: [],\n activeIndex: 0,\n query: \"\",\n }));\n\n fetchItems(provider, \"\", selected);\n return;\n }\n\n const rootLabel =\n current.breadcrumbs.length > 0\n ? current.breadcrumbs[0].label\n : selected.rootLabel ?? null;\n\n if (commandRef.current) {\n commandRef.current({\n id: selected.id,\n label: selected.label,\n entityType: selected.type,\n rootLabel,\n });\n }\n\n onMentionAddRef.current?.({\n id: selected.id,\n type: selected.type,\n label: selected.label,\n });\n },\n [fetchItems],\n );\n\n const goBack = useCallback(() => {\n const provider = providerRef.current;\n if (!provider) return;\n\n setUIState((prev) => {\n const newBreadcrumbs = prev.breadcrumbs.slice(0, -1);\n const parent = newBreadcrumbs[newBreadcrumbs.length - 1];\n\n if (parent) {\n fetchItems(provider, \"\", parent);\n } else {\n fetchItems(provider, prev.query);\n }\n\n return {\n ...prev,\n breadcrumbs: newBreadcrumbs,\n items: [],\n activeIndex: 0,\n state: \"loading\" as const,\n };\n });\n }, [fetchItems]);\n\n const close = useCallback(() => {\n debouncedFetchRef.current?.cancel();\n setUIState(IDLE_STATE);\n }, []);\n\n /* ---------------------------------------------------------------- */\n /* Nested search */\n /* ---------------------------------------------------------------- */\n\n const searchNested = useCallback(\n (query: string) => {\n const provider = providerRef.current;\n if (!provider) return;\n\n const current = stateRef.current;\n const parent = current.breadcrumbs[current.breadcrumbs.length - 1];\n if (parent) {\n scheduleFetch(provider, query, parent);\n }\n },\n [scheduleFetch],\n );\n\n /* ---------------------------------------------------------------- */\n /* Keyboard handler */\n /* ---------------------------------------------------------------- */\n\n const onKeyDown = useCallback(\n ({ event }: { event: KeyboardEvent }): boolean => {\n const current = stateRef.current;\n if (current.state === \"idle\") return false;\n\n switch (event.key) {\n case \"ArrowUp\":\n event.preventDefault();\n navigateUp();\n return true;\n case \"ArrowDown\":\n event.preventDefault();\n navigateDown();\n return true;\n case \"Enter\": {\n event.preventDefault();\n const selectedItem = current.items[current.activeIndex];\n if (selectedItem) {\n select(selectedItem);\n }\n return true;\n }\n case \"Tab\": {\n event.preventDefault();\n const selectedItem = current.items[current.activeIndex];\n if (selectedItem) {\n select(selectedItem);\n }\n return true;\n }\n case \"ArrowRight\": {\n const activeItem = current.items[current.activeIndex];\n if (activeItem?.hasChildren) {\n event.preventDefault();\n select(activeItem);\n return true;\n }\n return false;\n }\n case \"ArrowLeft\":\n if (current.breadcrumbs.length > 0) {\n event.preventDefault();\n goBack();\n return true;\n }\n return false;\n case \"Escape\":\n event.preventDefault();\n close();\n return true;\n default:\n return false;\n }\n },\n [navigateUp, navigateDown, select, goBack, close],\n );\n\n /* ---------------------------------------------------------------- */\n /* Build a ref that always points to the latest callbacks. */\n /* ---------------------------------------------------------------- */\n\n const callbacksRef: SuggestionCallbacksRef = useRef<SuggestionCallbacks>({\n onStart,\n onUpdate,\n onExit,\n onKeyDown,\n });\n\n callbacksRef.current = { onStart, onUpdate, onExit, onKeyDown };\n\n const actions: SuggestionActions = {\n navigateUp,\n navigateDown,\n select,\n goBack,\n close,\n searchNested,\n };\n\n return { uiState, actions, callbacksRef };\n}\n","/**\n * Returns a debounced version of `fn` that delays invocation until\n * `ms` milliseconds have elapsed since the last call.\n * Call `.cancel()` on the returned function to clear any pending timer.\n */\nexport function debounce<T extends (...args: any[]) => void>(\n fn: T,\n ms: number,\n): T & { cancel: () => void } {\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n const debounced = ((...args: any[]) => {\n if (timer != null) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n fn(...args);\n }, ms);\n }) as T & { cancel: () => void };\n\n debounced.cancel = () => {\n if (timer != null) {\n clearTimeout(timer);\n timer = null;\n }\n };\n\n return debounced;\n}\n","import React, { useEffect, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { MentionItem } from \"../types/MentionProvider\";\nimport { listboxAttrs, optionAttrs } from \"../utils/ariaHelpers\";\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport type SuggestionListProps = {\n items: MentionItem[];\n activeIndex: number;\n breadcrumbs: MentionItem[];\n loading: boolean;\n trigger: string | null;\n query: string;\n clientRect: (() => DOMRect | null) | null;\n onSelect: (item: MentionItem) => void;\n onHover: (index: number) => void;\n onGoBack: () => void;\n onSearchNested?: (query: string) => void;\n onNavigateUp?: () => void;\n onNavigateDown?: () => void;\n onClose?: () => void;\n onFocusEditor?: () => void;\n renderItem?: (item: MentionItem, depth: number) => ReactNode;\n renderEmpty?: (query: string) => ReactNode;\n renderLoading?: () => ReactNode;\n renderGroupHeader?: (group: string) => ReactNode;\n listboxId: string;\n};\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport function SuggestionList({\n items,\n activeIndex,\n breadcrumbs,\n loading,\n trigger,\n query,\n clientRect,\n onSelect,\n onHover,\n onGoBack,\n onSearchNested,\n onNavigateUp,\n onNavigateDown,\n onClose,\n onFocusEditor,\n renderItem,\n renderEmpty,\n renderLoading,\n renderGroupHeader,\n listboxId,\n}: SuggestionListProps) {\n const listRef = useRef<HTMLDivElement>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const depth = breadcrumbs.length;\n const [nestedQuery, setNestedQuery] = useState(\"\");\n\n const breadcrumbKey = breadcrumbs.map((b) => b.id).join(\"/\");\n const prevBreadcrumbKey = useRef(breadcrumbKey);\n useEffect(() => {\n if (prevBreadcrumbKey.current !== breadcrumbKey) {\n setNestedQuery(\"\");\n prevBreadcrumbKey.current = breadcrumbKey;\n }\n }, [breadcrumbKey]);\n\n const prevBreadcrumbsLen = useRef(breadcrumbs.length);\n useEffect(() => {\n if (prevBreadcrumbsLen.current > 0 && breadcrumbs.length === 0) {\n onFocusEditor?.();\n } else if (breadcrumbs.length > 0 && searchInputRef.current) {\n requestAnimationFrame(() => searchInputRef.current?.focus());\n }\n prevBreadcrumbsLen.current = breadcrumbs.length;\n }, [breadcrumbKey, breadcrumbs.length, onFocusEditor]);\n\n useEffect(() => {\n if (!listRef.current) return;\n const active = listRef.current.querySelector('[aria-selected=\"true\"]');\n active?.scrollIntoView({ block: \"nearest\" });\n }, [activeIndex]);\n\n const { style, position } = usePopoverPosition(clientRect);\n\n const activeQuery = breadcrumbs.length > 0 ? nestedQuery : query;\n const showEmpty = !loading && items.length === 0 && activeQuery.trim().length > 0;\n\n if (items.length === 0 && !loading && !showEmpty) return null;\n\n const handleSearchKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n onNavigateDown?.();\n break;\n case \"ArrowUp\":\n e.preventDefault();\n onNavigateUp?.();\n break;\n case \"Enter\": {\n e.preventDefault();\n e.stopPropagation();\n const selectedItem = items[activeIndex];\n if (selectedItem) onSelect(selectedItem);\n break;\n }\n case \"Escape\":\n e.preventDefault();\n onFocusEditor?.();\n onClose?.();\n break;\n case \"ArrowLeft\":\n if (nestedQuery === \"\" || e.currentTarget.selectionStart === 0) {\n e.preventDefault();\n onGoBack();\n }\n break;\n case \"ArrowRight\": {\n const item = items[activeIndex];\n if (item?.hasChildren) {\n e.preventDefault();\n onSelect(item);\n }\n break;\n }\n case \"Backspace\":\n if (nestedQuery === \"\") {\n e.preventDefault();\n onGoBack();\n }\n break;\n }\n };\n\n const hasGroups = items.some((item) => item.group);\n\n return (\n <div\n data-suggestions=\"\"\n data-trigger={trigger}\n data-suggestions-position={position}\n style={style}\n ref={listRef}\n >\n {breadcrumbs.length > 0 && (\n <div data-suggestion-breadcrumb=\"\">\n <button\n type=\"button\"\n data-suggestion-back=\"\"\n onClick={onGoBack}\n aria-label=\"Go back\"\n >\n ←\n </button>\n {breadcrumbs.map((crumb, i) => (\n <span key={crumb.id} data-suggestion-breadcrumb-item=\"\">\n {i > 0 && <span data-suggestion-breadcrumb-sep=\"\">/</span>}\n {crumb.label}\n </span>\n ))}\n </div>\n )}\n\n {breadcrumbs.length > 0 && (\n <div data-suggestion-search=\"\">\n <input\n ref={searchInputRef}\n type=\"text\"\n data-suggestion-search-input=\"\"\n placeholder=\"Search...\"\n value={nestedQuery}\n onChange={(e) => {\n const q = e.target.value;\n setNestedQuery(q);\n onSearchNested?.(q);\n }}\n onKeyDown={handleSearchKeyDown}\n autoComplete=\"off\"\n spellCheck={false}\n />\n </div>\n )}\n\n {loading && (\n <div data-suggestion-loading=\"\">\n {renderLoading ? renderLoading() : \"Loading...\"}\n </div>\n )}\n\n {showEmpty && (\n <div data-suggestion-empty=\"\">\n {renderEmpty ? renderEmpty(activeQuery) : \"No results\"}\n </div>\n )}\n\n {!loading && items.length > 0 && (\n <div {...listboxAttrs(listboxId, `${trigger ?? \"\"} suggestions`)}>\n {hasGroups\n ? renderGroupedItems(items, activeIndex, depth, onSelect, onHover, renderItem, renderGroupHeader)\n : items.map((item, index) => (\n <SuggestionItem\n key={item.id}\n item={item}\n index={index}\n isActive={index === activeIndex}\n depth={depth}\n onSelect={onSelect}\n onHover={onHover}\n renderItem={renderItem}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Grouped rendering */\n/* ------------------------------------------------------------------ */\n\nfunction renderGroupedItems(\n items: MentionItem[],\n activeIndex: number,\n depth: number,\n onSelect: (item: MentionItem) => void,\n onHover: (index: number) => void,\n renderItem?: (item: MentionItem, depth: number) => ReactNode,\n renderGroupHeader?: (group: string) => ReactNode,\n) {\n const elements: ReactNode[] = [];\n let lastGroup: string | undefined;\n\n items.forEach((item, index) => {\n if (item.group && item.group !== lastGroup) {\n lastGroup = item.group;\n elements.push(\n <div key={`group-${item.group}`} data-suggestion-group-header=\"\">\n {renderGroupHeader ? renderGroupHeader(item.group) : item.group}\n </div>,\n );\n }\n\n elements.push(\n <SuggestionItem\n key={item.id}\n item={item}\n index={index}\n isActive={index === activeIndex}\n depth={depth}\n onSelect={onSelect}\n onHover={onHover}\n renderItem={renderItem}\n />,\n );\n });\n\n return elements;\n}\n\n/* ------------------------------------------------------------------ */\n/* Single item */\n/* ------------------------------------------------------------------ */\n\nfunction SuggestionItem({\n item,\n index,\n isActive,\n depth,\n onSelect,\n onHover,\n renderItem,\n}: {\n item: MentionItem;\n index: number;\n isActive: boolean;\n depth: number;\n onSelect: (item: MentionItem) => void;\n onHover: (index: number) => void;\n renderItem?: (item: MentionItem, depth: number) => ReactNode;\n}) {\n const itemId = `mention-option-${item.id}`;\n\n return (\n <div\n {...optionAttrs(itemId, isActive, index)}\n data-suggestion-item=\"\"\n data-suggestion-item-active={isActive ? \"\" : undefined}\n data-has-children={item.hasChildren ? \"\" : undefined}\n onMouseEnter={() => onHover(index)}\n onClick={() => onSelect(item)}\n >\n {renderItem ? (\n renderItem(item, depth)\n ) : (\n <DefaultSuggestionItem item={item} />\n )}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Default item render */\n/* ------------------------------------------------------------------ */\n\nfunction DefaultSuggestionItem({ item }: { item: MentionItem }) {\n return (\n <>\n {item.icon && (\n <span data-suggestion-item-icon=\"\">{item.icon}</span>\n )}\n <span data-suggestion-item-label=\"\">{item.label}</span>\n {item.description && (\n <span data-suggestion-item-description=\"\">{item.description}</span>\n )}\n {item.hasChildren && (\n <span data-suggestion-item-chevron=\"\" aria-hidden=\"true\">\n ›\n </span>\n )}\n </>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Popover positioning with edge-aware flipping */\n/* ------------------------------------------------------------------ */\n\nconst POPOVER_HEIGHT_ESTIMATE = 280;\nconst POPOVER_WIDTH_ESTIMATE = 360;\n\nfunction usePopoverPosition(\n clientRect: (() => DOMRect | null) | null,\n): { style: React.CSSProperties; position: \"above\" | \"below\" } {\n if (!clientRect) {\n return { style: { display: \"none\" }, position: \"below\" };\n }\n\n const rect = clientRect();\n if (!rect) {\n return { style: { display: \"none\" }, position: \"below\" };\n }\n\n const viewportH = typeof window !== \"undefined\" ? window.innerHeight : 800;\n const viewportW = typeof window !== \"undefined\" ? window.innerWidth : 1200;\n\n const spaceBelow = viewportH - rect.bottom;\n const shouldFlip = spaceBelow < POPOVER_HEIGHT_ESTIMATE && rect.top > spaceBelow;\n\n let left = rect.left;\n if (left + POPOVER_WIDTH_ESTIMATE > viewportW) {\n left = Math.max(0, viewportW - POPOVER_WIDTH_ESTIMATE);\n }\n\n if (shouldFlip) {\n return {\n style: {\n position: \"fixed\",\n left: `${left}px`,\n bottom: `${viewportH - rect.top + 4}px`,\n zIndex: 50,\n },\n position: \"above\",\n };\n }\n\n return {\n style: {\n position: \"fixed\",\n left: `${left}px`,\n top: `${rect.bottom + 4}px`,\n zIndex: 50,\n },\n position: \"below\",\n };\n}\n","/**\n * Generates ARIA attributes for the suggestion combobox pattern.\n */\n\nexport function comboboxAttrs(expanded: boolean, listboxId: string) {\n return {\n role: \"combobox\" as const,\n \"aria-haspopup\": \"listbox\" as const,\n \"aria-expanded\": expanded,\n \"aria-owns\": expanded ? listboxId : undefined,\n };\n}\n\nexport function listboxAttrs(id: string, label: string) {\n return {\n id,\n role: \"listbox\" as const,\n \"aria-label\": label,\n };\n}\n\nexport function optionAttrs(\n id: string,\n selected: boolean,\n index: number,\n) {\n return {\n id,\n role: \"option\" as const,\n \"aria-selected\": selected,\n \"aria-posinset\": index + 1,\n };\n}\n"],"mappings":"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","names":["import_react","import_react","import_core","import_state","import_core","StarterKit","Placeholder","editor","import_react","import_react","import_jsx_runtime","MentionsInput"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/MentionsInput.tsx","../src/hooks/useMentionsEditor.ts","../src/core/mentionExtension.ts","../src/core/suggestionPlugin.ts","../src/core/markdownSerializer.ts","../src/core/markdownParser.ts","../src/hooks/useSuggestion.ts","../src/utils/debounce.ts","../src/components/SuggestionList.tsx","../src/utils/ariaHelpers.ts","../src/hooks/useMentionsContent.ts"],"sourcesContent":["/* ------------------------------------------------------------------ */\n/* Components */\n/* ------------------------------------------------------------------ */\nexport { MentionsInput } from \"./components/MentionsInput\";\n\n/* ------------------------------------------------------------------ */\n/* Hooks */\n/* ------------------------------------------------------------------ */\nexport { useMentionsContent } from \"./hooks/useMentionsContent\";\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\nexport type { MentionToken } from \"./types/MentionToken\";\nexport type {\n MentionProvider,\n MentionItem,\n} from \"./types/MentionProvider\";\nexport type { MentionsOutput } from \"./types/MentionsOutput\";\nexport type {\n MentionsInputProps,\n MentionsInputHandle,\n} from \"./types/MentionsInputProps\";\n\n/* ------------------------------------------------------------------ */\n/* Utilities */\n/* ------------------------------------------------------------------ */\nexport { serializeToMarkdown } from \"./core/markdownSerializer\";\nexport { parseFromMarkdown, extractFromMarkdown } from \"./core/markdownParser\";\n","import React, { forwardRef, useCallback, useId, useImperativeHandle } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { EditorContent } from \"@tiptap/react\";\nimport { useMentionsEditor } from \"../hooks/useMentionsEditor\";\nimport { useSuggestion } from \"../hooks/useSuggestion\";\nimport { SuggestionList } from \"./SuggestionList\";\nimport { comboboxAttrs } from \"../utils/ariaHelpers\";\nimport type {\n MentionsInputProps,\n MentionsInputHandle,\n} from \"../types/MentionsInputProps\";\n\n/**\n * `<MentionsInput>` — the single public component.\n *\n * A structured text editor with typed entity tokens.\n * Consumers register `providers` for each trigger character,\n * and receive structured output via `onChange` and `onSubmit`.\n */\nexport const MentionsInput = forwardRef<MentionsInputHandle, MentionsInputProps>(\n function MentionsInput(\n {\n value,\n providers,\n onChange,\n placeholder = \"Type a message...\",\n autoFocus = false,\n disabled = false,\n className,\n onSubmit,\n clearOnSubmit = true,\n maxLength,\n renderItem,\n renderChip,\n renderEmpty,\n renderLoading,\n renderGroupHeader,\n onFocus,\n onBlur,\n onMentionAdd,\n onMentionRemove,\n onMentionClick,\n onMentionHover,\n minHeight,\n maxHeight,\n submitKey = \"enter\",\n allowTrigger,\n validateMention,\n portalContainer,\n streaming,\n onStreamingComplete,\n },\n ref,\n ) {\n const instanceId = useId();\n const listboxId = `mentions-listbox-${instanceId}`;\n\n const { uiState, actions, callbacksRef } = useSuggestion(providers, {\n onMentionAdd,\n });\n\n const { editor, getOutput, clear, setContent, appendText, focus } = useMentionsEditor({\n providers,\n value,\n onChange,\n onSubmit,\n clearOnSubmit,\n placeholder,\n autoFocus,\n editable: !disabled,\n callbacksRef,\n onFocus,\n onBlur,\n submitKey,\n onMentionRemove,\n onMentionClick,\n onMentionHover,\n allowTrigger,\n validateMention,\n streaming,\n onStreamingComplete,\n });\n\n useImperativeHandle(\n ref,\n () => ({ clear, setContent, appendText, focus, getOutput }),\n [clear, setContent, appendText, focus, getOutput],\n );\n\n const isExpanded = uiState.state !== \"idle\";\n\n const handleHover = useCallback((index: number) => {\n void index;\n }, []);\n\n const handleFocusEditor = useCallback(() => {\n editor?.commands.focus();\n }, [editor]);\n\n const editorStyle: React.CSSProperties = {};\n if (minHeight != null) editorStyle.minHeight = `${minHeight}px`;\n if (maxHeight != null) {\n editorStyle.maxHeight = `${maxHeight}px`;\n editorStyle.overflowY = \"auto\";\n }\n\n const suggestionList = isExpanded ? (\n <SuggestionList\n items={uiState.items}\n activeIndex={uiState.activeIndex}\n breadcrumbs={uiState.breadcrumbs}\n loading={uiState.loading}\n trigger={uiState.trigger}\n query={uiState.query}\n clientRect={uiState.clientRect}\n onSelect={(item) => actions.select(item)}\n onHover={handleHover}\n onGoBack={actions.goBack}\n onSearchNested={actions.searchNested}\n onNavigateUp={actions.navigateUp}\n onNavigateDown={actions.navigateDown}\n onClose={actions.close}\n onFocusEditor={handleFocusEditor}\n renderItem={renderItem}\n renderEmpty={renderEmpty}\n renderLoading={renderLoading}\n renderGroupHeader={renderGroupHeader}\n listboxId={listboxId}\n />\n ) : null;\n\n return (\n <div\n className={className}\n data-mentions-input=\"\"\n data-disabled={disabled ? \"\" : undefined}\n {...comboboxAttrs(isExpanded, listboxId)}\n aria-activedescendant={\n isExpanded && uiState.items[uiState.activeIndex]\n ? `mention-option-${uiState.items[uiState.activeIndex].id}`\n : undefined\n }\n >\n <div style={editorStyle}>\n <EditorContent editor={editor} />\n </div>\n\n {portalContainer\n ? suggestionList && createPortal(suggestionList, portalContainer)\n : suggestionList}\n </div>\n );\n },\n);\n","import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { useEditor } from \"@tiptap/react\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\nimport { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { MentionNode } from \"../core/mentionExtension\";\nimport { createSuggestionExtension } from \"../core/suggestionPlugin\";\nimport type { StreamingRef } from \"../core/suggestionPlugin\";\nimport {\n serializeToMarkdown,\n extractTokens,\n extractPlainText,\n} from \"../core/markdownSerializer\";\nimport { parseFromMarkdown } from \"../core/markdownParser\";\nimport type { MentionProvider } from \"../types/MentionProvider\";\nimport type { MentionToken } from \"../types/MentionToken\";\nimport type { MentionsOutput } from \"../types/MentionsOutput\";\nimport type { SuggestionCallbacksRef } from \"../core/suggestionPlugin\";\n\n/* ------------------------------------------------------------------ */\n/* Helper: build MentionsOutput from the current editor */\n/* ------------------------------------------------------------------ */\n\nfunction buildOutput(editor: { getJSON: () => any }): MentionsOutput {\n const json = editor.getJSON();\n return {\n markdown: serializeToMarkdown(json),\n tokens: extractTokens(json),\n plainText: extractPlainText(json),\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Collect all mention tokens from a doc JSON */\n/* ------------------------------------------------------------------ */\n\nfunction collectMentionTokens(doc: any): MentionToken[] {\n const tokens: MentionToken[] = [];\n function walk(node: any) {\n if (node.type === \"mention\" && node.attrs) {\n tokens.push({\n id: node.attrs.id,\n type: node.attrs.entityType ?? node.attrs.type,\n label: node.attrs.label,\n });\n }\n if (node.content) {\n for (const child of node.content) walk(child);\n }\n }\n walk(doc);\n return tokens;\n}\n\n/* ------------------------------------------------------------------ */\n/* Submit keyboard shortcut extension (Cmd/Ctrl+Enter) */\n/* ------------------------------------------------------------------ */\n\nfunction createSubmitExtension(\n onSubmitRef: React.RefObject<((output: MentionsOutput) => void) | undefined>,\n clearOnSubmitRef: React.RefObject<boolean>,\n submitKeyRef: React.RefObject<string>,\n) {\n return Extension.create({\n name: \"submitShortcut\",\n priority: 150,\n\n addKeyboardShortcuts() {\n return {\n \"Mod-Enter\": () => {\n const key = submitKeyRef.current;\n if (key === \"mod+enter\" || key === \"enter\") {\n if (onSubmitRef.current) {\n onSubmitRef.current(buildOutput(this.editor));\n if (clearOnSubmitRef.current) {\n this.editor.commands.clearContent(true);\n }\n }\n return true;\n }\n return false;\n },\n };\n },\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Enter key handling */\n/* ------------------------------------------------------------------ */\n\nconst enterSubmitPluginKey = new PluginKey(\"enterSubmit\");\n\nfunction createEnterExtension(\n onSubmitRef: React.RefObject<((output: MentionsOutput) => void) | undefined>,\n clearOnSubmitRef: React.RefObject<boolean>,\n submitKeyRef: React.RefObject<string>,\n) {\n return Extension.create({\n name: \"enterSubmit\",\n priority: 150,\n\n addProseMirrorPlugins() {\n const editor = this.editor;\n\n return [\n new Plugin({\n key: enterSubmitPluginKey,\n props: {\n handleKeyDown(_view, event) {\n if (event.key !== \"Enter\") return false;\n\n const key = submitKeyRef.current;\n\n if (key === \"none\") return false;\n\n if (key === \"mod+enter\") {\n // Enter = new line (default PM behavior handles it)\n // Shift+Enter also new line\n return false;\n }\n\n // key === \"enter\" (default)\n if (event.shiftKey) {\n editor.commands.splitBlock();\n return true;\n }\n\n if (event.metaKey || event.ctrlKey) return false;\n\n if (onSubmitRef.current) {\n onSubmitRef.current(buildOutput(editor));\n if (clearOnSubmitRef.current) {\n editor.commands.clearContent(true);\n }\n }\n return true;\n },\n },\n }),\n ];\n },\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Mention removal detection plugin */\n/* ------------------------------------------------------------------ */\n\nconst mentionRemovePluginKey = new PluginKey(\"mentionRemove\");\n\nfunction createMentionRemoveExtension(\n onMentionRemoveRef: React.RefObject<((token: MentionToken) => void) | undefined>,\n) {\n return Extension.create({\n name: \"mentionRemoveDetector\",\n priority: 100,\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: mentionRemovePluginKey,\n appendTransaction(transactions, oldState, newState) {\n if (!onMentionRemoveRef.current) return null;\n\n const oldMentions = collectMentionTokens(oldState.doc.toJSON());\n const newMentions = collectMentionTokens(newState.doc.toJSON());\n\n if (oldMentions.length <= newMentions.length) return null;\n\n const newIds = new Set(newMentions.map((m) => m.id));\n for (const m of oldMentions) {\n if (!newIds.has(m.id)) {\n onMentionRemoveRef.current(m);\n }\n }\n\n return null;\n },\n }),\n ];\n },\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Streaming input blocker plugin */\n/* ------------------------------------------------------------------ */\n\nconst streamingBlockPluginKey = new PluginKey(\"streamingBlock\");\n\nfunction createStreamingBlockExtension(streamingRef: StreamingRef) {\n return Extension.create({\n name: \"streamingBlock\",\n priority: 200,\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: streamingBlockPluginKey,\n props: {\n handleKeyDown() {\n return streamingRef.current;\n },\n handleKeyPress() {\n return streamingRef.current;\n },\n handlePaste() {\n return streamingRef.current;\n },\n handleDrop() {\n return streamingRef.current;\n },\n },\n }),\n ];\n },\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Hook */\n/* ------------------------------------------------------------------ */\n\ntype UseMentionsEditorOptions = {\n providers: MentionProvider[];\n value?: string;\n onChange?: (output: MentionsOutput) => void;\n onSubmit?: (output: MentionsOutput) => void;\n clearOnSubmit?: boolean;\n placeholder?: string;\n autoFocus?: boolean;\n editable?: boolean;\n callbacksRef: SuggestionCallbacksRef;\n onFocus?: () => void;\n onBlur?: () => void;\n submitKey?: string;\n onMentionRemove?: (token: MentionToken) => void;\n onMentionClick?: (token: MentionToken, event: MouseEvent) => void;\n onMentionHover?: (token: MentionToken) => ReactNode;\n allowTrigger?: (trigger: string, context: { textBefore: string }) => boolean;\n validateMention?: (token: MentionToken) => boolean | Promise<boolean>;\n streaming?: boolean;\n onStreamingComplete?: (output: MentionsOutput) => void;\n};\n\nexport function useMentionsEditor({\n providers,\n value,\n onChange,\n onSubmit,\n clearOnSubmit = true,\n placeholder,\n autoFocus = false,\n editable = true,\n callbacksRef,\n onFocus,\n onBlur,\n submitKey = \"enter\",\n onMentionRemove,\n onMentionClick,\n onMentionHover,\n allowTrigger,\n validateMention,\n streaming = false,\n onStreamingComplete,\n}: UseMentionsEditorOptions) {\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n const onSubmitRef = useRef(onSubmit);\n onSubmitRef.current = onSubmit;\n\n const clearOnSubmitRef = useRef(clearOnSubmit);\n clearOnSubmitRef.current = clearOnSubmit;\n\n const onFocusRef = useRef(onFocus);\n onFocusRef.current = onFocus;\n\n const onBlurRef = useRef(onBlur);\n onBlurRef.current = onBlur;\n\n const submitKeyRef = useRef(submitKey);\n submitKeyRef.current = submitKey;\n\n const onMentionRemoveRef = useRef(onMentionRemove);\n onMentionRemoveRef.current = onMentionRemove;\n\n const onMentionClickRef = useRef(onMentionClick);\n onMentionClickRef.current = onMentionClick;\n\n const onMentionHoverRef = useRef(onMentionHover);\n onMentionHoverRef.current = onMentionHover;\n\n const allowTriggerRef = useRef(allowTrigger);\n allowTriggerRef.current = allowTrigger;\n\n const validateMentionRef = useRef(validateMention);\n validateMentionRef.current = validateMention;\n\n const onStreamingCompleteRef = useRef(onStreamingComplete);\n onStreamingCompleteRef.current = onStreamingComplete;\n\n // Streaming state — mutable ref so ProseMirror plugins can read it\n // without re-creating the extension chain.\n const streamingRef = useRef<boolean>(streaming);\n streamingRef.current = streaming;\n const prevStreamingRef = useRef(streaming);\n\n // Throttle state for onChange during streaming\n const throttleTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pendingOutputRef = useRef<MentionsOutput | null>(null);\n\n // Track internal value to avoid controlled-value infinite loops\n const internalMarkdownRef = useRef<string | null>(null);\n\n const initialContent = useMemo(() => {\n if (!value) return undefined;\n return parseFromMarkdown(value);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const triggersKey = providers.map((p) => p.trigger).join(\",\");\n const triggers = useMemo(\n () => providers.map((p) => p.trigger),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [triggersKey],\n );\n\n const suggestionExtension = useMemo(\n () =>\n createSuggestionExtension(\n triggers,\n callbacksRef,\n allowTriggerRef,\n streamingRef,\n ),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [triggersKey],\n );\n\n const submitExt = useMemo(\n () => createSubmitExtension(onSubmitRef, clearOnSubmitRef, submitKeyRef),\n [],\n );\n const enterExt = useMemo(\n () => createEnterExtension(onSubmitRef, clearOnSubmitRef, submitKeyRef),\n [],\n );\n const mentionRemoveExt = useMemo(\n () => createMentionRemoveExtension(onMentionRemoveRef),\n [],\n );\n\n const streamingBlockExt = useMemo(\n () => createStreamingBlockExtension(streamingRef),\n [],\n );\n\n const mentionNodeExt = useMemo(\n () =>\n MentionNode.configure({\n onClickRef: onMentionClickRef,\n onHoverRef: onMentionHoverRef,\n }),\n [],\n );\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({\n heading: false,\n blockquote: false,\n codeBlock: false,\n bulletList: false,\n orderedList: false,\n listItem: false,\n horizontalRule: false,\n hardBreak: false,\n }),\n Placeholder.configure({\n placeholder: ({ editor }) =>\n editor.isEmpty ? (placeholder ?? \"Type a message...\") : \"\",\n showOnlyCurrent: true,\n }),\n mentionNodeExt,\n suggestionExtension,\n submitExt,\n enterExt,\n mentionRemoveExt,\n streamingBlockExt,\n ],\n content: initialContent,\n autofocus: autoFocus ? \"end\" : false,\n editable,\n editorProps: {\n attributes: {\n class: \"mentions-editor\",\n },\n },\n onUpdate: ({ editor }) => {\n const output = buildOutput(editor);\n internalMarkdownRef.current = output.markdown;\n\n if (streamingRef.current) {\n pendingOutputRef.current = output;\n if (!throttleTimerRef.current) {\n throttleTimerRef.current = setTimeout(() => {\n throttleTimerRef.current = null;\n if (pendingOutputRef.current) {\n onChangeRef.current?.(pendingOutputRef.current);\n pendingOutputRef.current = null;\n }\n }, 150);\n }\n } else {\n onChangeRef.current?.(output);\n }\n },\n onFocus: () => {\n onFocusRef.current?.();\n },\n onBlur: () => {\n onBlurRef.current?.();\n },\n });\n\n // Flush throttled onChange and fire onStreamingComplete when streaming ends\n useEffect(() => {\n if (prevStreamingRef.current && !streaming && editor) {\n if (throttleTimerRef.current) {\n clearTimeout(throttleTimerRef.current);\n throttleTimerRef.current = null;\n }\n const output = buildOutput(editor);\n onChangeRef.current?.(output);\n onStreamingCompleteRef.current?.(output);\n pendingOutputRef.current = null;\n }\n prevStreamingRef.current = streaming;\n }, [streaming, editor]);\n\n // Clean up throttle timer on unmount\n useEffect(() => {\n return () => {\n if (throttleTimerRef.current) {\n clearTimeout(throttleTimerRef.current);\n }\n };\n }, []);\n\n // Sync editable state\n useEffect(() => {\n if (editor && editor.isEditable !== editable) {\n editor.setEditable(editable);\n }\n }, [editor, editable]);\n\n // Controlled value: update editor when external value changes\n useEffect(() => {\n if (!editor || value === undefined) return;\n if (value === internalMarkdownRef.current) return;\n const doc = parseFromMarkdown(value);\n editor.commands.setContent(doc);\n internalMarkdownRef.current = value;\n }, [editor, value]);\n\n // Mention validation\n useEffect(() => {\n if (!editor || !validateMention) return;\n\n const runValidation = async () => {\n const doc = editor.getJSON();\n const tokens = collectMentionTokens(doc);\n const invalidIds = new Set<string>();\n\n await Promise.all(\n tokens.map(async (token) => {\n const valid = await validateMention(token);\n if (!valid) invalidIds.add(token.id);\n }),\n );\n\n editor.view.dom.querySelectorAll(\"[data-mention]\").forEach((el) => {\n const id = el.getAttribute(\"data-id\");\n if (id && invalidIds.has(id)) {\n el.setAttribute(\"data-mention-invalid\", \"\");\n } else {\n el.removeAttribute(\"data-mention-invalid\");\n }\n });\n };\n\n runValidation();\n }, [editor, validateMention]);\n\n /* ---------------------------------------------------------------- */\n /* Imperative methods */\n /* ---------------------------------------------------------------- */\n\n const clear = useCallback(() => {\n editor?.commands.clearContent(true);\n }, [editor]);\n\n const setContent = useCallback(\n (markdown: string) => {\n if (!editor) return;\n const doc = parseFromMarkdown(markdown);\n editor.commands.setContent(doc);\n internalMarkdownRef.current = markdown;\n if (streamingRef.current) {\n editor.commands.focus(\"end\");\n }\n },\n [editor],\n );\n\n const appendText = useCallback(\n (text: string) => {\n if (!editor) return;\n const endPos = editor.state.doc.content.size - 1;\n editor.commands.insertContentAt(endPos, text);\n if (streamingRef.current) {\n editor.commands.focus(\"end\");\n }\n },\n [editor],\n );\n\n const focus = useCallback(() => {\n editor?.commands.focus(\"end\");\n }, [editor]);\n\n const getOutput = useCallback((): MentionsOutput | null => {\n if (!editor) return null;\n return buildOutput(editor);\n }, [editor]);\n\n return { editor, getOutput, clear, setContent, appendText, focus };\n}\n","import { mergeAttributes, Node } from \"@tiptap/core\";\nimport type { ReactNode } from \"react\";\nimport type { MentionToken } from \"../types/MentionToken\";\n\nexport interface MentionNodeAttrs {\n id: string;\n label: string;\n entityType: string;\n rootLabel?: string | null;\n}\n\nconst DEFAULT_PREFIXES: Record<string, string> = {\n workspace: \"@\",\n contract: \"@\",\n file: \"#\",\n web: \":\",\n};\n\nexport type MentionNodeOptions = {\n onClickRef?: React.RefObject<((token: MentionToken, event: MouseEvent) => void) | undefined>;\n onHoverRef?: React.RefObject<((token: MentionToken) => ReactNode) | undefined>;\n};\n\nexport const MentionNode = Node.create<MentionNodeOptions>({\n name: \"mention\",\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: true,\n draggable: false,\n\n addOptions() {\n return {\n onClickRef: undefined,\n onHoverRef: undefined,\n };\n },\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-id\"),\n renderHTML: (attributes) => ({ \"data-id\": attributes.id }),\n },\n label: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-label\"),\n renderHTML: (attributes) => ({ \"data-label\": attributes.label }),\n },\n entityType: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-type\"),\n renderHTML: (attributes) => ({ \"data-type\": attributes.entityType }),\n },\n rootLabel: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-root-label\"),\n renderHTML: (attributes) =>\n attributes.rootLabel\n ? { \"data-root-label\": attributes.rootLabel }\n : {},\n },\n };\n },\n\n parseHTML() {\n return [{ tag: 'span[data-mention]' }];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const entityType = node.attrs.entityType as string;\n const label = node.attrs.label as string;\n const prefix = DEFAULT_PREFIXES[entityType] ?? \"@\";\n const display = `${prefix}${label}`;\n\n const hasClick = !!this.options.onClickRef?.current;\n const extraAttrs: Record<string, string> = {};\n if (hasClick) {\n extraAttrs[\"data-mention-clickable\"] = \"\";\n }\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-mention\": \"\",\n class: \"mention-chip\",\n ...extraAttrs,\n }),\n display,\n ];\n },\n\n renderText({ node }) {\n const entityType = node.attrs.entityType as string;\n const label = node.attrs.label as string;\n const prefix = DEFAULT_PREFIXES[entityType] ?? \"@\";\n return `${prefix}${label}`;\n },\n\n addNodeView() {\n const options = this.options;\n\n return ({ node, HTMLAttributes }) => {\n const entityType = node.attrs.entityType as string;\n const label = node.attrs.label as string;\n const id = node.attrs.id as string;\n const prefix = DEFAULT_PREFIXES[entityType] ?? \"@\";\n\n const dom = document.createElement(\"span\");\n Object.entries(\n mergeAttributes(HTMLAttributes, {\n \"data-mention\": \"\",\n \"data-type\": entityType,\n \"data-id\": id,\n class: \"mention-chip\",\n }),\n ).forEach(([key, val]) => {\n if (val != null && val !== false) dom.setAttribute(key, String(val));\n });\n\n dom.textContent = `${prefix}${label}`;\n\n if (options.onClickRef?.current) {\n dom.setAttribute(\"data-mention-clickable\", \"\");\n dom.style.cursor = \"pointer\";\n }\n\n dom.addEventListener(\"click\", (event) => {\n const handler = options.onClickRef?.current;\n if (handler) {\n event.preventDefault();\n event.stopPropagation();\n handler({ id, type: entityType, label }, event);\n }\n });\n\n // Hover tooltip\n let tooltip: HTMLElement | null = null;\n\n dom.addEventListener(\"mouseenter\", () => {\n const hoverFn = options.onHoverRef?.current;\n if (!hoverFn) return;\n\n const content = hoverFn({ id, type: entityType, label });\n if (!content) return;\n\n tooltip = document.createElement(\"div\");\n tooltip.setAttribute(\"data-mention-tooltip\", \"\");\n tooltip.textContent = typeof content === \"string\" ? content : \"\";\n dom.style.position = \"relative\";\n dom.appendChild(tooltip);\n });\n\n dom.addEventListener(\"mouseleave\", () => {\n if (tooltip && tooltip.parentNode) {\n tooltip.parentNode.removeChild(tooltip);\n tooltip = null;\n }\n });\n\n return { dom };\n };\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () =>\n this.editor.commands.command(({ tr, state }) => {\n let isMention = false;\n const { selection } = state;\n const { empty, anchor } = selection;\n\n if (!empty) return false;\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true;\n tr.insertText(\"\", pos, pos + node.nodeSize);\n }\n });\n\n return isMention;\n }),\n };\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\n\n/* ------------------------------------------------------------------ */\n/* Suggestion state types */\n/* ------------------------------------------------------------------ */\n\nexport type SuggestionState =\n | \"idle\"\n | \"loading\"\n | \"showing\"\n | \"drilling\"\n | \"inserting\";\n\n/* ------------------------------------------------------------------ */\n/* Callbacks the React layer implements */\n/* ------------------------------------------------------------------ */\n\nexport type SuggestionCallbacks = {\n onStart: (props: SuggestionCallbackProps) => void;\n onUpdate: (props: SuggestionCallbackProps) => void;\n onExit: () => void;\n onKeyDown: (props: { event: KeyboardEvent }) => boolean;\n};\n\nexport type SuggestionCallbackProps = {\n query: string;\n trigger: string;\n clientRect: (() => DOMRect | null) | null;\n range: { from: number; to: number };\n command: (attrs: Record<string, unknown>) => void;\n};\n\n/* ------------------------------------------------------------------ */\n/* Trigger detection */\n/* ------------------------------------------------------------------ */\n\ntype TriggerMatch = {\n trigger: string;\n query: string;\n from: number;\n to: number;\n textBefore: string;\n};\n\nfunction detectTrigger(\n text: string,\n cursorPos: number,\n docStartPos: number,\n triggers: string[],\n): TriggerMatch | null {\n const relCursor = cursorPos - docStartPos;\n const before = text.slice(0, relCursor);\n\n for (let i = before.length - 1; i >= 0; i--) {\n const ch = before[i];\n if (ch === \"\\n\") return null;\n\n for (const trigger of triggers) {\n if (before.substring(i, i + trigger.length) === trigger) {\n if (i === 0 || /\\s/.test(before[i - 1])) {\n const query = before.slice(i + trigger.length);\n return {\n trigger,\n query,\n from: docStartPos + i,\n to: cursorPos,\n textBefore: before.slice(0, i),\n };\n }\n }\n }\n }\n\n return null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Plugin key */\n/* ------------------------------------------------------------------ */\n\nconst suggestionPluginKey = new PluginKey(\"mentionSuggestion\");\n\n/* ------------------------------------------------------------------ */\n/* Ref-based callback container (avoids stale closure issues) */\n/* ------------------------------------------------------------------ */\n\nexport type SuggestionCallbacksRef = { current: SuggestionCallbacks };\n\nexport type AllowTriggerRef = {\n current?: (trigger: string, context: { textBefore: string }) => boolean;\n};\n\nexport type StreamingRef = { current: boolean };\n\n/* ------------------------------------------------------------------ */\n/* Build the single multi-trigger suggestion extension */\n/* ------------------------------------------------------------------ */\n\nexport function createSuggestionExtension(\n triggers: string[],\n callbacksRef: SuggestionCallbacksRef,\n allowTriggerRef?: AllowTriggerRef,\n streamingRef?: StreamingRef,\n) {\n return Extension.create({\n name: \"mentionSuggestion\",\n priority: 200,\n\n addProseMirrorPlugins() {\n const editor = this.editor;\n let active = false;\n let lastQuery: string | null = null;\n let lastTrigger: string | null = null;\n\n const getClientRect = (\n view: EditorView,\n from: number,\n ): (() => DOMRect | null) => {\n return () => {\n try {\n const coords = view.coordsAtPos(from);\n return new DOMRect(\n coords.left,\n coords.top,\n 0,\n coords.bottom - coords.top,\n );\n } catch {\n return null;\n }\n };\n };\n\n const makeCommand = (range: { from: number; to: number }) => {\n return (attrs: Record<string, unknown>) => {\n editor\n .chain()\n .focus()\n .insertContentAt(range, [\n {\n type: \"mention\",\n attrs: {\n id: attrs.id,\n label: attrs.label,\n entityType: attrs.entityType,\n rootLabel: attrs.rootLabel ?? null,\n },\n },\n { type: \"text\", text: \" \" },\n ])\n .run();\n };\n };\n\n const plugin = new Plugin({\n key: suggestionPluginKey,\n\n props: {\n handleKeyDown(_view, event) {\n if (!active) return false;\n return callbacksRef.current.onKeyDown({ event });\n },\n },\n\n view() {\n return {\n update(view, _prevState) {\n if (streamingRef?.current) {\n if (active) {\n active = false;\n lastQuery = null;\n lastTrigger = null;\n callbacksRef.current.onExit();\n }\n return;\n }\n\n const { state } = view;\n const { selection } = state;\n\n if (!selection.empty) {\n if (active) {\n active = false;\n lastQuery = null;\n lastTrigger = null;\n callbacksRef.current.onExit();\n }\n return;\n }\n\n const $pos = selection.$from;\n const textBlock = $pos.parent;\n\n if (!textBlock.isTextblock) {\n if (active) {\n active = false;\n lastQuery = null;\n lastTrigger = null;\n callbacksRef.current.onExit();\n }\n return;\n }\n\n const blockStart = $pos.start();\n const blockText = textBlock.textContent;\n const cursorPos = $pos.pos;\n\n const match = detectTrigger(blockText, cursorPos, blockStart, triggers);\n\n if (match) {\n // Check allowTrigger gate\n if (allowTriggerRef?.current) {\n const allowed = allowTriggerRef.current(match.trigger, {\n textBefore: match.textBefore,\n });\n if (!allowed) {\n if (active) {\n active = false;\n lastQuery = null;\n lastTrigger = null;\n callbacksRef.current.onExit();\n }\n return;\n }\n }\n\n const range = { from: match.from, to: match.to };\n const props: SuggestionCallbackProps = {\n query: match.query,\n trigger: match.trigger,\n clientRect: getClientRect(view, match.from),\n range,\n command: makeCommand(range),\n };\n\n if (!active) {\n active = true;\n lastQuery = match.query;\n lastTrigger = match.trigger;\n callbacksRef.current.onStart(props);\n } else if (\n match.query !== lastQuery ||\n match.trigger !== lastTrigger\n ) {\n lastQuery = match.query;\n lastTrigger = match.trigger;\n callbacksRef.current.onUpdate(props);\n }\n } else {\n if (active) {\n active = false;\n lastQuery = null;\n lastTrigger = null;\n callbacksRef.current.onExit();\n }\n }\n },\n\n destroy() {\n if (active) {\n callbacksRef.current.onExit();\n }\n },\n };\n },\n });\n\n return [plugin];\n },\n });\n}\n","import type { JSONContent } from \"@tiptap/core\";\nimport type { MentionToken } from \"../types/MentionToken\";\n\n/**\n * Serialize a Tiptap JSON document to a markdown string.\n *\n * Mention nodes are encoded as `@[label](id)` or `@rootLabel[label](id)` when the mention has a root (e.g. file under workspace).\n * All other text passes through verbatim.\n */\nexport function serializeToMarkdown(doc: JSONContent): string {\n if (!doc.content) return \"\";\n\n const parts: string[] = [];\n\n for (const block of doc.content) {\n if (block.type === \"paragraph\") {\n parts.push(serializeParagraph(block));\n } else if (block.type === \"text\") {\n parts.push(block.text ?? \"\");\n }\n }\n\n return parts.join(\"\\n\");\n}\n\nfunction serializeParagraph(node: JSONContent): string {\n if (!node.content) return \"\";\n\n return node.content\n .map((child) => {\n if (child.type === \"mention\") {\n const { id, label, entityType, rootLabel } = child.attrs ?? {};\n const idPart =\n entityType && entityType !== \"unknown\"\n ? `${entityType}:${id}`\n : id;\n if (rootLabel != null && rootLabel !== \"\") {\n return `@${rootLabel}[${label}](${idPart})`;\n }\n return `@[${label}](${idPart})`;\n }\n return child.text ?? \"\";\n })\n .join(\"\");\n}\n\n/**\n * Extract all `MentionToken`s from a Tiptap JSON document, in document order.\n */\nexport function extractTokens(doc: JSONContent): MentionToken[] {\n const tokens: MentionToken[] = [];\n\n function walk(node: JSONContent) {\n if (node.type === \"mention\" && node.attrs) {\n tokens.push({\n id: node.attrs.id as string,\n type: node.attrs.entityType as string,\n label: node.attrs.label as string,\n });\n }\n if (node.content) {\n for (const child of node.content) {\n walk(child);\n }\n }\n }\n\n walk(doc);\n return tokens;\n}\n\n/**\n * Extract plain text from a Tiptap JSON document.\n * Mention nodes are replaced with their label (no trigger prefix in plain text).\n */\nexport function extractPlainText(doc: JSONContent): string {\n if (!doc.content) return \"\";\n\n const parts: string[] = [];\n\n for (const block of doc.content) {\n if (block.type === \"paragraph\") {\n parts.push(extractParagraphText(block));\n }\n }\n\n return parts.join(\"\\n\");\n}\n\nfunction extractParagraphText(node: JSONContent): string {\n if (!node.content) return \"\";\n\n return node.content\n .map((child) => {\n if (child.type === \"mention\") {\n return child.attrs?.label ?? \"\";\n }\n return child.text ?? \"\";\n })\n .join(\"\");\n}\n","import type { JSONContent } from \"@tiptap/core\";\nimport { extractTokens, extractPlainText } from \"./markdownSerializer\";\nimport type { MentionToken } from \"../types/MentionToken\";\n\n/**\n * Regex matching mention tokens:\n * - `@[label](id)` or `@[label](type:id)`\n * - `@rootLabel[label](type:id)` when the mention has a root (e.g. file under workspace).\n * Groups: (1) rootLabel (may be empty string), (2) label, (3) optional entityType, (4) id.\n *\n * `[^\\[@]` prevents the rootLabel from crossing `@` boundaries so that plain\n * `@word` in running text is never swallowed into a false rootLabel match.\n */\nconst MENTION_RE = /@([^\\[@]*)\\[([^\\]]+)\\]\\((?:([^:)]+):)?([^)]+)\\)/g;\n\n/**\n * Parse a markdown string (with `@[label](id)`, `@[label](type:id)`, or `@rootLabel[label](id)` tokens)\n * into a Tiptap-compatible JSON document.\n */\nexport function parseFromMarkdown(markdown: string): JSONContent {\n const lines = markdown.split(\"\\n\");\n\n const content: JSONContent[] = lines.map((line) => {\n const children = parseLine(line);\n return children.length > 0\n ? { type: \"paragraph\", content: children }\n : { type: \"paragraph\" };\n });\n\n return { type: \"doc\", content };\n}\n\nfunction parseLine(line: string): JSONContent[] {\n const nodes: JSONContent[] = [];\n let lastIndex = 0;\n\n // Reset regex state\n MENTION_RE.lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = MENTION_RE.exec(line)) !== null) {\n const fullMatch = match[0];\n const rootLabel = match[1] || null;\n const label = match[2];\n const entityType = match[3] ?? \"unknown\";\n const id = match[4];\n\n // Text before this mention\n if (match.index > lastIndex) {\n nodes.push({\n type: \"text\",\n text: line.slice(lastIndex, match.index),\n });\n }\n\n // Mention node\n nodes.push({\n type: \"mention\",\n attrs: {\n id,\n label,\n entityType,\n rootLabel,\n },\n });\n\n lastIndex = match.index + fullMatch.length;\n }\n\n // Trailing text\n if (lastIndex < line.length) {\n nodes.push({\n type: \"text\",\n text: line.slice(lastIndex),\n });\n }\n\n return nodes;\n}\n\n/* ------------------------------------------------------------------ */\n/* Convenience helper: markdown → tokens + plain text */\n/* ------------------------------------------------------------------ */\n\n/**\n * Parse a markdown string and extract structured data from it.\n *\n * This is a convenience wrapper that combines `parseFromMarkdown`,\n * `extractTokens`, and `extractPlainText` into a single call.\n *\n * @example\n * ```ts\n * const { tokens, plainText } = extractFromMarkdown(\n * \"Check @Marketing[Q4 Strategy.pdf](file_1) for details\"\n * );\n * // tokens → [{ id: \"file_1\", type: \"unknown\", label: \"Q4 Strategy.pdf\" }]\n * // plainText → \"Check Q4 Strategy.pdf for details\"\n * ```\n */\nexport function extractFromMarkdown(markdown: string): {\n tokens: MentionToken[];\n plainText: string;\n} {\n const doc = parseFromMarkdown(markdown);\n return {\n tokens: extractTokens(doc),\n plainText: extractPlainText(doc),\n };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { MentionItem, MentionProvider } from \"../types/MentionProvider\";\nimport type { MentionToken } from \"../types/MentionToken\";\nimport type {\n SuggestionCallbackProps,\n SuggestionCallbacks,\n SuggestionCallbacksRef,\n SuggestionState,\n} from \"../core/suggestionPlugin\";\nimport { debounce } from \"../utils/debounce\";\n\n/* ------------------------------------------------------------------ */\n/* Public state exposed to the UI layer */\n/* ------------------------------------------------------------------ */\n\nexport type SuggestionUIState = {\n state: SuggestionState;\n items: MentionItem[];\n breadcrumbs: MentionItem[];\n activeIndex: number;\n loading: boolean;\n clientRect: (() => DOMRect | null) | null;\n trigger: string | null;\n query: string;\n};\n\nexport type SuggestionActions = {\n navigateUp: () => void;\n navigateDown: () => void;\n select: (item?: MentionItem) => void;\n goBack: () => void;\n close: () => void;\n searchNested: (query: string) => void;\n};\n\nexport type SuggestionHookOptions = {\n onMentionAdd?: (token: MentionToken) => void;\n};\n\nconst IDLE_STATE: SuggestionUIState = {\n state: \"idle\",\n items: [],\n breadcrumbs: [],\n activeIndex: 0,\n loading: false,\n clientRect: null,\n trigger: null,\n query: \"\",\n};\n\n/* ------------------------------------------------------------------ */\n/* Hook */\n/* ------------------------------------------------------------------ */\n\nexport function useSuggestion(\n providers: MentionProvider[],\n options: SuggestionHookOptions = {},\n) {\n const [uiState, setUIState] = useState<SuggestionUIState>(IDLE_STATE);\n\n const stateRef = useRef(uiState);\n stateRef.current = uiState;\n\n const providersRef = useRef(providers);\n providersRef.current = providers;\n\n const onMentionAddRef = useRef(options.onMentionAdd);\n onMentionAddRef.current = options.onMentionAdd;\n\n const commandRef = useRef<((attrs: Record<string, unknown>) => void) | null>(\n null,\n );\n const providerRef = useRef<MentionProvider | null>(null);\n\n const debouncedFetchRef = useRef<ReturnType<typeof debounce> | null>(null);\n\n useEffect(() => {\n return () => {\n debouncedFetchRef.current?.cancel();\n };\n }, []);\n\n /* ---------------------------------------------------------------- */\n /* Fetch items from the provider */\n /* ---------------------------------------------------------------- */\n\n const fetchItems = useCallback(\n async (\n provider: MentionProvider,\n query: string,\n parent?: MentionItem,\n useSearchAll?: boolean,\n ) => {\n setUIState((prev) => ({ ...prev, loading: true, state: \"loading\" }));\n\n try {\n let items: MentionItem[];\n\n if (useSearchAll && provider.searchAll) {\n items = await provider.searchAll(query);\n } else if (parent && provider.getChildren) {\n items = await provider.getChildren(parent, query);\n } else {\n items = await provider.getRootItems(query);\n }\n\n setUIState((prev) => ({\n ...prev,\n items,\n loading: false,\n state: \"showing\",\n activeIndex: 0,\n }));\n } catch {\n setUIState((prev) => ({\n ...prev,\n items: [],\n loading: false,\n state: \"showing\",\n }));\n }\n },\n [],\n );\n\n const scheduleFetch = useCallback(\n (\n provider: MentionProvider,\n query: string,\n parent?: MentionItem,\n useSearchAll?: boolean,\n ) => {\n debouncedFetchRef.current?.cancel();\n\n const ms = provider.debounceMs;\n if (ms && ms > 0) {\n setUIState((prev) => ({ ...prev, loading: true }));\n const debouncedFn = debounce(() => {\n fetchItems(provider, query, parent, useSearchAll);\n }, ms);\n debouncedFetchRef.current = debouncedFn;\n debouncedFn();\n } else {\n fetchItems(provider, query, parent, useSearchAll);\n }\n },\n [fetchItems],\n );\n\n /* ---------------------------------------------------------------- */\n /* Suggestion plugin callbacks */\n /* ---------------------------------------------------------------- */\n\n const onStart = useCallback(\n (props: SuggestionCallbackProps) => {\n const provider = providersRef.current.find(\n (p) => p.trigger === props.trigger,\n );\n if (!provider) return;\n\n providerRef.current = provider;\n commandRef.current = props.command;\n\n setUIState({\n state: \"loading\",\n items: [],\n breadcrumbs: [],\n activeIndex: 0,\n loading: true,\n clientRect: props.clientRect,\n trigger: props.trigger,\n query: props.query,\n });\n\n if (!props.query.trim() && provider.getRecentItems) {\n provider.getRecentItems().then((recentItems) => {\n const tagged = recentItems.map((item) => ({\n ...item,\n group: item.group ?? \"Recent\",\n }));\n setUIState((prev) => ({\n ...prev,\n items: tagged,\n loading: false,\n state: \"showing\",\n activeIndex: 0,\n }));\n }).catch(() => {\n scheduleFetch(provider, props.query);\n });\n return;\n }\n\n if (props.query.trim() && provider.searchAll) {\n scheduleFetch(provider, props.query, undefined, true);\n } else {\n scheduleFetch(provider, props.query);\n }\n },\n [scheduleFetch],\n );\n\n const onUpdate = useCallback(\n (props: SuggestionCallbackProps) => {\n const provider = providerRef.current;\n if (!provider) return;\n\n commandRef.current = props.command;\n const current = stateRef.current;\n\n if (current.breadcrumbs.length > 0) {\n setUIState((prev) => ({\n ...prev,\n breadcrumbs: [],\n clientRect: props.clientRect,\n query: props.query,\n activeIndex: 0,\n }));\n } else {\n setUIState((prev) => ({\n ...prev,\n clientRect: props.clientRect,\n query: props.query,\n }));\n }\n\n if (props.query.trim() && provider.searchAll) {\n scheduleFetch(provider, props.query, undefined, true);\n } else if (!props.query.trim() && provider.getRecentItems) {\n provider.getRecentItems().then((recentItems) => {\n const tagged = recentItems.map((item) => ({\n ...item,\n group: item.group ?? \"Recent\",\n }));\n setUIState((prev) => ({\n ...prev,\n items: tagged,\n loading: false,\n state: \"showing\",\n activeIndex: 0,\n }));\n }).catch(() => {\n scheduleFetch(provider, props.query);\n });\n } else {\n scheduleFetch(provider, props.query);\n }\n },\n [scheduleFetch],\n );\n\n const onExit = useCallback(() => {\n debouncedFetchRef.current?.cancel();\n providerRef.current = null;\n commandRef.current = null;\n setUIState(IDLE_STATE);\n }, []);\n\n /* ---------------------------------------------------------------- */\n /* Navigation actions */\n /* ---------------------------------------------------------------- */\n\n const navigateUp = useCallback(() => {\n setUIState((prev) => ({\n ...prev,\n activeIndex: Math.max(0, prev.activeIndex - 1),\n }));\n }, []);\n\n const navigateDown = useCallback(() => {\n setUIState((prev) => ({\n ...prev,\n activeIndex: Math.min(prev.items.length - 1, prev.activeIndex + 1),\n }));\n }, []);\n\n const select = useCallback(\n (item?: MentionItem) => {\n const current = stateRef.current;\n const selected = item ?? current.items[current.activeIndex];\n if (!selected) return;\n\n const provider = providerRef.current;\n\n if (selected.hasChildren && provider?.getChildren) {\n setUIState((prev) => ({\n ...prev,\n state: \"drilling\",\n breadcrumbs: [...prev.breadcrumbs, selected],\n items: [],\n activeIndex: 0,\n query: \"\",\n }));\n\n fetchItems(provider, \"\", selected);\n return;\n }\n\n const rootLabel =\n current.breadcrumbs.length > 0\n ? current.breadcrumbs[0].label\n : selected.rootLabel ?? null;\n\n if (commandRef.current) {\n commandRef.current({\n id: selected.id,\n label: selected.label,\n entityType: selected.type,\n rootLabel,\n });\n }\n\n onMentionAddRef.current?.({\n id: selected.id,\n type: selected.type,\n label: selected.label,\n });\n },\n [fetchItems],\n );\n\n const goBack = useCallback(() => {\n const provider = providerRef.current;\n if (!provider) return;\n\n setUIState((prev) => {\n const newBreadcrumbs = prev.breadcrumbs.slice(0, -1);\n const parent = newBreadcrumbs[newBreadcrumbs.length - 1];\n\n if (parent) {\n fetchItems(provider, \"\", parent);\n } else {\n fetchItems(provider, prev.query);\n }\n\n return {\n ...prev,\n breadcrumbs: newBreadcrumbs,\n items: [],\n activeIndex: 0,\n state: \"loading\" as const,\n };\n });\n }, [fetchItems]);\n\n const close = useCallback(() => {\n debouncedFetchRef.current?.cancel();\n setUIState(IDLE_STATE);\n }, []);\n\n /* ---------------------------------------------------------------- */\n /* Nested search */\n /* ---------------------------------------------------------------- */\n\n const searchNested = useCallback(\n (query: string) => {\n const provider = providerRef.current;\n if (!provider) return;\n\n const current = stateRef.current;\n const parent = current.breadcrumbs[current.breadcrumbs.length - 1];\n if (parent) {\n scheduleFetch(provider, query, parent);\n }\n },\n [scheduleFetch],\n );\n\n /* ---------------------------------------------------------------- */\n /* Keyboard handler */\n /* ---------------------------------------------------------------- */\n\n const onKeyDown = useCallback(\n ({ event }: { event: KeyboardEvent }): boolean => {\n const current = stateRef.current;\n if (current.state === \"idle\") return false;\n\n switch (event.key) {\n case \"ArrowUp\":\n event.preventDefault();\n navigateUp();\n return true;\n case \"ArrowDown\":\n event.preventDefault();\n navigateDown();\n return true;\n case \"Enter\": {\n event.preventDefault();\n const selectedItem = current.items[current.activeIndex];\n if (selectedItem) {\n select(selectedItem);\n }\n return true;\n }\n case \"Tab\": {\n event.preventDefault();\n const selectedItem = current.items[current.activeIndex];\n if (selectedItem) {\n select(selectedItem);\n }\n return true;\n }\n case \"ArrowRight\": {\n const activeItem = current.items[current.activeIndex];\n if (activeItem?.hasChildren) {\n event.preventDefault();\n select(activeItem);\n return true;\n }\n return false;\n }\n case \"ArrowLeft\":\n if (current.breadcrumbs.length > 0) {\n event.preventDefault();\n goBack();\n return true;\n }\n return false;\n case \"Escape\":\n event.preventDefault();\n close();\n return true;\n default:\n return false;\n }\n },\n [navigateUp, navigateDown, select, goBack, close],\n );\n\n /* ---------------------------------------------------------------- */\n /* Build a ref that always points to the latest callbacks. */\n /* ---------------------------------------------------------------- */\n\n const callbacksRef: SuggestionCallbacksRef = useRef<SuggestionCallbacks>({\n onStart,\n onUpdate,\n onExit,\n onKeyDown,\n });\n\n callbacksRef.current = { onStart, onUpdate, onExit, onKeyDown };\n\n const actions: SuggestionActions = {\n navigateUp,\n navigateDown,\n select,\n goBack,\n close,\n searchNested,\n };\n\n return { uiState, actions, callbacksRef };\n}\n","/**\n * Returns a debounced version of `fn` that delays invocation until\n * `ms` milliseconds have elapsed since the last call.\n * Call `.cancel()` on the returned function to clear any pending timer.\n */\nexport function debounce<T extends (...args: any[]) => void>(\n fn: T,\n ms: number,\n): T & { cancel: () => void } {\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n const debounced = ((...args: any[]) => {\n if (timer != null) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n fn(...args);\n }, ms);\n }) as T & { cancel: () => void };\n\n debounced.cancel = () => {\n if (timer != null) {\n clearTimeout(timer);\n timer = null;\n }\n };\n\n return debounced;\n}\n","import React, { useEffect, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { MentionItem } from \"../types/MentionProvider\";\nimport { listboxAttrs, optionAttrs } from \"../utils/ariaHelpers\";\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport type SuggestionListProps = {\n items: MentionItem[];\n activeIndex: number;\n breadcrumbs: MentionItem[];\n loading: boolean;\n trigger: string | null;\n query: string;\n clientRect: (() => DOMRect | null) | null;\n onSelect: (item: MentionItem) => void;\n onHover: (index: number) => void;\n onGoBack: () => void;\n onSearchNested?: (query: string) => void;\n onNavigateUp?: () => void;\n onNavigateDown?: () => void;\n onClose?: () => void;\n onFocusEditor?: () => void;\n renderItem?: (item: MentionItem, depth: number) => ReactNode;\n renderEmpty?: (query: string) => ReactNode;\n renderLoading?: () => ReactNode;\n renderGroupHeader?: (group: string) => ReactNode;\n listboxId: string;\n};\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport function SuggestionList({\n items,\n activeIndex,\n breadcrumbs,\n loading,\n trigger,\n query,\n clientRect,\n onSelect,\n onHover,\n onGoBack,\n onSearchNested,\n onNavigateUp,\n onNavigateDown,\n onClose,\n onFocusEditor,\n renderItem,\n renderEmpty,\n renderLoading,\n renderGroupHeader,\n listboxId,\n}: SuggestionListProps) {\n const listRef = useRef<HTMLDivElement>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const depth = breadcrumbs.length;\n const [nestedQuery, setNestedQuery] = useState(\"\");\n\n const breadcrumbKey = breadcrumbs.map((b) => b.id).join(\"/\");\n const prevBreadcrumbKey = useRef(breadcrumbKey);\n useEffect(() => {\n if (prevBreadcrumbKey.current !== breadcrumbKey) {\n setNestedQuery(\"\");\n prevBreadcrumbKey.current = breadcrumbKey;\n }\n }, [breadcrumbKey]);\n\n const prevBreadcrumbsLen = useRef(breadcrumbs.length);\n useEffect(() => {\n if (prevBreadcrumbsLen.current > 0 && breadcrumbs.length === 0) {\n onFocusEditor?.();\n } else if (breadcrumbs.length > 0 && searchInputRef.current) {\n requestAnimationFrame(() => searchInputRef.current?.focus());\n }\n prevBreadcrumbsLen.current = breadcrumbs.length;\n }, [breadcrumbKey, breadcrumbs.length, onFocusEditor]);\n\n useEffect(() => {\n if (!listRef.current) return;\n const active = listRef.current.querySelector('[aria-selected=\"true\"]');\n active?.scrollIntoView({ block: \"nearest\" });\n }, [activeIndex]);\n\n const { style, position } = usePopoverPosition(clientRect);\n\n const activeQuery = breadcrumbs.length > 0 ? nestedQuery : query;\n const showEmpty = !loading && items.length === 0 && activeQuery.trim().length > 0;\n\n if (items.length === 0 && !loading && !showEmpty) return null;\n\n const handleSearchKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n onNavigateDown?.();\n break;\n case \"ArrowUp\":\n e.preventDefault();\n onNavigateUp?.();\n break;\n case \"Enter\": {\n e.preventDefault();\n e.stopPropagation();\n const selectedItem = items[activeIndex];\n if (selectedItem) onSelect(selectedItem);\n break;\n }\n case \"Escape\":\n e.preventDefault();\n onFocusEditor?.();\n onClose?.();\n break;\n case \"ArrowLeft\":\n if (nestedQuery === \"\" || e.currentTarget.selectionStart === 0) {\n e.preventDefault();\n onGoBack();\n }\n break;\n case \"ArrowRight\": {\n const item = items[activeIndex];\n if (item?.hasChildren) {\n e.preventDefault();\n onSelect(item);\n }\n break;\n }\n case \"Backspace\":\n if (nestedQuery === \"\") {\n e.preventDefault();\n onGoBack();\n }\n break;\n }\n };\n\n const hasGroups = items.some((item) => item.group);\n\n return (\n <div\n data-suggestions=\"\"\n data-trigger={trigger}\n data-suggestions-position={position}\n style={style}\n ref={listRef}\n >\n {breadcrumbs.length > 0 && (\n <div data-suggestion-breadcrumb=\"\">\n <button\n type=\"button\"\n data-suggestion-back=\"\"\n onClick={onGoBack}\n aria-label=\"Go back\"\n >\n ←\n </button>\n {breadcrumbs.map((crumb, i) => (\n <span key={crumb.id} data-suggestion-breadcrumb-item=\"\">\n {i > 0 && <span data-suggestion-breadcrumb-sep=\"\">/</span>}\n {crumb.label}\n </span>\n ))}\n </div>\n )}\n\n {breadcrumbs.length > 0 && (\n <div data-suggestion-search=\"\">\n <input\n ref={searchInputRef}\n type=\"text\"\n data-suggestion-search-input=\"\"\n placeholder=\"Search...\"\n value={nestedQuery}\n onChange={(e) => {\n const q = e.target.value;\n setNestedQuery(q);\n onSearchNested?.(q);\n }}\n onKeyDown={handleSearchKeyDown}\n autoComplete=\"off\"\n spellCheck={false}\n />\n </div>\n )}\n\n {loading && (\n <div data-suggestion-loading=\"\">\n {renderLoading ? renderLoading() : \"Loading...\"}\n </div>\n )}\n\n {showEmpty && (\n <div data-suggestion-empty=\"\">\n {renderEmpty ? renderEmpty(activeQuery) : \"No results\"}\n </div>\n )}\n\n {!loading && items.length > 0 && (\n <div {...listboxAttrs(listboxId, `${trigger ?? \"\"} suggestions`)}>\n {hasGroups\n ? renderGroupedItems(items, activeIndex, depth, onSelect, onHover, renderItem, renderGroupHeader)\n : items.map((item, index) => (\n <SuggestionItem\n key={item.id}\n item={item}\n index={index}\n isActive={index === activeIndex}\n depth={depth}\n onSelect={onSelect}\n onHover={onHover}\n renderItem={renderItem}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Grouped rendering */\n/* ------------------------------------------------------------------ */\n\nfunction renderGroupedItems(\n items: MentionItem[],\n activeIndex: number,\n depth: number,\n onSelect: (item: MentionItem) => void,\n onHover: (index: number) => void,\n renderItem?: (item: MentionItem, depth: number) => ReactNode,\n renderGroupHeader?: (group: string) => ReactNode,\n) {\n const elements: ReactNode[] = [];\n let lastGroup: string | undefined;\n\n items.forEach((item, index) => {\n if (item.group && item.group !== lastGroup) {\n lastGroup = item.group;\n elements.push(\n <div key={`group-${item.group}`} data-suggestion-group-header=\"\">\n {renderGroupHeader ? renderGroupHeader(item.group) : item.group}\n </div>,\n );\n }\n\n elements.push(\n <SuggestionItem\n key={item.id}\n item={item}\n index={index}\n isActive={index === activeIndex}\n depth={depth}\n onSelect={onSelect}\n onHover={onHover}\n renderItem={renderItem}\n />,\n );\n });\n\n return elements;\n}\n\n/* ------------------------------------------------------------------ */\n/* Single item */\n/* ------------------------------------------------------------------ */\n\nfunction SuggestionItem({\n item,\n index,\n isActive,\n depth,\n onSelect,\n onHover,\n renderItem,\n}: {\n item: MentionItem;\n index: number;\n isActive: boolean;\n depth: number;\n onSelect: (item: MentionItem) => void;\n onHover: (index: number) => void;\n renderItem?: (item: MentionItem, depth: number) => ReactNode;\n}) {\n const itemId = `mention-option-${item.id}`;\n\n return (\n <div\n {...optionAttrs(itemId, isActive, index)}\n data-suggestion-item=\"\"\n data-suggestion-item-active={isActive ? \"\" : undefined}\n data-has-children={item.hasChildren ? \"\" : undefined}\n onMouseEnter={() => onHover(index)}\n onClick={() => onSelect(item)}\n >\n {renderItem ? (\n renderItem(item, depth)\n ) : (\n <DefaultSuggestionItem item={item} />\n )}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Default item render */\n/* ------------------------------------------------------------------ */\n\nfunction DefaultSuggestionItem({ item }: { item: MentionItem }) {\n return (\n <>\n {item.icon && (\n <span data-suggestion-item-icon=\"\">{item.icon}</span>\n )}\n <span data-suggestion-item-label=\"\">{item.label}</span>\n {item.description && (\n <span data-suggestion-item-description=\"\">{item.description}</span>\n )}\n {item.hasChildren && (\n <span data-suggestion-item-chevron=\"\" aria-hidden=\"true\">\n ›\n </span>\n )}\n </>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Popover positioning with edge-aware flipping */\n/* ------------------------------------------------------------------ */\n\nconst POPOVER_HEIGHT_ESTIMATE = 280;\nconst POPOVER_WIDTH_ESTIMATE = 360;\n\nfunction usePopoverPosition(\n clientRect: (() => DOMRect | null) | null,\n): { style: React.CSSProperties; position: \"above\" | \"below\" } {\n if (!clientRect) {\n return { style: { display: \"none\" }, position: \"below\" };\n }\n\n const rect = clientRect();\n if (!rect) {\n return { style: { display: \"none\" }, position: \"below\" };\n }\n\n const viewportH = typeof window !== \"undefined\" ? window.innerHeight : 800;\n const viewportW = typeof window !== \"undefined\" ? window.innerWidth : 1200;\n\n const spaceBelow = viewportH - rect.bottom;\n const shouldFlip = spaceBelow < POPOVER_HEIGHT_ESTIMATE && rect.top > spaceBelow;\n\n let left = rect.left;\n if (left + POPOVER_WIDTH_ESTIMATE > viewportW) {\n left = Math.max(0, viewportW - POPOVER_WIDTH_ESTIMATE);\n }\n\n if (shouldFlip) {\n return {\n style: {\n position: \"fixed\",\n left: `${left}px`,\n bottom: `${viewportH - rect.top + 4}px`,\n zIndex: 50,\n },\n position: \"above\",\n };\n }\n\n return {\n style: {\n position: \"fixed\",\n left: `${left}px`,\n top: `${rect.bottom + 4}px`,\n zIndex: 50,\n },\n position: \"below\",\n };\n}\n","/**\n * Generates ARIA attributes for the suggestion combobox pattern.\n */\n\nexport function comboboxAttrs(expanded: boolean, listboxId: string) {\n return {\n role: \"combobox\" as const,\n \"aria-haspopup\": \"listbox\" as const,\n \"aria-expanded\": expanded,\n \"aria-owns\": expanded ? listboxId : undefined,\n };\n}\n\nexport function listboxAttrs(id: string, label: string) {\n return {\n id,\n role: \"listbox\" as const,\n \"aria-label\": label,\n };\n}\n\nexport function optionAttrs(\n id: string,\n selected: boolean,\n index: number,\n) {\n return {\n id,\n role: \"option\" as const,\n \"aria-selected\": selected,\n \"aria-posinset\": index + 1,\n };\n}\n","import { useCallback, useState } from \"react\";\nimport type { MentionsOutput } from \"../types/MentionsOutput\";\n\nexport function useMentionsContent() {\n const [output, setOutput] = useState<MentionsOutput | null>(null);\n const onChange = useCallback((o: MentionsOutput) => setOutput(o), []);\n\n return {\n output,\n onChange,\n hasContent: (output?.plainText ?? \"\").trim().length > 0,\n };\n}\n"],"mappings":"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","names":["import_react","import_react","import_core","import_state","import_core","StarterKit","Placeholder","editor","import_react","import_react","import_jsx_runtime","MentionsInput","import_react"]}
|