neuphlo-editor 1.8.2 → 2.0.0
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/dist/chunk-2DWEJI45.js +1296 -0
- package/dist/chunk-2DWEJI45.js.map +1 -0
- package/dist/chunk-457ETWB6.js +1351 -0
- package/dist/chunk-457ETWB6.js.map +1 -0
- package/dist/chunk-62DYB7FY.js +1305 -0
- package/dist/chunk-62DYB7FY.js.map +1 -0
- package/dist/chunk-DWGPGRTQ.js +1302 -0
- package/dist/chunk-DWGPGRTQ.js.map +1 -0
- package/dist/chunk-EG7NQJRA.js +1324 -0
- package/dist/chunk-EG7NQJRA.js.map +1 -0
- package/dist/chunk-FLLPFFI5.js +1296 -0
- package/dist/chunk-FLLPFFI5.js.map +1 -0
- package/dist/chunk-FVQHB6VC.js +1128 -0
- package/dist/chunk-FVQHB6VC.js.map +1 -0
- package/dist/chunk-GXJGZHKR.js +1326 -0
- package/dist/chunk-GXJGZHKR.js.map +1 -0
- package/dist/chunk-KCPPTLGY.js +1299 -0
- package/dist/chunk-KCPPTLGY.js.map +1 -0
- package/dist/chunk-LHG2NX6C.js +1123 -0
- package/dist/chunk-LHG2NX6C.js.map +1 -0
- package/dist/chunk-OCNM37WJ.js +1289 -0
- package/dist/chunk-OCNM37WJ.js.map +1 -0
- package/dist/chunk-RW6QBMJB.js +1300 -0
- package/dist/chunk-RW6QBMJB.js.map +1 -0
- package/dist/chunk-SOXTEP7H.js +6705 -0
- package/dist/chunk-SOXTEP7H.js.map +1 -0
- package/dist/headless/index.cjs +207 -144
- package/dist/headless/index.cjs.map +1 -1
- package/dist/headless/index.d.cts +9 -25
- package/dist/headless/index.d.ts +9 -25
- package/dist/headless/index.js +1 -1
- package/dist/react/index.cjs +1839 -723
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.css +364 -8
- package/dist/react/index.css.map +1 -1
- package/dist/react/index.d.cts +10 -2
- package/dist/react/index.d.ts +10 -2
- package/dist/react/index.js +1434 -547
- package/dist/react/index.js.map +1 -1
- package/dist/styles.css +410 -8
- package/package.json +7 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/headless/index.ts","../../src/headless/components/editor.tsx","../../src/headless/utils/store.ts","../../src/headless/components/editor-bubble.tsx","../../src/headless/components/editor-bubble-item.tsx","../../src/headless/components/editor-command.tsx","../../src/headless/utils/atoms.ts","../../src/headless/components/editor-command-item.tsx","../../src/headless/extensions/index.ts","../../src/headless/extensions/Mention/mention.tsx","../../src/headless/extensions/Mention/mention-command.tsx","../../src/headless/extensions/Mention/mention-node-view.tsx","../../src/headless/extensions/slash-command.tsx"],"sourcesContent":["export { useCurrentEditor as useEditor } from \"@tiptap/react\"\n\nexport {\n EditorRoot,\n EditorContent,\n type EditorContentProps,\n} from \"./components/editor\"\n\nexport { EditorBubble } from \"./components/editor-bubble\"\nexport { EditorBubbleItem } from \"./components/editor-bubble-item\"\nexport {\n EditorCommand,\n EditorCommandList,\n EditorCommandOut,\n} from \"./components/editor-command\"\nexport {\n EditorCommandItem,\n EditorCommandEmpty,\n} from \"./components/editor-command-item\"\n\nexport { Placeholder, StarterKit } from \"./extensions\"\nexport {\n Command as SlashCommand,\n renderItems as renderSlashCommandItems,\n createSuggestionItems,\n handleCommandNavigation,\n} from \"./extensions/slash-command\"\nexport {\n createMentionExtension,\n renderMentionSuggestion,\n MentionCommand,\n type MentionItem,\n type MentionOptions,\n} from \"./extensions/Mention\"\n// Path without extension to satisfy TS/tsup\n// (the file is at ./extensions/slash-command.tsx)\n// eslint-disable-next-line\n","import { EditorProvider } from \"@tiptap/react\"\nimport type { EditorProviderProps } from \"@tiptap/react\"\nimport { forwardRef } from \"react\"\nimport type { FC, ReactNode } from \"react\"\nimport { Provider } from \"jotai\"\nimport { novelStore } from \"../utils/store\"\n\nexport interface EditorRootProps {\n readonly children: ReactNode\n}\n\nexport const EditorRoot: FC<EditorRootProps> = ({ children }) => {\n return (\n <Provider store={novelStore as any}>\n {children as any}\n </Provider>\n )\n}\n\nexport type EditorContentProps = EditorProviderProps & {\n readonly children?: ReactNode\n readonly className?: string\n readonly initialContent?: any\n}\n\nexport const EditorContent = forwardRef<HTMLDivElement, EditorContentProps>(\n ({ className, children, initialContent, content, ...rest }, ref) => {\n const effectiveContent = content ?? initialContent\n return (\n <div ref={ref} className={className}>\n <EditorProvider {...rest} content={effectiveContent}>\n {children}\n </EditorProvider>\n </div>\n )\n }\n)\n\nEditorContent.displayName = \"EditorContent\"\n","import { createStore } from \"jotai\";\n\n// biome-ignore lint/suspicious/noExplicitAny: store is opaque to consumers\nexport const novelStore: any = createStore();\nexport * from \"jotai\";\n\n","import { useCurrentEditor } from \"@tiptap/react\";\nimport { BubbleMenu as BubbleMenuReact } from \"@tiptap/react/menus\";\nimport type { BubbleMenuProps } from \"@tiptap/react/menus\";\nimport type { ReactNode } from \"react\";\n\ntype ForwardedBubbleProps = Omit<BubbleMenuProps, \"editor\" | \"children\" | \"className\">;\n\nexport interface EditorBubbleProps extends ForwardedBubbleProps {\n readonly className?: string;\n readonly children: ReactNode;\n}\n\nexport function EditorBubble({ className, children, ...rest }: EditorBubbleProps) {\n const { editor } = useCurrentEditor();\n if (!editor) return null;\n\n return (\n <BubbleMenuReact editor={editor} {...rest}>\n <div className={className}>{children}</div>\n </BubbleMenuReact>\n );\n}\n","import { forwardRef, isValidElement, cloneElement } from \"react\"\nimport type { ComponentPropsWithoutRef, ReactElement, ReactNode } from \"react\"\nimport { useCurrentEditor } from \"@tiptap/react\"\nimport type { Editor as TiptapEditor } from \"@tiptap/react\"\n\ninterface EditorBubbleItemProps {\n readonly children: ReactNode\n readonly asChild?: boolean\n readonly onSelect?: (editor: TiptapEditor) => void\n}\n\nexport const EditorBubbleItem = forwardRef<\n HTMLDivElement,\n EditorBubbleItemProps & Omit<ComponentPropsWithoutRef<\"div\">, \"onSelect\">\n>(({ children, asChild, onSelect, ...rest }, ref) => {\n const { editor } = useCurrentEditor()\n\n if (!editor) return null\n\n const handleClick = (e: React.MouseEvent) => {\n e.preventDefault()\n onSelect?.(editor)\n }\n\n if (asChild && isValidElement(children)) {\n const child = children as ReactElement<any>\n const childOnClick = (child.props as any)?.onClick as\n | ((e: any) => void)\n | undefined\n const mergedOnClick = (e: any) => {\n childOnClick?.(e)\n if (!e?.defaultPrevented) onSelect?.(editor)\n }\n\n return cloneElement(child, {\n ...rest,\n ref: (child as any).ref ?? ref,\n onClick: mergedOnClick,\n })\n }\n\n return (\n <div ref={ref} {...rest} onClick={handleClick}>\n {children}\n </div>\n )\n})\n\nEditorBubbleItem.displayName = \"EditorBubbleItem\"\n\nexport default EditorBubbleItem\n","import { useAtom, useSetAtom } from \"jotai\"\nimport { useEffect, forwardRef } from \"react\"\nimport { Command } from \"cmdk\"\nimport { queryAtom, rangeAtom } from \"../utils/atoms\"\nimport { novelStore } from \"../utils/store\"\nimport type { FC } from \"react\"\nimport type { Range } from \"@tiptap/core\"\nimport tunnel from \"tunnel-rat\"\n\nconst commandTunnel: any = (tunnel as any)()\n\ninterface EditorCommandOutProps {\n readonly query: string\n readonly range: Range\n}\n\nexport const EditorCommandOut: FC<EditorCommandOutProps> = ({\n query,\n range,\n}) => {\n const setQuery = useSetAtom(queryAtom, { store: novelStore })\n const setRange = useSetAtom(rangeAtom, { store: novelStore })\n\n useEffect(() => {\n setQuery(query)\n }, [query, setQuery])\n\n useEffect(() => {\n setRange(range)\n }, [range, setRange])\n\n useEffect(() => {\n const navigationKeys = [\"ArrowUp\", \"ArrowDown\", \"Enter\"]\n const onKeyDown = (e: KeyboardEvent) => {\n if (navigationKeys.includes(e.key)) {\n e.preventDefault()\n const commandRef = document.querySelector(\"#slash-command\")\n\n if (commandRef)\n commandRef.dispatchEvent(\n new KeyboardEvent(\"keydown\", {\n key: e.key,\n cancelable: true,\n bubbles: true,\n })\n )\n\n return false\n }\n }\n document.addEventListener(\"keydown\", onKeyDown)\n return () => {\n document.removeEventListener(\"keydown\", onKeyDown)\n }\n }, [])\n\n return <commandTunnel.Out />\n}\n\nconst CommandAny: any = Command\nexport const EditorCommand = forwardRef<HTMLDivElement, any>(\n ({ children, className, ...rest }, ref) => {\n const [query, setQuery] = useAtom(queryAtom)\n\n return (\n <commandTunnel.In>\n <CommandAny\n ref={ref}\n onKeyDown={(e: any) => {\n e.stopPropagation()\n }}\n id=\"slash-command\"\n className={className}\n {...rest}\n >\n <CommandAny.Input\n value={query}\n onValueChange={setQuery}\n style={{ display: \"none\" }}\n />\n {children}\n </CommandAny>\n </commandTunnel.In>\n )\n }\n)\nexport const EditorCommandList: any = Command.List\n\nEditorCommand.displayName = \"EditorCommand\"\n","import { atom } from \"jotai\"\nimport type { Range } from \"@tiptap/core\"\n\nexport const queryAtom = atom(\"\")\nexport const rangeAtom = atom<Range | null>(null)\n\n","import { forwardRef } from \"react\"\nimport { CommandEmpty, CommandItem } from \"cmdk\"\nimport { useCurrentEditor } from \"@tiptap/react\"\nimport { useAtomValue } from \"jotai\"\nimport { rangeAtom } from \"../utils/atoms\"\nimport type { Editor, Range } from \"@tiptap/core\"\n\ninterface EditorCommandItemProps {\n readonly onCommand: ({\n editor,\n range,\n }: {\n editor: Editor\n range: Range\n }) => void\n}\n\nconst CommandItemAny: any = CommandItem\nconst CommandEmptyAny: any = CommandEmpty\n\nexport const EditorCommandItem = forwardRef<\n HTMLDivElement,\n EditorCommandItemProps & any\n>(({ children, onCommand, ...rest }, ref) => {\n const { editor } = useCurrentEditor()\n const range = useAtomValue(rangeAtom)\n\n if (!editor || !range) return null\n\n return (\n <CommandItemAny\n ref={ref}\n {...(rest as any)}\n onSelect={() => onCommand({ editor, range })}\n >\n {children}\n </CommandItemAny>\n )\n})\n\nEditorCommandItem.displayName = \"EditorCommandItem\"\n\nexport const EditorCommandEmpty: any = CommandEmptyAny\n\nexport default EditorCommandItem\n","export { StarterKit } from \"@tiptap/starter-kit\";\nexport { Placeholder } from \"@tiptap/extension-placeholder\";\n\n// Custom\nexport { CodeBlock } from \"./CodeBlock\";\nexport { Link } from \"./Link\";\nexport { ImageBlock } from \"./ImageBlock\";\nexport type { ImageBlockOptions } from \"./ImageBlock\";\nexport { AISuggestion, AISuggestionPluginKey } from \"./AISuggestion\";\nexport type { AISuggestionOptions } from \"./AISuggestion\";\nexport { createMentionExtension, renderMentionSuggestion, MentionCommand } from \"./Mention\";\nexport type { MentionItem, MentionOptions } from \"./Mention\";\n","import { ReactRenderer, ReactNodeViewRenderer } from \"@tiptap/react\"\nimport Suggestion from \"@tiptap/suggestion\"\nimport Mention from \"@tiptap/extension-mention\"\nimport type { SuggestionOptions } from \"@tiptap/suggestion\"\nimport type { RefObject } from \"react\"\nimport { MentionCommand } from \"./mention-command\"\nimport { MentionNodeView } from \"./mention-node-view\"\n\nexport interface MentionItem {\n id: string\n label: string\n avatar?: string\n email?: string\n type?: \"node\" | \"article\" // For reference mentions\n nodeId?: string // For node references (user-facing ID like \"TSK-1\")\n slug?: string // For article references (URL slug)\n}\n\nexport interface MentionOptions {\n /**\n * Function to fetch/filter mentionable items based on query\n */\n items?: (query: string) => MentionItem[] | Promise<MentionItem[]>\n\n /**\n * Custom render function for mention nodes\n */\n renderLabel?: (props: { node: any; options: any }) => string\n\n /**\n * Character that triggers the mention autocomplete (default: @)\n */\n char?: string\n\n /**\n * Custom name for the extension (to avoid duplicates)\n */\n name?: string\n}\n\n/**\n * Create the mention extension with custom suggestion rendering\n */\nexport const createMentionExtension = (options?: MentionOptions) => {\n const extensionName = options?.name ?? \"mention\"\n\n return Mention.extend({\n name: extensionName,\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-id\"),\n renderHTML: (attributes) => {\n if (!attributes.id) {\n return {}\n }\n return {\n \"data-id\": attributes.id,\n }\n },\n },\n label: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-label\"),\n renderHTML: (attributes) => {\n if (!attributes.label) {\n return {}\n }\n return {\n \"data-label\": attributes.label,\n }\n },\n },\n avatar: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-avatar\"),\n renderHTML: (attributes) => {\n if (!attributes.avatar) {\n return {}\n }\n return {\n \"data-avatar\": attributes.avatar,\n }\n },\n },\n type: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-ref-type\"),\n renderHTML: (attributes) => {\n if (!attributes.type) {\n return {}\n }\n return {\n \"data-ref-type\": attributes.type,\n }\n },\n },\n nodeId: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-node-id\"),\n renderHTML: (attributes) => {\n if (!attributes.nodeId) {\n return {}\n }\n return {\n \"data-node-id\": attributes.nodeId,\n }\n },\n },\n slug: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-slug\"),\n renderHTML: (attributes) => {\n if (!attributes.slug) {\n return {}\n }\n return {\n \"data-slug\": attributes.slug,\n }\n },\n },\n }\n },\n addNodeView() {\n return ReactNodeViewRenderer(MentionNodeView)\n },\n }).configure({\n HTMLAttributes: {\n class: \"mention\",\n },\n suggestion: {\n char: options?.char ?? \"@\",\n items: async ({ query }: { query: string }) => {\n if (!options?.items) return []\n const items = await options.items(query)\n return items\n },\n command: ({ editor, range, props: item }: any) => {\n editor\n .chain()\n .focus()\n .insertContentAt(range, [\n {\n type: extensionName,\n attrs: {\n id: item.id,\n label: item.label,\n avatar: item.avatar,\n type: item.type,\n nodeId: item.nodeId,\n slug: item.slug,\n },\n },\n ])\n .run()\n },\n render: renderMentionSuggestion,\n },\n renderLabel: options?.renderLabel ?? ((props) => {\n return `@${props.node.attrs.label ?? props.node.attrs.id}`\n }),\n })\n}\n\n/**\n * Render function for mention suggestions (autocomplete dropdown)\n */\nexport const renderMentionSuggestion = () => {\n let component: ReactRenderer | null = null\n let container: HTMLElement | null = null\n\n const destroy = () => {\n component?.destroy()\n component = null\n if (container) {\n container.remove()\n container = null\n }\n }\n\n const updatePosition = (clientRect?: DOMRect | null) => {\n if (!container || !clientRect) return\n\n const gap = 8\n const maxDropdownHeight = 300 // Match the maxHeight from MentionCommand\n const spaceBelow = window.innerHeight - clientRect.bottom\n const spaceAbove = clientRect.top\n\n // Position above if not enough space below, otherwise position below\n const shouldPositionAbove = spaceBelow < maxDropdownHeight && spaceAbove > spaceBelow\n\n const left = Math.round(clientRect.left)\n\n if (shouldPositionAbove) {\n const bottom = Math.round(window.innerHeight - clientRect.top + gap)\n container.style.bottom = `${bottom}px`\n container.style.top = 'auto'\n } else {\n const top = Math.round(clientRect.bottom + gap)\n container.style.top = `${top}px`\n container.style.bottom = 'auto'\n }\n\n container.style.left = `${left}px`\n }\n\n return {\n onStart: (props: any) => {\n component = new ReactRenderer(MentionCommand, {\n props: {\n items: props.items ?? [],\n command: props.command ?? (() => {}),\n query: props.query ?? \"\",\n },\n editor: props.editor,\n })\n\n container = document.createElement(\"div\")\n container.style.position = \"fixed\"\n container.style.zIndex = \"9999\"\n document.body.appendChild(container)\n container.appendChild(component.element)\n\n const rect =\n typeof props.clientRect === \"function\" ? props.clientRect() : null\n if (rect) updatePosition(rect)\n },\n onUpdate: (props: any) => {\n component?.updateProps({\n items: props.items ?? [],\n command: props.command ?? (() => {}),\n query: props.query ?? \"\",\n })\n const rect =\n typeof props.clientRect === \"function\" ? props.clientRect() : null\n if (rect) updatePosition(rect)\n },\n onKeyDown: ({ event }: { event: KeyboardEvent }) => {\n if (!component) return false\n\n if (event.key === \"Escape\") {\n event.preventDefault()\n event.stopPropagation()\n destroy()\n return true\n }\n\n // Handle arrow keys and enter\n if ([\"ArrowUp\", \"ArrowDown\", \"Enter\"].includes(event.key)) {\n event.preventDefault()\n event.stopPropagation()\n // Let the MentionList component handle keyboard navigation\n return (component.ref as any)?.onKeyDown?.({ event }) ?? false\n }\n\n return false\n },\n onExit: () => {\n destroy()\n },\n }\n}\n\nexport default createMentionExtension\n","import { forwardRef, useEffect, useImperativeHandle, useState } from \"react\"\nimport type { MentionItem } from \"./mention\"\n\ninterface MentionCommandProps {\n items: MentionItem[]\n command: (item: MentionItem) => void\n query: string\n}\n\n// Simple Avatar component with inline styles\nfunction Avatar({ src, fallback }: { src?: string; fallback: string }) {\n return (\n <div style={{\n position: \"relative\",\n display: \"flex\",\n height: \"24px\",\n width: \"24px\",\n flexShrink: 0,\n overflow: \"hidden\",\n borderRadius: \"9999px\",\n }}>\n {src ? (\n <img\n style={{\n aspectRatio: \"1\",\n height: \"100%\",\n width: \"100%\",\n }}\n src={src}\n alt={fallback}\n />\n ) : (\n <div style={{\n display: \"flex\",\n height: \"100%\",\n width: \"100%\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: \"9999px\",\n backgroundColor: \"var(--muted)\",\n color: \"var(--muted-foreground)\",\n fontSize: \"10px\",\n fontWeight: 600,\n }}>\n {fallback}\n </div>\n )}\n </div>\n )\n}\n\n// Icon component for reference types\nfunction ReferenceIcon({ type }: { type: \"node\" | \"article\" }) {\n if (type === \"node\") {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={{ flexShrink: 0 }}>\n <path d=\"M12 3l8 4.5v9l-8 4.5l-8-4.5v-9l8-4.5\"></path>\n <path d=\"M12 12l8-4.5\"></path>\n <path d=\"M12 12v9\"></path>\n <path d=\"M12 12l-8-4.5\"></path>\n </svg>\n )\n }\n\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={{ flexShrink: 0 }}>\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\"></path>\n <path d=\"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z\"></path>\n <path d=\"M9 9l1 0\"></path>\n <path d=\"M9 13l6 0\"></path>\n <path d=\"M9 17l6 0\"></path>\n </svg>\n )\n}\n\nexport const MentionCommand = forwardRef<any, MentionCommandProps>((props, ref) => {\n const [selectedIndex, setSelectedIndex] = useState(0)\n\n const selectItem = (index: number) => {\n const item = props.items[index]\n if (item) {\n props.command(item)\n }\n }\n\n const upHandler = () => {\n setSelectedIndex((selectedIndex + props.items.length - 1) % props.items.length)\n }\n\n const downHandler = () => {\n setSelectedIndex((selectedIndex + 1) % props.items.length)\n }\n\n const enterHandler = () => {\n selectItem(selectedIndex)\n }\n\n useEffect(() => setSelectedIndex(0), [props.items])\n\n useImperativeHandle(ref, () => ({\n onKeyDown: ({ event }: { event: KeyboardEvent }) => {\n if (event.key === \"ArrowUp\") {\n upHandler()\n return true\n }\n\n if (event.key === \"ArrowDown\") {\n downHandler()\n return true\n }\n\n if (event.key === \"Enter\") {\n enterHandler()\n return true\n }\n\n return false\n },\n }))\n\n return (\n <div\n id=\"mention-list\"\n style={{\n backgroundColor: \"var(--popover)\",\n color: \"var(--foreground)\",\n maxHeight: \"300px\",\n minWidth: \"280px\",\n overflow: \"hidden\",\n overflowY: \"auto\",\n borderRadius: \"12px\",\n border: \"1px solid var(--border)\",\n padding: \"4px\",\n boxShadow: \"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)\",\n }}\n >\n {props.items.length ? (\n props.items.map((item, index) => (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => selectItem(index)}\n onMouseEnter={() => setSelectedIndex(index)}\n style={{\n position: \"relative\",\n display: \"flex\",\n width: \"100%\",\n cursor: \"default\",\n userSelect: \"none\",\n alignItems: \"center\",\n gap: \"8px\",\n borderRadius: \"4px\",\n padding: \"10px 8px\",\n fontSize: \"14px\",\n outline: \"none\",\n backgroundColor: index === selectedIndex ? \"var(--accent)\" : \"transparent\",\n color: index === selectedIndex ? \"var(--accent-foreground)\" : \"inherit\",\n border: \"none\",\n textAlign: \"left\",\n }}\n >\n {item.type ? (\n <ReferenceIcon type={item.type} />\n ) : (\n <Avatar\n src={item.avatar}\n fallback={item.label.slice(0, 2).toUpperCase()}\n />\n )}\n <span style={{\n flex: 1,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}>\n {item.label}\n </span>\n </button>\n ))\n ) : (\n <div style={{\n padding: \"24px 0\",\n textAlign: \"center\",\n fontSize: \"14px\",\n color: \"var(--muted-foreground)\",\n }}>\n No results found\n </div>\n )}\n </div>\n )\n})\n\nMentionCommand.displayName = \"MentionCommand\"\n","import { NodeViewWrapper } from \"@tiptap/react\"\nimport type { NodeViewProps } from \"@tiptap/react\"\n\n// Icon components\nfunction NodeIcon() {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={{ flexShrink: 0 }}>\n <path d=\"M12 3l8 4.5v9l-8 4.5l-8-4.5v-9l8-4.5\"></path>\n <path d=\"M12 12l8-4.5\"></path>\n <path d=\"M12 12v9\"></path>\n <path d=\"M12 12l-8-4.5\"></path>\n </svg>\n )\n}\n\nfunction ArticleIcon() {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={{ flexShrink: 0 }}>\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\"></path>\n <path d=\"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z\"></path>\n <path d=\"M9 9l1 0\"></path>\n <path d=\"M9 13l6 0\"></path>\n <path d=\"M9 17l6 0\"></path>\n </svg>\n )\n}\n\nexport const MentionNodeView = (props: NodeViewProps) => {\n const { node } = props\n const { id, label, avatar, type } = node.attrs\n\n // Determine styling based on type\n const isNode = type === \"node\"\n const isArticle = type === \"article\"\n const isReference = isNode || isArticle\n\n const backgroundColor = isArticle\n ? \"rgba(249, 115, 22, 0.15)\" // Orange for articles\n : isNode\n ? \"rgba(107, 114, 128, 0.15)\" // Gray for nodes\n : \"var(--accent)\" // Default for user mentions\n\n const color = isArticle\n ? \"rgb(234, 88, 12)\" // Orange text\n : isNode\n ? \"rgb(75, 85, 99)\" // Gray text\n : \"var(--accent-foreground)\" // Default\n\n const border = isArticle\n ? \"1px solid rgba(249, 115, 22, 0.3)\"\n : isNode\n ? \"1px solid rgba(107, 114, 128, 0.3)\"\n : \"none\"\n\n return (\n <NodeViewWrapper\n as=\"span\"\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"3px\",\n backgroundColor,\n color,\n border,\n padding: isReference ? \"1px 6px\" : \"1px 6px 1px 1px\",\n borderRadius: \"12px\",\n fontSize: \"13px\",\n fontWeight: 500,\n verticalAlign: \"middle\",\n }}\n >\n {/* Show icon for references */}\n {isNode && <NodeIcon />}\n {isArticle && <ArticleIcon />}\n\n {/* Show avatar for user mentions */}\n {!isReference && avatar && (\n <img\n src={avatar}\n alt={label || id}\n style={{\n width: \"20px\",\n height: \"20px\",\n borderRadius: \"50%\",\n flexShrink: 0,\n }}\n />\n )}\n {!isReference && !avatar && (\n <div\n style={{\n width: \"20px\",\n height: \"20px\",\n borderRadius: \"50%\",\n backgroundColor: \"var(--muted)\",\n color: \"var(--muted-foreground)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"10px\",\n fontWeight: 600,\n flexShrink: 0,\n }}\n >\n {(label || id).slice(0, 2).toUpperCase()}\n </div>\n )}\n <span>{label || id}</span>\n </NodeViewWrapper>\n )\n}\n","import { ReactRenderer } from \"@tiptap/react\"\nimport Suggestion from \"@tiptap/suggestion\"\nimport { Extension } from \"@tiptap/core\"\nimport type { RefObject, ReactNode } from \"react\"\nimport { EditorCommandOut } from \"../components/editor-command\"\n\nexport const Command = Extension.create({\n name: \"slash-command\",\n addOptions() {\n return {\n suggestion: {\n char: \"/\",\n command: (ctx: any) => {\n ctx.props.command({ editor: ctx.editor, range: ctx.range })\n },\n } as any,\n }\n },\n addProseMirrorPlugins() {\n const base: any = this.options.suggestion ?? {}\n return [\n Suggestion({\n editor: this.editor,\n char: base.char ?? \"/\",\n // Only trigger slash command at start of line or after whitespace\n startOfLine: base.startOfLine ?? true,\n items: base.items ?? (() => [\"/\"] as any),\n command: (ctx: any) => {\n if (typeof ctx?.props?.command === \"function\") {\n ctx.props.command({ editor: ctx.editor, range: ctx.range })\n }\n },\n ...base,\n }),\n ]\n },\n})\n\nexport const renderItems = (elementRef?: RefObject<Element> | null) => {\n let component: ReactRenderer | null = null\n let container: HTMLElement | null = null\n\n const destroy = () => {\n component?.destroy()\n component = null\n if (container) {\n container.remove()\n container = null\n }\n }\n\n const updatePosition = (clientRect?: DOMRect | null) => {\n if (!container || !clientRect) return\n const top = Math.round(clientRect.bottom + 8)\n const left = Math.round(clientRect.left)\n container.style.top = `${top}px`\n container.style.left = `${left}px`\n }\n\n return {\n onStart: (props: {\n editor: any\n clientRect: (() => DOMRect | null) | null\n query?: string\n range?: any\n }) => {\n const { selection } = props.editor.state\n const parentNode = selection.$from.node(selection.$from.depth)\n const blockType = parentNode.type.name\n\n // Don't show slash menu in code blocks\n if (blockType === \"codeBlock\") return false\n\n // Don't show slash menu if inside code or link marks\n const { $from } = selection\n const marks = $from.marks()\n if (marks.some((mark: any) => mark.type.name === \"code\" || mark.type.name === \"link\")) {\n return false\n }\n\n component = new ReactRenderer(EditorCommandOut, {\n props: {\n query: (props as any).query ?? \"\",\n range: (props as any).range,\n },\n editor: props.editor,\n })\n\n container = document.createElement(\"div\")\n container.style.position = \"fixed\"\n container.style.zIndex = \"9999\"\n container.style.minWidth = \"240px\"\n ;(elementRef?.current ?? document.body).appendChild(container)\n container.appendChild(component.element)\n\n const rect =\n typeof props.clientRect === \"function\" ? props.clientRect() : null\n if (rect) updatePosition(rect)\n },\n onUpdate: (props: {\n editor: any\n clientRect: (() => DOMRect | null) | null\n query?: string\n range?: any\n }) => {\n component?.updateProps({\n query: (props as any).query ?? \"\",\n range: (props as any).range,\n })\n const rect =\n typeof props.clientRect === \"function\" ? props.clientRect() : null\n if (rect) updatePosition(rect)\n },\n onKeyDown: ({ event }: { event: KeyboardEvent }) => {\n if (event.key === \"Escape\") {\n destroy()\n return true\n }\n return false\n },\n onExit: () => {\n destroy()\n },\n }\n}\n\nexport interface SuggestionItem {\n title: string\n description: string\n icon: ReactNode\n searchTerms?: string[]\n command?: (props: {\n editor: any\n range: { from: number; to: number }\n }) => void\n}\n\nexport const createSuggestionItems = (items: SuggestionItem[]) => items\n\nexport const handleCommandNavigation = (event: KeyboardEvent) => {\n if ([\"ArrowUp\", \"ArrowDown\", \"Enter\"].includes(event.key)) {\n const slashCommand = document.querySelector(\"#slash-command\")\n if (slashCommand) return true\n }\n}\n"],"mappings":"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","names":["Command","import_react","import_react","import_jotai","import_react","import_jsx_runtime","BubbleMenuReact","import_react","import_jsx_runtime","import_jotai","import_react","import_jotai","import_jsx_runtime","tunnel","import_react","import_cmdk","import_jotai","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","Mention","import_react","Command","Suggestion"]}
|
|
1
|
+
{"version":3,"sources":["../../src/headless/index.ts","../../src/headless/components/editor.tsx","../../src/headless/utils/store.ts","../../src/headless/components/editor-bubble.tsx","../../src/headless/components/editor-bubble-item.tsx","../../src/headless/components/editor-command.tsx","../../src/headless/utils/atoms.ts","../../src/headless/components/editor-command-item.tsx","../../src/headless/extensions/index.ts","../../src/headless/extensions/Mention/mention.tsx","../../src/headless/extensions/Mention/mention-command.tsx","../../src/headless/extensions/Mention/mention-node-view.tsx","../../src/headless/extensions/slash-command.tsx"],"sourcesContent":["export { useCurrentEditor as useEditor } from \"@tiptap/react\"\n\nexport {\n EditorRoot,\n EditorContent,\n type EditorContentProps,\n} from \"./components/editor\"\n\nexport { EditorBubble } from \"./components/editor-bubble\"\nexport { EditorBubbleItem } from \"./components/editor-bubble-item\"\nexport {\n EditorCommand,\n EditorCommandList,\n EditorCommandOut,\n} from \"./components/editor-command\"\nexport {\n EditorCommandItem,\n EditorCommandEmpty,\n} from \"./components/editor-command-item\"\n\nexport { Placeholder, StarterKit } from \"./extensions\"\nexport {\n Command as SlashCommand,\n renderItems as renderSlashCommandItems,\n createSuggestionItems,\n handleCommandNavigation,\n} from \"./extensions/slash-command\"\nexport {\n createMentionExtension,\n renderMentionSuggestion,\n MentionCommand,\n type MentionItem,\n type MentionOptions,\n} from \"./extensions/Mention\"\n// Path without extension to satisfy TS/tsup\n// (the file is at ./extensions/slash-command.tsx)\n// eslint-disable-next-line\n","import { EditorProvider } from \"@tiptap/react\"\nimport type { EditorProviderProps } from \"@tiptap/react\"\nimport { forwardRef } from \"react\"\nimport type { FC, ReactNode } from \"react\"\nimport { Provider } from \"jotai\"\nimport { novelStore } from \"../utils/store\"\n\nexport interface EditorRootProps {\n readonly children: ReactNode\n}\n\nexport const EditorRoot: FC<EditorRootProps> = ({ children }) => {\n return (\n <Provider store={novelStore as any}>\n {children as any}\n </Provider>\n )\n}\n\nexport type EditorContentProps = EditorProviderProps & {\n readonly children?: ReactNode\n readonly className?: string\n readonly initialContent?: any\n}\n\nexport const EditorContent = forwardRef<HTMLDivElement, EditorContentProps>(\n ({ className, children, initialContent, content, ...rest }, ref) => {\n const effectiveContent = content ?? initialContent\n return (\n <div ref={ref} className={className}>\n <EditorProvider {...rest} content={effectiveContent}>\n {children}\n </EditorProvider>\n </div>\n )\n }\n)\n\nEditorContent.displayName = \"EditorContent\"\n","import { createStore } from \"jotai\";\n\n// biome-ignore lint/suspicious/noExplicitAny: store is opaque to consumers\nexport const novelStore: any = createStore();\nexport * from \"jotai\";\n\n","import { useCurrentEditor } from \"@tiptap/react\";\nimport { BubbleMenu as BubbleMenuReact } from \"@tiptap/react/menus\";\nimport type { BubbleMenuProps } from \"@tiptap/react/menus\";\nimport type { ReactNode } from \"react\";\n\ntype ForwardedBubbleProps = Omit<BubbleMenuProps, \"editor\" | \"children\" | \"className\">;\n\nexport interface EditorBubbleProps extends ForwardedBubbleProps {\n readonly className?: string;\n readonly children: ReactNode;\n}\n\nexport function EditorBubble({ className, children, ...rest }: EditorBubbleProps) {\n const { editor } = useCurrentEditor();\n if (!editor) return null;\n\n return (\n <BubbleMenuReact editor={editor} {...rest}>\n <div className={className}>{children}</div>\n </BubbleMenuReact>\n );\n}\n","import { forwardRef, isValidElement, cloneElement } from \"react\"\nimport type { ComponentPropsWithoutRef, ReactElement, ReactNode } from \"react\"\nimport { useCurrentEditor } from \"@tiptap/react\"\nimport type { Editor as TiptapEditor } from \"@tiptap/react\"\n\ninterface EditorBubbleItemProps {\n readonly children: ReactNode\n readonly asChild?: boolean\n readonly onSelect?: (editor: TiptapEditor) => void\n}\n\nexport const EditorBubbleItem = forwardRef<\n HTMLDivElement,\n EditorBubbleItemProps & Omit<ComponentPropsWithoutRef<\"div\">, \"onSelect\">\n>(({ children, asChild, onSelect, ...rest }, ref) => {\n const { editor } = useCurrentEditor()\n\n if (!editor) return null\n\n const handleClick = (e: React.MouseEvent) => {\n e.preventDefault()\n onSelect?.(editor)\n }\n\n if (asChild && isValidElement(children)) {\n const child = children as ReactElement<any>\n const childOnClick = (child.props as any)?.onClick as\n | ((e: any) => void)\n | undefined\n const mergedOnClick = (e: any) => {\n childOnClick?.(e)\n if (!e?.defaultPrevented) onSelect?.(editor)\n }\n\n return cloneElement(child, {\n ...rest,\n ref: (child as any).ref ?? ref,\n onClick: mergedOnClick,\n })\n }\n\n return (\n <div ref={ref} {...rest} onClick={handleClick}>\n {children}\n </div>\n )\n})\n\nEditorBubbleItem.displayName = \"EditorBubbleItem\"\n\nexport default EditorBubbleItem\n","import { useAtomValue } from \"jotai\"\nimport { forwardRef, useRef, useEffect, useLayoutEffect, useState, useCallback } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { queryAtom, slashMenuOpenAtom, slashMenuRectAtom } from \"../utils/atoms\"\nimport { novelStore } from \"../utils/store\"\n\n// EditorCommandOut is no longer needed — kept as a no-op for backward compatibility\nexport const EditorCommandOut = () => null\n\nexport const EditorCommand = forwardRef<HTMLDivElement, any>(\n ({ children, className, ...rest }, ref) => {\n const isOpen = useAtomValue(slashMenuOpenAtom, { store: novelStore })\n const rect = useAtomValue(slashMenuRectAtom, { store: novelStore })\n const containerRef = useRef<HTMLDivElement | null>(null)\n const [activeIndex, setActiveIndex] = useState(0)\n const contentRef = useRef<HTMLDivElement | null>(null)\n\n // Reset active index when query changes\n const query = useAtomValue(queryAtom, { store: novelStore })\n useEffect(() => {\n setActiveIndex(0)\n }, [query])\n\n // Create portal container once\n if (typeof document !== \"undefined\" && !containerRef.current) {\n const el = document.createElement(\"div\")\n el.style.position = \"fixed\"\n el.style.zIndex = \"9999\"\n el.style.minWidth = \"240px\"\n el.style.display = \"none\"\n containerRef.current = el\n }\n\n // Manage DOM attachment\n useEffect(() => {\n const el = containerRef.current\n if (!el) return\n document.body.appendChild(el)\n return () => {\n el.remove()\n }\n }, [])\n\n // Show/hide and position\n useLayoutEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n if (!isOpen || !rect) {\n container.style.display = \"none\"\n return\n }\n\n container.style.display = \"\"\n\n const menuHeight = container.offsetHeight || 360\n const viewportHeight = window.innerHeight\n const spaceBelow = viewportHeight - rect.bottom\n const spaceAbove = rect.top\n\n let top: number\n if (spaceBelow < menuHeight + 16 && spaceAbove > spaceBelow) {\n top = Math.round(rect.top - menuHeight - 8)\n if (top < 8) top = 8\n } else {\n top = Math.round(rect.bottom + 8)\n }\n\n let left = Math.round(rect.left)\n const menuWidth = container.offsetWidth || 280\n if (left + menuWidth > window.innerWidth - 8) {\n left = window.innerWidth - menuWidth - 8\n }\n if (left < 8) left = 8\n\n container.style.top = `${top}px`\n container.style.left = `${left}px`\n }, [isOpen, rect])\n\n // Keyboard navigation\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (!isOpen || !contentRef.current) return\n\n const items = contentRef.current.querySelectorAll(\"[role='option']\")\n if (items.length === 0) return\n\n if (e.key === \"ArrowDown\") {\n e.preventDefault()\n setActiveIndex((prev) => {\n const next = Math.min(prev + 1, items.length - 1)\n items[next]?.scrollIntoView({ block: \"nearest\" })\n return next\n })\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault()\n setActiveIndex((prev) => {\n const next = Math.max(prev - 1, 0)\n items[next]?.scrollIntoView({ block: \"nearest\" })\n return next\n })\n } else if (e.key === \"Enter\") {\n e.preventDefault()\n const activeItem = items[activeIndex] as HTMLElement | undefined\n activeItem?.click()\n }\n },\n [isOpen, activeIndex]\n )\n\n useEffect(() => {\n if (!isOpen) return\n document.addEventListener(\"keydown\", handleKeyDown)\n return () => document.removeEventListener(\"keydown\", handleKeyDown)\n }, [isOpen, handleKeyDown])\n\n // Apply active styling\n useEffect(() => {\n if (!contentRef.current) return\n const items = contentRef.current.querySelectorAll(\"[role='option']\")\n items.forEach((item, i) => {\n if (i === activeIndex) {\n item.setAttribute(\"aria-selected\", \"true\")\n } else {\n item.removeAttribute(\"aria-selected\")\n }\n })\n })\n\n if (!isOpen || !containerRef.current) return null\n\n return createPortal(\n <div\n ref={(el) => {\n contentRef.current = el\n if (typeof ref === \"function\") ref(el)\n else if (ref) ref.current = el\n }}\n id=\"slash-command\"\n className={className}\n {...rest}\n >\n {children}\n </div>,\n containerRef.current\n )\n }\n)\n\n// Simple list wrapper\nexport const EditorCommandList = forwardRef<HTMLDivElement, any>(\n ({ children, ...rest }, ref) => {\n return (\n <div ref={ref} role=\"listbox\" {...rest}>\n {children}\n </div>\n )\n }\n)\n\nEditorCommand.displayName = \"EditorCommand\"\nEditorCommandList.displayName = \"EditorCommandList\"\n","import { atom } from \"jotai\"\nimport type { Range } from \"@tiptap/core\"\n\nexport const queryAtom = atom(\"\")\nexport const rangeAtom = atom<Range | null>(null)\nexport const slashMenuOpenAtom = atom(false)\nexport const slashMenuRectAtom = atom<DOMRect | null>(null)\n","import { forwardRef } from \"react\"\nimport { useCurrentEditor } from \"@tiptap/react\"\nimport { useAtomValue } from \"jotai\"\nimport { rangeAtom, queryAtom } from \"../utils/atoms\"\nimport { novelStore } from \"../utils/store\"\nimport type { Editor, Range } from \"@tiptap/core\"\n\ninterface EditorCommandItemProps {\n readonly onCommand: ({\n editor,\n range,\n }: {\n editor: Editor\n range: Range\n }) => void\n readonly value?: string\n}\n\nexport const EditorCommandItem = forwardRef<\n HTMLDivElement,\n EditorCommandItemProps & any\n>(({ children, onCommand, value, className, ...rest }, ref) => {\n const { editor } = useCurrentEditor()\n const range = useAtomValue(rangeAtom, { store: novelStore })\n const query = useAtomValue(queryAtom, { store: novelStore })\n\n if (!editor || !range) return null\n\n // Filter: if query is set, check if this item matches\n if (query && value) {\n const searchText = value.toLowerCase()\n const q = query.toLowerCase()\n if (!searchText.includes(q)) return null\n }\n\n return (\n <div\n ref={ref}\n role=\"option\"\n className={className}\n onClick={() => onCommand({ editor, range })}\n {...rest}\n >\n {children}\n </div>\n )\n})\n\nEditorCommandItem.displayName = \"EditorCommandItem\"\n\nexport const EditorCommandEmpty = forwardRef<HTMLDivElement, any>(\n ({ children, ...rest }, ref) => {\n return (\n <div ref={ref} {...rest}>\n {children}\n </div>\n )\n }\n)\n\nEditorCommandEmpty.displayName = \"EditorCommandEmpty\"\n\nexport default EditorCommandItem\n","export { StarterKit } from \"@tiptap/starter-kit\";\nexport { Placeholder } from \"@tiptap/extension-placeholder\";\n\n// Custom\nexport { CodeBlock } from \"./CodeBlock\";\nexport { Link } from \"./Link\";\nexport { ImageBlock } from \"./ImageBlock\";\nexport type { ImageBlockOptions } from \"./ImageBlock\";\nexport { AISuggestion, AISuggestionPluginKey } from \"./AISuggestion\";\nexport type { AISuggestionOptions } from \"./AISuggestion\";\nexport { createMentionExtension, renderMentionSuggestion, MentionCommand } from \"./Mention\";\nexport type { MentionItem, MentionOptions } from \"./Mention\";\nexport { DragHandle, setDragHandleCallbacks } from \"./DragHandle\";\nexport type { DragHandleCallbacks } from \"./DragHandle\";\nexport { TableKit, Table, TableCell, TableHeader, TableRow } from \"./Table\";\nexport { MarkdownPaste } from \"./MarkdownPaste\";\n","import { ReactRenderer, ReactNodeViewRenderer } from \"@tiptap/react\"\nimport Suggestion from \"@tiptap/suggestion\"\nimport Mention from \"@tiptap/extension-mention\"\nimport type { SuggestionOptions } from \"@tiptap/suggestion\"\nimport type { RefObject } from \"react\"\nimport { MentionCommand } from \"./mention-command\"\nimport { MentionNodeView } from \"./mention-node-view\"\n\nexport interface MentionItem {\n id: string\n label: string\n avatar?: string\n email?: string\n type?: \"node\" | \"article\" // For reference mentions\n nodeId?: string // For node references (user-facing ID like \"TSK-1\")\n slug?: string // For article references (URL slug)\n}\n\nexport interface MentionOptions {\n /**\n * Function to fetch/filter mentionable items based on query\n */\n items?: (query: string) => MentionItem[] | Promise<MentionItem[]>\n\n /**\n * Custom render function for mention nodes\n */\n renderLabel?: (props: { node: any; options: any }) => string\n\n /**\n * Character that triggers the mention autocomplete (default: @)\n */\n char?: string\n\n /**\n * Custom name for the extension (to avoid duplicates)\n */\n name?: string\n}\n\n/**\n * Create the mention extension with custom suggestion rendering\n */\nexport const createMentionExtension = (options?: MentionOptions) => {\n const extensionName = options?.name ?? \"mention\"\n\n return Mention.extend({\n name: extensionName,\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-id\"),\n renderHTML: (attributes) => {\n if (!attributes.id) {\n return {}\n }\n return {\n \"data-id\": attributes.id,\n }\n },\n },\n label: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-label\"),\n renderHTML: (attributes) => {\n if (!attributes.label) {\n return {}\n }\n return {\n \"data-label\": attributes.label,\n }\n },\n },\n avatar: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-avatar\"),\n renderHTML: (attributes) => {\n if (!attributes.avatar) {\n return {}\n }\n return {\n \"data-avatar\": attributes.avatar,\n }\n },\n },\n type: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-ref-type\"),\n renderHTML: (attributes) => {\n if (!attributes.type) {\n return {}\n }\n return {\n \"data-ref-type\": attributes.type,\n }\n },\n },\n nodeId: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-node-id\"),\n renderHTML: (attributes) => {\n if (!attributes.nodeId) {\n return {}\n }\n return {\n \"data-node-id\": attributes.nodeId,\n }\n },\n },\n slug: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-slug\"),\n renderHTML: (attributes) => {\n if (!attributes.slug) {\n return {}\n }\n return {\n \"data-slug\": attributes.slug,\n }\n },\n },\n }\n },\n addNodeView() {\n return ReactNodeViewRenderer(MentionNodeView)\n },\n }).configure({\n HTMLAttributes: {\n class: \"mention\",\n },\n suggestion: {\n char: options?.char ?? \"@\",\n items: async ({ query }: { query: string }) => {\n if (!options?.items) return []\n const items = await options.items(query)\n return items\n },\n command: ({ editor, range, props: item }: any) => {\n editor\n .chain()\n .focus()\n .insertContentAt(range, [\n {\n type: extensionName,\n attrs: {\n id: item.id,\n label: item.label,\n avatar: item.avatar,\n type: item.type,\n nodeId: item.nodeId,\n slug: item.slug,\n },\n },\n ])\n .run()\n },\n render: renderMentionSuggestion,\n },\n renderLabel: options?.renderLabel ?? ((props) => {\n return `@${props.node.attrs.label ?? props.node.attrs.id}`\n }),\n })\n}\n\n/**\n * Render function for mention suggestions (autocomplete dropdown)\n */\nexport const renderMentionSuggestion = () => {\n let component: ReactRenderer | null = null\n let container: HTMLElement | null = null\n\n const destroy = () => {\n component?.destroy()\n component = null\n if (container) {\n container.remove()\n container = null\n }\n }\n\n const updatePosition = (clientRect?: DOMRect | null) => {\n if (!container || !clientRect) return\n\n const gap = 8\n const maxDropdownHeight = 300 // Match the maxHeight from MentionCommand\n const spaceBelow = window.innerHeight - clientRect.bottom\n const spaceAbove = clientRect.top\n\n // Position above if not enough space below, otherwise position below\n const shouldPositionAbove = spaceBelow < maxDropdownHeight && spaceAbove > spaceBelow\n\n const left = Math.round(clientRect.left)\n\n if (shouldPositionAbove) {\n const bottom = Math.round(window.innerHeight - clientRect.top + gap)\n container.style.bottom = `${bottom}px`\n container.style.top = 'auto'\n } else {\n const top = Math.round(clientRect.bottom + gap)\n container.style.top = `${top}px`\n container.style.bottom = 'auto'\n }\n\n container.style.left = `${left}px`\n }\n\n return {\n onStart: (props: any) => {\n component = new ReactRenderer(MentionCommand, {\n props: {\n items: props.items ?? [],\n command: props.command ?? (() => {}),\n query: props.query ?? \"\",\n },\n editor: props.editor,\n })\n\n container = document.createElement(\"div\")\n container.style.position = \"fixed\"\n container.style.zIndex = \"9999\"\n document.body.appendChild(container)\n container.appendChild(component.element)\n\n const rect =\n typeof props.clientRect === \"function\" ? props.clientRect() : null\n if (rect) updatePosition(rect)\n },\n onUpdate: (props: any) => {\n component?.updateProps({\n items: props.items ?? [],\n command: props.command ?? (() => {}),\n query: props.query ?? \"\",\n })\n const rect =\n typeof props.clientRect === \"function\" ? props.clientRect() : null\n if (rect) updatePosition(rect)\n },\n onKeyDown: ({ event }: { event: KeyboardEvent }) => {\n if (!component) return false\n\n if (event.key === \"Escape\") {\n event.preventDefault()\n event.stopPropagation()\n destroy()\n return true\n }\n\n // Handle arrow keys and enter\n if ([\"ArrowUp\", \"ArrowDown\", \"Enter\"].includes(event.key)) {\n event.preventDefault()\n event.stopPropagation()\n // Let the MentionList component handle keyboard navigation\n return (component.ref as any)?.onKeyDown?.({ event }) ?? false\n }\n\n return false\n },\n onExit: () => {\n destroy()\n },\n }\n}\n\nexport default createMentionExtension\n","import { forwardRef, useEffect, useImperativeHandle, useState } from \"react\"\nimport type { MentionItem } from \"./mention\"\n\ninterface MentionCommandProps {\n items: MentionItem[]\n command: (item: MentionItem) => void\n query: string\n}\n\n// Simple Avatar component with inline styles\nfunction Avatar({ src, fallback }: { src?: string; fallback: string }) {\n return (\n <div style={{\n position: \"relative\",\n display: \"flex\",\n height: \"24px\",\n width: \"24px\",\n flexShrink: 0,\n overflow: \"hidden\",\n borderRadius: \"9999px\",\n }}>\n {src ? (\n <img\n style={{\n aspectRatio: \"1\",\n height: \"100%\",\n width: \"100%\",\n }}\n src={src}\n alt={fallback}\n />\n ) : (\n <div style={{\n display: \"flex\",\n height: \"100%\",\n width: \"100%\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: \"9999px\",\n backgroundColor: \"var(--muted)\",\n color: \"var(--muted-foreground)\",\n fontSize: \"10px\",\n fontWeight: 600,\n }}>\n {fallback}\n </div>\n )}\n </div>\n )\n}\n\n// Icon component for reference types\nfunction ReferenceIcon({ type }: { type: \"node\" | \"article\" }) {\n if (type === \"node\") {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={{ flexShrink: 0 }}>\n <path d=\"M12 3l8 4.5v9l-8 4.5l-8-4.5v-9l8-4.5\"></path>\n <path d=\"M12 12l8-4.5\"></path>\n <path d=\"M12 12v9\"></path>\n <path d=\"M12 12l-8-4.5\"></path>\n </svg>\n )\n }\n\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={{ flexShrink: 0 }}>\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\"></path>\n <path d=\"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z\"></path>\n <path d=\"M9 9l1 0\"></path>\n <path d=\"M9 13l6 0\"></path>\n <path d=\"M9 17l6 0\"></path>\n </svg>\n )\n}\n\nexport const MentionCommand = forwardRef<any, MentionCommandProps>((props, ref) => {\n const [selectedIndex, setSelectedIndex] = useState(0)\n\n const selectItem = (index: number) => {\n const item = props.items[index]\n if (item) {\n props.command(item)\n }\n }\n\n const upHandler = () => {\n setSelectedIndex((selectedIndex + props.items.length - 1) % props.items.length)\n }\n\n const downHandler = () => {\n setSelectedIndex((selectedIndex + 1) % props.items.length)\n }\n\n const enterHandler = () => {\n selectItem(selectedIndex)\n }\n\n useEffect(() => setSelectedIndex(0), [props.items])\n\n useImperativeHandle(ref, () => ({\n onKeyDown: ({ event }: { event: KeyboardEvent }) => {\n if (event.key === \"ArrowUp\") {\n upHandler()\n return true\n }\n\n if (event.key === \"ArrowDown\") {\n downHandler()\n return true\n }\n\n if (event.key === \"Enter\") {\n enterHandler()\n return true\n }\n\n return false\n },\n }))\n\n return (\n <div\n id=\"mention-list\"\n style={{\n backgroundColor: \"var(--popover)\",\n color: \"var(--foreground)\",\n maxHeight: \"300px\",\n minWidth: \"280px\",\n overflow: \"hidden\",\n overflowY: \"auto\",\n borderRadius: \"12px\",\n border: \"1px solid var(--border)\",\n padding: \"4px\",\n boxShadow: \"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)\",\n }}\n >\n {props.items.length ? (\n props.items.map((item, index) => (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => selectItem(index)}\n onMouseEnter={() => setSelectedIndex(index)}\n style={{\n position: \"relative\",\n display: \"flex\",\n width: \"100%\",\n cursor: \"default\",\n userSelect: \"none\",\n alignItems: \"center\",\n gap: \"8px\",\n borderRadius: \"4px\",\n padding: \"10px 8px\",\n fontSize: \"14px\",\n outline: \"none\",\n backgroundColor: index === selectedIndex ? \"var(--accent)\" : \"transparent\",\n color: index === selectedIndex ? \"var(--accent-foreground)\" : \"inherit\",\n border: \"none\",\n textAlign: \"left\",\n }}\n >\n {item.type ? (\n <ReferenceIcon type={item.type} />\n ) : (\n <Avatar\n src={item.avatar}\n fallback={item.label.slice(0, 2).toUpperCase()}\n />\n )}\n <span style={{\n flex: 1,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}>\n {item.label}\n </span>\n </button>\n ))\n ) : (\n <div style={{\n padding: \"24px 0\",\n textAlign: \"center\",\n fontSize: \"14px\",\n color: \"var(--muted-foreground)\",\n }}>\n No results found\n </div>\n )}\n </div>\n )\n})\n\nMentionCommand.displayName = \"MentionCommand\"\n","import { NodeViewWrapper } from \"@tiptap/react\"\nimport type { NodeViewProps } from \"@tiptap/react\"\n\n// Icon components\nfunction NodeIcon() {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={{ flexShrink: 0 }}>\n <path d=\"M12 3l8 4.5v9l-8 4.5l-8-4.5v-9l8-4.5\"></path>\n <path d=\"M12 12l8-4.5\"></path>\n <path d=\"M12 12v9\"></path>\n <path d=\"M12 12l-8-4.5\"></path>\n </svg>\n )\n}\n\nfunction ArticleIcon() {\n return (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" style={{ flexShrink: 0 }}>\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\"></path>\n <path d=\"M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z\"></path>\n <path d=\"M9 9l1 0\"></path>\n <path d=\"M9 13l6 0\"></path>\n <path d=\"M9 17l6 0\"></path>\n </svg>\n )\n}\n\nexport const MentionNodeView = (props: NodeViewProps) => {\n const { node } = props\n const { id, label, avatar, type } = node.attrs\n\n // Determine styling based on type\n const isNode = type === \"node\"\n const isArticle = type === \"article\"\n const isReference = isNode || isArticle\n\n const backgroundColor = isArticle\n ? \"rgba(249, 115, 22, 0.15)\" // Orange for articles\n : isNode\n ? \"rgba(107, 114, 128, 0.15)\" // Gray for nodes\n : \"var(--accent)\" // Default for user mentions\n\n const color = isArticle\n ? \"rgb(234, 88, 12)\" // Orange text\n : isNode\n ? \"rgb(75, 85, 99)\" // Gray text\n : \"var(--accent-foreground)\" // Default\n\n const border = isArticle\n ? \"1px solid rgba(249, 115, 22, 0.3)\"\n : isNode\n ? \"1px solid rgba(107, 114, 128, 0.3)\"\n : \"none\"\n\n return (\n <NodeViewWrapper\n as=\"span\"\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"3px\",\n backgroundColor,\n color,\n border,\n padding: isReference ? \"1px 6px\" : \"1px 6px 1px 1px\",\n borderRadius: \"12px\",\n fontSize: \"13px\",\n fontWeight: 500,\n verticalAlign: \"middle\",\n }}\n >\n {/* Show icon for references */}\n {isNode && <NodeIcon />}\n {isArticle && <ArticleIcon />}\n\n {/* Show avatar for user mentions */}\n {!isReference && avatar && (\n <img\n src={avatar}\n alt={label || id}\n style={{\n width: \"20px\",\n height: \"20px\",\n borderRadius: \"50%\",\n flexShrink: 0,\n }}\n />\n )}\n {!isReference && !avatar && (\n <div\n style={{\n width: \"20px\",\n height: \"20px\",\n borderRadius: \"50%\",\n backgroundColor: \"var(--muted)\",\n color: \"var(--muted-foreground)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"10px\",\n fontWeight: 600,\n flexShrink: 0,\n }}\n >\n {(label || id).slice(0, 2).toUpperCase()}\n </div>\n )}\n <span>{label || id}</span>\n </NodeViewWrapper>\n )\n}\n","import Suggestion from \"@tiptap/suggestion\"\nimport { Extension } from \"@tiptap/core\"\nimport type { ReactNode } from \"react\"\nimport { queryAtom, rangeAtom, slashMenuOpenAtom, slashMenuRectAtom } from \"../utils/atoms\"\nimport { novelStore } from \"../utils/store\"\n\nexport const Command = Extension.create({\n name: \"slash-command\",\n addOptions() {\n return {\n suggestion: {\n char: \"/\",\n command: (ctx: any) => {\n ctx.props.command({ editor: ctx.editor, range: ctx.range })\n },\n } as any,\n }\n },\n addProseMirrorPlugins() {\n const base: any = this.options.suggestion ?? {}\n return [\n Suggestion({\n editor: this.editor,\n char: base.char ?? \"/\",\n startOfLine: base.startOfLine ?? true,\n items: base.items ?? (() => [\"/\"] as any),\n command: (ctx: any) => {\n if (typeof ctx?.props?.command === \"function\") {\n ctx.props.command({ editor: ctx.editor, range: ctx.range })\n }\n },\n ...base,\n render: () => {\n return {\n onStart: (props: any) => {\n const { selection } = props.editor.state\n const parentNode = selection.$from.node(selection.$from.depth)\n const blockType = parentNode.type.name\n\n if (blockType === \"codeBlock\") return false\n\n const { $from } = selection\n const marks = $from.marks()\n if (marks.some((mark: any) => mark.type.name === \"code\" || mark.type.name === \"link\")) {\n return false\n }\n\n novelStore.set(queryAtom, props.query ?? \"\")\n novelStore.set(rangeAtom, props.range ?? null)\n novelStore.set(slashMenuOpenAtom, true)\n\n const rect = typeof props.clientRect === \"function\" ? props.clientRect() : null\n novelStore.set(slashMenuRectAtom, rect)\n },\n onUpdate: (props: any) => {\n novelStore.set(queryAtom, props.query ?? \"\")\n novelStore.set(rangeAtom, props.range ?? null)\n\n const rect = typeof props.clientRect === \"function\" ? props.clientRect() : null\n novelStore.set(slashMenuRectAtom, rect)\n },\n onKeyDown: ({ event }: { event: KeyboardEvent }) => {\n if (event.key === \"Escape\") {\n novelStore.set(slashMenuOpenAtom, false)\n return true\n }\n\n if ([\"ArrowUp\", \"ArrowDown\", \"Enter\"].includes(event.key)) {\n const slashCommand = document.querySelector(\"#slash-command\")\n if (slashCommand) {\n slashCommand.dispatchEvent(\n new KeyboardEvent(\"keydown\", {\n key: event.key,\n cancelable: true,\n bubbles: true,\n })\n )\n return true\n }\n }\n\n return false\n },\n onExit: () => {\n novelStore.set(slashMenuOpenAtom, false)\n novelStore.set(queryAtom, \"\")\n novelStore.set(rangeAtom, null)\n novelStore.set(slashMenuRectAtom, null)\n },\n }\n },\n }),\n ]\n },\n})\n\nexport const renderItems = () => ({\n onStart: () => {},\n onUpdate: () => {},\n onKeyDown: () => false,\n onExit: () => {},\n})\n\nexport interface SuggestionItem {\n title: string\n description: string\n icon: ReactNode\n searchTerms?: string[]\n command?: (props: {\n editor: any\n range: { from: number; to: number }\n }) => void\n}\n\nexport const createSuggestionItems = (items: SuggestionItem[]) => items\n\nexport const handleCommandNavigation = (event: KeyboardEvent) => {\n if ([\"ArrowUp\", \"ArrowDown\", \"Enter\"].includes(event.key)) {\n const slashCommand = document.querySelector(\"#slash-command\")\n if (slashCommand) return true\n }\n}\n"],"mappings":"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","names":["import_react","import_react","import_jotai","import_react","import_jsx_runtime","BubbleMenuReact","import_react","import_jsx_runtime","import_jotai","import_react","import_jotai","import_jsx_runtime","import_react","import_jotai","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","Mention","Suggestion"]}
|
|
@@ -5,10 +5,10 @@ export { a as EditorContent, b as EditorContentProps, E as EditorRoot, d as Ment
|
|
|
5
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
6
|
import { BubbleMenuProps } from '@tiptap/react/menus';
|
|
7
7
|
import * as react from 'react';
|
|
8
|
-
import { ReactNode
|
|
9
|
-
import { Range, Extension } from '@tiptap/core';
|
|
8
|
+
import { ReactNode } from 'react';
|
|
10
9
|
export { StarterKit } from '@tiptap/starter-kit';
|
|
11
10
|
export { Placeholder } from '@tiptap/extension-placeholder';
|
|
11
|
+
import { Extension } from '@tiptap/core';
|
|
12
12
|
import '@tiptap/extension-mention';
|
|
13
13
|
|
|
14
14
|
type ForwardedBubbleProps = Omit<BubbleMenuProps, "editor" | "children" | "className">;
|
|
@@ -25,16 +25,12 @@ interface EditorBubbleItemProps {
|
|
|
25
25
|
}
|
|
26
26
|
declare const EditorBubbleItem: react.ForwardRefExoticComponent<EditorBubbleItemProps & Omit<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "onSelect"> & react.RefAttributes<HTMLDivElement>>;
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
readonly query: string;
|
|
30
|
-
readonly range: Range;
|
|
31
|
-
}
|
|
32
|
-
declare const EditorCommandOut: FC<EditorCommandOutProps>;
|
|
28
|
+
declare const EditorCommandOut: () => null;
|
|
33
29
|
declare const EditorCommand: react.ForwardRefExoticComponent<Omit<any, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
34
|
-
declare const EditorCommandList: any
|
|
30
|
+
declare const EditorCommandList: react.ForwardRefExoticComponent<Omit<any, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
35
31
|
|
|
36
32
|
declare const EditorCommandItem: react.ForwardRefExoticComponent<Omit<any, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
37
|
-
declare const EditorCommandEmpty: any
|
|
33
|
+
declare const EditorCommandEmpty: react.ForwardRefExoticComponent<Omit<any, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
38
34
|
|
|
39
35
|
interface MentionCommandProps {
|
|
40
36
|
items: MentionItem[];
|
|
@@ -44,22 +40,10 @@ interface MentionCommandProps {
|
|
|
44
40
|
declare const MentionCommand: react.ForwardRefExoticComponent<MentionCommandProps & react.RefAttributes<any>>;
|
|
45
41
|
|
|
46
42
|
declare const Command: Extension<any, any>;
|
|
47
|
-
declare const renderItems: (
|
|
48
|
-
onStart: (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
query?: string;
|
|
52
|
-
range?: any;
|
|
53
|
-
}) => false | undefined;
|
|
54
|
-
onUpdate: (props: {
|
|
55
|
-
editor: any;
|
|
56
|
-
clientRect: (() => DOMRect | null) | null;
|
|
57
|
-
query?: string;
|
|
58
|
-
range?: any;
|
|
59
|
-
}) => void;
|
|
60
|
-
onKeyDown: ({ event }: {
|
|
61
|
-
event: KeyboardEvent;
|
|
62
|
-
}) => boolean;
|
|
43
|
+
declare const renderItems: () => {
|
|
44
|
+
onStart: () => void;
|
|
45
|
+
onUpdate: () => void;
|
|
46
|
+
onKeyDown: () => boolean;
|
|
63
47
|
onExit: () => void;
|
|
64
48
|
};
|
|
65
49
|
interface SuggestionItem {
|
package/dist/headless/index.d.ts
CHANGED
|
@@ -5,10 +5,10 @@ export { a as EditorContent, b as EditorContentProps, E as EditorRoot, d as Ment
|
|
|
5
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
6
|
import { BubbleMenuProps } from '@tiptap/react/menus';
|
|
7
7
|
import * as react from 'react';
|
|
8
|
-
import { ReactNode
|
|
9
|
-
import { Range, Extension } from '@tiptap/core';
|
|
8
|
+
import { ReactNode } from 'react';
|
|
10
9
|
export { StarterKit } from '@tiptap/starter-kit';
|
|
11
10
|
export { Placeholder } from '@tiptap/extension-placeholder';
|
|
11
|
+
import { Extension } from '@tiptap/core';
|
|
12
12
|
import '@tiptap/extension-mention';
|
|
13
13
|
|
|
14
14
|
type ForwardedBubbleProps = Omit<BubbleMenuProps, "editor" | "children" | "className">;
|
|
@@ -25,16 +25,12 @@ interface EditorBubbleItemProps {
|
|
|
25
25
|
}
|
|
26
26
|
declare const EditorBubbleItem: react.ForwardRefExoticComponent<EditorBubbleItemProps & Omit<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "onSelect"> & react.RefAttributes<HTMLDivElement>>;
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
readonly query: string;
|
|
30
|
-
readonly range: Range;
|
|
31
|
-
}
|
|
32
|
-
declare const EditorCommandOut: FC<EditorCommandOutProps>;
|
|
28
|
+
declare const EditorCommandOut: () => null;
|
|
33
29
|
declare const EditorCommand: react.ForwardRefExoticComponent<Omit<any, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
34
|
-
declare const EditorCommandList: any
|
|
30
|
+
declare const EditorCommandList: react.ForwardRefExoticComponent<Omit<any, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
35
31
|
|
|
36
32
|
declare const EditorCommandItem: react.ForwardRefExoticComponent<Omit<any, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
37
|
-
declare const EditorCommandEmpty: any
|
|
33
|
+
declare const EditorCommandEmpty: react.ForwardRefExoticComponent<Omit<any, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
38
34
|
|
|
39
35
|
interface MentionCommandProps {
|
|
40
36
|
items: MentionItem[];
|
|
@@ -44,22 +40,10 @@ interface MentionCommandProps {
|
|
|
44
40
|
declare const MentionCommand: react.ForwardRefExoticComponent<MentionCommandProps & react.RefAttributes<any>>;
|
|
45
41
|
|
|
46
42
|
declare const Command: Extension<any, any>;
|
|
47
|
-
declare const renderItems: (
|
|
48
|
-
onStart: (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
query?: string;
|
|
52
|
-
range?: any;
|
|
53
|
-
}) => false | undefined;
|
|
54
|
-
onUpdate: (props: {
|
|
55
|
-
editor: any;
|
|
56
|
-
clientRect: (() => DOMRect | null) | null;
|
|
57
|
-
query?: string;
|
|
58
|
-
range?: any;
|
|
59
|
-
}) => void;
|
|
60
|
-
onKeyDown: ({ event }: {
|
|
61
|
-
event: KeyboardEvent;
|
|
62
|
-
}) => boolean;
|
|
43
|
+
declare const renderItems: () => {
|
|
44
|
+
onStart: () => void;
|
|
45
|
+
onUpdate: () => void;
|
|
46
|
+
onKeyDown: () => boolean;
|
|
63
47
|
onExit: () => void;
|
|
64
48
|
};
|
|
65
49
|
interface SuggestionItem {
|