@liveblocks/react-tiptap 3.18.1 → 3.18.3-test1

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.
Files changed (61) hide show
  1. package/LICENSE +16 -0
  2. package/dist/LiveblocksExtension.cjs +4 -7
  3. package/dist/LiveblocksExtension.cjs.map +1 -1
  4. package/dist/LiveblocksExtension.js +4 -7
  5. package/dist/LiveblocksExtension.js.map +1 -1
  6. package/dist/ai/AiExtension.cjs +1 -1
  7. package/dist/ai/AiExtension.cjs.map +1 -1
  8. package/dist/ai/AiExtension.js +1 -1
  9. package/dist/ai/AiExtension.js.map +1 -1
  10. package/dist/ai/AiToolbar.cjs +10 -17
  11. package/dist/ai/AiToolbar.cjs.map +1 -1
  12. package/dist/ai/AiToolbar.js +10 -17
  13. package/dist/ai/AiToolbar.js.map +1 -1
  14. package/dist/collaboration/collaboration.cjs +1 -0
  15. package/dist/collaboration/collaboration.cjs.map +1 -1
  16. package/dist/collaboration/collaboration.js +1 -0
  17. package/dist/collaboration/collaboration.js.map +1 -1
  18. package/dist/collaboration/helpers/isChangeOrigin.cjs.map +1 -1
  19. package/dist/collaboration/helpers/isChangeOrigin.js.map +1 -1
  20. package/dist/comments/AnchoredThreads.cjs +9 -18
  21. package/dist/comments/AnchoredThreads.cjs.map +1 -1
  22. package/dist/comments/AnchoredThreads.js +9 -18
  23. package/dist/comments/AnchoredThreads.js.map +1 -1
  24. package/dist/comments/CommentsExtension.cjs +5 -11
  25. package/dist/comments/CommentsExtension.cjs.map +1 -1
  26. package/dist/comments/CommentsExtension.js +5 -11
  27. package/dist/comments/CommentsExtension.js.map +1 -1
  28. package/dist/comments/FloatingComposer.cjs +1 -2
  29. package/dist/comments/FloatingComposer.cjs.map +1 -1
  30. package/dist/comments/FloatingComposer.js +1 -2
  31. package/dist/comments/FloatingComposer.js.map +1 -1
  32. package/dist/comments/FloatingThreads.cjs +4 -8
  33. package/dist/comments/FloatingThreads.cjs.map +1 -1
  34. package/dist/comments/FloatingThreads.js +4 -8
  35. package/dist/comments/FloatingThreads.js.map +1 -1
  36. package/dist/mentions/Mention.cjs +6 -15
  37. package/dist/mentions/Mention.cjs.map +1 -1
  38. package/dist/mentions/Mention.js +6 -15
  39. package/dist/mentions/Mention.js.map +1 -1
  40. package/dist/mentions/MentionExtension.cjs.map +1 -1
  41. package/dist/mentions/MentionExtension.js.map +1 -1
  42. package/dist/mentions/MentionsList.cjs +2 -4
  43. package/dist/mentions/MentionsList.cjs.map +1 -1
  44. package/dist/mentions/MentionsList.js +2 -4
  45. package/dist/mentions/MentionsList.js.map +1 -1
  46. package/dist/toolbar/FloatingToolbar.cjs.map +1 -1
  47. package/dist/toolbar/FloatingToolbar.js.map +1 -1
  48. package/dist/utils.cjs +2 -4
  49. package/dist/utils.cjs.map +1 -1
  50. package/dist/utils.js +2 -4
  51. package/dist/utils.js.map +1 -1
  52. package/dist/version-history/HistoryVersionPreview.cjs.map +1 -1
  53. package/dist/version-history/HistoryVersionPreview.js.map +1 -1
  54. package/dist/version.cjs +1 -1
  55. package/dist/version.cjs.map +1 -1
  56. package/dist/version.js +1 -1
  57. package/dist/version.js.map +1 -1
  58. package/package.json +46 -35
  59. package/src/styles/index.css +3 -3
  60. package/styles.css +1 -1
  61. package/styles.css.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AiToolbar.js","sources":["../../src/ai/AiToolbar.tsx"],"sourcesContent":["import {\n autoUpdate,\n type DetectOverflowOptions,\n hide,\n limitShift,\n type Middleware,\n offset,\n shift,\n useFloating,\n type UseFloatingOptions,\n} from \"@floating-ui/react-dom\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n ArrowCornerDownRightIcon,\n Button,\n CheckIcon,\n cn,\n CrossIcon,\n EditIcon,\n LengthenIcon,\n Portal,\n QuestionMarkIcon,\n SendIcon,\n ShortcutTooltip,\n ShortenIcon,\n SparklesIcon,\n SparklesTextIcon,\n StopIcon,\n TooltipProvider,\n UndoIcon,\n useRefs,\n WarningIcon,\n} from \"@liveblocks/react-ui/_private\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport { Command, useCommandState } from \"cmdk\";\nimport type {\n ComponentProps,\n ComponentType,\n KeyboardEvent as ReactKeyboardEvent,\n PropsWithChildren,\n ReactNode,\n RefObject,\n} from \"react\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { EditorProvider, useCurrentEditor } from \"../context\";\nimport type { AiToolbarState, ChainedAiCommands } from \"../types\";\nimport { getDomRangeFromSelection } from \"../utils\";\nimport { DEFAULT_STATE, isContextualPromptDiffResponse } from \"./AiExtension\";\n\nexport const AI_TOOLBAR_COLLISION_PADDING = 10;\n\nexport interface AiToolbarProps\n extends Omit<ComponentProps<\"div\">, \"value\" | \"defaultValue\" | \"children\"> {\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n\n /**\n * The vertical offset of the AI toolbar from the selection.\n */\n offset?: number;\n\n /**\n * The prompt suggestions to display below the AI toolbar.\n */\n suggestions?: ReactNode | ComponentType<PropsWithChildren>;\n}\n\ntype AiToolbarDropdownSeparatorProps = ComponentProps<\"div\">;\n\ninterface AiToolbarDropdownItemProps\n extends ComponentProps<typeof Command.Item> {\n icon?: ReactNode;\n}\n\ntype AiToolbarSuggestionsSeparatorProps = AiToolbarDropdownSeparatorProps;\n\ntype AiToolbarSuggestionsLabelProps = ComponentProps<\"span\">;\n\ninterface AiToolbarSuggestionProps extends ComponentProps<\"div\"> {\n prompt?: string;\n icon?: ReactNode;\n}\n\ninterface AiToolbarContext {\n state: AiToolbarState;\n toolbarRef: RefObject<HTMLDivElement>;\n dropdownRef: RefObject<HTMLDivElement>;\n isDropdownHidden: boolean;\n}\n\nconst AiToolbarContext = createContext<AiToolbarContext | null>(null);\n\nfunction useAiToolbarContext() {\n const context = useContext(AiToolbarContext);\n\n if (!context) {\n throw new Error(\"useAiToolbarContext must be used within an AiToolbar\");\n }\n\n return context;\n}\n\n/**\n * A custom Floating UI middleware to position/scale the toolbar:\n * - Vertically: relative to the reference (e.g. selection)\n * - Horizontally: relative to the editor\n * - Width: relative to the editor\n */\nfunction tiptapFloating(editor: Editor | null): Middleware {\n return {\n name: \"tiptap\",\n options: editor,\n fn({ elements }) {\n if (!editor) {\n return {};\n }\n\n const editorRect = editor.view.dom.getBoundingClientRect();\n\n elements.floating.style.setProperty(\n \"--lb-tiptap-editor-width\",\n `${editorRect.width}px`\n );\n elements.floating.style.setProperty(\n \"--lb-tiptap-editor-height\",\n `${editorRect.height}px`\n );\n\n return {\n x: editorRect.x,\n };\n },\n };\n}\n\n/**\n * A custom Floating UI middleware to flip the toolbar/dropdown when shifted more than 100%.\n */\nfunction flipToolbar(): Middleware {\n return {\n name: \"flipToolbar\",\n fn({ elements, middlewareData, rects }) {\n const shiftOffsetY = middlewareData.shift?.y ?? 0;\n\n if (Math.abs(shiftOffsetY) >= rects.floating.height) {\n elements.floating.setAttribute(\"data-liveblocks-ai-toolbar-flip\", \"\");\n } else {\n elements.floating.removeAttribute(\"data-liveblocks-ai-toolbar-flip\");\n }\n\n return {};\n },\n };\n}\n\nconst AiToolbarDropdownSeparator = forwardRef<\n HTMLDivElement,\n AiToolbarDropdownSeparatorProps\n>(({ className, ...props }, forwardedRef) => {\n return (\n <Command.Separator\n className={cn(\"lb-dropdown-separator\", className)}\n {...props}\n ref={forwardedRef}\n />\n );\n});\n\nconst AiToolbarSuggestionsSeparator = forwardRef<\n HTMLDivElement,\n AiToolbarSuggestionsSeparatorProps\n>((props, forwardedRef) => {\n return <AiToolbarDropdownSeparator ref={forwardedRef} {...props} />;\n});\n\nconst AiToolbarDropdownItem = forwardRef<\n HTMLDivElement,\n AiToolbarDropdownItemProps\n>(({ children, onSelect, icon, className, ...props }, forwardedRef) => {\n return (\n <Command.Item\n className={cn(\"lb-dropdown-item\", className)}\n onSelect={onSelect}\n {...props}\n ref={forwardedRef}\n >\n {icon ? <span className=\"lb-icon-container\">{icon}</span> : null}\n {children ? (\n <span className=\"lb-dropdown-item-label\">{children}</span>\n ) : null}\n </Command.Item>\n );\n});\n\nconst AiToolbarSuggestionsLabel = forwardRef<\n HTMLDivElement,\n AiToolbarSuggestionsLabelProps\n>(({ children, className, ...props }, forwardedRef) => {\n return (\n <span\n ref={forwardedRef}\n className={cn(\"lb-dropdown-label\", className)}\n {...props}\n >\n {children}\n </span>\n );\n});\n\nconst AiToolbarSuggestion = forwardRef<\n HTMLDivElement,\n AiToolbarSuggestionProps\n>(({ prompt: manualPrompt, ...props }, forwardedRef) => {\n const editor = useCurrentEditor(\"Suggestion\", \"AiToolbar\");\n\n const handleSelect = useCallback(\n (prompt: string) => {\n editor.commands.$startAiToolbarThinking(manualPrompt ?? prompt);\n },\n [editor, manualPrompt]\n );\n\n return (\n <AiToolbarDropdownItem\n {...props}\n onSelect={handleSelect}\n ref={forwardedRef}\n />\n );\n});\n\nfunction AiToolbarReviewingSuggestions() {\n const editor = useCurrentEditor(\"ReviewingSuggestions\", \"AiToolbar\");\n const { state } = useAiToolbarContext();\n const { response } = state as Extract<AiToolbarState, { phase: \"reviewing\" }>;\n\n if (isContextualPromptDiffResponse(response)) {\n return (\n <>\n <AiToolbarDropdownItem\n icon={<CheckIcon />}\n onSelect={editor.commands.$acceptAiToolbarResponse}\n >\n Accept\n </AiToolbarDropdownItem>\n <AiToolbarDropdownItem\n icon={<UndoIcon />}\n onSelect={editor.commands.$startAiToolbarThinking}\n >\n Try again\n </AiToolbarDropdownItem>\n <AiToolbarDropdownItem\n icon={<CrossIcon />}\n onSelect={editor.commands.$closeAiToolbar}\n >\n Discard\n </AiToolbarDropdownItem>\n </>\n );\n } else {\n return (\n <>\n <AiToolbarDropdownItem\n icon={<ArrowCornerDownRightIcon />}\n onSelect={editor.commands.$acceptAiToolbarResponse}\n >\n Insert below\n </AiToolbarDropdownItem>\n <AiToolbarDropdownItem\n icon={<UndoIcon />}\n onSelect={editor.commands.$startAiToolbarThinking}\n >\n Try again\n </AiToolbarDropdownItem>\n <AiToolbarDropdownItem\n icon={<CrossIcon />}\n onSelect={editor.commands.$closeAiToolbar}\n >\n Discard\n </AiToolbarDropdownItem>\n </>\n );\n }\n}\n\nfunction AiToolbarCustomPromptContent() {\n const editor = useCurrentEditor(\"CustomPromptContent\", \"AiToolbar\");\n // Eslint doesn't seem to like Tiptap's Type declaration strategy\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n const aiName = editor.storage.liveblocksAi.name;\n const textAreaRef = useRef<HTMLTextAreaElement>(null);\n const { state, dropdownRef, isDropdownHidden } = useAiToolbarContext();\n const { customPrompt } = state as Exclude<\n AiToolbarState,\n { phase: \"closed\" }\n >;\n const isCustomPromptEmpty = useMemo(\n () => customPrompt.trim() === \"\",\n [customPrompt]\n );\n\n useLayoutEffect(\n () => {\n requestAnimationFrame(() => {\n const textArea = textAreaRef.current;\n\n if (!textArea) {\n return;\n }\n\n textArea.focus();\n textArea.setSelectionRange(\n textArea.value.length,\n textArea.value.length\n );\n });\n },\n [] // eslint-disable-line react-hooks/exhaustive-deps\n );\n\n const handlePromptKeyDown = (\n event: ReactKeyboardEvent<HTMLTextAreaElement>\n ) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n\n if (event.shiftKey) {\n // If the shift key is pressed, add a new line\n editor.commands._updateAiToolbarCustomPrompt(\n (customPrompt) => customPrompt + \"\\n\"\n );\n } else {\n const selectedDropdownItem = dropdownRef.current?.querySelector(\n \"[role='option'][data-selected='true']\"\n ) as HTMLElement | null;\n\n if (!isDropdownHidden && selectedDropdownItem) {\n // If there's a selected dropdown item, select it\n selectedDropdownItem.click();\n } else if (!isCustomPromptEmpty) {\n // Otherwise, submit the custom prompt\n editor.commands.$startAiToolbarThinking(\n customPrompt,\n state.phase === \"reviewing\"\n );\n }\n }\n }\n };\n\n const handleCustomPromptChange = useCallback(\n (customPrompt: string) => {\n editor.commands._updateAiToolbarCustomPrompt(customPrompt);\n },\n [editor]\n );\n\n const handleSendClick = useCallback(() => {\n if (isCustomPromptEmpty) {\n return;\n }\n\n editor.commands.$startAiToolbarThinking(\n customPrompt,\n state.phase === \"reviewing\"\n );\n }, [editor, customPrompt, isCustomPromptEmpty, state.phase]);\n\n return (\n <div className=\"lb-tiptap-ai-toolbar-content\">\n <span className=\"lb-icon-container lb-tiptap-ai-toolbar-icon-container\">\n <SparklesIcon />\n </span>\n <div\n className=\"lb-tiptap-ai-toolbar-custom-prompt-container\"\n data-value={customPrompt}\n >\n <Command.Input\n value={customPrompt}\n onValueChange={handleCustomPromptChange}\n asChild\n >\n <textarea\n ref={textAreaRef}\n className=\"lb-tiptap-ai-toolbar-custom-prompt\"\n placeholder={`Ask ${aiName} anything…`}\n onKeyDown={handlePromptKeyDown}\n rows={1}\n autoFocus\n />\n </Command.Input>\n </div>\n <div className=\"lb-tiptap-ai-toolbar-actions\">\n <ShortcutTooltip content={`Ask ${aiName}`} shortcut=\"Enter\">\n <Button\n className=\"lb-tiptap-ai-toolbar-action\"\n variant=\"primary\"\n aria-label={`Ask ${aiName}`}\n icon={<SendIcon />}\n disabled={isCustomPromptEmpty}\n onClick={handleSendClick}\n />\n </ShortcutTooltip>\n </div>\n </div>\n );\n}\n\nfunction AiToolbarAsking() {\n const { state } = useAiToolbarContext();\n const { error } = state as Exclude<AiToolbarState, { phase: \"closed\" }>;\n\n return (\n <>\n <AiToolbarCustomPromptContent />\n {error ? (\n <div className=\"lb-tiptap-ai-toolbar-error\">\n <span className=\"lb-icon-container\">\n <WarningIcon />\n </span>\n There was a problem with your request.\n </div>\n ) : null}\n </>\n );\n}\n\nfunction AiToolbarThinking() {\n const editor = useCurrentEditor(\"AiToolbarThinking\", \"AiToolbar\");\n const contentRef = useRef<HTMLDivElement>(null);\n const aiName = editor.storage.liveblocksAi.name;\n\n const handleAbort = useCallback(() => {\n editor.commands.$cancelAiToolbarThinking();\n }, [editor]);\n\n // Focus the toolbar content and clear the current window selection while thinking\n useLayoutEffect(() => {\n contentRef.current?.focus();\n window.getSelection()?.removeAllRanges();\n }, []);\n\n return (\n <>\n <div\n className=\"lb-tiptap-ai-toolbar-content\"\n tabIndex={0}\n ref={contentRef}\n >\n <span className=\"lb-icon-container lb-tiptap-ai-toolbar-icon-container\">\n <SparklesIcon />\n </span>\n <div className=\"lb-tiptap-ai-toolbar-thinking\">\n {aiName} is thinking…\n </div>\n <div className=\"lb-tiptap-ai-toolbar-actions\">\n <ShortcutTooltip content=\"Abort response\" shortcut=\"Escape\">\n <Button\n className=\"lb-tiptap-ai-toolbar-action\"\n variant=\"secondary\"\n aria-label=\"Abort response\"\n icon={<StopIcon />}\n onClick={handleAbort}\n />\n </ShortcutTooltip>\n </div>\n </div>\n </>\n );\n}\n\nfunction AiToolbarReviewing() {\n const { state } = useAiToolbarContext();\n const { response } = state as Extract<AiToolbarState, { phase: \"reviewing\" }>;\n\n return (\n <>\n {response.type === \"other\" ? (\n <div className=\"lb-tiptap-ai-toolbar-response-container\">\n <div className=\"lb-tiptap-ai-toolbar-response\">{response.text}</div>\n </div>\n ) : null}\n <AiToolbarCustomPromptContent />\n </>\n );\n}\n\nfunction AiToolbarContainer({\n state,\n toolbarRef,\n dropdownRef,\n children,\n}: PropsWithChildren<{\n state: AiToolbarState;\n toolbarRef: RefObject<HTMLDivElement>;\n dropdownRef: RefObject<HTMLDivElement>;\n}>) {\n const editor = useCurrentEditor(\"AiToolbarContainer\", \"AiToolbar\");\n const customPrompt = state.customPrompt;\n const isCustomPromptMultiline = useMemo(\n () => customPrompt?.includes(\"\\n\"),\n [customPrompt]\n );\n const hasDropdownItems = useCommandState(\n (state) => state.filtered.count > 0\n ) as boolean;\n const isDropdownHidden = isCustomPromptMultiline || !hasDropdownItems;\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (!event.defaultPrevented && event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n\n if (state.phase === \"thinking\") {\n editor.commands.$cancelAiToolbarThinking();\n } else {\n (editor.chain() as ChainedAiCommands).$closeAiToolbar().focus().run();\n }\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [editor, state.phase]);\n\n return (\n <AiToolbarContext.Provider\n value={{\n state,\n toolbarRef,\n dropdownRef,\n isDropdownHidden,\n }}\n >\n <div className=\"lb-tiptap-ai-toolbar-container\">\n <div className=\"lb-elevation lb-tiptap-ai-toolbar\">\n {state.phase === \"asking\" ? (\n <AiToolbarAsking />\n ) : state.phase === \"thinking\" ? (\n <AiToolbarThinking />\n ) : state.phase === \"reviewing\" ? (\n <AiToolbarReviewing />\n ) : null}\n </div>\n <div\n className=\"lb-tiptap-ai-toolbar-halo\"\n data-active={state.phase === \"thinking\" ? \"\" : undefined}\n aria-hidden\n >\n <div className=\"lb-tiptap-ai-toolbar-halo-horizontal\" />\n <div className=\"lb-tiptap-ai-toolbar-halo-vertical\" />\n </div>\n </div>\n {state.phase === \"asking\" || state.phase === \"reviewing\" ? (\n <Command.List\n className=\"lb-elevation lb-dropdown lb-tiptap-ai-toolbar-dropdown\"\n data-hidden={isDropdownHidden ? \"\" : undefined}\n ref={dropdownRef}\n >\n {state.phase === \"reviewing\" ? (\n <AiToolbarReviewingSuggestions />\n ) : (\n children\n )}\n </Command.List>\n ) : null}\n </AiToolbarContext.Provider>\n );\n}\n\nconst defaultSuggestions = (\n <>\n <AiToolbarSuggestion\n icon={<EditIcon />}\n prompt=\"Improve the quality of the text\"\n >\n Improve writing\n </AiToolbarSuggestion>\n <AiToolbarSuggestion\n icon={<CheckIcon />}\n prompt=\"Fix spelling & grammar errors in the text\"\n >\n Fix mistakes\n </AiToolbarSuggestion>\n <AiToolbarSuggestion\n icon={<ShortenIcon />}\n prompt=\"Shorten the text, simplifying it\"\n >\n Simplify\n </AiToolbarSuggestion>\n <AiToolbarSuggestion\n icon={<LengthenIcon />}\n prompt=\"Lengthen the text, going into more detail\"\n >\n Add more detail\n </AiToolbarSuggestion>\n <AiToolbarSuggestionsSeparator />\n <AiToolbarSuggestion\n icon={<SparklesTextIcon />}\n prompt=\"Continue writing from the text's end\"\n >\n Continue writing\n </AiToolbarSuggestion>\n <AiToolbarSuggestion\n icon={<QuestionMarkIcon />}\n prompt=\"Explain what the text is about\"\n >\n Explain\n </AiToolbarSuggestion>\n </>\n);\n\n/**\n * @beta\n *\n * A floating AI toolbar attached to the editor.\n */\nexport const AiToolbar = Object.assign(\n forwardRef<HTMLDivElement, AiToolbarProps>(\n (\n {\n offset: sideOffset = 6,\n editor,\n className,\n suggestions: Suggestions = defaultSuggestions,\n ...props\n },\n forwardedRef\n ) => {\n const state =\n useEditorState({\n editor,\n selector: (ctx) => {\n return ctx.editor?.storage.liveblocksAi?.state;\n },\n }) ?? DEFAULT_STATE;\n const selection = editor?.state.selection;\n const floatingOptions: UseFloatingOptions = useMemo(() => {\n const detectOverflowOptions: DetectOverflowOptions = {\n padding: AI_TOOLBAR_COLLISION_PADDING,\n };\n\n return {\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n tiptapFloating(editor),\n hide(detectOverflowOptions),\n offset(sideOffset),\n shift({\n ...detectOverflowOptions,\n mainAxis: false,\n crossAxis: true,\n limiter: limitShift(),\n }),\n flipToolbar(),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n };\n }, [editor, sideOffset]);\n const isOpen = selection !== undefined && state.phase !== \"closed\";\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n isPositioned,\n } = useFloating({\n ...floatingOptions,\n open: isOpen,\n });\n const toolbarRef = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, toolbarRef, setFloating);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const [selectedDropdownValue, setSelectedDropdownValue] = useState(\"\");\n\n // Reset the selected dropdown value when the toolbar is closed\n useEffect(() => {\n if (state.phase === \"closed\") {\n setSelectedDropdownValue(\"\");\n }\n }, [state.phase]);\n\n useEffect(() => {\n // Reset the selected dropdown value when the dropdown is closed\n if (state.phase === \"closed\") {\n setSelectedDropdownValue(\"\");\n\n return;\n }\n\n // Otherwise, make sure a dropdown item is selected when moving between phases\n const selectedDropdownItem = dropdownRef.current?.querySelector(\n \"[role='option'][data-selected='true']\"\n );\n\n if (selectedDropdownItem) {\n return;\n }\n\n const firstDropdownItem =\n dropdownRef.current?.querySelector(\"[role='option']\");\n\n setSelectedDropdownValue(\n (firstDropdownItem as HTMLElement | null)?.dataset.value ?? \"\"\n );\n }, [state.phase, dropdownRef, setSelectedDropdownValue]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n if (!selection && state.phase !== \"closed\") {\n editor.commands.$closeAiToolbar();\n }\n }, [state.phase, editor, selection]);\n\n useLayoutEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n setReference(null);\n\n setTimeout(() => {\n if (\n state.phase === \"reviewing\" &&\n isContextualPromptDiffResponse(state.response)\n ) {\n const changes = editor.view.dom.querySelectorAll(\n \"ychange[data-liveblocks]\"\n );\n\n // When diffs are displayed, we manually calculate bounds around all the\n // rendered changes instead of using the selection\n setReference({\n getBoundingClientRect: () => {\n const rects: DOMRect[] = [];\n\n changes.forEach((change) => {\n rects.push(change.getBoundingClientRect());\n });\n\n const minX = Math.min(...rects.map((rect) => rect.left));\n const minY = Math.min(...rects.map((rect) => rect.top));\n const maxX = Math.max(...rects.map((rect) => rect.right));\n const maxY = Math.max(...rects.map((rect) => rect.bottom));\n\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n top: minY,\n left: minX,\n bottom: maxY,\n right: maxX,\n };\n },\n });\n } else if (selection) {\n const domRange = getDomRangeFromSelection(editor, selection);\n setReference(domRange);\n } else {\n setReference(null);\n }\n }, 0);\n }, [\n selection,\n editor,\n isOpen,\n setReference,\n state.phase,\n state.response,\n ]);\n\n // Close the toolbar when clicking anywhere outside of it\n useEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n const handleOutsideEvent = (event: MouseEvent) => {\n if (!toolbarRef.current) {\n return;\n }\n\n if (\n event.target &&\n !toolbarRef.current.contains(event.target as Node) &&\n (dropdownRef.current\n ? !dropdownRef.current.contains(event.target as Node)\n : true)\n ) {\n editor.commands.$closeAiToolbar();\n }\n };\n\n setTimeout(() => {\n document.addEventListener(\"pointerdown\", handleOutsideEvent);\n }, 0);\n\n return () => {\n document.removeEventListener(\"pointerdown\", handleOutsideEvent);\n };\n }, [editor, isOpen]);\n\n if (!editor || !isOpen) {\n return null;\n }\n\n return (\n <TooltipProvider>\n <EditorProvider editor={editor}>\n <Portal asChild>\n <Command\n role=\"toolbar\"\n label=\"AI toolbar\"\n aria-orientation=\"horizontal\"\n className={cn(\n \"lb-root lb-portal lb-tiptap-ai-toolbar-portal\",\n className\n )}\n ref={mergedRefs}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: isPositioned\n ? `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`\n : \"translate3d(0, -200%, 0)\",\n }}\n value={selectedDropdownValue}\n onValueChange={setSelectedDropdownValue}\n {...props}\n >\n <AiToolbarContainer\n state={state}\n dropdownRef={dropdownRef}\n toolbarRef={toolbarRef}\n >\n {typeof Suggestions === \"function\" ? (\n <Suggestions children={defaultSuggestions} />\n ) : (\n Suggestions\n )}\n </AiToolbarContainer>\n </Command>\n </Portal>\n </EditorProvider>\n </TooltipProvider>\n );\n }\n ),\n {\n /**\n * @beta\n *\n * A prompt suggestion displayed in the AI toolbar.\n */\n Suggestion: AiToolbarSuggestion,\n\n /**\n * @beta\n *\n * A label to describe a group of prompt suggestions displayed in the AI toolbar.\n */\n SuggestionsLabel: AiToolbarSuggestionsLabel,\n\n /**\n * @beta\n *\n * A separator between groups of prompt suggestions displayed in the AI toolbar.\n */\n SuggestionsSeparator: AiToolbarSuggestionsSeparator,\n }\n);\n"],"names":["customPrompt","state"],"mappings":"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"}
1
+ {"version":3,"file":"AiToolbar.js","sources":["../../src/ai/AiToolbar.tsx"],"sourcesContent":["import {\n autoUpdate,\n type DetectOverflowOptions,\n hide,\n limitShift,\n type Middleware,\n offset,\n shift,\n useFloating,\n type UseFloatingOptions,\n} from \"@floating-ui/react-dom\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n ArrowCornerDownRightIcon,\n Button,\n CheckIcon,\n cn,\n CrossIcon,\n EditIcon,\n LengthenIcon,\n Portal,\n QuestionMarkIcon,\n SendIcon,\n ShortcutTooltip,\n ShortenIcon,\n SparklesIcon,\n SparklesTextIcon,\n StopIcon,\n TooltipProvider,\n UndoIcon,\n useRefs,\n WarningIcon,\n} from \"@liveblocks/react-ui/_private\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport { Command, useCommandState } from \"cmdk\";\nimport type {\n ComponentProps,\n ComponentType,\n KeyboardEvent as ReactKeyboardEvent,\n PropsWithChildren,\n ReactNode,\n RefObject,\n} from \"react\";\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { EditorProvider, useCurrentEditor } from \"../context\";\nimport type { AiToolbarState, ChainedAiCommands } from \"../types\";\nimport { getDomRangeFromSelection } from \"../utils\";\nimport { DEFAULT_STATE, isContextualPromptDiffResponse } from \"./AiExtension\";\n\nexport const AI_TOOLBAR_COLLISION_PADDING = 10;\n\nexport interface AiToolbarProps extends Omit<\n ComponentProps<\"div\">,\n \"value\" | \"defaultValue\" | \"children\"\n> {\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n\n /**\n * The vertical offset of the AI toolbar from the selection.\n */\n offset?: number;\n\n /**\n * The prompt suggestions to display below the AI toolbar.\n */\n suggestions?: ReactNode | ComponentType<PropsWithChildren>;\n}\n\ntype AiToolbarDropdownSeparatorProps = ComponentProps<\"div\">;\n\ninterface AiToolbarDropdownItemProps extends ComponentProps<\n typeof Command.Item\n> {\n icon?: ReactNode;\n}\n\ntype AiToolbarSuggestionsSeparatorProps = AiToolbarDropdownSeparatorProps;\n\ntype AiToolbarSuggestionsLabelProps = ComponentProps<\"span\">;\n\ninterface AiToolbarSuggestionProps extends ComponentProps<\"div\"> {\n prompt?: string;\n icon?: ReactNode;\n}\n\ninterface AiToolbarContext {\n state: AiToolbarState;\n toolbarRef: RefObject<HTMLDivElement>;\n dropdownRef: RefObject<HTMLDivElement>;\n isDropdownHidden: boolean;\n}\n\nconst AiToolbarContext = createContext<AiToolbarContext | null>(null);\n\nfunction useAiToolbarContext() {\n const context = useContext(AiToolbarContext);\n\n if (!context) {\n throw new Error(\"useAiToolbarContext must be used within an AiToolbar\");\n }\n\n return context;\n}\n\n/**\n * A custom Floating UI middleware to position/scale the toolbar:\n * - Vertically: relative to the reference (e.g. selection)\n * - Horizontally: relative to the editor\n * - Width: relative to the editor\n */\nfunction tiptapFloating(editor: Editor | null): Middleware {\n return {\n name: \"tiptap\",\n options: editor,\n fn({ elements }) {\n if (!editor) {\n return {};\n }\n\n const editorRect = editor.view.dom.getBoundingClientRect();\n\n elements.floating.style.setProperty(\n \"--lb-tiptap-editor-width\",\n `${editorRect.width}px`\n );\n elements.floating.style.setProperty(\n \"--lb-tiptap-editor-height\",\n `${editorRect.height}px`\n );\n\n return {\n x: editorRect.x,\n };\n },\n };\n}\n\n/**\n * A custom Floating UI middleware to flip the toolbar/dropdown when shifted more than 100%.\n */\nfunction flipToolbar(): Middleware {\n return {\n name: \"flipToolbar\",\n fn({ elements, middlewareData, rects }) {\n const shiftOffsetY = middlewareData.shift?.y ?? 0;\n\n if (Math.abs(shiftOffsetY) >= rects.floating.height) {\n elements.floating.setAttribute(\"data-liveblocks-ai-toolbar-flip\", \"\");\n } else {\n elements.floating.removeAttribute(\"data-liveblocks-ai-toolbar-flip\");\n }\n\n return {};\n },\n };\n}\n\nconst AiToolbarDropdownSeparator = forwardRef<\n HTMLDivElement,\n AiToolbarDropdownSeparatorProps\n>(({ className, ...props }, forwardedRef) => {\n return (\n <Command.Separator\n className={cn(\"lb-dropdown-separator\", className)}\n {...props}\n ref={forwardedRef}\n />\n );\n});\n\nconst AiToolbarSuggestionsSeparator = forwardRef<\n HTMLDivElement,\n AiToolbarSuggestionsSeparatorProps\n>((props, forwardedRef) => {\n return <AiToolbarDropdownSeparator ref={forwardedRef} {...props} />;\n});\n\nconst AiToolbarDropdownItem = forwardRef<\n HTMLDivElement,\n AiToolbarDropdownItemProps\n>(({ children, onSelect, icon, className, ...props }, forwardedRef) => {\n return (\n <Command.Item\n className={cn(\"lb-dropdown-item\", className)}\n onSelect={onSelect}\n {...props}\n ref={forwardedRef}\n >\n {icon ? <span className=\"lb-icon-container\">{icon}</span> : null}\n {children ? (\n <span className=\"lb-dropdown-item-label\">{children}</span>\n ) : null}\n </Command.Item>\n );\n});\n\nconst AiToolbarSuggestionsLabel = forwardRef<\n HTMLDivElement,\n AiToolbarSuggestionsLabelProps\n>(({ children, className, ...props }, forwardedRef) => {\n return (\n <span\n ref={forwardedRef}\n className={cn(\"lb-dropdown-label\", className)}\n {...props}\n >\n {children}\n </span>\n );\n});\n\nconst AiToolbarSuggestion = forwardRef<\n HTMLDivElement,\n AiToolbarSuggestionProps\n>(({ prompt: manualPrompt, ...props }, forwardedRef) => {\n const editor = useCurrentEditor(\"Suggestion\", \"AiToolbar\");\n\n const handleSelect = useCallback(\n (prompt: string) => {\n editor.commands.$startAiToolbarThinking(manualPrompt ?? prompt);\n },\n [editor, manualPrompt]\n );\n\n return (\n <AiToolbarDropdownItem\n {...props}\n onSelect={handleSelect}\n ref={forwardedRef}\n />\n );\n});\n\nfunction AiToolbarReviewingSuggestions() {\n const editor = useCurrentEditor(\"ReviewingSuggestions\", \"AiToolbar\");\n const { state } = useAiToolbarContext();\n const { response } = state as Extract<AiToolbarState, { phase: \"reviewing\" }>;\n\n if (isContextualPromptDiffResponse(response)) {\n return (\n <>\n <AiToolbarDropdownItem\n icon={<CheckIcon />}\n onSelect={editor.commands.$acceptAiToolbarResponse}\n >\n Accept\n </AiToolbarDropdownItem>\n <AiToolbarDropdownItem\n icon={<UndoIcon />}\n onSelect={editor.commands.$startAiToolbarThinking}\n >\n Try again\n </AiToolbarDropdownItem>\n <AiToolbarDropdownItem\n icon={<CrossIcon />}\n onSelect={editor.commands.$closeAiToolbar}\n >\n Discard\n </AiToolbarDropdownItem>\n </>\n );\n } else {\n return (\n <>\n <AiToolbarDropdownItem\n icon={<ArrowCornerDownRightIcon />}\n onSelect={editor.commands.$acceptAiToolbarResponse}\n >\n Insert below\n </AiToolbarDropdownItem>\n <AiToolbarDropdownItem\n icon={<UndoIcon />}\n onSelect={editor.commands.$startAiToolbarThinking}\n >\n Try again\n </AiToolbarDropdownItem>\n <AiToolbarDropdownItem\n icon={<CrossIcon />}\n onSelect={editor.commands.$closeAiToolbar}\n >\n Discard\n </AiToolbarDropdownItem>\n </>\n );\n }\n}\n\nfunction AiToolbarCustomPromptContent() {\n const editor = useCurrentEditor(\"CustomPromptContent\", \"AiToolbar\");\n // Eslint doesn't seem to like Tiptap's Type declaration strategy\n const aiName = editor.storage.liveblocksAi.name;\n const textAreaRef = useRef<HTMLTextAreaElement>(null);\n const { state, dropdownRef, isDropdownHidden } = useAiToolbarContext();\n const { customPrompt } = state as Exclude<\n AiToolbarState,\n { phase: \"closed\" }\n >;\n const isCustomPromptEmpty = useMemo(\n () => customPrompt.trim() === \"\",\n [customPrompt]\n );\n\n useLayoutEffect(() => {\n requestAnimationFrame(() => {\n const textArea = textAreaRef.current;\n\n if (!textArea) {\n return;\n }\n\n textArea.focus();\n textArea.setSelectionRange(textArea.value.length, textArea.value.length);\n });\n }, []);\n\n const handlePromptKeyDown = (\n event: ReactKeyboardEvent<HTMLTextAreaElement>\n ) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n event.stopPropagation();\n\n if (event.shiftKey) {\n // If the shift key is pressed, add a new line\n editor.commands._updateAiToolbarCustomPrompt(\n (customPrompt) => customPrompt + \"\\n\"\n );\n } else {\n const selectedDropdownItem = dropdownRef.current?.querySelector(\n \"[role='option'][data-selected='true']\"\n ) as HTMLElement | null;\n\n if (!isDropdownHidden && selectedDropdownItem) {\n // If there's a selected dropdown item, select it\n selectedDropdownItem.click();\n } else if (!isCustomPromptEmpty) {\n // Otherwise, submit the custom prompt\n editor.commands.$startAiToolbarThinking(\n customPrompt,\n state.phase === \"reviewing\"\n );\n }\n }\n }\n };\n\n const handleCustomPromptChange = useCallback(\n (customPrompt: string) => {\n editor.commands._updateAiToolbarCustomPrompt(customPrompt);\n },\n [editor]\n );\n\n const handleSendClick = useCallback(() => {\n if (isCustomPromptEmpty) {\n return;\n }\n\n editor.commands.$startAiToolbarThinking(\n customPrompt,\n state.phase === \"reviewing\"\n );\n }, [editor, customPrompt, isCustomPromptEmpty, state.phase]);\n\n return (\n <div className=\"lb-tiptap-ai-toolbar-content\">\n <span className=\"lb-icon-container lb-tiptap-ai-toolbar-icon-container\">\n <SparklesIcon />\n </span>\n <div\n className=\"lb-tiptap-ai-toolbar-custom-prompt-container\"\n data-value={customPrompt}\n >\n <Command.Input\n value={customPrompt}\n onValueChange={handleCustomPromptChange}\n asChild\n >\n <textarea\n ref={textAreaRef}\n className=\"lb-tiptap-ai-toolbar-custom-prompt\"\n placeholder={`Ask ${aiName} anything…`}\n onKeyDown={handlePromptKeyDown}\n rows={1}\n autoFocus\n />\n </Command.Input>\n </div>\n <div className=\"lb-tiptap-ai-toolbar-actions\">\n <ShortcutTooltip content={`Ask ${aiName}`} shortcut=\"Enter\">\n <Button\n className=\"lb-tiptap-ai-toolbar-action\"\n variant=\"primary\"\n aria-label={`Ask ${aiName}`}\n icon={<SendIcon />}\n disabled={isCustomPromptEmpty}\n onClick={handleSendClick}\n />\n </ShortcutTooltip>\n </div>\n </div>\n );\n}\n\nfunction AiToolbarAsking() {\n const { state } = useAiToolbarContext();\n const { error } = state as Exclude<AiToolbarState, { phase: \"closed\" }>;\n\n return (\n <>\n <AiToolbarCustomPromptContent />\n {error ? (\n <div className=\"lb-tiptap-ai-toolbar-error\">\n <span className=\"lb-icon-container\">\n <WarningIcon />\n </span>\n There was a problem with your request.\n </div>\n ) : null}\n </>\n );\n}\n\nfunction AiToolbarThinking() {\n const editor = useCurrentEditor(\"AiToolbarThinking\", \"AiToolbar\");\n const contentRef = useRef<HTMLDivElement>(null);\n const aiName = editor.storage.liveblocksAi.name;\n\n const handleAbort = useCallback(() => {\n editor.commands.$cancelAiToolbarThinking();\n }, [editor]);\n\n // Focus the toolbar content and clear the current window selection while thinking\n useLayoutEffect(() => {\n contentRef.current?.focus();\n window.getSelection()?.removeAllRanges();\n }, []);\n\n return (\n <>\n <div\n className=\"lb-tiptap-ai-toolbar-content\"\n tabIndex={0}\n ref={contentRef}\n >\n <span className=\"lb-icon-container lb-tiptap-ai-toolbar-icon-container\">\n <SparklesIcon />\n </span>\n <div className=\"lb-tiptap-ai-toolbar-thinking\">\n {aiName} is thinking…\n </div>\n <div className=\"lb-tiptap-ai-toolbar-actions\">\n <ShortcutTooltip content=\"Abort response\" shortcut=\"Escape\">\n <Button\n className=\"lb-tiptap-ai-toolbar-action\"\n variant=\"secondary\"\n aria-label=\"Abort response\"\n icon={<StopIcon />}\n onClick={handleAbort}\n />\n </ShortcutTooltip>\n </div>\n </div>\n </>\n );\n}\n\nfunction AiToolbarReviewing() {\n const { state } = useAiToolbarContext();\n const { response } = state as Extract<AiToolbarState, { phase: \"reviewing\" }>;\n\n return (\n <>\n {response.type === \"other\" ? (\n <div className=\"lb-tiptap-ai-toolbar-response-container\">\n <div className=\"lb-tiptap-ai-toolbar-response\">{response.text}</div>\n </div>\n ) : null}\n <AiToolbarCustomPromptContent />\n </>\n );\n}\n\nfunction AiToolbarContainer({\n state,\n toolbarRef,\n dropdownRef,\n children,\n}: PropsWithChildren<{\n state: AiToolbarState;\n toolbarRef: RefObject<HTMLDivElement>;\n dropdownRef: RefObject<HTMLDivElement>;\n}>) {\n const editor = useCurrentEditor(\"AiToolbarContainer\", \"AiToolbar\");\n const customPrompt = state.customPrompt;\n const isCustomPromptMultiline = useMemo(\n () => customPrompt?.includes(\"\\n\"),\n [customPrompt]\n );\n const hasDropdownItems = useCommandState(\n (state) => state.filtered.count > 0\n ) as boolean;\n const isDropdownHidden = isCustomPromptMultiline || !hasDropdownItems;\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (!event.defaultPrevented && event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n\n if (state.phase === \"thinking\") {\n editor.commands.$cancelAiToolbarThinking();\n } else {\n (editor.chain() as ChainedAiCommands).$closeAiToolbar().focus().run();\n }\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [editor, state.phase]);\n\n return (\n <AiToolbarContext.Provider\n value={{\n state,\n toolbarRef,\n dropdownRef,\n isDropdownHidden,\n }}\n >\n <div className=\"lb-tiptap-ai-toolbar-container\">\n <div className=\"lb-elevation lb-tiptap-ai-toolbar\">\n {state.phase === \"asking\" ? (\n <AiToolbarAsking />\n ) : state.phase === \"thinking\" ? (\n <AiToolbarThinking />\n ) : state.phase === \"reviewing\" ? (\n <AiToolbarReviewing />\n ) : null}\n </div>\n <div\n className=\"lb-tiptap-ai-toolbar-halo\"\n data-active={state.phase === \"thinking\" ? \"\" : undefined}\n aria-hidden\n >\n <div className=\"lb-tiptap-ai-toolbar-halo-horizontal\" />\n <div className=\"lb-tiptap-ai-toolbar-halo-vertical\" />\n </div>\n </div>\n {state.phase === \"asking\" || state.phase === \"reviewing\" ? (\n <Command.List\n className=\"lb-elevation lb-dropdown lb-tiptap-ai-toolbar-dropdown\"\n data-hidden={isDropdownHidden ? \"\" : undefined}\n ref={dropdownRef}\n >\n {state.phase === \"reviewing\" ? (\n <AiToolbarReviewingSuggestions />\n ) : (\n children\n )}\n </Command.List>\n ) : null}\n </AiToolbarContext.Provider>\n );\n}\n\nconst defaultSuggestions = (\n <>\n <AiToolbarSuggestion\n icon={<EditIcon />}\n prompt=\"Improve the quality of the text\"\n >\n Improve writing\n </AiToolbarSuggestion>\n <AiToolbarSuggestion\n icon={<CheckIcon />}\n prompt=\"Fix spelling & grammar errors in the text\"\n >\n Fix mistakes\n </AiToolbarSuggestion>\n <AiToolbarSuggestion\n icon={<ShortenIcon />}\n prompt=\"Shorten the text, simplifying it\"\n >\n Simplify\n </AiToolbarSuggestion>\n <AiToolbarSuggestion\n icon={<LengthenIcon />}\n prompt=\"Lengthen the text, going into more detail\"\n >\n Add more detail\n </AiToolbarSuggestion>\n <AiToolbarSuggestionsSeparator />\n <AiToolbarSuggestion\n icon={<SparklesTextIcon />}\n prompt=\"Continue writing from the text's end\"\n >\n Continue writing\n </AiToolbarSuggestion>\n <AiToolbarSuggestion\n icon={<QuestionMarkIcon />}\n prompt=\"Explain what the text is about\"\n >\n Explain\n </AiToolbarSuggestion>\n </>\n);\n\n/**\n * @beta\n *\n * A floating AI toolbar attached to the editor.\n */\nexport const AiToolbar = Object.assign(\n forwardRef<HTMLDivElement, AiToolbarProps>(\n (\n {\n offset: sideOffset = 6,\n editor,\n className,\n suggestions: Suggestions = defaultSuggestions,\n ...props\n },\n forwardedRef\n ) => {\n const state =\n useEditorState({\n editor,\n selector: (ctx) => {\n return ctx.editor?.storage.liveblocksAi?.state;\n },\n }) ?? DEFAULT_STATE;\n const selection = editor?.state.selection;\n const floatingOptions: UseFloatingOptions = useMemo(() => {\n const detectOverflowOptions: DetectOverflowOptions = {\n padding: AI_TOOLBAR_COLLISION_PADDING,\n };\n\n return {\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n tiptapFloating(editor),\n hide(detectOverflowOptions),\n offset(sideOffset),\n shift({\n ...detectOverflowOptions,\n mainAxis: false,\n crossAxis: true,\n limiter: limitShift(),\n }),\n flipToolbar(),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n };\n }, [editor, sideOffset]);\n const isOpen = selection !== undefined && state.phase !== \"closed\";\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n isPositioned,\n } = useFloating({\n ...floatingOptions,\n open: isOpen,\n });\n const toolbarRef = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, toolbarRef, setFloating);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const [selectedDropdownValue, setSelectedDropdownValue] = useState(\"\");\n\n // Reset the selected dropdown value when the toolbar is closed\n useEffect(() => {\n if (state.phase === \"closed\") {\n setSelectedDropdownValue(\"\");\n }\n }, [state.phase]);\n\n useEffect(() => {\n // Reset the selected dropdown value when the dropdown is closed\n if (state.phase === \"closed\") {\n setSelectedDropdownValue(\"\");\n\n return;\n }\n\n // Otherwise, make sure a dropdown item is selected when moving between phases\n const selectedDropdownItem = dropdownRef.current?.querySelector(\n \"[role='option'][data-selected='true']\"\n );\n\n if (selectedDropdownItem) {\n return;\n }\n\n const firstDropdownItem =\n dropdownRef.current?.querySelector(\"[role='option']\");\n\n setSelectedDropdownValue(\n (firstDropdownItem as HTMLElement | null)?.dataset.value ?? \"\"\n );\n }, [state.phase, dropdownRef, setSelectedDropdownValue]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n if (!selection && state.phase !== \"closed\") {\n editor.commands.$closeAiToolbar();\n }\n }, [state.phase, editor, selection]);\n\n useLayoutEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n setReference(null);\n\n setTimeout(() => {\n if (\n state.phase === \"reviewing\" &&\n isContextualPromptDiffResponse(state.response)\n ) {\n const changes = editor.view.dom.querySelectorAll(\n \"ychange[data-liveblocks]\"\n );\n\n // When diffs are displayed, we manually calculate bounds around all the\n // rendered changes instead of using the selection\n setReference({\n getBoundingClientRect: () => {\n const rects: DOMRect[] = [];\n\n changes.forEach((change) => {\n rects.push(change.getBoundingClientRect());\n });\n\n const minX = Math.min(...rects.map((rect) => rect.left));\n const minY = Math.min(...rects.map((rect) => rect.top));\n const maxX = Math.max(...rects.map((rect) => rect.right));\n const maxY = Math.max(...rects.map((rect) => rect.bottom));\n\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n top: minY,\n left: minX,\n bottom: maxY,\n right: maxX,\n };\n },\n });\n } else if (selection) {\n const domRange = getDomRangeFromSelection(editor, selection);\n setReference(domRange);\n } else {\n setReference(null);\n }\n }, 0);\n }, [\n selection,\n editor,\n isOpen,\n setReference,\n state.phase,\n state.response,\n ]);\n\n // Close the toolbar when clicking anywhere outside of it\n useEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n const handleOutsideEvent = (event: MouseEvent) => {\n if (!toolbarRef.current) {\n return;\n }\n\n if (\n event.target &&\n !toolbarRef.current.contains(event.target as Node) &&\n (dropdownRef.current\n ? !dropdownRef.current.contains(event.target as Node)\n : true)\n ) {\n editor.commands.$closeAiToolbar();\n }\n };\n\n setTimeout(() => {\n document.addEventListener(\"pointerdown\", handleOutsideEvent);\n }, 0);\n\n return () => {\n document.removeEventListener(\"pointerdown\", handleOutsideEvent);\n };\n }, [editor, isOpen]);\n\n if (!editor || !isOpen) {\n return null;\n }\n\n return (\n <TooltipProvider>\n <EditorProvider editor={editor}>\n <Portal asChild>\n <Command\n role=\"toolbar\"\n label=\"AI toolbar\"\n aria-orientation=\"horizontal\"\n className={cn(\n \"lb-root lb-portal lb-tiptap-ai-toolbar-portal\",\n className\n )}\n ref={mergedRefs}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: isPositioned\n ? `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`\n : \"translate3d(0, -200%, 0)\",\n }}\n value={selectedDropdownValue}\n onValueChange={setSelectedDropdownValue}\n {...props}\n >\n <AiToolbarContainer\n state={state}\n dropdownRef={dropdownRef}\n toolbarRef={toolbarRef}\n >\n {typeof Suggestions === \"function\" ? (\n <Suggestions children={defaultSuggestions} />\n ) : (\n Suggestions\n )}\n </AiToolbarContainer>\n </Command>\n </Portal>\n </EditorProvider>\n </TooltipProvider>\n );\n }\n ),\n {\n /**\n * @beta\n *\n * A prompt suggestion displayed in the AI toolbar.\n */\n Suggestion: AiToolbarSuggestion,\n\n /**\n * @beta\n *\n * A label to describe a group of prompt suggestions displayed in the AI toolbar.\n */\n SuggestionsLabel: AiToolbarSuggestionsLabel,\n\n /**\n * @beta\n *\n * A separator between groups of prompt suggestions displayed in the AI toolbar.\n */\n SuggestionsSeparator: AiToolbarSuggestionsSeparator,\n }\n);\n"],"names":["customPrompt","state"],"mappings":"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"}
@@ -125,6 +125,7 @@ const Collaboration = core.Extension.create({
125
125
  });
126
126
  return false;
127
127
  }
128
+ return;
128
129
  });
129
130
  }
130
131
  return [
@@ -1 +1 @@
1
- {"version":3,"file":"collaboration.cjs","sources":["../../src/collaboration/collaboration.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\nimport {\n redo,\n undo,\n ySyncPlugin,\n yUndoPlugin,\n yUndoPluginKey,\n yXmlFragmentToProsemirrorJSON,\n} from \"y-prosemirror\";\nimport type { Doc, UndoManager, XmlFragment } from \"yjs\";\n\nimport {\n createMappablePosition,\n getUpdatedPosition,\n} from \"./helpers/CollaborationMappablePosition\";\n\ntype YSyncOpts = Parameters<typeof ySyncPlugin>[1];\ntype YUndoOpts = Parameters<typeof yUndoPlugin>[0];\n\nexport interface CollaborationStorage {\n /**\n * Whether collaboration is currently disabled.\n * Disabling collaboration will prevent any changes from being synced with other users.\n */\n isDisabled: boolean;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n collaboration: {\n /**\n * Undo recent changes\n * @example editor.commands.undo()\n */\n undo: () => ReturnType;\n /**\n * Reapply reverted changes\n * @example editor.commands.redo()\n */\n redo: () => ReturnType;\n };\n }\n\n interface Storage {\n collaboration: CollaborationStorage;\n }\n}\n\nexport interface CollaborationOptions {\n /**\n * An initialized Y.js document.\n * @example new Y.Doc()\n */\n document?: Doc | null;\n\n /**\n * Name of a Y.js fragment, can be changed to sync multiple fields with one Y.js document.\n * @default 'default'\n * @example 'my-custom-field'\n */\n field?: string;\n\n /**\n * A raw Y.js fragment, can be used instead of `document` and `field`.\n * @example new Y.Doc().getXmlFragment('body')\n */\n fragment?: XmlFragment | null;\n\n /**\n * The collaboration provider.\n * @default null\n */\n provider?: any | null;\n\n /**\n * Fired when the content from Yjs is initially rendered to Tiptap.\n */\n onFirstRender?: () => void;\n\n /**\n * Options for the Yjs sync plugin.\n */\n ySyncOptions?: YSyncOpts;\n\n /**\n * Options for the Yjs undo plugin.\n */\n yUndoOptions?: YUndoOpts;\n}\n\n/**\n * This extension allows you to collaborate with others in real-time.\n * @see https://tiptap.dev/api/extensions/collaboration\n */\nexport const Collaboration = Extension.create<\n CollaborationOptions,\n CollaborationStorage\n>({\n name: \"collaboration\",\n\n priority: 1000,\n\n addOptions() {\n return {\n document: null,\n field: \"default\",\n fragment: null,\n provider: null,\n };\n },\n\n addStorage() {\n return {\n isDisabled: false,\n };\n },\n\n onCreate() {\n if (\n this.editor.extensionManager.extensions.find(\n (extension) => extension.name === \"undoRedo\"\n )\n ) {\n console.warn(\n '[tiptap warn]: \"@tiptap/extension-collaboration\" comes with its own history support and is not compatible with \"@tiptap/extension-undo-redo\".'\n );\n }\n },\n\n onBeforeCreate() {\n this.editor.utils.getUpdatedPosition = (position, transaction) =>\n getUpdatedPosition(position, transaction, this.editor.state);\n this.editor.utils.createMappablePosition = (position) =>\n createMappablePosition(position, this.editor.state);\n },\n\n addCommands() {\n return {\n undo:\n () =>\n ({ tr, state, dispatch }) => {\n tr.setMeta(\"preventDispatch\", true);\n\n const undoManager: UndoManager =\n yUndoPluginKey.getState(state)!.undoManager;\n\n if (undoManager.undoStack.length === 0) {\n return false;\n }\n\n if (!dispatch) {\n return true;\n }\n\n return undo(state);\n },\n redo:\n () =>\n ({ tr, state, dispatch }) => {\n tr.setMeta(\"preventDispatch\", true);\n\n const undoManager: UndoManager =\n yUndoPluginKey.getState(state)!.undoManager;\n\n if (undoManager.redoStack.length === 0) {\n return false;\n }\n\n if (!dispatch) {\n return true;\n }\n\n return redo(state);\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n \"Mod-z\": () => this.editor.commands.undo(),\n \"Mod-y\": () => this.editor.commands.redo(),\n \"Shift-Mod-z\": () => this.editor.commands.redo(),\n };\n },\n\n addProseMirrorPlugins() {\n const fragment = this.options.fragment\n ? this.options.fragment\n : (this.options.document as Doc).getXmlFragment(this.options.field);\n\n // Quick fix until there is an official implementation (thanks to @hamflx).\n // See https://github.com/yjs/y-prosemirror/issues/114 and https://github.com/yjs/y-prosemirror/issues/102\n const yUndoPluginInstance = yUndoPlugin(this.options.yUndoOptions);\n const originalUndoPluginView = yUndoPluginInstance.spec.view;\n\n yUndoPluginInstance.spec.view = (view: EditorView) => {\n const { undoManager } = yUndoPluginKey.getState(view.state)!;\n\n if (\n \"restore\" in undoManager &&\n typeof undoManager.restore === \"function\"\n ) {\n undoManager.restore();\n undoManager.restore = () => {\n // noop\n };\n }\n\n const viewRet = originalUndoPluginView\n ? originalUndoPluginView(view)\n : undefined;\n\n return {\n destroy: () => {\n const hasUndoManSelf = undoManager.trackedOrigins.has(undoManager);\n // eslint-disable-next-line no-underscore-dangle\n const observers = undoManager._observers;\n\n if (\n \"restore\" in undoManager &&\n typeof undoManager.restore === \"function\"\n ) {\n undoManager.restore = () => {\n if (hasUndoManSelf) {\n undoManager.trackedOrigins.add(undoManager);\n }\n\n undoManager.doc.on(\n \"afterTransaction\",\n undoManager.afterTransactionHandler\n );\n // eslint-disable-next-line no-underscore-dangle\n undoManager._observers = observers;\n };\n }\n\n if (viewRet?.destroy) {\n viewRet.destroy();\n }\n },\n };\n };\n\n const ySyncPluginOptions: YSyncOpts = {\n ...this.options.ySyncOptions,\n onFirstRender: this.options.onFirstRender,\n };\n\n const ySyncPluginInstance = ySyncPlugin(fragment, ySyncPluginOptions);\n\n if (this.editor.options.enableContentCheck) {\n fragment.doc?.on(\"beforeTransaction\", () => {\n try {\n const jsonContent = yXmlFragmentToProsemirrorJSON(fragment);\n\n if (jsonContent.content.length === 0) {\n return;\n }\n\n this.editor.schema.nodeFromJSON(jsonContent).check();\n } catch (error) {\n this.editor.emit(\"contentError\", {\n error: error as Error,\n editor: this.editor,\n disableCollaboration: () => {\n fragment.doc?.destroy();\n this.storage.isDisabled = true;\n },\n });\n // If the content is invalid, return false to prevent the transaction from being applied\n return false;\n }\n });\n }\n\n return [\n ySyncPluginInstance,\n yUndoPluginInstance,\n // Only add the filterInvalidContent plugin if content checking is enabled\n this.editor.options.enableContentCheck &&\n new Plugin({\n key: new PluginKey(\"filterInvalidContent\"),\n filterTransaction: () => {\n // When collaboration is disabled, prevent any sync transactions from being applied\n if (this.storage.isDisabled !== false) {\n // Destroy the Yjs document to prevent any further sync transactions\n fragment.doc?.destroy();\n\n return true;\n }\n // TODO should we be returning false when the transaction is a collaboration transaction?\n\n return true;\n },\n }),\n ].filter(Boolean);\n },\n});\n"],"names":["Extension","getUpdatedPosition","createMappablePosition","yUndoPluginKey","undo","redo","yUndoPlugin","ySyncPlugin","yXmlFragmentToProsemirrorJSON","Plugin","PluginKey"],"mappings":"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"}
1
+ {"version":3,"file":"collaboration.cjs","sources":["../../src/collaboration/collaboration.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\nimport {\n redo,\n undo,\n ySyncPlugin,\n yUndoPlugin,\n yUndoPluginKey,\n yXmlFragmentToProsemirrorJSON,\n} from \"y-prosemirror\";\nimport type { Doc, UndoManager, XmlFragment } from \"yjs\";\n\nimport {\n createMappablePosition,\n getUpdatedPosition,\n} from \"./helpers/CollaborationMappablePosition\";\n\ntype YSyncOpts = Parameters<typeof ySyncPlugin>[1];\ntype YUndoOpts = Parameters<typeof yUndoPlugin>[0];\n\nexport interface CollaborationStorage {\n /**\n * Whether collaboration is currently disabled.\n * Disabling collaboration will prevent any changes from being synced with other users.\n */\n isDisabled: boolean;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n collaboration: {\n /**\n * Undo recent changes\n * @example editor.commands.undo()\n */\n undo: () => ReturnType;\n /**\n * Reapply reverted changes\n * @example editor.commands.redo()\n */\n redo: () => ReturnType;\n };\n }\n\n interface Storage {\n collaboration: CollaborationStorage;\n }\n}\n\nexport interface CollaborationOptions {\n /**\n * An initialized Y.js document.\n * @example new Y.Doc()\n */\n document?: Doc | null;\n\n /**\n * Name of a Y.js fragment, can be changed to sync multiple fields with one Y.js document.\n * @default 'default'\n * @example 'my-custom-field'\n */\n field?: string;\n\n /**\n * A raw Y.js fragment, can be used instead of `document` and `field`.\n * @example new Y.Doc().getXmlFragment('body')\n */\n fragment?: XmlFragment | null;\n\n /**\n * The collaboration provider.\n * @default null\n */\n provider?: any | null;\n\n /**\n * Fired when the content from Yjs is initially rendered to Tiptap.\n */\n onFirstRender?: () => void;\n\n /**\n * Options for the Yjs sync plugin.\n */\n ySyncOptions?: YSyncOpts;\n\n /**\n * Options for the Yjs undo plugin.\n */\n yUndoOptions?: YUndoOpts;\n}\n\n/**\n * This extension allows you to collaborate with others in real-time.\n * @see https://tiptap.dev/api/extensions/collaboration\n */\nexport const Collaboration = Extension.create<\n CollaborationOptions,\n CollaborationStorage\n>({\n name: \"collaboration\",\n\n priority: 1000,\n\n addOptions() {\n return {\n document: null,\n field: \"default\",\n fragment: null,\n provider: null,\n };\n },\n\n addStorage() {\n return {\n isDisabled: false,\n };\n },\n\n onCreate() {\n if (\n this.editor.extensionManager.extensions.find(\n (extension) => extension.name === \"undoRedo\"\n )\n ) {\n console.warn(\n '[tiptap warn]: \"@tiptap/extension-collaboration\" comes with its own history support and is not compatible with \"@tiptap/extension-undo-redo\".'\n );\n }\n },\n\n onBeforeCreate() {\n this.editor.utils.getUpdatedPosition = (position, transaction) =>\n getUpdatedPosition(position, transaction, this.editor.state);\n this.editor.utils.createMappablePosition = (position) =>\n createMappablePosition(position, this.editor.state);\n },\n\n addCommands() {\n return {\n undo:\n () =>\n ({ tr, state, dispatch }) => {\n tr.setMeta(\"preventDispatch\", true);\n\n const undoManager: UndoManager =\n yUndoPluginKey.getState(state)!.undoManager;\n\n if (undoManager.undoStack.length === 0) {\n return false;\n }\n\n if (!dispatch) {\n return true;\n }\n\n return undo(state);\n },\n redo:\n () =>\n ({ tr, state, dispatch }) => {\n tr.setMeta(\"preventDispatch\", true);\n\n const undoManager: UndoManager =\n yUndoPluginKey.getState(state)!.undoManager;\n\n if (undoManager.redoStack.length === 0) {\n return false;\n }\n\n if (!dispatch) {\n return true;\n }\n\n return redo(state);\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n \"Mod-z\": () => this.editor.commands.undo(),\n \"Mod-y\": () => this.editor.commands.redo(),\n \"Shift-Mod-z\": () => this.editor.commands.redo(),\n };\n },\n\n addProseMirrorPlugins() {\n const fragment = this.options.fragment\n ? this.options.fragment\n : (this.options.document as Doc).getXmlFragment(this.options.field);\n\n // Quick fix until there is an official implementation (thanks to @hamflx).\n // See https://github.com/yjs/y-prosemirror/issues/114 and https://github.com/yjs/y-prosemirror/issues/102\n const yUndoPluginInstance = yUndoPlugin(this.options.yUndoOptions);\n const originalUndoPluginView = yUndoPluginInstance.spec.view;\n\n yUndoPluginInstance.spec.view = (view: EditorView) => {\n const { undoManager } = yUndoPluginKey.getState(view.state)!;\n\n if (\n \"restore\" in undoManager &&\n typeof undoManager.restore === \"function\"\n ) {\n undoManager.restore();\n undoManager.restore = () => {\n // noop\n };\n }\n\n const viewRet = originalUndoPluginView\n ? originalUndoPluginView(view)\n : undefined;\n\n return {\n destroy: () => {\n const hasUndoManSelf = undoManager.trackedOrigins.has(undoManager);\n const observers = undoManager._observers;\n\n if (\n \"restore\" in undoManager &&\n typeof undoManager.restore === \"function\"\n ) {\n undoManager.restore = () => {\n if (hasUndoManSelf) {\n undoManager.trackedOrigins.add(undoManager);\n }\n\n undoManager.doc.on(\n \"afterTransaction\",\n undoManager.afterTransactionHandler\n );\n undoManager._observers = observers;\n };\n }\n\n if (viewRet?.destroy) {\n viewRet.destroy();\n }\n },\n };\n };\n\n const ySyncPluginOptions: YSyncOpts = {\n ...this.options.ySyncOptions,\n onFirstRender: this.options.onFirstRender,\n };\n\n const ySyncPluginInstance = ySyncPlugin(fragment, ySyncPluginOptions);\n\n if (this.editor.options.enableContentCheck) {\n fragment.doc?.on(\"beforeTransaction\", () => {\n try {\n const jsonContent = yXmlFragmentToProsemirrorJSON(fragment);\n\n if (jsonContent.content.length === 0) {\n return;\n }\n\n this.editor.schema.nodeFromJSON(jsonContent).check();\n } catch (error) {\n this.editor.emit(\"contentError\", {\n error: error as Error,\n editor: this.editor,\n disableCollaboration: () => {\n fragment.doc?.destroy();\n this.storage.isDisabled = true;\n },\n });\n // If the content is invalid, return false to prevent the transaction from being applied\n return false;\n }\n return;\n });\n }\n\n return [\n ySyncPluginInstance,\n yUndoPluginInstance,\n // Only add the filterInvalidContent plugin if content checking is enabled\n this.editor.options.enableContentCheck &&\n new Plugin({\n key: new PluginKey(\"filterInvalidContent\"),\n filterTransaction: () => {\n // When collaboration is disabled, prevent any sync transactions from being applied\n if (this.storage.isDisabled !== false) {\n // Destroy the Yjs document to prevent any further sync transactions\n fragment.doc?.destroy();\n\n return true;\n }\n // TODO should we be returning false when the transaction is a collaboration transaction?\n\n return true;\n },\n }),\n ].filter(Boolean);\n },\n});\n"],"names":["Extension","getUpdatedPosition","createMappablePosition","yUndoPluginKey","undo","redo","yUndoPlugin","ySyncPlugin","yXmlFragmentToProsemirrorJSON","Plugin","PluginKey"],"mappings":"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"}
@@ -123,6 +123,7 @@ const Collaboration = Extension.create({
123
123
  });
124
124
  return false;
125
125
  }
126
+ return;
126
127
  });
127
128
  }
128
129
  return [
@@ -1 +1 @@
1
- {"version":3,"file":"collaboration.js","sources":["../../src/collaboration/collaboration.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\nimport {\n redo,\n undo,\n ySyncPlugin,\n yUndoPlugin,\n yUndoPluginKey,\n yXmlFragmentToProsemirrorJSON,\n} from \"y-prosemirror\";\nimport type { Doc, UndoManager, XmlFragment } from \"yjs\";\n\nimport {\n createMappablePosition,\n getUpdatedPosition,\n} from \"./helpers/CollaborationMappablePosition\";\n\ntype YSyncOpts = Parameters<typeof ySyncPlugin>[1];\ntype YUndoOpts = Parameters<typeof yUndoPlugin>[0];\n\nexport interface CollaborationStorage {\n /**\n * Whether collaboration is currently disabled.\n * Disabling collaboration will prevent any changes from being synced with other users.\n */\n isDisabled: boolean;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n collaboration: {\n /**\n * Undo recent changes\n * @example editor.commands.undo()\n */\n undo: () => ReturnType;\n /**\n * Reapply reverted changes\n * @example editor.commands.redo()\n */\n redo: () => ReturnType;\n };\n }\n\n interface Storage {\n collaboration: CollaborationStorage;\n }\n}\n\nexport interface CollaborationOptions {\n /**\n * An initialized Y.js document.\n * @example new Y.Doc()\n */\n document?: Doc | null;\n\n /**\n * Name of a Y.js fragment, can be changed to sync multiple fields with one Y.js document.\n * @default 'default'\n * @example 'my-custom-field'\n */\n field?: string;\n\n /**\n * A raw Y.js fragment, can be used instead of `document` and `field`.\n * @example new Y.Doc().getXmlFragment('body')\n */\n fragment?: XmlFragment | null;\n\n /**\n * The collaboration provider.\n * @default null\n */\n provider?: any | null;\n\n /**\n * Fired when the content from Yjs is initially rendered to Tiptap.\n */\n onFirstRender?: () => void;\n\n /**\n * Options for the Yjs sync plugin.\n */\n ySyncOptions?: YSyncOpts;\n\n /**\n * Options for the Yjs undo plugin.\n */\n yUndoOptions?: YUndoOpts;\n}\n\n/**\n * This extension allows you to collaborate with others in real-time.\n * @see https://tiptap.dev/api/extensions/collaboration\n */\nexport const Collaboration = Extension.create<\n CollaborationOptions,\n CollaborationStorage\n>({\n name: \"collaboration\",\n\n priority: 1000,\n\n addOptions() {\n return {\n document: null,\n field: \"default\",\n fragment: null,\n provider: null,\n };\n },\n\n addStorage() {\n return {\n isDisabled: false,\n };\n },\n\n onCreate() {\n if (\n this.editor.extensionManager.extensions.find(\n (extension) => extension.name === \"undoRedo\"\n )\n ) {\n console.warn(\n '[tiptap warn]: \"@tiptap/extension-collaboration\" comes with its own history support and is not compatible with \"@tiptap/extension-undo-redo\".'\n );\n }\n },\n\n onBeforeCreate() {\n this.editor.utils.getUpdatedPosition = (position, transaction) =>\n getUpdatedPosition(position, transaction, this.editor.state);\n this.editor.utils.createMappablePosition = (position) =>\n createMappablePosition(position, this.editor.state);\n },\n\n addCommands() {\n return {\n undo:\n () =>\n ({ tr, state, dispatch }) => {\n tr.setMeta(\"preventDispatch\", true);\n\n const undoManager: UndoManager =\n yUndoPluginKey.getState(state)!.undoManager;\n\n if (undoManager.undoStack.length === 0) {\n return false;\n }\n\n if (!dispatch) {\n return true;\n }\n\n return undo(state);\n },\n redo:\n () =>\n ({ tr, state, dispatch }) => {\n tr.setMeta(\"preventDispatch\", true);\n\n const undoManager: UndoManager =\n yUndoPluginKey.getState(state)!.undoManager;\n\n if (undoManager.redoStack.length === 0) {\n return false;\n }\n\n if (!dispatch) {\n return true;\n }\n\n return redo(state);\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n \"Mod-z\": () => this.editor.commands.undo(),\n \"Mod-y\": () => this.editor.commands.redo(),\n \"Shift-Mod-z\": () => this.editor.commands.redo(),\n };\n },\n\n addProseMirrorPlugins() {\n const fragment = this.options.fragment\n ? this.options.fragment\n : (this.options.document as Doc).getXmlFragment(this.options.field);\n\n // Quick fix until there is an official implementation (thanks to @hamflx).\n // See https://github.com/yjs/y-prosemirror/issues/114 and https://github.com/yjs/y-prosemirror/issues/102\n const yUndoPluginInstance = yUndoPlugin(this.options.yUndoOptions);\n const originalUndoPluginView = yUndoPluginInstance.spec.view;\n\n yUndoPluginInstance.spec.view = (view: EditorView) => {\n const { undoManager } = yUndoPluginKey.getState(view.state)!;\n\n if (\n \"restore\" in undoManager &&\n typeof undoManager.restore === \"function\"\n ) {\n undoManager.restore();\n undoManager.restore = () => {\n // noop\n };\n }\n\n const viewRet = originalUndoPluginView\n ? originalUndoPluginView(view)\n : undefined;\n\n return {\n destroy: () => {\n const hasUndoManSelf = undoManager.trackedOrigins.has(undoManager);\n // eslint-disable-next-line no-underscore-dangle\n const observers = undoManager._observers;\n\n if (\n \"restore\" in undoManager &&\n typeof undoManager.restore === \"function\"\n ) {\n undoManager.restore = () => {\n if (hasUndoManSelf) {\n undoManager.trackedOrigins.add(undoManager);\n }\n\n undoManager.doc.on(\n \"afterTransaction\",\n undoManager.afterTransactionHandler\n );\n // eslint-disable-next-line no-underscore-dangle\n undoManager._observers = observers;\n };\n }\n\n if (viewRet?.destroy) {\n viewRet.destroy();\n }\n },\n };\n };\n\n const ySyncPluginOptions: YSyncOpts = {\n ...this.options.ySyncOptions,\n onFirstRender: this.options.onFirstRender,\n };\n\n const ySyncPluginInstance = ySyncPlugin(fragment, ySyncPluginOptions);\n\n if (this.editor.options.enableContentCheck) {\n fragment.doc?.on(\"beforeTransaction\", () => {\n try {\n const jsonContent = yXmlFragmentToProsemirrorJSON(fragment);\n\n if (jsonContent.content.length === 0) {\n return;\n }\n\n this.editor.schema.nodeFromJSON(jsonContent).check();\n } catch (error) {\n this.editor.emit(\"contentError\", {\n error: error as Error,\n editor: this.editor,\n disableCollaboration: () => {\n fragment.doc?.destroy();\n this.storage.isDisabled = true;\n },\n });\n // If the content is invalid, return false to prevent the transaction from being applied\n return false;\n }\n });\n }\n\n return [\n ySyncPluginInstance,\n yUndoPluginInstance,\n // Only add the filterInvalidContent plugin if content checking is enabled\n this.editor.options.enableContentCheck &&\n new Plugin({\n key: new PluginKey(\"filterInvalidContent\"),\n filterTransaction: () => {\n // When collaboration is disabled, prevent any sync transactions from being applied\n if (this.storage.isDisabled !== false) {\n // Destroy the Yjs document to prevent any further sync transactions\n fragment.doc?.destroy();\n\n return true;\n }\n // TODO should we be returning false when the transaction is a collaboration transaction?\n\n return true;\n },\n }),\n ].filter(Boolean);\n },\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collaboration.js","sources":["../../src/collaboration/collaboration.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\nimport {\n redo,\n undo,\n ySyncPlugin,\n yUndoPlugin,\n yUndoPluginKey,\n yXmlFragmentToProsemirrorJSON,\n} from \"y-prosemirror\";\nimport type { Doc, UndoManager, XmlFragment } from \"yjs\";\n\nimport {\n createMappablePosition,\n getUpdatedPosition,\n} from \"./helpers/CollaborationMappablePosition\";\n\ntype YSyncOpts = Parameters<typeof ySyncPlugin>[1];\ntype YUndoOpts = Parameters<typeof yUndoPlugin>[0];\n\nexport interface CollaborationStorage {\n /**\n * Whether collaboration is currently disabled.\n * Disabling collaboration will prevent any changes from being synced with other users.\n */\n isDisabled: boolean;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n collaboration: {\n /**\n * Undo recent changes\n * @example editor.commands.undo()\n */\n undo: () => ReturnType;\n /**\n * Reapply reverted changes\n * @example editor.commands.redo()\n */\n redo: () => ReturnType;\n };\n }\n\n interface Storage {\n collaboration: CollaborationStorage;\n }\n}\n\nexport interface CollaborationOptions {\n /**\n * An initialized Y.js document.\n * @example new Y.Doc()\n */\n document?: Doc | null;\n\n /**\n * Name of a Y.js fragment, can be changed to sync multiple fields with one Y.js document.\n * @default 'default'\n * @example 'my-custom-field'\n */\n field?: string;\n\n /**\n * A raw Y.js fragment, can be used instead of `document` and `field`.\n * @example new Y.Doc().getXmlFragment('body')\n */\n fragment?: XmlFragment | null;\n\n /**\n * The collaboration provider.\n * @default null\n */\n provider?: any | null;\n\n /**\n * Fired when the content from Yjs is initially rendered to Tiptap.\n */\n onFirstRender?: () => void;\n\n /**\n * Options for the Yjs sync plugin.\n */\n ySyncOptions?: YSyncOpts;\n\n /**\n * Options for the Yjs undo plugin.\n */\n yUndoOptions?: YUndoOpts;\n}\n\n/**\n * This extension allows you to collaborate with others in real-time.\n * @see https://tiptap.dev/api/extensions/collaboration\n */\nexport const Collaboration = Extension.create<\n CollaborationOptions,\n CollaborationStorage\n>({\n name: \"collaboration\",\n\n priority: 1000,\n\n addOptions() {\n return {\n document: null,\n field: \"default\",\n fragment: null,\n provider: null,\n };\n },\n\n addStorage() {\n return {\n isDisabled: false,\n };\n },\n\n onCreate() {\n if (\n this.editor.extensionManager.extensions.find(\n (extension) => extension.name === \"undoRedo\"\n )\n ) {\n console.warn(\n '[tiptap warn]: \"@tiptap/extension-collaboration\" comes with its own history support and is not compatible with \"@tiptap/extension-undo-redo\".'\n );\n }\n },\n\n onBeforeCreate() {\n this.editor.utils.getUpdatedPosition = (position, transaction) =>\n getUpdatedPosition(position, transaction, this.editor.state);\n this.editor.utils.createMappablePosition = (position) =>\n createMappablePosition(position, this.editor.state);\n },\n\n addCommands() {\n return {\n undo:\n () =>\n ({ tr, state, dispatch }) => {\n tr.setMeta(\"preventDispatch\", true);\n\n const undoManager: UndoManager =\n yUndoPluginKey.getState(state)!.undoManager;\n\n if (undoManager.undoStack.length === 0) {\n return false;\n }\n\n if (!dispatch) {\n return true;\n }\n\n return undo(state);\n },\n redo:\n () =>\n ({ tr, state, dispatch }) => {\n tr.setMeta(\"preventDispatch\", true);\n\n const undoManager: UndoManager =\n yUndoPluginKey.getState(state)!.undoManager;\n\n if (undoManager.redoStack.length === 0) {\n return false;\n }\n\n if (!dispatch) {\n return true;\n }\n\n return redo(state);\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n \"Mod-z\": () => this.editor.commands.undo(),\n \"Mod-y\": () => this.editor.commands.redo(),\n \"Shift-Mod-z\": () => this.editor.commands.redo(),\n };\n },\n\n addProseMirrorPlugins() {\n const fragment = this.options.fragment\n ? this.options.fragment\n : (this.options.document as Doc).getXmlFragment(this.options.field);\n\n // Quick fix until there is an official implementation (thanks to @hamflx).\n // See https://github.com/yjs/y-prosemirror/issues/114 and https://github.com/yjs/y-prosemirror/issues/102\n const yUndoPluginInstance = yUndoPlugin(this.options.yUndoOptions);\n const originalUndoPluginView = yUndoPluginInstance.spec.view;\n\n yUndoPluginInstance.spec.view = (view: EditorView) => {\n const { undoManager } = yUndoPluginKey.getState(view.state)!;\n\n if (\n \"restore\" in undoManager &&\n typeof undoManager.restore === \"function\"\n ) {\n undoManager.restore();\n undoManager.restore = () => {\n // noop\n };\n }\n\n const viewRet = originalUndoPluginView\n ? originalUndoPluginView(view)\n : undefined;\n\n return {\n destroy: () => {\n const hasUndoManSelf = undoManager.trackedOrigins.has(undoManager);\n const observers = undoManager._observers;\n\n if (\n \"restore\" in undoManager &&\n typeof undoManager.restore === \"function\"\n ) {\n undoManager.restore = () => {\n if (hasUndoManSelf) {\n undoManager.trackedOrigins.add(undoManager);\n }\n\n undoManager.doc.on(\n \"afterTransaction\",\n undoManager.afterTransactionHandler\n );\n undoManager._observers = observers;\n };\n }\n\n if (viewRet?.destroy) {\n viewRet.destroy();\n }\n },\n };\n };\n\n const ySyncPluginOptions: YSyncOpts = {\n ...this.options.ySyncOptions,\n onFirstRender: this.options.onFirstRender,\n };\n\n const ySyncPluginInstance = ySyncPlugin(fragment, ySyncPluginOptions);\n\n if (this.editor.options.enableContentCheck) {\n fragment.doc?.on(\"beforeTransaction\", () => {\n try {\n const jsonContent = yXmlFragmentToProsemirrorJSON(fragment);\n\n if (jsonContent.content.length === 0) {\n return;\n }\n\n this.editor.schema.nodeFromJSON(jsonContent).check();\n } catch (error) {\n this.editor.emit(\"contentError\", {\n error: error as Error,\n editor: this.editor,\n disableCollaboration: () => {\n fragment.doc?.destroy();\n this.storage.isDisabled = true;\n },\n });\n // If the content is invalid, return false to prevent the transaction from being applied\n return false;\n }\n return;\n });\n }\n\n return [\n ySyncPluginInstance,\n yUndoPluginInstance,\n // Only add the filterInvalidContent plugin if content checking is enabled\n this.editor.options.enableContentCheck &&\n new Plugin({\n key: new PluginKey(\"filterInvalidContent\"),\n filterTransaction: () => {\n // When collaboration is disabled, prevent any sync transactions from being applied\n if (this.storage.isDisabled !== false) {\n // Destroy the Yjs document to prevent any further sync transactions\n fragment.doc?.destroy();\n\n return true;\n }\n // TODO should we be returning false when the transaction is a collaboration transaction?\n\n return true;\n },\n }),\n ].filter(Boolean);\n },\n});\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"isChangeOrigin.cjs","sources":["../../../src/collaboration/helpers/isChangeOrigin.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { ySyncPluginKey } from \"y-prosemirror\";\n\n/**\n * Checks if a transaction was originated from a Yjs change.\n * @param {Transaction} transaction - The transaction to check.\n * @returns {boolean} - True if the transaction was originated from a Yjs change, false otherwise.\n * @example\n * const transaction = new Transaction(doc)\n * const isOrigin = isChangeOrigin(transaction) // returns false\n */\nexport function isChangeOrigin(transaction: Transaction): boolean {\n return !!transaction.getMeta(ySyncPluginKey);\n}\n"],"names":["ySyncPluginKey"],"mappings":";;;;AAyBO,SAAS,eAAe,WAAmC,EAAA;AAChE,EAAA,OAAO,CAAC,CAAC,WAAY,CAAA,OAAA,CAAQA,2BAAc,CAAA,CAAA;AAC7C;;;;"}
1
+ {"version":3,"file":"isChangeOrigin.cjs","sources":["../../../src/collaboration/helpers/isChangeOrigin.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { ySyncPluginKey } from \"y-prosemirror\";\n\n/**\n * Checks if a transaction was originated from a Yjs change.\n * @param {Transaction} transaction - The transaction to check.\n * @returns {boolean} - True if the transaction was originated from a Yjs change, false otherwise.\n * @example\n * const transaction = new Transaction(doc)\n * const isOrigin = isChangeOrigin(transaction) // returns false\n */\nexport function isChangeOrigin(transaction: Transaction): boolean {\n return !!transaction.getMeta(ySyncPluginKey);\n}\n"],"names":["ySyncPluginKey"],"mappings":";;;;AAyBO,SAAS,eAAe,WAAmC,EAAA;AAChE,EAAA,OAAO,CAAC,CAAC,WAAY,CAAA,OAAA,CAAQA,2BAAc,CAAA,CAAA;AAC7C;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"isChangeOrigin.js","sources":["../../../src/collaboration/helpers/isChangeOrigin.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { ySyncPluginKey } from \"y-prosemirror\";\n\n/**\n * Checks if a transaction was originated from a Yjs change.\n * @param {Transaction} transaction - The transaction to check.\n * @returns {boolean} - True if the transaction was originated from a Yjs change, false otherwise.\n * @example\n * const transaction = new Transaction(doc)\n * const isOrigin = isChangeOrigin(transaction) // returns false\n */\nexport function isChangeOrigin(transaction: Transaction): boolean {\n return !!transaction.getMeta(ySyncPluginKey);\n}\n"],"names":[],"mappings":";;AAyBO,SAAS,eAAe,WAAmC,EAAA;AAChE,EAAA,OAAO,CAAC,CAAC,WAAY,CAAA,OAAA,CAAQ,cAAc,CAAA,CAAA;AAC7C;;;;"}
1
+ {"version":3,"file":"isChangeOrigin.js","sources":["../../../src/collaboration/helpers/isChangeOrigin.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { ySyncPluginKey } from \"y-prosemirror\";\n\n/**\n * Checks if a transaction was originated from a Yjs change.\n * @param {Transaction} transaction - The transaction to check.\n * @returns {boolean} - True if the transaction was originated from a Yjs change, false otherwise.\n * @example\n * const transaction = new Transaction(doc)\n * const isOrigin = isChangeOrigin(transaction) // returns false\n */\nexport function isChangeOrigin(transaction: Transaction): boolean {\n return !!transaction.getMeta(ySyncPluginKey);\n}\n"],"names":[],"mappings":";;AAyBO,SAAS,eAAe,WAAmC,EAAA;AAChE,EAAA,OAAO,CAAC,CAAC,WAAY,CAAA,OAAA,CAAQ,cAAc,CAAA,CAAA;AAC7C;;;;"}
@@ -29,16 +29,14 @@ function AnchoredThreads({
29
29
  const { pluginState } = react$1.useEditorState({
30
30
  editor,
31
31
  selector: (ctx) => {
32
- if (!ctx?.editor?.state)
33
- return { pluginState: void 0 };
32
+ if (!ctx?.editor?.state) return { pluginState: void 0 };
34
33
  const state = types.THREADS_PLUGIN_KEY.getState(ctx.editor.state);
35
34
  return {
36
35
  pluginState: state
37
36
  };
38
37
  },
39
38
  equalityFn: (prev, next) => {
40
- if (!prev || !next)
41
- return false;
39
+ if (!prev || !next) return false;
42
40
  return prev.pluginState?.selectedThreadId === next.pluginState?.selectedThreadId && prev.pluginState?.threadPositions === next.pluginState?.threadPositions;
43
41
  }
44
42
  }) ?? { pluginState: void 0 };
@@ -61,8 +59,7 @@ function AnchoredThreads({
61
59
  let top = rect.top - container.getBoundingClientRect().top;
62
60
  for (const [id, position2] of newPositions) {
63
61
  const el = elements.get(id);
64
- if (el === void 0)
65
- continue;
62
+ if (el === void 0) continue;
66
63
  if (top >= position2 && top <= position2 + el.getBoundingClientRect().height) {
67
64
  top = position2 + el.getBoundingClientRect().height;
68
65
  }
@@ -73,8 +70,7 @@ function AnchoredThreads({
73
70
  const coords = editor.view.coordsAtPos(position.from);
74
71
  const rect = utils.getRectFromCoords(coords);
75
72
  const el = elements.get(thread.id);
76
- if (el === void 0)
77
- continue;
73
+ if (el === void 0) continue;
78
74
  let top = rect.top - container.getBoundingClientRect().top;
79
75
  for (const [, position2] of newPositions) {
80
76
  if (top >= position2 - el.getBoundingClientRect().height) {
@@ -86,8 +82,7 @@ function AnchoredThreads({
86
82
  setPositions(newPositions);
87
83
  }, [editor, orderedThreads, pluginState?.selectedThreadId, elements]);
88
84
  react.useEffect(() => {
89
- if (!pluginState)
90
- return;
85
+ if (!pluginState) return;
91
86
  setOrderedThreads(
92
87
  Array.from(pluginState.threadPositions, ([threadId, position]) => ({
93
88
  threadId,
@@ -97,8 +92,7 @@ function AnchoredThreads({
97
92
  const thread = threads.find(
98
93
  (thread2) => thread2.id === threadId && !thread2.resolved
99
94
  );
100
- if (!thread)
101
- return acc;
95
+ if (!thread) return acc;
102
96
  acc.push({ thread, position });
103
97
  return acc;
104
98
  },
@@ -131,14 +125,12 @@ function AnchoredThreads({
131
125
  }, []);
132
126
  const onThreadSelect = react.useCallback(
133
127
  (id) => {
134
- if (!editor)
135
- return;
128
+ if (!editor) return;
136
129
  editor.commands.selectThread(id);
137
130
  },
138
131
  [editor]
139
132
  );
140
- if (!editor)
141
- return null;
133
+ if (!editor) return null;
142
134
  return /* @__PURE__ */ jsxRuntime.jsx(
143
135
  "div",
144
136
  {
@@ -199,8 +191,7 @@ function ThreadWrapper({
199
191
  const divRef = react.useRef(null);
200
192
  _private$1.useLayoutEffect(() => {
201
193
  const el = divRef.current;
202
- if (el === null)
203
- return;
194
+ if (el === null) return;
204
195
  onItemAdd(thread.id, el);
205
196
  return () => {
206
197
  onItemRemove(thread.id);
@@ -1 +1 @@
1
- {"version":3,"file":"AnchoredThreads.cjs","sources":["../../src/comments/AnchoredThreads.tsx"],"sourcesContent":["import type { BaseMetadata, DCM, DTM, ThreadData } from \"@liveblocks/core\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport { cn, useStableComponent } from \"@liveblocks/react-ui/_private\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport type { ComponentPropsWithoutRef, ComponentType } from \"react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { THREADS_PLUGIN_KEY } from \"../types\";\nimport { getRectFromCoords } from \"../utils\";\n\nconst DEFAULT_GAP = 20;\nconst DEFAULT_ACTIVE_THREAD_OFFSET = -12;\n\n// TODO: move that back to a variable\nconst GAP = `var(--lb-tiptap-anchored-threads-gap, ${DEFAULT_GAP}px)`;\nconst ACTIVE_THREAD_OFFSET = `var(--lb-tiptap-anchored-threads-active-thread-offset, ${DEFAULT_ACTIVE_THREAD_OFFSET}px)`;\n\ntype AnchoredThreadsComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface AnchoredThreadsProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<TM, CM>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<AnchoredThreadsComponents>;\n\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n}\n\nexport function AnchoredThreads({\n threads,\n components,\n className,\n style,\n editor,\n ...props\n}: AnchoredThreadsProps) {\n const Thread = useStableComponent(components?.Thread, DefaultThread);\n const containerRef = useRef<HTMLDivElement>(null);\n const [orderedThreads, setOrderedThreads] = useState<\n { position: { from: number; to: number }; thread: ThreadData }[]\n >([]);\n const [elements, setElements] = useState<Map<string, HTMLElement>>(new Map());\n const [positions, setPositions] = useState<Map<string, number>>(new Map()); // A map of thread ids to their 'top' position in the document\n\n const { pluginState } = useEditorState({\n editor,\n selector: (ctx) => {\n if (!ctx?.editor?.state) return { pluginState: undefined };\n const state = THREADS_PLUGIN_KEY.getState(ctx.editor.state);\n return {\n pluginState: state,\n };\n },\n equalityFn: (prev, next) => {\n if (!prev || !next) return false;\n return (\n prev.pluginState?.selectedThreadId ===\n next.pluginState?.selectedThreadId &&\n prev.pluginState?.threadPositions === next.pluginState?.threadPositions\n ); // new map is made each time threadPos updates so shallow equality is fine\n },\n }) ?? { pluginState: undefined };\n\n // TODO: lexical supoprts multiple threads being active, should probably do that here as well\n const handlePositionThreads = useCallback(() => {\n const container = containerRef.current;\n if (\n container === null ||\n !editor ||\n !editor.view ||\n editor.view.isDestroyed\n ) {\n return;\n }\n\n const activeIndex = orderedThreads.findIndex(\n ({ thread }) => thread.id === pluginState?.selectedThreadId\n );\n const ascending =\n activeIndex !== -1 ? orderedThreads.slice(activeIndex) : orderedThreads;\n const descending =\n activeIndex !== -1 ? orderedThreads.slice(0, activeIndex) : [];\n\n const newPositions = new Map<string, number>();\n\n // Iterate over each thread and calculate its new position by taking into account the position of the previously positioned threads\n for (const { thread, position } of ascending) {\n const coords = editor.view.coordsAtPos(\n Math.min(position.from, editor.view.state.doc.content.size - 1)\n );\n const rect = getRectFromCoords(coords);\n let top = rect.top - container.getBoundingClientRect().top;\n\n for (const [id, position] of newPositions) {\n // Retrieve the element associated with the thread\n const el = elements.get(id);\n if (el === undefined) continue;\n\n if (\n top >= position &&\n top <= position + el.getBoundingClientRect().height\n ) {\n top = position + el.getBoundingClientRect().height;\n }\n }\n\n newPositions.set(thread.id, top);\n }\n\n for (const { thread, position } of descending.reverse()) {\n const coords = editor.view.coordsAtPos(position.from);\n const rect = getRectFromCoords(coords);\n // Retrieve the element associated with the current thread\n const el = elements.get(thread.id);\n if (el === undefined) continue;\n\n let top = rect.top - container.getBoundingClientRect().top;\n for (const [, position] of newPositions) {\n if (top >= position - el.getBoundingClientRect().height) {\n top = position - el.getBoundingClientRect().height;\n }\n }\n\n newPositions.set(thread.id, top);\n }\n\n setPositions(newPositions);\n }, [editor, orderedThreads, pluginState?.selectedThreadId, elements]);\n\n useEffect(() => {\n if (!pluginState) return;\n setOrderedThreads(\n Array.from(pluginState.threadPositions, ([threadId, position]) => ({\n threadId,\n position,\n })).reduce(\n (acc, { threadId, position }) => {\n const thread = threads.find(\n (thread) => thread.id === threadId && !thread.resolved\n );\n if (!thread) return acc;\n acc.push({ thread, position });\n return acc;\n },\n [] as { thread: ThreadData; position: { from: number; to: number } }[]\n )\n );\n handlePositionThreads();\n // disable exhaustive deps because we don't want an infinite loop\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pluginState, threads]);\n\n useLayoutEffect(handlePositionThreads, [handlePositionThreads]);\n\n useEffect(() => {\n const observer = new ResizeObserver(handlePositionThreads);\n const container = editor?.view?.dom;\n if (container) {\n observer.observe(container);\n }\n for (const element of elements.values()) {\n observer.observe(element);\n }\n\n return () => observer.disconnect();\n }, [elements, editor, handlePositionThreads]);\n\n const onItemAdd = useCallback((id: string, el: HTMLElement) => {\n setElements((prev) => new Map(prev).set(id, el));\n }, []);\n\n const onItemRemove = useCallback((id: string) => {\n setElements((prev) => {\n const items = new Map(prev);\n items.delete(id);\n return items;\n });\n }, []);\n\n const onThreadSelect = useCallback(\n (id: string) => {\n if (!editor) return;\n editor.commands.selectThread(id);\n },\n [editor]\n );\n\n if (!editor) return null;\n\n return (\n <div\n {...props}\n className={cn(className, \"lb-root lb-tiptap-anchored-threads\")}\n ref={containerRef}\n style={{\n position: \"relative\",\n ...style,\n }}\n >\n {orderedThreads.map(({ thread, position }) => {\n // In blocknote, it's possible for this to be undefined\n if (!editor.view || editor.view.isDestroyed) {\n return null;\n }\n const coords = editor.view.coordsAtPos(\n Math.min(position.from, editor.state.doc.content.size - 1)\n );\n const rect = getRectFromCoords(coords);\n\n const offset = editor.view.dom.getBoundingClientRect().top ?? 0;\n\n let top = rect.top - offset;\n\n if (positions.has(thread.id)) {\n top = positions.get(thread.id)!;\n }\n\n const isActive = thread.id === pluginState?.selectedThreadId;\n\n return (\n <ThreadWrapper\n key={thread.id}\n onThreadClick={onThreadSelect}\n onItemAdd={onItemAdd}\n onItemRemove={onItemRemove}\n Thread={Thread}\n thread={thread}\n isActive={isActive}\n style={{\n position: \"absolute\",\n transform: `translate3d(${isActive ? ACTIVE_THREAD_OFFSET : 0}, ${top}px, 0)`,\n insetInlineStart: 0,\n inlineSize: \"100%\",\n paddingBlockEnd: GAP,\n }}\n />\n );\n })}\n </div>\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n Thread: ComponentType<ThreadProps>;\n onThreadClick: (id: string) => void;\n onItemAdd: (id: string, el: HTMLElement) => void;\n onItemRemove: (id: string) => void;\n isActive: boolean;\n}\n\nfunction ThreadWrapper({\n onThreadClick,\n onItemAdd,\n onItemRemove,\n thread,\n Thread,\n className,\n isActive,\n ...props\n}: ThreadWrapperProps) {\n const divRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n const el = divRef.current;\n if (el === null) return;\n\n onItemAdd(thread.id, el);\n return () => {\n onItemRemove(thread.id);\n };\n }, [onItemAdd, onItemRemove, thread.id]);\n\n function handleThreadClick() {\n onThreadClick(thread.id);\n }\n\n return (\n <div\n ref={divRef}\n className={cn(\"lb-tiptap-anchored-threads-thread-container\", className)}\n {...props}\n >\n <Thread\n thread={thread}\n data-state={isActive ? \"active\" : \"inactive\"}\n onClick={handleThreadClick}\n className=\"lb-tiptap-anchored-threads-thread\"\n showComposer={isActive ? true : false}\n />\n </div>\n );\n}\n"],"names":["useStableComponent","DefaultThread","useRef","useState","useEditorState","THREADS_PLUGIN_KEY","useCallback","getRectFromCoords","position","useEffect","thread","useLayoutEffect","jsx","cn"],"mappings":"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"}
1
+ {"version":3,"file":"AnchoredThreads.cjs","sources":["../../src/comments/AnchoredThreads.tsx"],"sourcesContent":["import type { BaseMetadata, DCM, DTM, ThreadData } from \"@liveblocks/core\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport { cn, useStableComponent } from \"@liveblocks/react-ui/_private\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport type { ComponentPropsWithoutRef, ComponentType } from \"react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { THREADS_PLUGIN_KEY } from \"../types\";\nimport { getRectFromCoords } from \"../utils\";\n\nconst DEFAULT_GAP = 20;\nconst DEFAULT_ACTIVE_THREAD_OFFSET = -12;\n\n// TODO: move that back to a variable\nconst GAP = `var(--lb-tiptap-anchored-threads-gap, ${DEFAULT_GAP}px)`;\nconst ACTIVE_THREAD_OFFSET = `var(--lb-tiptap-anchored-threads-active-thread-offset, ${DEFAULT_ACTIVE_THREAD_OFFSET}px)`;\n\ntype AnchoredThreadsComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface AnchoredThreadsProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<TM, CM>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<AnchoredThreadsComponents>;\n\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n}\n\nexport function AnchoredThreads({\n threads,\n components,\n className,\n style,\n editor,\n ...props\n}: AnchoredThreadsProps) {\n const Thread = useStableComponent(components?.Thread, DefaultThread);\n const containerRef = useRef<HTMLDivElement>(null);\n const [orderedThreads, setOrderedThreads] = useState<\n { position: { from: number; to: number }; thread: ThreadData }[]\n >([]);\n const [elements, setElements] = useState<Map<string, HTMLElement>>(new Map());\n const [positions, setPositions] = useState<Map<string, number>>(new Map()); // A map of thread ids to their 'top' position in the document\n\n const { pluginState } = useEditorState({\n editor,\n selector: (ctx) => {\n if (!ctx?.editor?.state) return { pluginState: undefined };\n const state = THREADS_PLUGIN_KEY.getState(ctx.editor.state);\n return {\n pluginState: state,\n };\n },\n equalityFn: (prev, next) => {\n if (!prev || !next) return false;\n return (\n prev.pluginState?.selectedThreadId ===\n next.pluginState?.selectedThreadId &&\n prev.pluginState?.threadPositions === next.pluginState?.threadPositions\n ); // new map is made each time threadPos updates so shallow equality is fine\n },\n }) ?? { pluginState: undefined };\n\n // TODO: lexical supoprts multiple threads being active, should probably do that here as well\n const handlePositionThreads = useCallback(() => {\n const container = containerRef.current;\n if (\n container === null ||\n !editor ||\n !editor.view ||\n editor.view.isDestroyed\n ) {\n return;\n }\n\n const activeIndex = orderedThreads.findIndex(\n ({ thread }) => thread.id === pluginState?.selectedThreadId\n );\n const ascending =\n activeIndex !== -1 ? orderedThreads.slice(activeIndex) : orderedThreads;\n const descending =\n activeIndex !== -1 ? orderedThreads.slice(0, activeIndex) : [];\n\n const newPositions = new Map<string, number>();\n\n // Iterate over each thread and calculate its new position by taking into account the position of the previously positioned threads\n for (const { thread, position } of ascending) {\n const coords = editor.view.coordsAtPos(\n Math.min(position.from, editor.view.state.doc.content.size - 1)\n );\n const rect = getRectFromCoords(coords);\n let top = rect.top - container.getBoundingClientRect().top;\n\n for (const [id, position] of newPositions) {\n // Retrieve the element associated with the thread\n const el = elements.get(id);\n if (el === undefined) continue;\n\n if (\n top >= position &&\n top <= position + el.getBoundingClientRect().height\n ) {\n top = position + el.getBoundingClientRect().height;\n }\n }\n\n newPositions.set(thread.id, top);\n }\n\n for (const { thread, position } of descending.reverse()) {\n const coords = editor.view.coordsAtPos(position.from);\n const rect = getRectFromCoords(coords);\n // Retrieve the element associated with the current thread\n const el = elements.get(thread.id);\n if (el === undefined) continue;\n\n let top = rect.top - container.getBoundingClientRect().top;\n for (const [, position] of newPositions) {\n if (top >= position - el.getBoundingClientRect().height) {\n top = position - el.getBoundingClientRect().height;\n }\n }\n\n newPositions.set(thread.id, top);\n }\n\n setPositions(newPositions);\n }, [editor, orderedThreads, pluginState?.selectedThreadId, elements]);\n\n useEffect(() => {\n if (!pluginState) return;\n setOrderedThreads(\n Array.from(pluginState.threadPositions, ([threadId, position]) => ({\n threadId,\n position,\n })).reduce(\n (acc, { threadId, position }) => {\n const thread = threads.find(\n (thread) => thread.id === threadId && !thread.resolved\n );\n if (!thread) return acc;\n acc.push({ thread, position });\n return acc;\n },\n [] as { thread: ThreadData; position: { from: number; to: number } }[]\n )\n );\n handlePositionThreads();\n // disable exhaustive deps because we don't want an infinite loop\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pluginState, threads]);\n\n useLayoutEffect(handlePositionThreads, [handlePositionThreads]);\n\n useEffect(() => {\n const observer = new ResizeObserver(handlePositionThreads);\n const container = editor?.view?.dom;\n if (container) {\n observer.observe(container);\n }\n for (const element of elements.values()) {\n observer.observe(element);\n }\n\n return () => observer.disconnect();\n }, [elements, editor, handlePositionThreads]);\n\n const onItemAdd = useCallback((id: string, el: HTMLElement) => {\n setElements((prev) => new Map(prev).set(id, el));\n }, []);\n\n const onItemRemove = useCallback((id: string) => {\n setElements((prev) => {\n const items = new Map(prev);\n items.delete(id);\n return items;\n });\n }, []);\n\n const onThreadSelect = useCallback(\n (id: string) => {\n if (!editor) return;\n editor.commands.selectThread(id);\n },\n [editor]\n );\n\n if (!editor) return null;\n\n return (\n <div\n {...props}\n className={cn(className, \"lb-root lb-tiptap-anchored-threads\")}\n ref={containerRef}\n style={{\n position: \"relative\",\n ...style,\n }}\n >\n {orderedThreads.map(({ thread, position }) => {\n // In blocknote, it's possible for this to be undefined\n if (!editor.view || editor.view.isDestroyed) {\n return null;\n }\n const coords = editor.view.coordsAtPos(\n Math.min(position.from, editor.state.doc.content.size - 1)\n );\n const rect = getRectFromCoords(coords);\n\n const offset = editor.view.dom.getBoundingClientRect().top ?? 0;\n\n let top = rect.top - offset;\n\n if (positions.has(thread.id)) {\n top = positions.get(thread.id)!;\n }\n\n const isActive = thread.id === pluginState?.selectedThreadId;\n\n return (\n <ThreadWrapper\n key={thread.id}\n onThreadClick={onThreadSelect}\n onItemAdd={onItemAdd}\n onItemRemove={onItemRemove}\n Thread={Thread}\n thread={thread}\n isActive={isActive}\n style={{\n position: \"absolute\",\n transform: `translate3d(${isActive ? ACTIVE_THREAD_OFFSET : 0}, ${top}px, 0)`,\n insetInlineStart: 0,\n inlineSize: \"100%\",\n paddingBlockEnd: GAP,\n }}\n />\n );\n })}\n </div>\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n Thread: ComponentType<ThreadProps>;\n onThreadClick: (id: string) => void;\n onItemAdd: (id: string, el: HTMLElement) => void;\n onItemRemove: (id: string) => void;\n isActive: boolean;\n}\n\nfunction ThreadWrapper({\n onThreadClick,\n onItemAdd,\n onItemRemove,\n thread,\n Thread,\n className,\n isActive,\n ...props\n}: ThreadWrapperProps) {\n const divRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n const el = divRef.current;\n if (el === null) return;\n\n onItemAdd(thread.id, el);\n return () => {\n onItemRemove(thread.id);\n };\n }, [onItemAdd, onItemRemove, thread.id]);\n\n function handleThreadClick() {\n onThreadClick(thread.id);\n }\n\n return (\n <div\n ref={divRef}\n className={cn(\"lb-tiptap-anchored-threads-thread-container\", className)}\n {...props}\n >\n <Thread\n thread={thread}\n data-state={isActive ? \"active\" : \"inactive\"}\n onClick={handleThreadClick}\n className=\"lb-tiptap-anchored-threads-thread\"\n showComposer={isActive ? true : false}\n />\n </div>\n );\n}\n"],"names":["useStableComponent","DefaultThread","useRef","useState","useEditorState","THREADS_PLUGIN_KEY","useCallback","getRectFromCoords","position","useEffect","thread","useLayoutEffect","jsx","cn"],"mappings":"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"}