@4399ywkf/editor 0.3.1 → 0.4.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/dist/{DocView-WQIV7HIE.js → DocView-CZV7LGFK.js} +4 -3
- package/dist/DocView-CZV7LGFK.js.map +1 -0
- package/dist/button-CWX5Uuj-.d.ts +14 -0
- package/dist/{chunk-Y2XE4CYZ.js → chunk-2GHNI22G.js} +18 -1141
- package/dist/chunk-2GHNI22G.js.map +1 -0
- package/dist/chunk-T2DZHEJJ.js +1145 -0
- package/dist/chunk-T2DZHEJJ.js.map +1 -0
- package/dist/doc.d.ts +3 -12
- package/dist/doc.js +2 -1
- package/dist/doc.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/plugins/ai.d.ts +127 -0
- package/dist/plugins/ai.js +3 -0
- package/dist/plugins/ai.js.map +1 -0
- package/package.json +6 -2
- package/dist/DocView-WQIV7HIE.js.map +0 -1
- package/dist/chunk-Y2XE4CYZ.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-tiptap-editor.ts","../src/plugins/ai/use-ai-context.ts","../src/plugins/ai/ai-context.ts","../src/plugins/ai/ai-button-visibility.ts","../src/components/tiptap-icons/sparkles-icon.tsx","../src/components/tiptap-ui-primitive/tooltip/tooltip.tsx","../src/lib/tiptap-utils.ts","../src/components/tiptap-ui-primitive/button/button.tsx","../src/components/tiptap-ui-primitive/popover/popover.tsx","../src/components/tiptap-ui-primitive/input/input.tsx","../src/components/tiptap-ui-primitive/card/card.tsx","../src/components/tiptap-icons/send-icon.tsx","../src/plugins/ai/ai-dialog.tsx","../src/lib/tiptap-collab-utils.ts","../src/plugins/ai/ai-button.tsx"],"names":["useState","createContext","useContext","jsx","TooltipTrigger","TooltipContent","isMac","jsxs","forwardRef","useMemo","memo","useEffect","NodeSelection","nodeType","CellSelection","useCallback"],"mappings":"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","file":"chunk-T2DZHEJJ.js","sourcesContent":["import type { Editor } from \"@tiptap/react\"\nimport { useCurrentEditor, useEditorState } from \"@tiptap/react\"\nimport { useEffect, useState } from \"react\"\n\nfunction getActivePageEditor(editor: Editor): Editor | null {\n const storage = editor.storage as unknown as Record<string, unknown>\n const pages = storage.pages as { activeEditor?: Editor | null } | undefined\n if (!pages || !(\"activeEditor\" in pages)) return null\n return pages.activeEditor ?? null\n}\n\nexport function useTiptapEditor(providedEditor?: Editor | null): {\n editor: Editor | null\n editorState?: Editor[\"state\"]\n canCommand?: Editor[\"can\"]\n} {\n const { editor: coreEditor } = useCurrentEditor()\n const mainEditor = providedEditor ?? coreEditor\n\n const [storageEditor, setStorageEditor] = useState<Editor | null>(null)\n\n useEffect(() => {\n if (!mainEditor) {\n setStorageEditor(null)\n return\n }\n\n const updateHandler = () =>\n setStorageEditor(getActivePageEditor(mainEditor))\n\n updateHandler()\n\n mainEditor.on(\"update\", updateHandler)\n mainEditor.on(\"selectionUpdate\", updateHandler)\n\n return () => {\n mainEditor.off(\"update\", updateHandler)\n mainEditor.off(\"selectionUpdate\", updateHandler)\n }\n }, [mainEditor])\n\n useEffect(() => {\n if (!storageEditor) return\n\n const handleDestroy = () => setStorageEditor(null)\n\n storageEditor.on(\"destroy\", handleDestroy)\n return () => {\n storageEditor.off(\"destroy\", handleDestroy)\n }\n }, [storageEditor])\n\n const editorState = useEditorState({\n editor: storageEditor ?? mainEditor,\n selector(context) {\n if (!context.editor) {\n return { editor: null, editorState: undefined, canCommand: undefined }\n }\n\n return {\n editor: context.editor,\n editorState: context.editor.state,\n canCommand: context.editor.can,\n }\n },\n })\n\n return editorState ?? { editor: null }\n}\n","import { useCallback } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\nimport type { AIContextData } from \"./types\"\n\nconst CONTEXT_WINDOW_SIZE = 300\n\n/**\n * Extract text content from a Tiptap node recursively\n */\nfunction extractTextFromNode(node: any): string {\n if (node.isText) {\n return node.text || \"\"\n }\n if (node.content) {\n return node.content.map(extractTextFromNode).join(\"\")\n }\n return \"\"\n}\n\n/**\n * Get text at a specific position in the document\n */\nfunction getTextAtPosition(editor: Editor, pos: number, length: number): string {\n try {\n const { from, to } = editor.state.selection\n const $from = editor.state.doc.resolve(Math.max(1, pos - length))\n const $to = editor.state.doc.resolve(Math.min(editor.state.doc.content.size, pos + length))\n return editor.state.doc.textBetween($from.pos, $to.pos, \"\\n\", \" \")\n } catch {\n return \"\"\n }\n}\n\n/**\n * Get the node type at the current selection\n */\nfunction getNodeTypeAtSelection(editor: Editor): string | undefined {\n const { from } = editor.state.selection\n const $from = editor.state.doc.resolve(from)\n return $from.parent.type.name\n}\n\n/**\n * Get the heading level if the selection is inside a heading\n */\nfunction getHeadingLevel(editor: Editor): number | undefined {\n const { from } = editor.state.selection\n const $from = editor.state.doc.resolve(from)\n\n for (let d = $from.depth; d > 0; d--) {\n const node = $from.node(d)\n const match = node.type.name.match(/heading(\\d)/)\n if (match) {\n return parseInt(match[1], 10)\n }\n }\n\n return undefined\n}\n\n/**\n * Get the full document as text\n */\nfunction getFullDocument(editor: Editor): string {\n return editor.state.doc.textContent\n}\n\nexport function useAIContext(editor: Editor | null) {\n const buildContext = useCallback(\n (prompt: string): AIContextData | null => {\n if (!editor) {\n return null\n }\n\n const { from, to } = editor.state.selection\n const selectedText = editor.state.doc.textBetween(from, to)\n\n if (!selectedText) {\n return null\n }\n\n // Get the line and column number (simplified: count newlines before selection)\n const textBefore = editor.state.doc.textBetween(0, from)\n const lines = textBefore.split(\"\\n\")\n const line = lines.length\n const column = lines[lines.length - 1].length\n\n // Get surrounding context\n const precedingPos = Math.max(1, from - CONTEXT_WINDOW_SIZE)\n const followingPos = Math.min(editor.state.doc.content.size, to + CONTEXT_WINDOW_SIZE)\n\n const precedingText = editor.state.doc.textBetween(precedingPos, from)\n const followingText = editor.state.doc.textBetween(to, followingPos)\n\n return {\n prompt,\n selectedText,\n position: {\n line,\n column,\n },\n precedingText,\n followingText,\n nodeType: getNodeTypeAtSelection(editor),\n currentHeadingLevel: getHeadingLevel(editor),\n fullDocument: getFullDocument(editor),\n documentFormat: \"markdown\",\n }\n },\n [editor]\n )\n\n return { buildContext }\n}\n","import { createContext, useContext } from \"react\"\nimport type { AIPluginConfig } from \"./types\"\n\nexport const AIConfigContext = createContext<AIPluginConfig | null>(null)\n\nexport function useAIConfig(): AIPluginConfig | null {\n return useContext(AIConfigContext)\n}\n","export interface AIButtonVisibilityInput {\n /** 插件配置里的开关(`enabled !== false`)。 */\n enabled: boolean\n /** 「没得用就藏起来」。 */\n hideWhenUnavailable: boolean\n /** 编辑器是否可编辑。 */\n isEditable: boolean\n /** 当前选区是否可以拿去问 AI。 */\n hasValidSelection: boolean\n}\n\n/**\n * AI 按钮该不该渲染。\n *\n * 抽成纯函数不是为了复用,是为了能测 —— 这个判断写在组件里时曾经把\n * `hideWhenUnavailable` 取反用(`!hideWhenUnavailable && hasValidSelection`),\n * 于是工具栏传 `true` 的那条路上按钮**永远**渲染不出来,而构建、类型、\n * 导出检查全是绿的。一个布尔取反,静态手段一个都拦不住。\n */\nexport const shouldShowAIButton = ({\n enabled,\n hideWhenUnavailable,\n isEditable,\n hasValidSelection,\n}: AIButtonVisibilityInput): boolean =>\n enabled && (hideWhenUnavailable ? hasValidSelection : isEditable)\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const SparklesIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M12 2C12.5523 2 13 2.44772 13 3V5C13 5.55228 12.5523 6 12 6C11.4477 6 11 5.55228 11 5V3C11 2.44772 11.4477 2 12 2Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M19.5 4.5C19.8978 4.10221 20.5244 4.10221 20.9222 4.5C21.32 4.89779 21.32 5.52441 20.9222 5.92221L19.5 7.34442C19.1022 7.74221 18.4756 7.74221 18.0778 7.34442C17.68 6.94663 17.68 6.32001 18.0778 5.92221L19.5 4.5Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M22 11C22.5523 11 23 11.4477 23 12C23 12.5523 22.5523 13 22 13H20C19.4477 13 19 12.5523 19 12C19 11.4477 19.4477 11 20 11H22Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M19.5 19.5L20.9222 18.0778C21.32 17.68 21.32 17.0534 20.9222 16.6556C20.5244 16.2578 19.8978 16.2578 19.5 16.6556L18.0778 18.0778C17.68 18.4756 17.68 19.1022 18.0778 19.5C18.4756 19.8978 19.1022 19.8978 19.5 19.5Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M12 18C12.5523 18 13 18.4477 13 19V21C13 21.5523 12.5523 22 12 22C11.4477 22 11 21.5523 11 21V19C11 18.4477 11.4477 18 12 18Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M4.5 19.5C4.89779 19.8978 4.89779 20.5244 4.5 20.9222C4.10221 21.32 3.47559 21.32 3.0778 20.9222L1.65558 19.5C1.25779 19.1022 1.25779 18.4756 1.65558 18.0778C2.05337 17.68 2.67999 17.68 3.0778 18.0778L4.5 19.5Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M2 12C2.55228 12 3 12.4477 3 13C3 13.5523 2.55228 14 2 14H0C-0.552285 14 -1 13.5523 -1 13C-1 12.4477 -0.552285 12 0 12H2Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M4.5 4.5C4.89779 4.10221 5.52441 4.10221 5.92221 4.5C6.32001 4.89779 6.32001 5.52441 5.92221 5.92221L4.5 7.34442C4.10221 7.74221 3.47559 7.74221 3.0778 7.34442C2.68001 6.94663 2.68001 6.32001 3.0778 5.92221L4.5 4.5Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M12 8C10.3431 8 9 9.34315 9 11C9 12.6569 10.3431 14 12 14C13.6569 14 15 12.6569 15 11C15 9.34315 13.6569 8 12 8Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nSparklesIcon.displayName = \"SparklesIcon\"\n","import {\n cloneElement,\n createContext,\n forwardRef,\n isValidElement,\n useContext,\n useMemo,\n useState,\n version,\n} from \"react\"\nimport {\n useFloating,\n autoUpdate,\n offset,\n flip,\n shift,\n useHover,\n useFocus,\n useDismiss,\n useRole,\n useInteractions,\n useMergeRefs,\n FloatingPortal,\n type Placement,\n type UseFloatingReturn,\n type ReferenceType,\n FloatingDelayGroup,\n} from \"@floating-ui/react\"\nimport \"./tooltip.scss\"\n\ninterface TooltipProviderProps {\n children: React.ReactNode\n initialOpen?: boolean\n placement?: Placement\n open?: boolean\n onOpenChange?: (open: boolean) => void\n delay?: number\n closeDelay?: number\n timeout?: number\n useDelayGroup?: boolean\n}\n\ninterface TooltipTriggerProps extends Omit<\n React.HTMLProps<HTMLElement>,\n \"ref\"\n> {\n asChild?: boolean\n children: React.ReactNode\n}\n\ninterface TooltipContentProps extends Omit<\n React.HTMLProps<HTMLDivElement>,\n \"ref\"\n> {\n children?: React.ReactNode\n portal?: boolean\n portalProps?: Omit<React.ComponentProps<typeof FloatingPortal>, \"children\">\n}\n\ninterface TooltipContextValue extends UseFloatingReturn<ReferenceType> {\n open: boolean\n setOpen: (open: boolean) => void\n getReferenceProps: (\n userProps?: React.HTMLProps<HTMLElement>\n ) => Record<string, unknown>\n getFloatingProps: (\n userProps?: React.HTMLProps<HTMLDivElement>\n ) => Record<string, unknown>\n}\n\nfunction useTooltip({\n initialOpen = false,\n placement = \"top\",\n open: controlledOpen,\n onOpenChange: setControlledOpen,\n delay = 600,\n closeDelay = 0,\n}: Omit<TooltipProviderProps, \"children\"> = {}) {\n const [uncontrolledOpen, setUncontrolledOpen] = useState<boolean>(initialOpen)\n\n const open = controlledOpen ?? uncontrolledOpen\n const setOpen = setControlledOpen ?? setUncontrolledOpen\n\n const data = useFloating({\n placement,\n open,\n onOpenChange: setOpen,\n whileElementsMounted: autoUpdate,\n middleware: [\n offset(4),\n flip({\n crossAxis: placement.includes(\"-\"),\n fallbackAxisSideDirection: \"start\",\n padding: 4,\n }),\n shift({ padding: 4 }),\n ],\n })\n\n const context = data.context\n\n const hover = useHover(context, {\n mouseOnly: true,\n move: false,\n restMs: delay,\n enabled: controlledOpen == null,\n delay: {\n close: closeDelay,\n },\n })\n const focus = useFocus(context, {\n enabled: controlledOpen == null,\n })\n const dismiss = useDismiss(context)\n const role = useRole(context, { role: \"tooltip\" })\n\n const interactions = useInteractions([hover, focus, dismiss, role])\n\n return useMemo(\n () => ({\n open,\n setOpen,\n ...interactions,\n ...data,\n }),\n [open, setOpen, interactions, data]\n )\n}\n\nconst TooltipContext = createContext<TooltipContextValue | null>(null)\n\nfunction useTooltipContext() {\n const context = useContext(TooltipContext)\n\n if (context == null) {\n throw new Error(\"Tooltip components must be wrapped in <TooltipProvider />\")\n }\n\n return context\n}\n\nexport function Tooltip({ children, ...props }: TooltipProviderProps) {\n const tooltip = useTooltip(props)\n\n if (!props.useDelayGroup) {\n return (\n <TooltipContext.Provider value={tooltip}>\n {children}\n </TooltipContext.Provider>\n )\n }\n\n return (\n <FloatingDelayGroup\n delay={{ open: props.delay ?? 0, close: props.closeDelay ?? 0 }}\n timeoutMs={props.timeout}\n >\n <TooltipContext.Provider value={tooltip}>\n {children}\n </TooltipContext.Provider>\n </FloatingDelayGroup>\n )\n}\n\nexport const TooltipTrigger = forwardRef<HTMLElement, TooltipTriggerProps>(\n function TooltipTrigger({ children, asChild = false, ...props }, propRef) {\n const context = useTooltipContext()\n const childrenRef = isValidElement(children)\n ? parseInt(version, 10) >= 19\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (children as { props: { ref?: React.Ref<any> } }).props.ref\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (children as any).ref\n : undefined\n const ref = useMergeRefs([context.refs.setReference, propRef, childrenRef])\n\n if (asChild && isValidElement(children)) {\n const dataAttributes = {\n \"data-tooltip-state\": context.open ? \"open\" : \"closed\",\n }\n\n return cloneElement(\n children,\n context.getReferenceProps({\n ref,\n ...props,\n ...(typeof children.props === \"object\" ? children.props : {}),\n ...dataAttributes,\n })\n )\n }\n\n return (\n <button\n ref={ref}\n data-tooltip-state={context.open ? \"open\" : \"closed\"}\n {...context.getReferenceProps(props)}\n >\n {children}\n </button>\n )\n }\n)\n\nexport const TooltipContent = forwardRef<HTMLDivElement, TooltipContentProps>(\n function TooltipContent(\n { style, children, portal = true, portalProps = {}, ...props },\n propRef\n ) {\n const context = useTooltipContext()\n const ref = useMergeRefs([context.refs.setFloating, propRef])\n\n if (!context.open) return null\n\n const content = (\n <div\n ref={ref}\n style={{\n ...context.floatingStyles,\n ...style,\n }}\n {...context.getFloatingProps(props)}\n className=\"tiptap-tooltip\"\n >\n {children}\n </div>\n )\n\n if (portal) {\n return <FloatingPortal {...portalProps}>{content}</FloatingPortal>\n }\n\n return content\n }\n)\n\nTooltip.displayName = \"Tooltip\"\nTooltipTrigger.displayName = \"TooltipTrigger\"\nTooltipContent.displayName = \"TooltipContent\"\n","import type { Node as PMNode } from \"@tiptap/pm/model\"\nimport type { Transaction } from \"@tiptap/pm/state\"\nimport {\n AllSelection,\n NodeSelection,\n Selection,\n TextSelection,\n} from \"@tiptap/pm/state\"\nimport { cellAround, CellSelection } from \"@tiptap/pm/tables\"\nimport {\n findParentNodeClosestToPos,\n type Editor,\n type NodeWithPos,\n} from \"@tiptap/react\"\n\nexport const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB\n\nexport const MAC_SYMBOLS: Record<string, string> = {\n mod: \"⌘\",\n command: \"⌘\",\n meta: \"⌘\",\n ctrl: \"⌃\",\n control: \"⌃\",\n alt: \"⌥\",\n option: \"⌥\",\n shift: \"⇧\",\n backspace: \"Del\",\n delete: \"⌦\",\n enter: \"⏎\",\n escape: \"⎋\",\n capslock: \"⇪\",\n} as const\n\nexport const SR_ONLY = {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n padding: 0,\n margin: \"-1px\",\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n borderWidth: 0,\n} as const\n\nexport function cn(\n ...classes: (string | boolean | undefined | null)[]\n): string {\n return classes.filter(Boolean).join(\" \")\n}\n\n/**\n * Determines if the current platform is macOS\n * @returns boolean indicating if the current platform is Mac\n */\nexport function isMac(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n navigator.platform.toLowerCase().includes(\"mac\")\n )\n}\n\n/**\n * Formats a shortcut key based on the platform (Mac or non-Mac)\n * @param key - The key to format (e.g., \"ctrl\", \"alt\", \"shift\")\n * @param isMac - Boolean indicating if the platform is Mac\n * @param capitalize - Whether to capitalize the key (default: true)\n * @returns Formatted shortcut key symbol\n */\nexport const formatShortcutKey = (\n key: string,\n isMac: boolean,\n capitalize: boolean = true\n) => {\n if (isMac) {\n const lowerKey = key.toLowerCase()\n return MAC_SYMBOLS[lowerKey] || (capitalize ? key.toUpperCase() : key)\n }\n\n return capitalize ? key.charAt(0).toUpperCase() + key.slice(1) : key\n}\n\n/**\n * Parses a shortcut key string into an array of formatted key symbols\n * @param shortcutKeys - The string of shortcut keys (e.g., \"ctrl-alt-shift\")\n * @param delimiter - The delimiter used to split the keys (default: \"-\")\n * @param capitalize - Whether to capitalize the keys (default: true)\n * @returns Array of formatted shortcut key symbols\n */\nexport const parseShortcutKeys = (props: {\n shortcutKeys: string | undefined\n delimiter?: string\n capitalize?: boolean\n}) => {\n const { shortcutKeys, delimiter = \"+\", capitalize = true } = props\n\n if (!shortcutKeys) return []\n\n return shortcutKeys\n .split(delimiter)\n .map((key) => key.trim())\n .map((key) => formatShortcutKey(key, isMac(), capitalize))\n}\n\n/**\n * Checks if a mark exists in the editor schema\n * @param markName - The name of the mark to check\n * @param editor - The editor instance\n * @returns boolean indicating if the mark exists in the schema\n */\nexport const isMarkInSchema = (\n markName: string,\n editor: Editor | null\n): boolean => {\n if (!editor?.schema) return false\n return editor.schema.spec.marks.get(markName) !== undefined\n}\n\n/**\n * Checks if a node exists in the editor schema\n * @param nodeName - The name of the node to check\n * @param editor - The editor instance\n * @returns boolean indicating if the node exists in the schema\n */\nexport const isNodeInSchema = (\n nodeName: string,\n editor: Editor | null\n): boolean => {\n if (!editor?.schema) return false\n return editor.schema.spec.nodes.get(nodeName) !== undefined\n}\n\n/**\n * Moves the focus to the next node in the editor\n * @param editor - The editor instance\n * @returns boolean indicating if the focus was moved\n */\nexport function focusNextNode(editor: Editor) {\n const { state, view } = editor\n const { doc, selection } = state\n\n const nextSel = Selection.findFrom(selection.$to, 1, true)\n if (nextSel) {\n view.dispatch(state.tr.setSelection(nextSel).scrollIntoView())\n return true\n }\n\n const paragraphType = state.schema.nodes.paragraph\n if (!paragraphType) {\n console.warn(\"No paragraph node type found in schema.\")\n return false\n }\n\n const end = doc.content.size\n const para = paragraphType.create()\n let tr = state.tr.insert(end, para)\n\n // Place the selection inside the new paragraph\n const $inside = tr.doc.resolve(end + 1)\n tr = tr.setSelection(TextSelection.near($inside)).scrollIntoView()\n view.dispatch(tr)\n return true\n}\n\n/**\n * Checks if a value is a valid number (not null, undefined, or NaN)\n * @param value - The value to check\n * @returns boolean indicating if the value is a valid number\n */\nexport function isValidPosition(pos: number | null | undefined): pos is number {\n return typeof pos === \"number\" && pos >= 0\n}\n\n/**\n * Checks if one or more extensions are registered in the Tiptap editor.\n * @param editor - The Tiptap editor instance\n * @param extensionNames - A single extension name or an array of names to check\n * @returns True if at least one of the extensions is available, false otherwise\n */\nexport function isExtensionAvailable(\n editor: Editor | null,\n extensionNames: string | string[]\n): boolean {\n if (!editor) return false\n\n const names = Array.isArray(extensionNames)\n ? extensionNames\n : [extensionNames]\n\n const found = names.some((name) =>\n editor.extensionManager.extensions.some((ext) => ext.name === name)\n )\n\n if (!found) {\n console.warn(\n `None of the extensions [${names.join(\", \")}] were found in the editor schema. Ensure they are included in the editor configuration.`\n )\n }\n\n return found\n}\n\n/**\n * Finds a node at the specified position with error handling\n * @param editor The Tiptap editor instance\n * @param position The position in the document to find the node\n * @returns The node at the specified position, or null if not found\n */\nexport function findNodeAtPosition(editor: Editor, position: number) {\n try {\n const node = editor.state.doc.nodeAt(position)\n if (!node) {\n console.warn(`No node found at position ${position}`)\n return null\n }\n return node\n } catch (error) {\n console.error(`Error getting node at position ${position}:`, error)\n return null\n }\n}\n\n/**\n * Finds the position and instance of a node in the document\n * @param props Object containing editor, node (optional), and nodePos (optional)\n * @param props.editor The Tiptap editor instance\n * @param props.node The node to find (optional if nodePos is provided)\n * @param props.nodePos The position of the node to find (optional if node is provided)\n * @returns An object with the position and node, or null if not found\n */\nexport function findNodePosition(props: {\n editor: Editor | null\n node?: PMNode | null\n nodePos?: number | null\n}): { pos: number; node: PMNode } | null {\n const { editor, node, nodePos } = props\n\n if (!editor || !editor.state?.doc) return null\n\n // Zero is valid position\n const hasValidNode = node !== undefined && node !== null\n const hasValidPos = isValidPosition(nodePos)\n\n if (!hasValidNode && !hasValidPos) {\n return null\n }\n\n // First search for the node in the document if we have a node\n if (hasValidNode) {\n let foundPos = -1\n let foundNode: PMNode | null = null\n\n editor.state.doc.descendants((currentNode, pos) => {\n // TODO: Needed?\n // if (currentNode.type && currentNode.type.name === node!.type.name) {\n if (currentNode === node) {\n foundPos = pos\n foundNode = currentNode\n return false\n }\n return true\n })\n\n if (foundPos !== -1 && foundNode !== null) {\n return { pos: foundPos, node: foundNode }\n }\n }\n\n // If we have a valid position, use findNodeAtPosition\n if (hasValidPos) {\n const nodeAtPos = findNodeAtPosition(editor, nodePos!)\n if (nodeAtPos) {\n return { pos: nodePos!, node: nodeAtPos }\n }\n }\n\n return null\n}\n\n/**\n * Determines whether the current selection contains a node whose type matches\n * any of the provided node type names.\n * @param editor Tiptap editor instance\n * @param nodeTypeNames List of node type names to match against\n * @param checkAncestorNodes Whether to check ancestor node types up the depth chain\n */\nexport function isNodeTypeSelected(\n editor: Editor | null,\n nodeTypeNames: string[] = [],\n checkAncestorNodes: boolean = false\n): boolean {\n if (!editor || !editor.state.selection) return false\n\n const { selection } = editor.state\n if (selection.empty) return false\n\n // Direct node selection check\n if (selection instanceof NodeSelection) {\n const selectedNode = selection.node\n return selectedNode ? nodeTypeNames.includes(selectedNode.type.name) : false\n }\n\n // Depth-based ancestor node check\n if (checkAncestorNodes) {\n const { $from } = selection\n for (let depth = $from.depth; depth > 0; depth--) {\n const ancestorNode = $from.node(depth)\n if (nodeTypeNames.includes(ancestorNode.type.name)) {\n return true\n }\n }\n }\n\n return false\n}\n\n/**\n * Check whether the current selection is fully within nodes\n * whose type names are in the provided `types` list.\n *\n * - NodeSelection → checks the selected node.\n * - Text/AllSelection → ensures all textblocks within [from, to) are allowed.\n */\nexport function selectionWithinConvertibleTypes(\n editor: Editor,\n types: string[] = []\n): boolean {\n if (!editor || types.length === 0) return false\n\n const { state } = editor\n const { selection } = state\n const allowed = new Set(types)\n\n if (selection instanceof NodeSelection) {\n const nodeType = selection.node?.type?.name\n return !!nodeType && allowed.has(nodeType)\n }\n\n if (selection instanceof TextSelection || selection instanceof AllSelection) {\n let valid = true\n state.doc.nodesBetween(selection.from, selection.to, (node) => {\n if (node.isTextblock && !allowed.has(node.type.name)) {\n valid = false\n return false // stop early\n }\n return valid\n })\n return valid\n }\n\n return false\n}\n\n/**\n * Handles image upload with progress tracking and abort capability\n * @param file The file to upload\n * @param onProgress Optional callback for tracking upload progress\n * @param abortSignal Optional AbortSignal for cancelling the upload\n * @returns Promise resolving to the URL of the uploaded image\n */\nexport const handleImageUpload = async (\n file: File,\n onProgress?: (event: { progress: number }) => void,\n abortSignal?: AbortSignal\n): Promise<string> => {\n // Validate file\n if (!file) {\n throw new Error(\"No file provided\")\n }\n\n if (file.size > MAX_FILE_SIZE) {\n throw new Error(\n `File size exceeds maximum allowed (${MAX_FILE_SIZE / (1024 * 1024)}MB)`\n )\n }\n\n // For demo/testing: Simulate upload progress. In production, replace the following code\n // with your own upload implementation.\n for (let progress = 0; progress <= 100; progress += 10) {\n if (abortSignal?.aborted) {\n throw new Error(\"Upload cancelled\")\n }\n await new Promise((resolve) => setTimeout(resolve, 500))\n onProgress?.({ progress })\n }\n\n return \"/images/tiptap-ui-placeholder-image.jpg\"\n}\n\ntype ProtocolOptions = {\n /**\n * The protocol scheme to be registered.\n * @default '''\n * @example 'ftp'\n * @example 'git'\n */\n scheme: string\n\n /**\n * If enabled, it allows optional slashes after the protocol.\n * @default false\n * @example true\n */\n optionalSlashes?: boolean\n}\n\ntype ProtocolConfig = Array<ProtocolOptions | string>\n\nconst ATTR_WHITESPACE =\n // eslint-disable-next-line no-control-regex\n /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g\n\nexport function isAllowedUri(\n uri: string | undefined,\n protocols?: ProtocolConfig\n) {\n const allowedProtocols: string[] = [\n \"http\",\n \"https\",\n \"ftp\",\n \"ftps\",\n \"mailto\",\n \"tel\",\n \"callto\",\n \"sms\",\n \"cid\",\n \"xmpp\",\n ]\n\n if (protocols) {\n protocols.forEach((protocol) => {\n const nextProtocol =\n typeof protocol === \"string\" ? protocol : protocol.scheme\n\n if (nextProtocol) {\n allowedProtocols.push(nextProtocol)\n }\n })\n }\n\n return (\n !uri ||\n uri.replace(ATTR_WHITESPACE, \"\").match(\n new RegExp(\n // eslint-disable-next-line no-useless-escape\n `^(?:(?:${allowedProtocols.join(\"|\")}):|[^a-z]|[a-z0-9+.\\-]+(?:[^a-z+.\\-:]|$))`,\n \"i\"\n )\n )\n )\n}\n\nexport function sanitizeUrl(\n inputUrl: string,\n baseUrl: string,\n protocols?: ProtocolConfig\n): string {\n try {\n const url = new URL(inputUrl, baseUrl)\n\n if (isAllowedUri(url.href, protocols)) {\n return url.href\n }\n } catch {\n // If URL creation fails, it's considered invalid\n }\n return \"#\"\n}\n\n/**\n * Update a single attribute on multiple nodes.\n *\n * @param tr - The transaction to mutate\n * @param targets - Array of { node, pos }\n * @param attrName - Attribute key to update\n * @param next - New value OR updater function receiving previous value\n * Pass `undefined` to remove the attribute.\n * @returns true if at least one node was updated, false otherwise\n */\nexport function updateNodesAttr<A extends string = string, V = unknown>(\n tr: Transaction,\n targets: readonly NodeWithPos[],\n attrName: A,\n next: V | ((prev: V | undefined) => V | undefined)\n): boolean {\n if (!targets.length) return false\n\n let changed = false\n\n for (const { pos } of targets) {\n // Always re-read from the transaction's current doc\n const currentNode = tr.doc.nodeAt(pos)\n if (!currentNode) continue\n\n const prevValue = (currentNode.attrs as Record<string, unknown>)[\n attrName\n ] as V | undefined\n const resolvedNext =\n typeof next === \"function\"\n ? (next as (p: V | undefined) => V | undefined)(prevValue)\n : next\n\n if (prevValue === resolvedNext) continue\n\n const nextAttrs: Record<string, unknown> = { ...currentNode.attrs }\n if (resolvedNext === undefined) {\n // Remove the key entirely instead of setting null\n delete nextAttrs[attrName]\n } else {\n nextAttrs[attrName] = resolvedNext\n }\n\n tr.setNodeMarkup(pos, undefined, nextAttrs)\n changed = true\n }\n\n return changed\n}\n\n/**\n * Selects the entire content of the current block node if the selection is empty.\n * If the selection is not empty, it does nothing.\n * @param editor The Tiptap editor instance\n */\nexport function selectCurrentBlockContent(editor: Editor) {\n const { selection, doc } = editor.state\n\n if (!selection.empty) return\n\n const $pos = selection.$from\n let blockNode: PMNode | null = null\n let blockPos = -1\n\n for (let depth = $pos.depth; depth >= 0; depth--) {\n const node = $pos.node(depth)\n const pos = $pos.start(depth)\n\n if (node.isBlock && node.textContent.trim()) {\n blockNode = node\n blockPos = pos\n break\n }\n }\n\n if (blockNode && blockPos >= 0) {\n const from = blockPos\n const to = blockPos + blockNode.nodeSize - 2 // -2 to exclude the closing tag\n\n if (from < to) {\n const $from = doc.resolve(from)\n const $to = doc.resolve(to)\n const newSelection = TextSelection.between($from, $to, 1)\n\n if (newSelection && !selection.eq(newSelection)) {\n editor.view.dispatch(editor.state.tr.setSelection(newSelection))\n }\n }\n }\n}\n\n/**\n * Retrieves all nodes of specified types from the current selection.\n * @param selection The current editor selection\n * @param allowedNodeTypes An array of node type names to look for (e.g., [\"image\", \"table\"])\n * @returns An array of objects containing the node and its position\n */\nexport function getSelectedNodesOfType(\n selection: Selection,\n allowedNodeTypes: string[]\n): NodeWithPos[] {\n const results: NodeWithPos[] = []\n const allowed = new Set(allowedNodeTypes)\n\n if (selection instanceof CellSelection) {\n selection.forEachCell((node: PMNode, pos: number) => {\n if (allowed.has(node.type.name)) {\n results.push({ node, pos })\n }\n })\n return results\n }\n\n if (selection instanceof NodeSelection) {\n const { node, from: pos } = selection\n if (node && allowed.has(node.type.name)) {\n results.push({ node, pos })\n }\n return results\n }\n\n const { $anchor } = selection\n const cell = cellAround($anchor)\n\n if (cell) {\n const cellNode = selection.$anchor.doc.nodeAt(cell.pos)\n if (cellNode && allowed.has(cellNode.type.name)) {\n results.push({ node: cellNode, pos: cell.pos })\n return results\n }\n }\n\n // Fallback: find parent nodes of allowed types\n const parentNode = findParentNodeClosestToPos($anchor, (node) =>\n allowed.has(node.type.name)\n )\n\n if (parentNode) {\n results.push({ node: parentNode.node, pos: parentNode.pos })\n }\n\n return results\n}\n\n/**\n * Clamps a value between min and max bounds\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(value, max))\n}\n\nexport function getSelectedBlockNodes(editor: Editor): PMNode[] {\n const { doc } = editor.state\n const { from, to } = editor.state.selection\n\n const blocks: PMNode[] = []\n const seen = new Set<number>()\n\n doc.nodesBetween(from, to, (node, pos) => {\n if (!node.isBlock) return\n\n if (!seen.has(pos)) {\n seen.add(pos)\n blocks.push(node)\n }\n\n return false\n })\n\n return blocks\n}\n","import { forwardRef, Fragment, useMemo } from \"react\"\n\n// --- Tiptap UI Primitive ---\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../tooltip\"\n\n// --- Lib ---\nimport { cn, parseShortcutKeys } from \"../../../lib/tiptap-utils\"\n\nimport \"./button-colors.scss\"\nimport \"./button.scss\"\n\nexport type ButtonVariant = \"ghost\" | \"primary\"\nexport type ButtonSize = \"small\" | \"default\" | \"large\"\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n showTooltip?: boolean\n tooltip?: React.ReactNode\n shortcutKeys?: string\n variant?: ButtonVariant\n size?: ButtonSize\n}\n\nexport const ShortcutDisplay: React.FC<{ shortcuts: string[] }> = ({\n shortcuts,\n}) => {\n if (shortcuts.length === 0) return null\n\n return (\n <div>\n {shortcuts.map((key, index) => (\n <Fragment key={index}>\n {index > 0 && <kbd>+</kbd>}\n <kbd>{key}</kbd>\n </Fragment>\n ))}\n </div>\n )\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n children,\n tooltip,\n showTooltip = true,\n shortcutKeys,\n variant,\n size,\n ...props\n },\n ref\n ) => {\n const shortcuts = useMemo<string[]>(\n () => parseShortcutKeys({ shortcutKeys }),\n [shortcutKeys]\n )\n\n if (!tooltip || !showTooltip) {\n return (\n <button\n data-slot=\"tiptap-button\"\n className={cn(\"tiptap-button\", className)}\n ref={ref}\n data-style={variant}\n data-size={size}\n {...props}\n >\n {children}\n </button>\n )\n }\n\n return (\n <Tooltip delay={200}>\n <TooltipTrigger\n data-slot=\"tiptap-button\"\n className={cn(\"tiptap-button\", className)}\n ref={ref}\n data-style={variant}\n data-size={size}\n {...props}\n >\n {children}\n </TooltipTrigger>\n <TooltipContent>\n {tooltip}\n <ShortcutDisplay shortcuts={shortcuts} />\n </TooltipContent>\n </Tooltip>\n )\n }\n)\n\nButton.displayName = \"Button\"\n\nexport default Button\n","\"use client\"\n\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\"\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport \"./popover.scss\"\n\nfunction Popover({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root {...props} />\n}\n\nfunction PopoverTrigger({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n align={align}\n sideOffset={sideOffset}\n className={cn(\"tiptap-popover\", className)}\n {...props}\n />\n </PopoverPrimitive.Portal>\n )\n}\n\nexport { Popover, PopoverTrigger, PopoverContent }\n","\"use client\"\n\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport \"./input.scss\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"tiptap-input\"\n className={cn(\"tiptap-input\", className)}\n {...props}\n />\n )\n}\n\nexport { Input }\n","import { forwardRef } from \"react\"\nimport { cn } from \"../../../lib/tiptap-utils\"\nimport \"./card.scss\"\n\nconst Card = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return <div ref={ref} className={cn(\"tiptap-card\", className)} {...props} />\n }\n)\nCard.displayName = \"Card\"\n\nconst CardHeader = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"tiptap-card-header\", className)}\n {...props}\n />\n )\n }\n)\nCardHeader.displayName = \"CardHeader\"\n\nconst CardBody = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"tiptap-card-body\", className)} {...props} />\n )\n }\n)\nCardBody.displayName = \"CardBody\"\n\nconst CardItemGroup = forwardRef<\n HTMLDivElement,\n React.ComponentProps<\"div\"> & {\n orientation?: \"horizontal\" | \"vertical\"\n }\n>(({ className, orientation = \"vertical\", ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-orientation={orientation}\n className={cn(\"tiptap-card-item-group\", className)}\n {...props}\n />\n )\n})\nCardItemGroup.displayName = \"CardItemGroup\"\n\nconst CardGroupLabel = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"tiptap-card-group-label\", className)}\n {...props}\n />\n )\n }\n)\nCardGroupLabel.displayName = \"CardGroupLabel\"\n\nconst CardFooter = forwardRef<HTMLDivElement, React.ComponentProps<\"div\">>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\"tiptap-card-footer\", className)}\n {...props}\n />\n )\n }\n)\nCardFooter.displayName = \"CardFooter\"\n\nexport { Card, CardHeader, CardFooter, CardBody, CardItemGroup, CardGroupLabel }\n","import { memo } from \"react\"\n\ntype SvgProps = React.ComponentPropsWithoutRef<\"svg\">\n\nexport const SendIcon = memo(({ className, ...props }: SvgProps) => {\n return (\n <svg\n width=\"24\"\n height=\"24\"\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M16.6915026,12.4744748 L3.50612381,13.2599618 C3.19218622,13.2599618 3.03521743,13.4170592 3.03521743,13.5741566 L1.15159189,20.0151496 C0.8376543,20.8006365 0.99,21.89 1.77946707,22.52 C2.41,22.99 3.50612381,23.1 4.13399899,22.8429026 L21.714504,14.0454487 C22.6563168,13.5741566 23.1272231,12.6315722 22.9702544,11.6889879 L4.13399899,1.16865248 C3.34915502,0.9115551 2.40734225,1.01399899 1.77946707,1.4852911 C0.994623095,2.1181258 0.837654326,3.20946707 1.15159189,3.99495876 L3.03521743,10.4359518 C3.03521743,10.5930492 3.19218622,10.7501467 3.50612381,10.7501467 L16.6915026,11.5356335 C16.6915026,11.5356335 17.1624089,11.5356335 17.1624089,12.0068766 C17.1624089,12.4781197 16.6915026,12.4744748 16.6915026,12.4744748 Z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n})\n\nSendIcon.displayName = \"SendIcon\"\n","\"use client\"\n\nimport { useEffect, useRef, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\n\n// --- Types ---\nimport type { AIContextData, AIPluginConfig } from \"./types\"\n\n// --- UI Primitives ---\nimport { Button } from \"../../components/tiptap-ui-primitive/button\"\nimport { Input } from \"../../components/tiptap-ui-primitive/input\"\nimport {\n Card,\n CardBody,\n CardItemGroup,\n} from \"../../components/tiptap-ui-primitive/card\"\n\n// --- Icons ---\nimport { SparklesIcon } from \"../../components/tiptap-icons/sparkles-icon\"\nimport { SendIcon } from \"../../components/tiptap-icons/send-icon\"\n\nimport \"./ai-dialog.scss\"\n\nexport interface AIDialogProps {\n editor: Editor\n config: AIPluginConfig\n buildContext: (prompt: string) => AIContextData | null\n onClose: () => void\n}\n\nexport function AIDialog({\n editor,\n config,\n buildContext,\n onClose,\n}: AIDialogProps) {\n const [prompt, setPrompt] = useState(\"\")\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n\n // Focus input when dialog opens\n useEffect(() => {\n inputRef.current?.focus()\n }, [])\n\n const handleSubmit = async () => {\n if (!prompt.trim()) {\n return\n }\n\n setError(null)\n setIsLoading(true)\n\n try {\n const context = buildContext(prompt)\n\n if (!context) {\n setError(\"No text selected\")\n setIsLoading(false)\n return\n }\n\n // Call the AI plugin\n const result = await config.plugin.process(context)\n\n if (result.error) {\n setError(result.error)\n setIsLoading(false)\n return\n }\n\n // A plugin that applies the edit itself (e.g. by handing the prompt to an\n // agent with document-editing tools) returns no text — replacing here would\n // clobber that agent's work.\n if (result.result) {\n const { from, to } = editor.state.selection\n const tr = editor.state.tr.replaceWith(from, to, [\n editor.state.schema.text(result.result),\n ])\n editor.view.dispatch(tr)\n }\n\n // Close the dialog\n onClose()\n setPrompt(\"\")\n } catch (err) {\n setError(err instanceof Error ? err.message : \"An error occurred\")\n } finally {\n setIsLoading(false)\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault()\n handleSubmit()\n }\n }\n\n return (\n <Card className=\"ai-dialog\">\n <CardItemGroup>\n <div className=\"ai-dialog-header\">\n <SparklesIcon className=\"ai-dialog-icon\" />\n <span>AI Assistant</span>\n </div>\n </CardItemGroup>\n\n <CardBody className=\"ai-dialog-body\">\n <div className=\"ai-dialog-input-group\">\n <Input\n ref={inputRef}\n type=\"text\"\n placeholder=\"What would you like me to do with the selected text?\"\n value={prompt}\n onChange={(e) => {\n setPrompt(e.target.value)\n setError(null)\n }}\n onKeyDown={handleKeyDown}\n disabled={isLoading}\n className=\"ai-dialog-input\"\n />\n </div>\n\n {error && (\n <div className=\"ai-dialog-error\">\n {error}\n </div>\n )}\n\n <div className=\"ai-dialog-actions\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={onClose}\n disabled={isLoading}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n onClick={handleSubmit}\n disabled={isLoading || !prompt.trim()}\n >\n {isLoading ? \"Processing...\" : \"Send\"}\n {!isLoading && <SendIcon className=\"ai-dialog-button-icon\" />}\n </Button>\n </div>\n </CardBody>\n </Card>\n )\n}\n","import { NodeSelection, type Selection } from \"@tiptap/pm/state\"\nimport { CellSelection } from \"@tiptap/pm/tables\"\nimport type { JSONContent, Editor } from \"@tiptap/react\"\nimport { isTextSelection, isNodeSelection, posToDOMRect } from \"@tiptap/react\"\n\n\nconst NODE_TYPE_LABELS: Record<string, string> = {\n paragraph: \"Text\",\n heading: \"Heading\",\n blockquote: \"Blockquote\",\n listItem: \"List Item\",\n codeBlock: \"Code Block\",\n table: \"Table\",\n tocNode: \"Table of contents\",\n}\nexport type OverflowPosition = \"none\" | \"top\" | \"bottom\" | \"both\"\n\n/**\n * Utility function to get URL parameters\n */\nexport const getUrlParam = (param: string): string | null => {\n if (typeof window === \"undefined\") return null\n const params = new URLSearchParams(window.location.search)\n return params.get(param)\n}\n\n/**\n * Returns a display name for the current node in the editor\n * @param editor The Tiptap editor instance\n * @returns The display name of the current node\n */\nexport const getNodeDisplayName = (editor: Editor | null): string => {\n if (!editor) return \"Node\"\n\n const { selection } = editor.state\n\n if (selection instanceof NodeSelection) {\n const nodeType = selection.node.type.name\n return NODE_TYPE_LABELS[nodeType] || nodeType.toLowerCase()\n }\n\n if (selection instanceof CellSelection) {\n return \"Table\"\n }\n\n const { $anchor } = selection\n const nodeType = $anchor.parent.type.name\n return NODE_TYPE_LABELS[nodeType] || nodeType.toLowerCase()\n}\n\n/**\n * Removes empty paragraph nodes from content\n */\nexport const removeEmptyParagraphs = (content: JSONContent) => ({\n ...content,\n content: content.content?.filter(\n (node) =>\n node.type !== \"paragraph\" ||\n node.content?.some((child) => child.text?.trim() || child.type !== \"text\")\n ),\n})\n\n/**\n * Determines how a target element overflows relative to a container element\n */\nexport function getElementOverflowPosition(\n targetElement: Element,\n containerElement: HTMLElement\n): OverflowPosition {\n const targetBounds = targetElement.getBoundingClientRect()\n const containerBounds = containerElement.getBoundingClientRect()\n\n const isOverflowingTop = targetBounds.top < containerBounds.top\n const isOverflowingBottom = targetBounds.bottom > containerBounds.bottom\n\n if (isOverflowingTop && isOverflowingBottom) return \"both\"\n if (isOverflowingTop) return \"top\"\n if (isOverflowingBottom) return \"bottom\"\n return \"none\"\n}\n\n/**\n * Checks if the current selection is valid for a given editor\n */\nexport const isSelectionValid = (\n editor: Editor | null,\n selection?: Selection,\n excludedNodeTypes: string[] = [\"imageUpload\", \"horizontalRule\"]\n): boolean => {\n if (!editor) return false\n if (!selection) selection = editor.state.selection\n\n const { state } = editor\n const { doc } = state\n const { empty, from, to } = selection\n\n const isEmptyTextBlock =\n !doc.textBetween(from, to).length && isTextSelection(selection)\n const isCodeBlock =\n selection.$from.parent.type.spec.code ||\n (isNodeSelection(selection) && selection.node.type.spec.code)\n const isExcludedNode =\n isNodeSelection(selection) &&\n excludedNodeTypes.includes(selection.node.type.name)\n const isTableCell = selection instanceof CellSelection\n\n return (\n !empty &&\n !isEmptyTextBlock &&\n !isCodeBlock &&\n !isExcludedNode &&\n !isTableCell\n )\n}\n\n/**\n * Checks if the current text selection is valid for editing\n * - Not empty\n * - Not a code block\n * - Not a node selection\n */\nexport const isTextSelectionValid = (editor: Editor | null): boolean => {\n if (!editor) return false\n const { state } = editor\n const { selection } = state\n const isValid =\n isTextSelection(selection) &&\n !selection.empty &&\n !selection.$from.parent.type.spec.code &&\n !isNodeSelection(selection)\n\n return isValid\n}\n\n/**\n * Gets the bounding rect of the current selection in the editor.\n */\nexport const getSelectionBoundingRect = (editor: Editor): DOMRect | null => {\n const { state } = editor.view\n const { selection } = state\n const { ranges } = selection\n\n const from = Math.min(...ranges.map((range) => range.$from.pos))\n const to = Math.max(...ranges.map((range) => range.$to.pos))\n\n if (isNodeSelection(selection)) {\n const node = editor.view.nodeDOM(from) as HTMLElement\n if (node) {\n return node.getBoundingClientRect()\n }\n }\n\n return posToDOMRect(editor.view, from, to)\n}\n\n/**\n * Generates a deterministic avatar URL from a user name\n */\nexport const getAvatar = (name: string) => {\n if (!name) {\n return \"/avatars/memoji_01.png\"\n }\n\n let hash = 0\n for (let i = 0; i < name.length; i++) {\n hash = name.charCodeAt(i) + ((hash << 5) - hash)\n hash = hash & hash\n }\n\n const randomFraction = (Math.abs(hash) % 1000000) / 1000000\n const id = 1 + Math.floor(randomFraction * 20)\n const idString = id.toString().padStart(2, \"0\")\n return `/avatars/memoji_${idString}.png`\n}\n\n\n","\"use client\"\n\nimport { forwardRef, useCallback, useEffect, useState } from \"react\"\nimport type { Editor } from \"@tiptap/react\"\n\n// --- Hooks ---\nimport { useTiptapEditor } from \"../../hooks/use-tiptap-editor\"\nimport { useAIContext } from \"./use-ai-context\"\nimport { useAIConfig } from \"./ai-context\"\nimport { shouldShowAIButton } from \"./ai-button-visibility\"\n\n// --- Types ---\nimport type { AIPluginConfig } from \"./types\"\n\n// --- Icons ---\nimport { SparklesIcon } from \"../../components/tiptap-icons/sparkles-icon\"\n\n// --- UI Primitives ---\nimport type { ButtonProps } from \"../../components/tiptap-ui-primitive/button\"\nimport { Button } from \"../../components/tiptap-ui-primitive/button\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../components/tiptap-ui-primitive/popover\"\n\n// --- AI Dialog ---\nimport { AIDialog } from \"./ai-dialog\"\nimport { isSelectionValid } from \"../../lib/tiptap-collab-utils\"\n\nexport interface AIButtonProps extends Omit<ButtonProps, \"type\"> {\n /**\n * The Tiptap editor instance\n */\n editor?: Editor | null\n\n /**\n * AI plugin configuration (optional, will use context if not provided)\n */\n config?: AIPluginConfig\n\n /**\n * Whether to hide the button when no valid selection\n * @default true\n */\n hideWhenUnavailable?: boolean\n}\n\n/**\n * AI Button component for triggering the AI processing dialog\n *\n * Usage:\n * ```tsx\n * <AIButton\n * config={{ plugin: new MyAIPlugin() }}\n * hideWhenUnavailable\n * />\n * ```\n */\nexport const AIButton = forwardRef<HTMLButtonElement, AIButtonProps>(\n (\n {\n editor: providedEditor,\n config: providedConfig,\n hideWhenUnavailable = true,\n onClick,\n ...buttonProps\n },\n ref\n ) => {\n const { editor } = useTiptapEditor(providedEditor)\n const { buildContext } = useAIContext(editor)\n const contextConfig = useAIConfig()\n const [isOpen, setIsOpen] = useState(false)\n const [shouldShow, setShouldShow] = useState(false)\n\n const config = providedConfig || contextConfig\n const isEnabled = config?.enabled !== false\n\n useEffect(() => {\n if (!editor) {\n setShouldShow(false)\n return\n }\n\n const updateVisibility = () => {\n setShouldShow(\n shouldShowAIButton({\n enabled: isEnabled,\n hasValidSelection: isSelectionValid(editor),\n hideWhenUnavailable,\n isEditable: editor.isEditable,\n })\n )\n }\n\n updateVisibility()\n editor.on(\"selectionUpdate\", updateVisibility)\n\n return () => {\n editor.off(\"selectionUpdate\", updateVisibility)\n }\n }, [editor, hideWhenUnavailable, isEnabled])\n\n const handleOpenChange = useCallback(\n (open: boolean) => {\n setIsOpen(open)\n },\n []\n )\n\n const handleClick = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n setIsOpen(true)\n }\n },\n [onClick]\n )\n\n if (!shouldShow || !editor || !config) {\n return null\n }\n\n return (\n <Popover open={isOpen} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>\n <Button\n ref={ref}\n type=\"button\"\n variant=\"ghost\"\n role=\"button\"\n tabIndex={-1}\n aria-label=\"AI Assistant\"\n tooltip=\"AI Assistant\"\n onClick={handleClick}\n {...buttonProps}\n >\n <SparklesIcon className=\"tiptap-button-icon\" />\n </Button>\n </PopoverTrigger>\n\n {/* 不用 asChild:AIDialog 不转发 ref,Radix 量不到尺寸会定位错位 */}\n <PopoverContent side=\"top\" align=\"start\" sideOffset={4}>\n <AIDialog\n editor={editor}\n config={config}\n buildContext={buildContext}\n onClose={() => handleOpenChange(false)}\n />\n </PopoverContent>\n </Popover>\n )\n }\n)\n\nAIButton.displayName = \"AIButton\"\n"]}
|
package/dist/doc.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ import { Doc } from 'yjs';
|
|
|
6
6
|
import { UseFloatingOptions, UseDismissProps, AutoUpdateOptions } from '@floating-ui/react';
|
|
7
7
|
import { Selection, Transaction } from '@tiptap/pm/state';
|
|
8
8
|
import { Node } from '@tiptap/pm/model';
|
|
9
|
+
import { B as ButtonProps } from './button-CWX5Uuj-.js';
|
|
10
|
+
export { a as Button } from './button-CWX5Uuj-.js';
|
|
9
11
|
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
10
12
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
11
13
|
|
|
@@ -824,17 +826,6 @@ declare function findSelectionPosition(params: {
|
|
|
824
826
|
nodePos?: number | null;
|
|
825
827
|
}): number | null;
|
|
826
828
|
|
|
827
|
-
type ButtonVariant = "ghost" | "primary";
|
|
828
|
-
type ButtonSize = "small" | "default" | "large";
|
|
829
|
-
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
830
|
-
showTooltip?: boolean;
|
|
831
|
-
tooltip?: React.ReactNode;
|
|
832
|
-
shortcutKeys?: string;
|
|
833
|
-
variant?: ButtonVariant;
|
|
834
|
-
size?: ButtonSize;
|
|
835
|
-
}
|
|
836
|
-
declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
837
|
-
|
|
838
829
|
type BaseProps = React.HTMLAttributes<HTMLDivElement>;
|
|
839
830
|
interface ToolbarProps extends BaseProps {
|
|
840
831
|
variant?: "floating" | "fixed";
|
|
@@ -1105,4 +1096,4 @@ declare const MediaUploadButton: react.ForwardRefExoticComponent<MediaUploadButt
|
|
|
1105
1096
|
*/
|
|
1106
1097
|
declare function pickFile(accept: string, multiple?: boolean): Promise<File[]>;
|
|
1107
1098
|
|
|
1108
|
-
export { ArticleViewer, type ArticleViewerProps, Audio,
|
|
1099
|
+
export { ArticleViewer, type ArticleViewerProps, Audio, ButtonProps, CollabContext, type CollabContextValue, CollabProvider, type CollabProviderLike, Column, type ColumnLayout, Columns, DEFAULT_MAX_FILE_SIZES, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, type EditorCollabConfig, type EditorConfig, EditorConfigProvider, type EditorConfigProviderProps, EditorContentArea, type EditorProviderProps, type EditorUploadConfig, type EditorUserConfig, FileAttachment, type FileAttachmentAttrs, FloatingElement, HIDE_FLOATING_META, LoadingSpinner, MAC_SYMBOLS, MAX_FILE_SIZE, type MediaKind, type MediaKindForButton, MediaUploadButton, type MediaUploadButtonProps, MediaUploadPlaceholder, NotionEditor, NotionEditorContent, EditorProvider as NotionEditorInner, type NotionEditorProps, type OverflowPosition, PasteDropMedia, type PasteDropMediaOptions, type PasteDropMediaUploadFn, type PasteDropRehostProgressEvent, Popover, PopoverContent, PopoverTrigger, type RehostProgressEvent, SR_ONLY, Separator, Spacer, Toolbar, ToolbarGroup, ToolbarSeparator, UiState, UiState as UiStateType, type User, UserContext, type UserContextValue, UserProvider, Video, clamp, cn, defaultUiState, detectMediaKind, findNodeAtPosition, findNodePosition, findSelectionPosition, focusNextNode, formatShortcutKey, getAvatar, getElementOverflowPosition, getNodeDisplayName, getSelectedBlockNodes, getSelectedNodesOfType, getSelectionBoundingRect, getUrlParam, handleImageUpload, hasContentAbove, isAllowedUri, isExtensionAvailable, isMac, isMarkInSchema, isNodeInSchema, isNodeTypeSelected, isSelectionValid, isTextSelectionValid, isValidPosition, markHideFloatingOnNext, parseShortcutKeys, pickFile, removeEmptyParagraphs, resolveMaxSize, runMediaUpload, sanitizeUrl, selectCurrentBlockContent, selectNodeAndHideFloating, selectionWithinConvertibleTypes, updateNodesAttr, useCollab, useCollaboration, useComposedRef, useCursorVisibility, useEditorConfig, useElementRect, useFloatingElement, useFloatingToolbarVisibility, useIsBreakpoint, useIsomorphicLayoutEffect, useMenuNavigation, useOnClickOutside, useScrolling, useThrottledCallback, useTiptapEditor, useUiEditorState, useUiEditorState as useUiEditorStateDefault, useUnmount, useUser, useWindowSize };
|
package/dist/doc.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { ArticleViewer, Audio,
|
|
1
|
+
export { ArticleViewer, Audio, CollabContext, CollabProvider, Column, Columns, DEFAULT_MAX_FILE_SIZES, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EditorConfigProvider, EditorContentArea, FileAttachment, FloatingElement, HIDE_FLOATING_META, LoadingSpinner, MediaUploadButton, MediaUploadPlaceholder, NotionEditor, NotionEditorContent, EditorProvider as NotionEditorInner, PasteDropMedia, Separator, Spacer, Toolbar, ToolbarGroup, ToolbarSeparator, UiState, UserContext, UserProvider, Video, defaultUiState, detectMediaKind, findSelectionPosition, hasContentAbove, markHideFloatingOnNext, pickFile, resolveMaxSize, runMediaUpload, selectNodeAndHideFloating, useCollab, useCollaboration, useComposedRef, useCursorVisibility, useEditorConfig, useElementRect, useFloatingElement, useFloatingToolbarVisibility, useIsBreakpoint, useIsomorphicLayoutEffect, useMenuNavigation, useOnClickOutside, useThrottledCallback, useUiEditorState, use_ui_editor_state_default as useUiEditorStateDefault, useUnmount, useUser, useWindowSize } from './chunk-2GHNI22G.js';
|
|
2
|
+
export { Button, MAC_SYMBOLS, MAX_FILE_SIZE, Popover, PopoverContent, PopoverTrigger, SR_ONLY, clamp, cn, findNodeAtPosition, findNodePosition, focusNextNode, formatShortcutKey, getAvatar, getElementOverflowPosition, getNodeDisplayName, getSelectedBlockNodes, getSelectedNodesOfType, getSelectionBoundingRect, getUrlParam, handleImageUpload, isAllowedUri, isExtensionAvailable, isMac, isMarkInSchema, isNodeInSchema, isNodeTypeSelected, isSelectionValid, isTextSelectionValid, isValidPosition, parseShortcutKeys, removeEmptyParagraphs, sanitizeUrl, selectCurrentBlockContent, selectionWithinConvertibleTypes, updateNodesAttr, useTiptapEditor } from './chunk-T2DZHEJJ.js';
|
|
2
3
|
import { useState, useEffect } from 'react';
|
|
3
4
|
|
|
4
5
|
function useScrolling(target, options = {}) {
|
package/dist/doc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/use-scrolling.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-scrolling.ts"],"names":[],"mappings":";;;;AAWO,SAAS,YAAA,CACd,MAAA,EACA,OAAA,GAA+B,EAAC,EACvB;AACT,EAAA,MAAM,EAAE,QAAA,GAAW,GAAA,EAAK,kBAAA,GAAqB,MAAK,GAAI,OAAA;AACtD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,KAAK,CAAA;AAEpD,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,MAAM,OAAA,GACJ,UAAU,OAAO,MAAA,KAAW,eAAe,MAAA,YAAkB,MAAA,GACzD,MAAA,GACE,MAAA,EAAmC,OAAA,IAAW,MAAA;AAGtD,IAAA,MAAM,cACJ,kBAAA,IACA,OAAA,KAAY,UACZ,OAAO,QAAA,KAAa,cAChB,QAAA,GACA,OAAA;AAEN,IAAA,MAAM,EAAA,GAAK,CACT,EAAA,EACA,KAAA,EACA,YACG,EAAA,CAAG,gBAAA,CAAiB,KAAA,EAAO,OAAA,EAAS,IAAI,CAAA;AAE7C,IAAA,MAAM,GAAA,GAAM,CACV,EAAA,EACA,KAAA,EACA,YACG,EAAA,CAAG,mBAAA,CAAoB,OAAO,OAAO,CAAA;AAE1C,IAAA,IAAI,OAAA;AACJ,IAAA,MAAM,iBAAA,GAAoB,OAAA,KAAY,MAAA,IAAU,aAAA,IAAiB,MAAA;AAEjE,IAAA,MAAM,eAA8B,MAAM;AACxC,MAAA,IAAI,CAAC,WAAA,EAAa,cAAA,CAAe,IAAI,CAAA;AAErC,MAAA,IAAI,CAAC,iBAAA,EAAmB;AACtB,QAAA,YAAA,CAAa,OAAO,CAAA;AACpB,QAAA,OAAA,GAAU,UAAA,CAAW,MAAM,cAAA,CAAe,KAAK,GAAG,QAAQ,CAAA;AAAA,MAC5D;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,eAAA,GAAiC,MAAM,cAAA,CAAe,KAAK,CAAA;AAEjE,IAAA,EAAA,CAAG,WAAA,EAAa,UAAU,YAAY,CAAA;AACtC,IAAA,IAAI,iBAAA,EAAmB;AACrB,MAAA,EAAA,CAAG,WAAA,EAAa,aAAa,eAAe,CAAA;AAAA,IAC9C;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,GAAA,CAAI,WAAA,EAAa,UAAU,YAAY,CAAA;AACvC,MAAA,IAAI,iBAAA,EAAmB;AACrB,QAAA,GAAA,CAAI,WAAA,EAAa,aAAa,eAAe,CAAA;AAAA,MAC/C;AACA,MAAA,YAAA,CAAa,OAAO,CAAA;AAAA,IACtB,CAAA;AAAA,EACF,GAAG,CAAC,MAAA,EAAQ,QAAA,EAAU,kBAAA,EAAoB,WAAW,CAAC,CAAA;AAEtD,EAAA,OAAO,WAAA;AACT","file":"doc.js","sourcesContent":["import type { RefObject } from \"react\"\nimport { useEffect, useState } from \"react\"\n\ntype ScrollTarget = RefObject<HTMLElement> | Window | null | undefined\ntype EventTargetWithScroll = Window | HTMLElement | Document\n\ninterface UseScrollingOptions {\n debounce?: number\n fallbackToDocument?: boolean\n}\n\nexport function useScrolling(\n target?: ScrollTarget,\n options: UseScrollingOptions = {}\n): boolean {\n const { debounce = 150, fallbackToDocument = true } = options\n const [isScrolling, setIsScrolling] = useState(false)\n\n useEffect(() => {\n // Resolve element or window\n const element: EventTargetWithScroll =\n target && typeof Window !== \"undefined\" && target instanceof Window\n ? target\n : ((target as RefObject<HTMLElement>)?.current ?? window)\n\n // Mobile: fallback to document when using window\n const eventTarget: EventTargetWithScroll =\n fallbackToDocument &&\n element === window &&\n typeof document !== \"undefined\"\n ? document\n : element\n\n const on = (\n el: EventTargetWithScroll,\n event: string,\n handler: EventListener\n ) => el.addEventListener(event, handler, true)\n\n const off = (\n el: EventTargetWithScroll,\n event: string,\n handler: EventListener\n ) => el.removeEventListener(event, handler)\n\n let timeout: ReturnType<typeof setTimeout>\n const supportsScrollEnd = element === window && \"onscrollend\" in window\n\n const handleScroll: EventListener = () => {\n if (!isScrolling) setIsScrolling(true)\n\n if (!supportsScrollEnd) {\n clearTimeout(timeout)\n timeout = setTimeout(() => setIsScrolling(false), debounce)\n }\n }\n\n const handleScrollEnd: EventListener = () => setIsScrolling(false)\n\n on(eventTarget, \"scroll\", handleScroll)\n if (supportsScrollEnd) {\n on(eventTarget, \"scrollend\", handleScrollEnd)\n }\n\n return () => {\n off(eventTarget, \"scroll\", handleScroll)\n if (supportsScrollEnd) {\n off(eventTarget, \"scrollend\", handleScrollEnd)\n }\n clearTimeout(timeout)\n }\n }, [target, debounce, fallbackToDocument, isScrolling])\n\n return isScrolling\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,7 @@ registerFormat({
|
|
|
29
29
|
importExtensions: [".docx", ".md", ".html"],
|
|
30
30
|
exportFormats: ["docx", "html", "json", "markdown"]
|
|
31
31
|
},
|
|
32
|
-
load: () => import('./DocView-
|
|
32
|
+
load: () => import('./DocView-CZV7LGFK.js')
|
|
33
33
|
});
|
|
34
34
|
registerFormat({
|
|
35
35
|
format: "sheet",
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { Editor } from '@tiptap/react';
|
|
3
|
+
import { B as ButtonProps } from '../button-CWX5Uuj-.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* AI Plugin System - Core Types
|
|
7
|
+
*
|
|
8
|
+
* This module defines the interface for AI plugins.
|
|
9
|
+
* Plugins should implement the AIPlugin interface to integrate with the editor's AI button.
|
|
10
|
+
*/
|
|
11
|
+
interface AIContextData {
|
|
12
|
+
/** User's instruction/prompt */
|
|
13
|
+
prompt: string;
|
|
14
|
+
/** Currently selected text */
|
|
15
|
+
selectedText: string;
|
|
16
|
+
/** Selection position in document */
|
|
17
|
+
position: {
|
|
18
|
+
line: number;
|
|
19
|
+
column: number;
|
|
20
|
+
};
|
|
21
|
+
/** Text before the selection (for context) */
|
|
22
|
+
precedingText: string;
|
|
23
|
+
/** Text after the selection (for context) */
|
|
24
|
+
followingText: string;
|
|
25
|
+
/** Type of the node containing selection */
|
|
26
|
+
nodeType?: string;
|
|
27
|
+
/** Current heading level if inside a heading */
|
|
28
|
+
currentHeadingLevel?: number;
|
|
29
|
+
/** Full document for plugins that need it */
|
|
30
|
+
fullDocument?: string;
|
|
31
|
+
/** Document format */
|
|
32
|
+
documentFormat?: 'markdown' | 'html' | 'plaintext';
|
|
33
|
+
}
|
|
34
|
+
interface AIPluginResult {
|
|
35
|
+
/**
|
|
36
|
+
* The text to replace the selection with.
|
|
37
|
+
*
|
|
38
|
+
* Omit it when the plugin applies the edit itself — e.g. it hands the prompt to
|
|
39
|
+
* an agent that edits the document through its own tools. The editor then leaves
|
|
40
|
+
* the selection untouched.
|
|
41
|
+
*/
|
|
42
|
+
result?: string;
|
|
43
|
+
/** Optional error message */
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* AI Plugin Interface
|
|
48
|
+
*
|
|
49
|
+
* Implement this interface to create an AI plugin for the editor.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* class DeepseekPlugin implements AIPlugin {
|
|
54
|
+
* async process(context: AIContextData): Promise<AIPluginResult> {
|
|
55
|
+
* const response = await fetch('https://api.deepseek.com/...', {
|
|
56
|
+
* method: 'POST',
|
|
57
|
+
* body: JSON.stringify({
|
|
58
|
+
* prompt: context.prompt,
|
|
59
|
+
* text: context.selectedText,
|
|
60
|
+
* context: context.precedingText + context.followingText,
|
|
61
|
+
* })
|
|
62
|
+
* })
|
|
63
|
+
* const data = await response.json()
|
|
64
|
+
* return { result: data.output }
|
|
65
|
+
* }
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
interface AIPlugin {
|
|
70
|
+
/**
|
|
71
|
+
* Process the AI request
|
|
72
|
+
* @param context - The context data from the editor
|
|
73
|
+
* @returns The AI processing result
|
|
74
|
+
*/
|
|
75
|
+
process(context: AIContextData): Promise<AIPluginResult>;
|
|
76
|
+
}
|
|
77
|
+
interface AIPluginConfig {
|
|
78
|
+
/** The AI plugin instance */
|
|
79
|
+
plugin: AIPlugin;
|
|
80
|
+
/** Whether to enable the AI button */
|
|
81
|
+
enabled?: boolean;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface AIButtonProps extends Omit<ButtonProps, "type"> {
|
|
85
|
+
/**
|
|
86
|
+
* The Tiptap editor instance
|
|
87
|
+
*/
|
|
88
|
+
editor?: Editor | null;
|
|
89
|
+
/**
|
|
90
|
+
* AI plugin configuration (optional, will use context if not provided)
|
|
91
|
+
*/
|
|
92
|
+
config?: AIPluginConfig;
|
|
93
|
+
/**
|
|
94
|
+
* Whether to hide the button when no valid selection
|
|
95
|
+
* @default true
|
|
96
|
+
*/
|
|
97
|
+
hideWhenUnavailable?: boolean;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* AI Button component for triggering the AI processing dialog
|
|
101
|
+
*
|
|
102
|
+
* Usage:
|
|
103
|
+
* ```tsx
|
|
104
|
+
* <AIButton
|
|
105
|
+
* config={{ plugin: new MyAIPlugin() }}
|
|
106
|
+
* hideWhenUnavailable
|
|
107
|
+
* />
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
declare const AIButton: react.ForwardRefExoticComponent<AIButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
111
|
+
|
|
112
|
+
interface AIDialogProps {
|
|
113
|
+
editor: Editor;
|
|
114
|
+
config: AIPluginConfig;
|
|
115
|
+
buildContext: (prompt: string) => AIContextData | null;
|
|
116
|
+
onClose: () => void;
|
|
117
|
+
}
|
|
118
|
+
declare function AIDialog({ editor, config, buildContext, onClose, }: AIDialogProps): react.JSX.Element;
|
|
119
|
+
|
|
120
|
+
declare function useAIContext(editor: Editor | null): {
|
|
121
|
+
buildContext: (prompt: string) => AIContextData | null;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
declare const AIConfigContext: react.Context<AIPluginConfig | null>;
|
|
125
|
+
declare function useAIConfig(): AIPluginConfig | null;
|
|
126
|
+
|
|
127
|
+
export { AIButton, type AIButtonProps, AIConfigContext, type AIContextData, AIDialog, type AIDialogProps, type AIPlugin, type AIPluginConfig, type AIPluginResult, useAIConfig, useAIContext };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"ai.js"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4399ywkf/editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "4399 多格式文档编辑器:doc(tiptap) / sheet(univer) / pdf,含 docx 导入导出与 AI 可驱动的结构化编辑面(./doc-runtime)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
"types": "./dist/doc-runtime.d.ts",
|
|
31
31
|
"import": "./dist/doc-runtime.js"
|
|
32
32
|
},
|
|
33
|
+
"./plugins/ai": {
|
|
34
|
+
"types": "./dist/plugins/ai.d.ts",
|
|
35
|
+
"import": "./dist/plugins/ai.js"
|
|
36
|
+
},
|
|
33
37
|
"./styles": "./dist/style.css",
|
|
34
38
|
"./package.json": "./package.json"
|
|
35
39
|
},
|
|
@@ -123,7 +127,7 @@
|
|
|
123
127
|
"scripts": {
|
|
124
128
|
"build": "tsup && node scripts/build-styles.mjs",
|
|
125
129
|
"dev": "tsup --watch",
|
|
126
|
-
"test": "node --experimental-strip-types --test src/docx/*.test.ts src/doc-runtime/*.test.ts",
|
|
130
|
+
"test": "node --experimental-strip-types --test src/docx/*.test.ts src/doc-runtime/*.test.ts src/plugins/**/*.test.ts",
|
|
127
131
|
"typecheck": "tsc --noEmit"
|
|
128
132
|
}
|
|
129
133
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/views/DocView.tsx"],"names":[],"mappings":";;;AAMe,SAAR,QAAyB,EAAE,OAAA,EAAS,UAAU,IAAA,EAAM,SAAA,EAAW,SAAQ,EAAsB;AAClG,EAAA,2BACG,KAAA,EAAA,EAAI,SAAA,EACH,8BAAC,oBAAA,EAAA,EAAqB,MAAA,EAAQ,EAAC,EAC7B,QAAA,kBAAA,GAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,MAAM,IAAA,IAAQ,SAAA;AAAA,MACd,OAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA,EAAe,CAAC,MAAA,KAAmB,OAAA,GAAU,MAAM;AAAA;AAAA,KAEvD,CAAA,EACF,CAAA;AAEJ","file":"DocView-WQIV7HIE.js","sourcesContent":["import type { Editor } from \"@tiptap/react\"\nimport { EditorConfigProvider } from \"../contexts/editor-config-context\"\nimport { NotionEditor } from \"../components/tiptap-templates/notion-like/notion-like-editor\"\nimport type { DocumentViewProps } from \"../registry\"\n\n/** doc 通道:云文档与本地 doc 是同一套 tiptap,不做区分 */\nexport default function DocView({ content, readOnly, room, className, onReady }: DocumentViewProps) {\n return (\n <div className={className}>\n <EditorConfigProvider config={{}}>\n <NotionEditor\n room={room ?? \"default\"}\n content={content as string}\n readOnly={readOnly}\n onEditorReady={(editor: Editor) => onReady?.(editor)}\n />\n </EditorConfigProvider>\n </div>\n )\n}\n"]}
|