@liveblocks/react-tiptap
Advanced tools
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"AnchoredThreads.cjs","sources":["../../src/comments/AnchoredThreads.tsx"],"sourcesContent":["import type { BaseMetadata, DM, 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 } 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<M extends BaseMetadata = DM>\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<M>[];\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 = 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 (container === null || !editor || !editor.view) return;\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) {\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 const offset = editor.options.element?.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":["DefaultThread","useRef","useState","useEditorState","THREADS_PLUGIN_KEY","useCallback","getRectFromCoords","position","useEffect","thread","useLayoutEffect","jsx","cn"],"mappings":"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"} | ||
| {"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 } 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 = 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 (container === null || !editor || !editor.view) return;\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) {\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 const offset = editor.options.element?.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":["DefaultThread","useRef","useState","useEditorState","THREADS_PLUGIN_KEY","useCallback","getRectFromCoords","position","useEffect","thread","useLayoutEffect","jsx","cn"],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"AnchoredThreads.js","sources":["../../src/comments/AnchoredThreads.tsx"],"sourcesContent":["import type { BaseMetadata, DM, 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 } 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<M extends BaseMetadata = DM>\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<M>[];\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 = 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 (container === null || !editor || !editor.view) return;\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) {\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 const offset = editor.options.element?.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":["Thread","DefaultThread","position","thread"],"mappings":";;;;;;;;;AAcA,MAAM,WAAc,GAAA,EAAA,CAAA;AACpB,MAAM,4BAA+B,GAAA,CAAA,EAAA,CAAA;AAGrC,MAAM,GAAA,GAAM,yCAAyC,WAAW,CAAA,GAAA,CAAA,CAAA;AAChE,MAAM,oBAAA,GAAuB,0DAA0D,4BAA4B,CAAA,GAAA,CAAA,CAAA;AAwB5G,SAAS,eAAgB,CAAA;AAAA,EAC9B,OAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAG,KAAA;AACL,CAAyB,EAAA;AACvB,EAAM,MAAAA,QAAA,GAAS,YAAY,MAAU,IAAAC,MAAA,CAAA;AACrC,EAAM,MAAA,YAAA,GAAe,OAAuB,IAAI,CAAA,CAAA;AAChD,EAAA,MAAM,CAAC,cAAgB,EAAA,iBAAiB,CAAI,GAAA,QAAA,CAE1C,EAAE,CAAA,CAAA;AACJ,EAAA,MAAM,CAAC,QAAU,EAAA,WAAW,IAAI,QAAmC,iBAAA,IAAI,KAAK,CAAA,CAAA;AAC5E,EAAA,MAAM,CAAC,SAAW,EAAA,YAAY,IAAI,QAA8B,iBAAA,IAAI,KAAK,CAAA,CAAA;AAEzE,EAAM,MAAA,EAAE,WAAY,EAAA,GAAI,cAAe,CAAA;AAAA,IACrC,MAAA;AAAA,IACA,QAAA,EAAU,CAAC,GAAQ,KAAA;AACjB,MAAI,IAAA,CAAC,KAAK,MAAQ,EAAA,KAAA;AAAO,QAAO,OAAA,EAAE,aAAa,KAAU,CAAA,EAAA,CAAA;AACzD,MAAA,MAAM,KAAQ,GAAA,kBAAA,CAAmB,QAAS,CAAA,GAAA,CAAI,OAAO,KAAK,CAAA,CAAA;AAC1D,MAAO,OAAA;AAAA,QACL,WAAa,EAAA,KAAA;AAAA,OACf,CAAA;AAAA,KACF;AAAA,IACA,UAAA,EAAY,CAAC,IAAA,EAAM,IAAS,KAAA;AAC1B,MAAI,IAAA,CAAC,QAAQ,CAAC,IAAA;AAAM,QAAO,OAAA,KAAA,CAAA;AAC3B,MACE,OAAA,IAAA,CAAK,WAAa,EAAA,gBAAA,KAClB,IAAK,CAAA,WAAA,EAAa,oBAClB,IAAK,CAAA,WAAA,EAAa,eAAoB,KAAA,IAAA,CAAK,WAAa,EAAA,eAAA,CAAA;AAAA,KAE5D;AAAA,GACD,CAAA,IAAK,EAAE,WAAA,EAAa,KAAU,CAAA,EAAA,CAAA;AAG/B,EAAM,MAAA,qBAAA,GAAwB,YAAY,MAAM;AAC9C,IAAA,MAAM,YAAY,YAAa,CAAA,OAAA,CAAA;AAC/B,IAAA,IAAI,SAAc,KAAA,IAAA,IAAQ,CAAC,MAAA,IAAU,CAAC,MAAO,CAAA,IAAA;AAAM,MAAA,OAAA;AAEnD,IAAA,MAAM,cAAc,cAAe,CAAA,SAAA;AAAA,MACjC,CAAC,EAAE,MAAA,EAAa,KAAA,MAAA,CAAO,OAAO,WAAa,EAAA,gBAAA;AAAA,KAC7C,CAAA;AACA,IAAA,MAAM,YACJ,WAAgB,KAAA,CAAA,CAAA,GAAK,cAAe,CAAA,KAAA,CAAM,WAAW,CAAI,GAAA,cAAA,CAAA;AAC3D,IAAM,MAAA,UAAA,GACJ,gBAAgB,CAAK,CAAA,GAAA,cAAA,CAAe,MAAM,CAAG,EAAA,WAAW,IAAI,EAAC,CAAA;AAE/D,IAAM,MAAA,YAAA,uBAAmB,GAAoB,EAAA,CAAA;AAG7C,IAAA,KAAA,MAAW,EAAE,MAAA,EAAQ,QAAS,EAAA,IAAK,SAAW,EAAA;AAC5C,MAAM,MAAA,MAAA,GAAS,OAAO,IAAK,CAAA,WAAA;AAAA,QACzB,IAAA,CAAK,GAAI,CAAA,QAAA,CAAS,IAAM,EAAA,MAAA,CAAO,KAAK,KAAM,CAAA,GAAA,CAAI,OAAQ,CAAA,IAAA,GAAO,CAAC,CAAA;AAAA,OAChE,CAAA;AACA,MAAM,MAAA,IAAA,GAAO,kBAAkB,MAAM,CAAA,CAAA;AACrC,MAAA,IAAI,GAAM,GAAA,IAAA,CAAK,GAAM,GAAA,SAAA,CAAU,uBAAwB,CAAA,GAAA,CAAA;AAEvD,MAAA,KAAA,MAAW,CAAC,EAAA,EAAIC,SAAQ,CAAA,IAAK,YAAc,EAAA;AAEzC,QAAM,MAAA,EAAA,GAAK,QAAS,CAAA,GAAA,CAAI,EAAE,CAAA,CAAA;AAC1B,QAAA,IAAI,EAAO,KAAA,KAAA,CAAA;AAAW,UAAA,SAAA;AAEtB,QAAA,IACE,OAAOA,SACP,IAAA,GAAA,IAAOA,YAAW,EAAG,CAAA,qBAAA,GAAwB,MAC7C,EAAA;AACA,UAAMA,GAAAA,GAAAA,SAAAA,GAAW,EAAG,CAAA,qBAAA,EAAwB,CAAA,MAAA,CAAA;AAAA,SAC9C;AAAA,OACF;AAEA,MAAa,YAAA,CAAA,GAAA,CAAI,MAAO,CAAA,EAAA,EAAI,GAAG,CAAA,CAAA;AAAA,KACjC;AAEA,IAAA,KAAA,MAAW,EAAE,MAAQ,EAAA,QAAA,EAAc,IAAA,UAAA,CAAW,SAAW,EAAA;AACvD,MAAA,MAAM,MAAS,GAAA,MAAA,CAAO,IAAK,CAAA,WAAA,CAAY,SAAS,IAAI,CAAA,CAAA;AACpD,MAAM,MAAA,IAAA,GAAO,kBAAkB,MAAM,CAAA,CAAA;AAErC,MAAA,MAAM,EAAK,GAAA,QAAA,CAAS,GAAI,CAAA,MAAA,CAAO,EAAE,CAAA,CAAA;AACjC,MAAA,IAAI,EAAO,KAAA,KAAA,CAAA;AAAW,QAAA,SAAA;AAEtB,MAAA,IAAI,GAAM,GAAA,IAAA,CAAK,GAAM,GAAA,SAAA,CAAU,uBAAwB,CAAA,GAAA,CAAA;AACvD,MAAA,KAAA,MAAW,GAAGA,SAAQ,CAAA,IAAK,YAAc,EAAA;AACvC,QAAA,IAAI,GAAOA,IAAAA,SAAAA,GAAW,EAAG,CAAA,qBAAA,GAAwB,MAAQ,EAAA;AACvD,UAAMA,GAAAA,GAAAA,SAAAA,GAAW,EAAG,CAAA,qBAAA,EAAwB,CAAA,MAAA,CAAA;AAAA,SAC9C;AAAA,OACF;AAEA,MAAa,YAAA,CAAA,GAAA,CAAI,MAAO,CAAA,EAAA,EAAI,GAAG,CAAA,CAAA;AAAA,KACjC;AAEA,IAAA,YAAA,CAAa,YAAY,CAAA,CAAA;AAAA,KACxB,CAAC,MAAA,EAAQ,gBAAgB,WAAa,EAAA,gBAAA,EAAkB,QAAQ,CAAC,CAAA,CAAA;AAEpE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,WAAA;AAAa,MAAA,OAAA;AAClB,IAAA,iBAAA;AAAA,MACE,KAAA,CAAM,KAAK,WAAY,CAAA,eAAA,EAAiB,CAAC,CAAC,QAAA,EAAU,QAAQ,CAAO,MAAA;AAAA,QACjE,QAAA;AAAA,QACA,QAAA;AAAA,QACA,CAAE,CAAA,MAAA;AAAA,QACF,CAAC,GAAA,EAAK,EAAE,QAAA,EAAU,UAAe,KAAA;AAC/B,UAAA,MAAM,SAAS,OAAQ,CAAA,IAAA;AAAA,YACrB,CAACC,OAAWA,KAAAA,OAAAA,CAAO,EAAO,KAAA,QAAA,IAAY,CAACA,OAAO,CAAA,QAAA;AAAA,WAChD,CAAA;AACA,UAAA,IAAI,CAAC,MAAA;AAAQ,YAAO,OAAA,GAAA,CAAA;AACpB,UAAA,GAAA,CAAI,IAAK,CAAA,EAAE,MAAQ,EAAA,QAAA,EAAU,CAAA,CAAA;AAC7B,UAAO,OAAA,GAAA,CAAA;AAAA,SACT;AAAA,QACA,EAAC;AAAA,OACH;AAAA,KACF,CAAA;AACA,IAAsB,qBAAA,EAAA,CAAA;AAAA,GAGrB,EAAA,CAAC,WAAa,EAAA,OAAO,CAAC,CAAA,CAAA;AAEzB,EAAgB,eAAA,CAAA,qBAAA,EAAuB,CAAC,qBAAqB,CAAC,CAAA,CAAA;AAE9D,EAAA,SAAA,CAAU,MAAM;AACd,IAAM,MAAA,QAAA,GAAW,IAAI,cAAA,CAAe,qBAAqB,CAAA,CAAA;AACzD,IAAM,MAAA,SAAA,GAAY,QAAQ,IAAM,EAAA,GAAA,CAAA;AAChC,IAAA,IAAI,SAAW,EAAA;AACb,MAAA,QAAA,CAAS,QAAQ,SAAS,CAAA,CAAA;AAAA,KAC5B;AACA,IAAW,KAAA,MAAA,OAAA,IAAW,QAAS,CAAA,MAAA,EAAU,EAAA;AACvC,MAAA,QAAA,CAAS,QAAQ,OAAO,CAAA,CAAA;AAAA,KAC1B;AAEA,IAAO,OAAA,MAAM,SAAS,UAAW,EAAA,CAAA;AAAA,GAChC,EAAA,CAAC,QAAU,EAAA,MAAA,EAAQ,qBAAqB,CAAC,CAAA,CAAA;AAE5C,EAAA,MAAM,SAAY,GAAA,WAAA,CAAY,CAAC,EAAA,EAAY,EAAoB,KAAA;AAC7D,IAAY,WAAA,CAAA,CAAC,SAAS,IAAI,GAAA,CAAI,IAAI,CAAE,CAAA,GAAA,CAAI,EAAI,EAAA,EAAE,CAAC,CAAA,CAAA;AAAA,GACjD,EAAG,EAAE,CAAA,CAAA;AAEL,EAAM,MAAA,YAAA,GAAe,WAAY,CAAA,CAAC,EAAe,KAAA;AAC/C,IAAA,WAAA,CAAY,CAAC,IAAS,KAAA;AACpB,MAAM,MAAA,KAAA,GAAQ,IAAI,GAAA,CAAI,IAAI,CAAA,CAAA;AAC1B,MAAA,KAAA,CAAM,OAAO,EAAE,CAAA,CAAA;AACf,MAAO,OAAA,KAAA,CAAA;AAAA,KACR,CAAA,CAAA;AAAA,GACH,EAAG,EAAE,CAAA,CAAA;AAEL,EAAA,MAAM,cAAiB,GAAA,WAAA;AAAA,IACrB,CAAC,EAAe,KAAA;AACd,MAAA,IAAI,CAAC,MAAA;AAAQ,QAAA,OAAA;AACb,MAAO,MAAA,CAAA,QAAA,CAAS,aAAa,EAAE,CAAA,CAAA;AAAA,KACjC;AAAA,IACA,CAAC,MAAM,CAAA;AAAA,GACT,CAAA;AAEA,EAAA,IAAI,CAAC,MAAA;AAAQ,IAAO,OAAA,IAAA,CAAA;AAEpB,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,KAAA;AAAA,MACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,oCAAoC,CAAA;AAAA,MAC7D,GAAK,EAAA,YAAA;AAAA,MACL,KAAO,EAAA;AAAA,QACL,QAAU,EAAA,UAAA;AAAA,QACV,GAAG,KAAA;AAAA,OACL;AAAA,MAEC,yBAAe,GAAI,CAAA,CAAC,EAAE,MAAA,EAAQ,UAAe,KAAA;AAE5C,QAAI,IAAA,CAAC,OAAO,IAAM,EAAA;AAChB,UAAO,OAAA,IAAA,CAAA;AAAA,SACT;AACA,QAAM,MAAA,MAAA,GAAS,OAAO,IAAK,CAAA,WAAA;AAAA,UACzB,IAAA,CAAK,IAAI,QAAS,CAAA,IAAA,EAAM,OAAO,KAAM,CAAA,GAAA,CAAI,OAAQ,CAAA,IAAA,GAAO,CAAC,CAAA;AAAA,SAC3D,CAAA;AACA,QAAM,MAAA,IAAA,GAAO,kBAAkB,MAAM,CAAA,CAAA;AACrC,QAAA,MAAM,SAAS,MAAO,CAAA,OAAA,CAAQ,OAAS,EAAA,qBAAA,GAAwB,GAAO,IAAA,CAAA,CAAA;AAEtE,QAAI,IAAA,GAAA,GAAM,KAAK,GAAM,GAAA,MAAA,CAAA;AAErB,QAAA,IAAI,SAAU,CAAA,GAAA,CAAI,MAAO,CAAA,EAAE,CAAG,EAAA;AAC5B,UAAM,GAAA,GAAA,SAAA,CAAU,GAAI,CAAA,MAAA,CAAO,EAAE,CAAA,CAAA;AAAA,SAC/B;AAEA,QAAM,MAAA,QAAA,GAAW,MAAO,CAAA,EAAA,KAAO,WAAa,EAAA,gBAAA,CAAA;AAE5C,QACE,uBAAA,GAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YAEC,aAAe,EAAA,cAAA;AAAA,YACf,SAAA;AAAA,YACA,YAAA;AAAA,oBACAH,QAAA;AAAA,YACA,MAAA;AAAA,YACA,QAAA;AAAA,YACA,KAAO,EAAA;AAAA,cACL,QAAU,EAAA,UAAA;AAAA,cACV,WAAW,CAAe,YAAA,EAAA,QAAA,GAAW,oBAAuB,GAAA,CAAC,KAAK,GAAG,CAAA,MAAA,CAAA;AAAA,cACrE,gBAAkB,EAAA,CAAA;AAAA,cAClB,UAAY,EAAA,MAAA;AAAA,cACZ,eAAiB,EAAA,GAAA;AAAA,aACnB;AAAA,WAAA;AAAA,UAbK,MAAO,CAAA,EAAA;AAAA,SAcd,CAAA;AAAA,OAEH,CAAA;AAAA,KAAA;AAAA,GACH,CAAA;AAEJ,CAAA;AAUA,SAAS,aAAc,CAAA;AAAA,EACrB,aAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG,KAAA;AACL,CAAuB,EAAA;AACrB,EAAM,MAAA,MAAA,GAAS,OAAuB,IAAI,CAAA,CAAA;AAE1C,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAA,MAAM,KAAK,MAAO,CAAA,OAAA,CAAA;AAClB,IAAA,IAAI,EAAO,KAAA,IAAA;AAAM,MAAA,OAAA;AAEjB,IAAU,SAAA,CAAA,MAAA,CAAO,IAAI,EAAE,CAAA,CAAA;AACvB,IAAA,OAAO,MAAM;AACX,MAAA,YAAA,CAAa,OAAO,EAAE,CAAA,CAAA;AAAA,KACxB,CAAA;AAAA,KACC,CAAC,SAAA,EAAW,YAAc,EAAA,MAAA,CAAO,EAAE,CAAC,CAAA,CAAA;AAEvC,EAAA,SAAS,iBAAoB,GAAA;AAC3B,IAAA,aAAA,CAAc,OAAO,EAAE,CAAA,CAAA;AAAA,GACzB;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAK,EAAA,MAAA;AAAA,MACL,SAAA,EAAW,EAAG,CAAA,6CAAA,EAA+C,SAAS,CAAA;AAAA,MACrE,GAAG,KAAA;AAAA,MAEJ,QAAA,kBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,YAAA,EAAY,WAAW,QAAW,GAAA,UAAA;AAAA,UAClC,OAAS,EAAA,iBAAA;AAAA,UACT,SAAU,EAAA,mCAAA;AAAA,UACV,YAAA,EAAc,WAAW,IAAO,GAAA,KAAA;AAAA,SAAA;AAAA,OAClC;AAAA,KAAA;AAAA,GACF,CAAA;AAEJ;;;;"} | ||
| {"version":3,"file":"AnchoredThreads.js","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 } 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 = 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 (container === null || !editor || !editor.view) return;\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) {\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 const offset = editor.options.element?.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":["Thread","DefaultThread","position","thread"],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"FloatingComposer.cjs","sources":["../../src/comments/FloatingComposer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer as DefaultComposer } from \"@liveblocks/react-ui\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport type {\n ComponentType,\n FormEvent,\n KeyboardEvent,\n MouseEvent,\n} from \"react\";\nimport { forwardRef, useCallback } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type {\n ExtendedChainedCommands,\n} from \"../types\";\nimport { compareSelections, getDomRangeFromSelection } from \"../utils\";\n\ntype FloatingComposerComponents = {\n Composer: ComponentType<Omit<ComposerProps, \"threadId\" | \"commentId\">>;\n};\n\nexport type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n> & {\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingComposerComponents>;\n\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n};\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nexport const FloatingComposer = forwardRef<\n HTMLFormElement,\n FloatingComposerProps\n>(function FloatingComposer(\n { editor, onComposerSubmit, onKeyDown, onClick, components, ...props },\n forwardedRef\n) {\n const Composer = components?.Composer ?? DefaultComposer;\n const createThread = useCreateThread();\n const pendingCommentSelection =\n useEditorState({\n editor,\n selector: (ctx) => {\n if (!ctx.editor) {\n return undefined;\n }\n\n const hasPendingComment = ctx.editor.storage.liveblocksComments.pendingComment;\n const isEmpty = ctx.editor.state.selection.empty;\n\n return hasPendingComment && !isEmpty ? ctx.editor.state.selection : undefined;\n },\n equalityFn: compareSelections,\n }) ?? undefined;\n const isOpen = pendingCommentSelection !== undefined;\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n if (!pendingCommentSelection) {\n setReference(null);\n } else {\n const domRange = getDomRangeFromSelection(\n editor,\n pendingCommentSelection\n );\n\n setReference(domRange);\n }\n }, [pendingCommentSelection, editor, isOpen, setReference]);\n\n // Submit a new thread and update the comment highlight to show a completed highlight\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n if (!editor) {\n return;\n }\n\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n editor.commands.addComment(thread.id);\n },\n [onComposerSubmit, editor, createThread, props.metadata]\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLFormElement>) => {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented() || !editor) {\n return;\n }\n\n if (event.key === \"Escape\") {\n (editor.chain() as ExtendedChainedCommands<\"closePendingComment\">)\n .closePendingComment()\n .run();\n }\n },\n [editor, onKeyDown]\n );\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLFormElement>) => {\n onClick?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n // Don't send up a click event from emoji picker and close the composer.\n event.stopPropagation();\n },\n [onClick]\n );\n\n if (!isOpen || !editor) {\n return null;\n }\n\n return createPortal(\n <div\n className=\"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-composer\"\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n >\n <Composer\n ref={forwardedRef}\n autoFocus\n {...props}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n onClick={handleClick}\n />\n </div>,\n document.body\n );\n});\n"],"names":["forwardRef","FloatingComposer","DefaultComposer","useCreateThread","useEditorState","compareSelections","useFloating","inline","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","getDomRangeFromSelection","useCallback","createPortal","jsx"],"mappings":"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"} | ||
| {"version":3,"file":"FloatingComposer.cjs","sources":["../../src/comments/FloatingComposer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DCM, DTM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer as DefaultComposer } from \"@liveblocks/react-ui\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport type {\n ComponentType,\n FormEvent,\n KeyboardEvent,\n MouseEvent,\n} from \"react\";\nimport { forwardRef, useCallback } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type { ExtendedChainedCommands } from \"../types\";\nimport { compareSelections, getDomRangeFromSelection } from \"../utils\";\n\ntype ExcludeProps<T, K extends Record<string, unknown>> = Omit<\n Exclude<T, T & K>,\n keyof K\n>;\n\ntype ComposerPropsCreateThread<\n TM extends BaseMetadata,\n CM extends BaseMetadata,\n> = ExcludeProps<\n ComposerProps<TM, CM>,\n { threadId: string; commentId: string }\n>;\n\ntype FloatingComposerComponents = {\n Composer: ComponentType<ComposerPropsCreateThread<DTM, DCM>>;\n};\n\nexport type FloatingComposerProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> = ComposerPropsCreateThread<TM, CM> & {\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingComposerComponents>;\n\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n};\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nexport const FloatingComposer = forwardRef<\n HTMLFormElement,\n FloatingComposerProps\n>(function FloatingComposer(\n { editor, onComposerSubmit, onKeyDown, onClick, components, ...props },\n forwardedRef\n) {\n const Composer = components?.Composer ?? DefaultComposer;\n const createThread = useCreateThread();\n const pendingCommentSelection =\n useEditorState({\n editor,\n selector: (ctx) => {\n if (!ctx.editor) {\n return undefined;\n }\n\n const hasPendingComment =\n ctx.editor.storage.liveblocksComments.pendingComment;\n const isEmpty = ctx.editor.state.selection.empty;\n\n return hasPendingComment && !isEmpty\n ? ctx.editor.state.selection\n : undefined;\n },\n equalityFn: compareSelections,\n }) ?? undefined;\n const isOpen = pendingCommentSelection !== undefined;\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n if (!pendingCommentSelection) {\n setReference(null);\n } else {\n const domRange = getDomRangeFromSelection(\n editor,\n pendingCommentSelection\n );\n\n setReference(domRange);\n }\n }, [pendingCommentSelection, editor, isOpen, setReference]);\n\n // Submit a new thread and update the comment highlight to show a completed highlight\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n if (!editor) {\n return;\n }\n\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n editor.commands.addComment(thread.id);\n },\n [onComposerSubmit, editor, createThread, props.metadata]\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLFormElement>) => {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented() || !editor) {\n return;\n }\n\n if (event.key === \"Escape\") {\n (editor.chain() as ExtendedChainedCommands<\"closePendingComment\">)\n .closePendingComment()\n .run();\n }\n },\n [editor, onKeyDown]\n );\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLFormElement>) => {\n onClick?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n // Don't send up a click event from emoji picker and close the composer.\n event.stopPropagation();\n },\n [onClick]\n );\n\n if (!isOpen || !editor) {\n return null;\n }\n\n return createPortal(\n <div\n className=\"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-composer\"\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n >\n <Composer\n ref={forwardedRef}\n autoFocus\n {...props}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n onClick={handleClick}\n />\n </div>,\n document.body\n );\n});\n"],"names":["forwardRef","FloatingComposer","DefaultComposer","useCreateThread","useEditorState","compareSelections","useFloating","inline","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","getDomRangeFromSelection","useCallback","createPortal","jsx"],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"FloatingComposer.js","sources":["../../src/comments/FloatingComposer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer as DefaultComposer } from \"@liveblocks/react-ui\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport type {\n ComponentType,\n FormEvent,\n KeyboardEvent,\n MouseEvent,\n} from \"react\";\nimport { forwardRef, useCallback } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type {\n ExtendedChainedCommands,\n} from \"../types\";\nimport { compareSelections, getDomRangeFromSelection } from \"../utils\";\n\ntype FloatingComposerComponents = {\n Composer: ComponentType<Omit<ComposerProps, \"threadId\" | \"commentId\">>;\n};\n\nexport type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n> & {\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingComposerComponents>;\n\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n};\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nexport const FloatingComposer = forwardRef<\n HTMLFormElement,\n FloatingComposerProps\n>(function FloatingComposer(\n { editor, onComposerSubmit, onKeyDown, onClick, components, ...props },\n forwardedRef\n) {\n const Composer = components?.Composer ?? DefaultComposer;\n const createThread = useCreateThread();\n const pendingCommentSelection =\n useEditorState({\n editor,\n selector: (ctx) => {\n if (!ctx.editor) {\n return undefined;\n }\n\n const hasPendingComment = ctx.editor.storage.liveblocksComments.pendingComment;\n const isEmpty = ctx.editor.state.selection.empty;\n\n return hasPendingComment && !isEmpty ? ctx.editor.state.selection : undefined;\n },\n equalityFn: compareSelections,\n }) ?? undefined;\n const isOpen = pendingCommentSelection !== undefined;\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n if (!pendingCommentSelection) {\n setReference(null);\n } else {\n const domRange = getDomRangeFromSelection(\n editor,\n pendingCommentSelection\n );\n\n setReference(domRange);\n }\n }, [pendingCommentSelection, editor, isOpen, setReference]);\n\n // Submit a new thread and update the comment highlight to show a completed highlight\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n if (!editor) {\n return;\n }\n\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n editor.commands.addComment(thread.id);\n },\n [onComposerSubmit, editor, createThread, props.metadata]\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLFormElement>) => {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented() || !editor) {\n return;\n }\n\n if (event.key === \"Escape\") {\n (editor.chain() as ExtendedChainedCommands<\"closePendingComment\">)\n .closePendingComment()\n .run();\n }\n },\n [editor, onKeyDown]\n );\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLFormElement>) => {\n onClick?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n // Don't send up a click event from emoji picker and close the composer.\n event.stopPropagation();\n },\n [onClick]\n );\n\n if (!isOpen || !editor) {\n return null;\n }\n\n return createPortal(\n <div\n className=\"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-composer\"\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n >\n <Composer\n ref={forwardedRef}\n autoFocus\n {...props}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n onClick={handleClick}\n />\n </div>,\n document.body\n );\n});\n"],"names":["FloatingComposer","Composer","DefaultComposer"],"mappings":"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"} | ||
| {"version":3,"file":"FloatingComposer.js","sources":["../../src/comments/FloatingComposer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DCM, DTM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer as DefaultComposer } from \"@liveblocks/react-ui\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport type {\n ComponentType,\n FormEvent,\n KeyboardEvent,\n MouseEvent,\n} from \"react\";\nimport { forwardRef, useCallback } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport type { ExtendedChainedCommands } from \"../types\";\nimport { compareSelections, getDomRangeFromSelection } from \"../utils\";\n\ntype ExcludeProps<T, K extends Record<string, unknown>> = Omit<\n Exclude<T, T & K>,\n keyof K\n>;\n\ntype ComposerPropsCreateThread<\n TM extends BaseMetadata,\n CM extends BaseMetadata,\n> = ExcludeProps<\n ComposerProps<TM, CM>,\n { threadId: string; commentId: string }\n>;\n\ntype FloatingComposerComponents = {\n Composer: ComponentType<ComposerPropsCreateThread<DTM, DCM>>;\n};\n\nexport type FloatingComposerProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> = ComposerPropsCreateThread<TM, CM> & {\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingComposerComponents>;\n\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n};\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nexport const FloatingComposer = forwardRef<\n HTMLFormElement,\n FloatingComposerProps\n>(function FloatingComposer(\n { editor, onComposerSubmit, onKeyDown, onClick, components, ...props },\n forwardedRef\n) {\n const Composer = components?.Composer ?? DefaultComposer;\n const createThread = useCreateThread();\n const pendingCommentSelection =\n useEditorState({\n editor,\n selector: (ctx) => {\n if (!ctx.editor) {\n return undefined;\n }\n\n const hasPendingComment =\n ctx.editor.storage.liveblocksComments.pendingComment;\n const isEmpty = ctx.editor.state.selection.empty;\n\n return hasPendingComment && !isEmpty\n ? ctx.editor.state.selection\n : undefined;\n },\n equalityFn: compareSelections,\n }) ?? undefined;\n const isOpen = pendingCommentSelection !== undefined;\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n if (!editor || !isOpen) {\n return;\n }\n\n if (!pendingCommentSelection) {\n setReference(null);\n } else {\n const domRange = getDomRangeFromSelection(\n editor,\n pendingCommentSelection\n );\n\n setReference(domRange);\n }\n }, [pendingCommentSelection, editor, isOpen, setReference]);\n\n // Submit a new thread and update the comment highlight to show a completed highlight\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n if (!editor) {\n return;\n }\n\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n editor.commands.addComment(thread.id);\n },\n [onComposerSubmit, editor, createThread, props.metadata]\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLFormElement>) => {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented() || !editor) {\n return;\n }\n\n if (event.key === \"Escape\") {\n (editor.chain() as ExtendedChainedCommands<\"closePendingComment\">)\n .closePendingComment()\n .run();\n }\n },\n [editor, onKeyDown]\n );\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLFormElement>) => {\n onClick?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n // Don't send up a click event from emoji picker and close the composer.\n event.stopPropagation();\n },\n [onClick]\n );\n\n if (!isOpen || !editor) {\n return null;\n }\n\n return createPortal(\n <div\n className=\"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-composer\"\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n >\n <Composer\n ref={forwardedRef}\n autoFocus\n {...props}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n onClick={handleClick}\n />\n </div>,\n document.body\n );\n});\n"],"names":["FloatingComposer","Composer","DefaultComposer"],"mappings":";;;;;;;;;;AAiEO,MAAM,mCAAsC,GAAA,GAAA;AAE5C,MAAM,gBAAmB,GAAA,UAAA,CAG9B,SAASA,iBAAAA,CACT,EAAE,MAAA,EAAQ,gBAAkB,EAAA,SAAA,EAAW,OAAS,EAAA,UAAA,EAAY,GAAG,KAAA,IAC/D,YACA,EAAA;AACA,EAAM,MAAAC,UAAA,GAAW,YAAY,QAAY,IAAAC,QAAA,CAAA;AACzC,EAAA,MAAM,eAAe,eAAgB,EAAA,CAAA;AACrC,EAAA,MAAM,0BACJ,cAAe,CAAA;AAAA,IACb,MAAA;AAAA,IACA,QAAA,EAAU,CAAC,GAAQ,KAAA;AACjB,MAAI,IAAA,CAAC,IAAI,MAAQ,EAAA;AACf,QAAO,OAAA,KAAA,CAAA,CAAA;AAAA,OACT;AAEA,MAAA,MAAM,iBACJ,GAAA,GAAA,CAAI,MAAO,CAAA,OAAA,CAAQ,kBAAmB,CAAA,cAAA,CAAA;AACxC,MAAA,MAAM,OAAU,GAAA,GAAA,CAAI,MAAO,CAAA,KAAA,CAAM,SAAU,CAAA,KAAA,CAAA;AAE3C,MAAA,OAAO,qBAAqB,CAAC,OAAA,GACzB,GAAI,CAAA,MAAA,CAAO,MAAM,SACjB,GAAA,KAAA,CAAA,CAAA;AAAA,KACN;AAAA,IACA,UAAY,EAAA,iBAAA;AAAA,GACb,CAAK,IAAA,KAAA,CAAA,CAAA;AACR,EAAA,MAAM,SAAS,uBAA4B,KAAA,KAAA,CAAA,CAAA;AAC3C,EAAM,MAAA;AAAA,IACJ,IAAA,EAAM,EAAE,YAAA,EAAc,WAAY,EAAA;AAAA,IAClC,QAAA;AAAA,IACA,CAAA;AAAA,IACA,CAAA;AAAA,MACE,WAAY,CAAA;AAAA,IACd,QAAU,EAAA,OAAA;AAAA,IACV,SAAW,EAAA,QAAA;AAAA,IACX,UAAY,EAAA;AAAA,MACV,MAAO,CAAA,EAAE,OAAS,EAAA,mCAAA,EAAqC,CAAA;AAAA,MACvD,KAAK,EAAE,OAAA,EAAS,mCAAqC,EAAA,SAAA,EAAW,OAAO,CAAA;AAAA,MACvE,OAAO,EAAE,CAAA;AAAA,MACT,IAAK,CAAA,EAAE,OAAS,EAAA,mCAAA,EAAqC,CAAA;AAAA,MACrD,KAAM,CAAA;AAAA,QACJ,OAAS,EAAA,mCAAA;AAAA,QACT,SAAS,UAAW,EAAA;AAAA,OACrB,CAAA;AAAA,MACD,IAAK,CAAA,EAAE,OAAS,EAAA,mCAAA,EAAqC,CAAA;AAAA,KACvD;AAAA,IACA,oBAAA,EAAsB,IAAI,IAAS,KAAA;AACjC,MAAO,OAAA,UAAA,CAAW,GAAG,IAAM,EAAA;AAAA,QACzB,cAAgB,EAAA,IAAA;AAAA,OACjB,CAAA,CAAA;AAAA,KACH;AAAA,GACD,CAAA,CAAA;AAED,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAI,IAAA,CAAC,MAAU,IAAA,CAAC,MAAQ,EAAA;AACtB,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,IAAI,CAAC,uBAAyB,EAAA;AAC5B,MAAA,YAAA,CAAa,IAAI,CAAA,CAAA;AAAA,KACZ,MAAA;AACL,MAAA,MAAM,QAAW,GAAA,wBAAA;AAAA,QACf,MAAA;AAAA,QACA,uBAAA;AAAA,OACF,CAAA;AAEA,MAAA,YAAA,CAAa,QAAQ,CAAA,CAAA;AAAA,KACvB;AAAA,KACC,CAAC,uBAAA,EAAyB,MAAQ,EAAA,MAAA,EAAQ,YAAY,CAAC,CAAA,CAAA;AAG1D,EAAA,MAAM,oBAAuB,GAAA,WAAA;AAAA,IAC3B,CAAC,SAAgC,KAAsC,KAAA;AACrE,MAAA,gBAAA,GAAmB,SAAS,KAAK,CAAA,CAAA;AACjC,MAAA,IAAI,KAAM,CAAA,gBAAA;AAAkB,QAAA,OAAA;AAE5B,MAAA,IAAI,CAAC,MAAQ,EAAA;AACX,QAAA,OAAA;AAAA,OACF;AAEA,MAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AAErB,MAAA,MAAM,SAAS,YAAa,CAAA;AAAA,QAC1B,MAAM,OAAQ,CAAA,IAAA;AAAA,QACd,aAAa,OAAQ,CAAA,WAAA;AAAA,QACrB,QAAA,EAAU,KAAM,CAAA,QAAA,IAAY,EAAC;AAAA,OAC9B,CAAA,CAAA;AACD,MAAO,MAAA,CAAA,QAAA,CAAS,UAAW,CAAA,MAAA,CAAO,EAAE,CAAA,CAAA;AAAA,KACtC;AAAA,IACA,CAAC,gBAAA,EAAkB,MAAQ,EAAA,YAAA,EAAc,MAAM,QAAQ,CAAA;AAAA,GACzD,CAAA;AAEA,EAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,IACpB,CAAC,KAA0C,KAAA;AACzC,MAAA,SAAA,GAAY,KAAK,CAAA,CAAA;AAEjB,MAAA,IAAI,KAAM,CAAA,kBAAA,EAAwB,IAAA,CAAC,MAAQ,EAAA;AACzC,QAAA,OAAA;AAAA,OACF;AAEA,MAAI,IAAA,KAAA,CAAM,QAAQ,QAAU,EAAA;AAC1B,QAAC,MAAO,CAAA,KAAA,EACL,CAAA,mBAAA,GACA,GAAI,EAAA,CAAA;AAAA,OACT;AAAA,KACF;AAAA,IACA,CAAC,QAAQ,SAAS,CAAA;AAAA,GACpB,CAAA;AAEA,EAAA,MAAM,WAAc,GAAA,WAAA;AAAA,IAClB,CAAC,KAAuC,KAAA;AACtC,MAAA,OAAA,GAAU,KAAK,CAAA,CAAA;AAEf,MAAA,IAAI,MAAM,gBAAkB,EAAA;AAC1B,QAAA,OAAA;AAAA,OACF;AAGA,MAAA,KAAA,CAAM,eAAgB,EAAA,CAAA;AAAA,KACxB;AAAA,IACA,CAAC,OAAO,CAAA;AAAA,GACV,CAAA;AAEA,EAAI,IAAA,CAAC,MAAU,IAAA,CAAC,MAAQ,EAAA;AACtB,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EAAO,OAAA,YAAA;AAAA,oBACL,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAU,EAAA,+EAAA;AAAA,QACV,GAAK,EAAA,WAAA;AAAA,QACL,KAAO,EAAA;AAAA,UACL,QAAU,EAAA,QAAA;AAAA,UACV,GAAK,EAAA,CAAA;AAAA,UACL,IAAM,EAAA,CAAA;AAAA,UACN,SAAA,EAAW,CAAe,YAAA,EAAA,IAAA,CAAK,KAAM,CAAA,CAAC,CAAC,CAAO,IAAA,EAAA,IAAA,CAAK,KAAM,CAAA,CAAC,CAAC,CAAA,MAAA,CAAA;AAAA,UAC3D,QAAU,EAAA,aAAA;AAAA,SACZ;AAAA,QAEA,QAAA,kBAAA,GAAA;AAAA,UAACD,UAAA;AAAA,UAAA;AAAA,YACC,GAAK,EAAA,YAAA;AAAA,YACL,SAAS,EAAA,IAAA;AAAA,YACR,GAAG,KAAA;AAAA,YACJ,SAAW,EAAA,aAAA;AAAA,YACX,gBAAkB,EAAA,oBAAA;AAAA,YAClB,OAAS,EAAA,WAAA;AAAA,WAAA;AAAA,SACX;AAAA,OAAA;AAAA,KACF;AAAA,IACA,QAAS,CAAA,IAAA;AAAA,GACX,CAAA;AACF,CAAC;;;;"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"FloatingThreads.cjs","sources":["../../src/comments/FloatingThreads.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport type { BaseMetadata, DM, 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 } from \"@liveblocks/react-ui/_private\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { THREADS_PLUGIN_KEY } from \"../types\";\n\ntype FloatingThreadsComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<M extends BaseMetadata = DM>\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<M>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingThreadsComponents>;\n\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n}\n\nexport function FloatingThreads({\n threads,\n components,\n editor,\n ...props\n}: FloatingThreadsProps) {\n const Thread = components?.Thread ?? DefaultThread;\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?.selectedThreadPos ===\n next.pluginState?.selectedThreadPos &&\n prev.pluginState?.selectedThreadId ===\n next.pluginState?.selectedThreadId\n );\n },\n }) ?? { pluginState: undefined };\n\n const [activeThread, setActiveThread] = useState<ThreadData | null>(null);\n\n useEffect(() => {\n if (!editor || !pluginState) {\n setActiveThread(null);\n return;\n }\n const { selectedThreadId, selectedThreadPos } = pluginState;\n if (selectedThreadId === null || selectedThreadPos === null) {\n setActiveThread(null);\n return;\n }\n const active = (threads ?? []).find(\n (thread) => selectedThreadId === thread.id\n );\n setActiveThread(active ?? null);\n }, [editor, pluginState, threads]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (!editor || activeThread === null) return false;\n editor.commands.selectThread(null);\n return true;\n }, [activeThread, editor]);\n\n if (!activeThread || !editor || activeThread.resolved) return null;\n\n return (\n <FloatingThreadPortal\n thread={activeThread}\n editor={editor}\n container={document.body}\n {...props}\n >\n {activeThread && (\n <ThreadWrapper\n key={activeThread.id}\n thread={activeThread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-tiptap-floating-threads-thread\"\n />\n )}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n thread: ThreadData;\n editor: Editor;\n container: HTMLElement;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal({\n container,\n editor,\n thread,\n children,\n className,\n style,\n ...props\n}: FloatingThreadPortalProps) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"absolute\",\n placement: \"bottom\",\n middleware: [\n flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),\n shift({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n apply({ availableWidth, availableHeight, elements }) {\n elements.floating.style.setProperty(\n \"--lb-tiptap-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-tiptap-floating-threads-available-height\",\n `${availableHeight}px`\n );\n },\n }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n const updateRef = useCallback(() => {\n const el = editor.view.dom.querySelector(\n `[data-lb-thread-id=\"${thread.id}\"]`\n );\n if (el) {\n setReference(el);\n }\n }, [setReference, editor, thread.id]);\n\n // Remote cursor updates and other edits can cause the ref to break\n useEffect(() => {\n editor.on(\"transaction\", updateRef);\n return () => {\n editor.off(\"transaction\", updateRef);\n };\n }, [editor, updateRef]);\n\n useLayoutEffect(updateRef, [updateRef]);\n\n return createPortal(\n <div\n ref={setFloating}\n {...props}\n style={{\n ...style,\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n className={cn(\n \"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-threads\",\n className\n )}\n >\n {children}\n </div>,\n container\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n thread: ThreadData;\n Thread: ComponentType<ThreadProps>;\n onEscapeKeydown: () => void;\n}\n\nfunction ThreadWrapper({\n thread,\n Thread,\n onEscapeKeydown,\n onKeyDown,\n ...threadProps\n}: ThreadWrapperProps) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n // TODO: Add ability to preventDefault on keydown to override the default behavior, e.g. to show an alert dialog\n if (event.key === \"Escape\") {\n onEscapeKeydown();\n }\n },\n [onEscapeKeydown, onKeyDown]\n );\n\n return <Thread thread={thread} onKeyDown={handleKeyDown} {...threadProps} />;\n}\n"],"names":["DefaultThread","useEditorState","THREADS_PLUGIN_KEY","useState","useEffect","useCallback","jsx","useFloating","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","createPortal","cn"],"mappings":"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"} | ||
| {"version":3,"file":"FloatingThreads.cjs","sources":["../../src/comments/FloatingThreads.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport 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 } from \"@liveblocks/react-ui/_private\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { THREADS_PLUGIN_KEY } from \"../types\";\n\ntype FloatingThreadsComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<HTMLAttributes<HTMLDivElement>, \"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<FloatingThreadsComponents>;\n\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n}\n\nexport function FloatingThreads({\n threads,\n components,\n editor,\n ...props\n}: FloatingThreadsProps) {\n const Thread = components?.Thread ?? DefaultThread;\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?.selectedThreadPos ===\n next.pluginState?.selectedThreadPos &&\n prev.pluginState?.selectedThreadId ===\n next.pluginState?.selectedThreadId\n );\n },\n }) ?? { pluginState: undefined };\n\n const [activeThread, setActiveThread] = useState<ThreadData | null>(null);\n\n useEffect(() => {\n if (!editor || !pluginState) {\n setActiveThread(null);\n return;\n }\n const { selectedThreadId, selectedThreadPos } = pluginState;\n if (selectedThreadId === null || selectedThreadPos === null) {\n setActiveThread(null);\n return;\n }\n const active = (threads ?? []).find(\n (thread) => selectedThreadId === thread.id\n );\n setActiveThread(active ?? null);\n }, [editor, pluginState, threads]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (!editor || activeThread === null) return false;\n editor.commands.selectThread(null);\n return true;\n }, [activeThread, editor]);\n\n if (!activeThread || !editor || activeThread.resolved) return null;\n\n return (\n <FloatingThreadPortal\n thread={activeThread}\n editor={editor}\n container={document.body}\n {...props}\n >\n {activeThread && (\n <ThreadWrapper\n key={activeThread.id}\n thread={activeThread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-tiptap-floating-threads-thread\"\n />\n )}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n thread: ThreadData;\n editor: Editor;\n container: HTMLElement;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal({\n container,\n editor,\n thread,\n children,\n className,\n style,\n ...props\n}: FloatingThreadPortalProps) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"absolute\",\n placement: \"bottom\",\n middleware: [\n flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),\n shift({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n apply({ availableWidth, availableHeight, elements }) {\n elements.floating.style.setProperty(\n \"--lb-tiptap-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-tiptap-floating-threads-available-height\",\n `${availableHeight}px`\n );\n },\n }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n const updateRef = useCallback(() => {\n const el = editor.view.dom.querySelector(\n `[data-lb-thread-id=\"${thread.id}\"]`\n );\n if (el) {\n setReference(el);\n }\n }, [setReference, editor, thread.id]);\n\n // Remote cursor updates and other edits can cause the ref to break\n useEffect(() => {\n editor.on(\"transaction\", updateRef);\n return () => {\n editor.off(\"transaction\", updateRef);\n };\n }, [editor, updateRef]);\n\n useLayoutEffect(updateRef, [updateRef]);\n\n return createPortal(\n <div\n ref={setFloating}\n {...props}\n style={{\n ...style,\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n className={cn(\n \"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-threads\",\n className\n )}\n >\n {children}\n </div>,\n container\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n thread: ThreadData;\n Thread: ComponentType<ThreadProps>;\n onEscapeKeydown: () => void;\n}\n\nfunction ThreadWrapper({\n thread,\n Thread,\n onEscapeKeydown,\n onKeyDown,\n ...threadProps\n}: ThreadWrapperProps) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n // TODO: Add ability to preventDefault on keydown to override the default behavior, e.g. to show an alert dialog\n if (event.key === \"Escape\") {\n onEscapeKeydown();\n }\n },\n [onEscapeKeydown, onKeyDown]\n );\n\n return <Thread thread={thread} onKeyDown={handleKeyDown} {...threadProps} />;\n}\n"],"names":["DefaultThread","useEditorState","THREADS_PLUGIN_KEY","useState","useEffect","useCallback","jsx","useFloating","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","createPortal","cn"],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"FloatingThreads.js","sources":["../../src/comments/FloatingThreads.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport type { BaseMetadata, DM, 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 } from \"@liveblocks/react-ui/_private\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { THREADS_PLUGIN_KEY } from \"../types\";\n\ntype FloatingThreadsComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<M extends BaseMetadata = DM>\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<M>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingThreadsComponents>;\n\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n}\n\nexport function FloatingThreads({\n threads,\n components,\n editor,\n ...props\n}: FloatingThreadsProps) {\n const Thread = components?.Thread ?? DefaultThread;\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?.selectedThreadPos ===\n next.pluginState?.selectedThreadPos &&\n prev.pluginState?.selectedThreadId ===\n next.pluginState?.selectedThreadId\n );\n },\n }) ?? { pluginState: undefined };\n\n const [activeThread, setActiveThread] = useState<ThreadData | null>(null);\n\n useEffect(() => {\n if (!editor || !pluginState) {\n setActiveThread(null);\n return;\n }\n const { selectedThreadId, selectedThreadPos } = pluginState;\n if (selectedThreadId === null || selectedThreadPos === null) {\n setActiveThread(null);\n return;\n }\n const active = (threads ?? []).find(\n (thread) => selectedThreadId === thread.id\n );\n setActiveThread(active ?? null);\n }, [editor, pluginState, threads]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (!editor || activeThread === null) return false;\n editor.commands.selectThread(null);\n return true;\n }, [activeThread, editor]);\n\n if (!activeThread || !editor || activeThread.resolved) return null;\n\n return (\n <FloatingThreadPortal\n thread={activeThread}\n editor={editor}\n container={document.body}\n {...props}\n >\n {activeThread && (\n <ThreadWrapper\n key={activeThread.id}\n thread={activeThread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-tiptap-floating-threads-thread\"\n />\n )}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n thread: ThreadData;\n editor: Editor;\n container: HTMLElement;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal({\n container,\n editor,\n thread,\n children,\n className,\n style,\n ...props\n}: FloatingThreadPortalProps) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"absolute\",\n placement: \"bottom\",\n middleware: [\n flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),\n shift({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n apply({ availableWidth, availableHeight, elements }) {\n elements.floating.style.setProperty(\n \"--lb-tiptap-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-tiptap-floating-threads-available-height\",\n `${availableHeight}px`\n );\n },\n }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n const updateRef = useCallback(() => {\n const el = editor.view.dom.querySelector(\n `[data-lb-thread-id=\"${thread.id}\"]`\n );\n if (el) {\n setReference(el);\n }\n }, [setReference, editor, thread.id]);\n\n // Remote cursor updates and other edits can cause the ref to break\n useEffect(() => {\n editor.on(\"transaction\", updateRef);\n return () => {\n editor.off(\"transaction\", updateRef);\n };\n }, [editor, updateRef]);\n\n useLayoutEffect(updateRef, [updateRef]);\n\n return createPortal(\n <div\n ref={setFloating}\n {...props}\n style={{\n ...style,\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n className={cn(\n \"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-threads\",\n className\n )}\n >\n {children}\n </div>,\n container\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n thread: ThreadData;\n Thread: ComponentType<ThreadProps>;\n onEscapeKeydown: () => void;\n}\n\nfunction ThreadWrapper({\n thread,\n Thread,\n onEscapeKeydown,\n onKeyDown,\n ...threadProps\n}: ThreadWrapperProps) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n // TODO: Add ability to preventDefault on keydown to override the default behavior, e.g. to show an alert dialog\n if (event.key === \"Escape\") {\n onEscapeKeydown();\n }\n },\n [onEscapeKeydown, onKeyDown]\n );\n\n return <Thread thread={thread} onKeyDown={handleKeyDown} {...threadProps} />;\n}\n"],"names":["Thread","DefaultThread"],"mappings":";;;;;;;;;;AAqDO,SAAS,eAAgB,CAAA;AAAA,EAC9B,OAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAG,KAAA;AACL,CAAyB,EAAA;AACvB,EAAM,MAAAA,QAAA,GAAS,YAAY,MAAU,IAAAC,MAAA,CAAA;AAErC,EAAM,MAAA,EAAE,WAAY,EAAA,GAAI,cAAe,CAAA;AAAA,IACrC,MAAA;AAAA,IACA,QAAA,EAAU,CAAC,GAAQ,KAAA;AACjB,MAAI,IAAA,CAAC,KAAK,MAAQ,EAAA,KAAA;AAAO,QAAO,OAAA,EAAE,aAAa,KAAU,CAAA,EAAA,CAAA;AACzD,MAAA,MAAM,KAAQ,GAAA,kBAAA,CAAmB,QAAS,CAAA,GAAA,CAAI,OAAO,KAAK,CAAA,CAAA;AAC1D,MAAO,OAAA;AAAA,QACL,WAAa,EAAA,KAAA;AAAA,OACf,CAAA;AAAA,KACF;AAAA,IACA,UAAA,EAAY,CAAC,IAAA,EAAM,IAAS,KAAA;AAC1B,MAAI,IAAA,CAAC,QAAQ,CAAC,IAAA;AAAM,QAAO,OAAA,KAAA,CAAA;AAC3B,MACE,OAAA,IAAA,CAAK,WAAa,EAAA,iBAAA,KAChB,IAAK,CAAA,WAAA,EAAa,qBACpB,IAAK,CAAA,WAAA,EAAa,gBAChB,KAAA,IAAA,CAAK,WAAa,EAAA,gBAAA,CAAA;AAAA,KAExB;AAAA,GACD,CAAA,IAAK,EAAE,WAAA,EAAa,KAAU,CAAA,EAAA,CAAA;AAE/B,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAA4B,IAAI,CAAA,CAAA;AAExE,EAAA,SAAA,CAAU,MAAM;AACd,IAAI,IAAA,CAAC,MAAU,IAAA,CAAC,WAAa,EAAA;AAC3B,MAAA,eAAA,CAAgB,IAAI,CAAA,CAAA;AACpB,MAAA,OAAA;AAAA,KACF;AACA,IAAM,MAAA,EAAE,gBAAkB,EAAA,iBAAA,EAAsB,GAAA,WAAA,CAAA;AAChD,IAAI,IAAA,gBAAA,KAAqB,IAAQ,IAAA,iBAAA,KAAsB,IAAM,EAAA;AAC3D,MAAA,eAAA,CAAgB,IAAI,CAAA,CAAA;AACpB,MAAA,OAAA;AAAA,KACF;AACA,IAAM,MAAA,MAAA,GAAA,CAAU,OAAW,IAAA,EAAI,EAAA,IAAA;AAAA,MAC7B,CAAC,MAAW,KAAA,gBAAA,KAAqB,MAAO,CAAA,EAAA;AAAA,KAC1C,CAAA;AACA,IAAA,eAAA,CAAgB,UAAU,IAAI,CAAA,CAAA;AAAA,GAC7B,EAAA,CAAC,MAAQ,EAAA,WAAA,EAAa,OAAO,CAAC,CAAA,CAAA;AAEjC,EAAM,MAAA,mBAAA,GAAsB,YAAY,MAAe;AACrD,IAAI,IAAA,CAAC,UAAU,YAAiB,KAAA,IAAA;AAAM,MAAO,OAAA,KAAA,CAAA;AAC7C,IAAO,MAAA,CAAA,QAAA,CAAS,aAAa,IAAI,CAAA,CAAA;AACjC,IAAO,OAAA,IAAA,CAAA;AAAA,GACN,EAAA,CAAC,YAAc,EAAA,MAAM,CAAC,CAAA,CAAA;AAEzB,EAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,MAAA,IAAU,YAAa,CAAA,QAAA;AAAU,IAAO,OAAA,IAAA,CAAA;AAE9D,EACE,uBAAA,GAAA;AAAA,IAAC,oBAAA;AAAA,IAAA;AAAA,MACC,MAAQ,EAAA,YAAA;AAAA,MACR,MAAA;AAAA,MACA,WAAW,QAAS,CAAA,IAAA;AAAA,MACnB,GAAG,KAAA;AAAA,MAEH,QACC,EAAA,YAAA,oBAAA,GAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UAEC,MAAQ,EAAA,YAAA;AAAA,kBACRD,QAAA;AAAA,UACA,eAAiB,EAAA,mBAAA;AAAA,UACjB,SAAU,EAAA,mCAAA;AAAA,SAAA;AAAA,QAJL,YAAa,CAAA,EAAA;AAAA,OAKpB;AAAA,KAAA;AAAA,GAEJ,CAAA;AAEJ,CAAA;AAUO,MAAM,iCAAoC,GAAA,GAAA;AAEjD,SAAS,oBAAqB,CAAA;AAAA,EAC5B,SAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA,GAAG,KAAA;AACL,CAA8B,EAAA;AAC5B,EAAM,MAAA;AAAA,IACJ,IAAA,EAAM,EAAE,YAAA,EAAc,WAAY,EAAA;AAAA,IAClC,QAAA;AAAA,IACA,CAAA;AAAA,IACA,CAAA;AAAA,MACE,WAAY,CAAA;AAAA,IACd,QAAU,EAAA,UAAA;AAAA,IACV,SAAW,EAAA,QAAA;AAAA,IACX,UAAY,EAAA;AAAA,MACV,KAAK,EAAE,OAAA,EAAS,iCAAmC,EAAA,SAAA,EAAW,OAAO,CAAA;AAAA,MACrE,OAAO,EAAE,CAAA;AAAA,MACT,IAAK,CAAA,EAAE,OAAS,EAAA,iCAAA,EAAmC,CAAA;AAAA,MACnD,KAAM,CAAA;AAAA,QACJ,OAAS,EAAA,iCAAA;AAAA,QACT,SAAS,UAAW,EAAA;AAAA,OACrB,CAAA;AAAA,MACD,IAAK,CAAA;AAAA,QACH,OAAS,EAAA,iCAAA;AAAA,QACT,KAAM,CAAA,EAAE,cAAgB,EAAA,eAAA,EAAiB,UAAY,EAAA;AACnD,UAAA,QAAA,CAAS,SAAS,KAAM,CAAA,WAAA;AAAA,YACtB,8CAAA;AAAA,YACA,GAAG,cAAc,CAAA,EAAA,CAAA;AAAA,WACnB,CAAA;AACA,UAAA,QAAA,CAAS,SAAS,KAAM,CAAA,WAAA;AAAA,YACtB,+CAAA;AAAA,YACA,GAAG,eAAe,CAAA,EAAA,CAAA;AAAA,WACpB,CAAA;AAAA,SACF;AAAA,OACD,CAAA;AAAA,KACH;AAAA,IACA,oBAAA,EAAsB,IAAI,IAAS,KAAA;AACjC,MAAO,OAAA,UAAA,CAAW,GAAG,IAAM,EAAA;AAAA,QACzB,cAAgB,EAAA,IAAA;AAAA,OACjB,CAAA,CAAA;AAAA,KACH;AAAA,GACD,CAAA,CAAA;AAED,EAAM,MAAA,SAAA,GAAY,YAAY,MAAM;AAClC,IAAM,MAAA,EAAA,GAAK,MAAO,CAAA,IAAA,CAAK,GAAI,CAAA,aAAA;AAAA,MACzB,CAAA,oBAAA,EAAuB,OAAO,EAAE,CAAA,EAAA,CAAA;AAAA,KAClC,CAAA;AACA,IAAA,IAAI,EAAI,EAAA;AACN,MAAA,YAAA,CAAa,EAAE,CAAA,CAAA;AAAA,KACjB;AAAA,KACC,CAAC,YAAA,EAAc,MAAQ,EAAA,MAAA,CAAO,EAAE,CAAC,CAAA,CAAA;AAGpC,EAAA,SAAA,CAAU,MAAM;AACd,IAAO,MAAA,CAAA,EAAA,CAAG,eAAe,SAAS,CAAA,CAAA;AAClC,IAAA,OAAO,MAAM;AACX,MAAO,MAAA,CAAA,GAAA,CAAI,eAAe,SAAS,CAAA,CAAA;AAAA,KACrC,CAAA;AAAA,GACC,EAAA,CAAC,MAAQ,EAAA,SAAS,CAAC,CAAA,CAAA;AAEtB,EAAgB,eAAA,CAAA,SAAA,EAAW,CAAC,SAAS,CAAC,CAAA,CAAA;AAEtC,EAAO,OAAA,YAAA;AAAA,oBACL,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAK,EAAA,WAAA;AAAA,QACJ,GAAG,KAAA;AAAA,QACJ,KAAO,EAAA;AAAA,UACL,GAAG,KAAA;AAAA,UACH,QAAU,EAAA,QAAA;AAAA,UACV,GAAK,EAAA,CAAA;AAAA,UACL,IAAM,EAAA,CAAA;AAAA,UACN,SAAA,EAAW,CAAe,YAAA,EAAA,IAAA,CAAK,KAAM,CAAA,CAAC,CAAC,CAAO,IAAA,EAAA,IAAA,CAAK,KAAM,CAAA,CAAC,CAAC,CAAA,MAAA,CAAA;AAAA,UAC3D,QAAU,EAAA,aAAA;AAAA,SACZ;AAAA,QACA,SAAW,EAAA,EAAA;AAAA,UACT,8EAAA;AAAA,UACA,SAAA;AAAA,SACF;AAAA,QAEC,QAAA;AAAA,OAAA;AAAA,KACH;AAAA,IACA,SAAA;AAAA,GACF,CAAA;AACF,CAAA;AAQA,SAAS,aAAc,CAAA;AAAA,EACrB,MAAA;AAAA,EACA,MAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG,WAAA;AACL,CAAuB,EAAA;AACrB,EAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,IACpB,CAAC,KAAyC,KAAA;AACxC,MAAA,SAAA,GAAY,KAAK,CAAA,CAAA;AAGjB,MAAI,IAAA,KAAA,CAAM,QAAQ,QAAU,EAAA;AAC1B,QAAgB,eAAA,EAAA,CAAA;AAAA,OAClB;AAAA,KACF;AAAA,IACA,CAAC,iBAAiB,SAAS,CAAA;AAAA,GAC7B,CAAA;AAEA,EAAA,2BAAQ,MAAO,EAAA,EAAA,MAAA,EAAgB,SAAW,EAAA,aAAA,EAAgB,GAAG,WAAa,EAAA,CAAA,CAAA;AAC5E;;;;"} | ||
| {"version":3,"file":"FloatingThreads.js","sources":["../../src/comments/FloatingThreads.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport 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 } from \"@liveblocks/react-ui/_private\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { THREADS_PLUGIN_KEY } from \"../types\";\n\ntype FloatingThreadsComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<HTMLAttributes<HTMLDivElement>, \"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<FloatingThreadsComponents>;\n\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n}\n\nexport function FloatingThreads({\n threads,\n components,\n editor,\n ...props\n}: FloatingThreadsProps) {\n const Thread = components?.Thread ?? DefaultThread;\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?.selectedThreadPos ===\n next.pluginState?.selectedThreadPos &&\n prev.pluginState?.selectedThreadId ===\n next.pluginState?.selectedThreadId\n );\n },\n }) ?? { pluginState: undefined };\n\n const [activeThread, setActiveThread] = useState<ThreadData | null>(null);\n\n useEffect(() => {\n if (!editor || !pluginState) {\n setActiveThread(null);\n return;\n }\n const { selectedThreadId, selectedThreadPos } = pluginState;\n if (selectedThreadId === null || selectedThreadPos === null) {\n setActiveThread(null);\n return;\n }\n const active = (threads ?? []).find(\n (thread) => selectedThreadId === thread.id\n );\n setActiveThread(active ?? null);\n }, [editor, pluginState, threads]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (!editor || activeThread === null) return false;\n editor.commands.selectThread(null);\n return true;\n }, [activeThread, editor]);\n\n if (!activeThread || !editor || activeThread.resolved) return null;\n\n return (\n <FloatingThreadPortal\n thread={activeThread}\n editor={editor}\n container={document.body}\n {...props}\n >\n {activeThread && (\n <ThreadWrapper\n key={activeThread.id}\n thread={activeThread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-tiptap-floating-threads-thread\"\n />\n )}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n thread: ThreadData;\n editor: Editor;\n container: HTMLElement;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal({\n container,\n editor,\n thread,\n children,\n className,\n style,\n ...props\n}: FloatingThreadPortalProps) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"absolute\",\n placement: \"bottom\",\n middleware: [\n flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),\n shift({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n apply({ availableWidth, availableHeight, elements }) {\n elements.floating.style.setProperty(\n \"--lb-tiptap-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-tiptap-floating-threads-available-height\",\n `${availableHeight}px`\n );\n },\n }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n const updateRef = useCallback(() => {\n const el = editor.view.dom.querySelector(\n `[data-lb-thread-id=\"${thread.id}\"]`\n );\n if (el) {\n setReference(el);\n }\n }, [setReference, editor, thread.id]);\n\n // Remote cursor updates and other edits can cause the ref to break\n useEffect(() => {\n editor.on(\"transaction\", updateRef);\n return () => {\n editor.off(\"transaction\", updateRef);\n };\n }, [editor, updateRef]);\n\n useLayoutEffect(updateRef, [updateRef]);\n\n return createPortal(\n <div\n ref={setFloating}\n {...props}\n style={{\n ...style,\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n className={cn(\n \"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-threads\",\n className\n )}\n >\n {children}\n </div>,\n container\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n thread: ThreadData;\n Thread: ComponentType<ThreadProps>;\n onEscapeKeydown: () => void;\n}\n\nfunction ThreadWrapper({\n thread,\n Thread,\n onEscapeKeydown,\n onKeyDown,\n ...threadProps\n}: ThreadWrapperProps) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n // TODO: Add ability to preventDefault on keydown to override the default behavior, e.g. to show an alert dialog\n if (event.key === \"Escape\") {\n onEscapeKeydown();\n }\n },\n [onEscapeKeydown, onKeyDown]\n );\n\n return <Thread thread={thread} onKeyDown={handleKeyDown} {...threadProps} />;\n}\n"],"names":["Thread","DefaultThread"],"mappings":"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"} |
+13
-8
@@ -1,2 +0,2 @@ | ||
| import { ContextualPromptContext, ContextualPromptResponse, ThreadData, Relax, MentionData, BaseMetadata, DM, HistoryVersion } from '@liveblocks/core'; | ||
| import { ContextualPromptContext, ContextualPromptResponse, ThreadData, Relax, MentionData, BaseMetadata, DTM, DCM, HistoryVersion } from '@liveblocks/core'; | ||
| import { LiveblocksYjsProvider } from '@liveblocks/yjs'; | ||
@@ -259,7 +259,7 @@ import { Content, Range, Extension, Node } from '@tiptap/core'; | ||
| }; | ||
| interface AnchoredThreadsProps<M extends BaseMetadata = DM> extends Omit<ComponentPropsWithoutRef<"div">, "children"> { | ||
| interface AnchoredThreadsProps<TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM> extends Omit<ComponentPropsWithoutRef<"div">, "children"> { | ||
| /** | ||
| * The threads to display. | ||
| */ | ||
| threads: ThreadData<M>[]; | ||
| threads: ThreadData<TM, CM>[]; | ||
| /** | ||
@@ -276,6 +276,11 @@ * Override the component's components. | ||
| type ExcludeProps<T, K extends Record<string, unknown>> = Omit<Exclude<T, T & K>, keyof K>; | ||
| type ComposerPropsCreateThread<TM extends BaseMetadata$1, CM extends BaseMetadata$1> = ExcludeProps<ComposerProps<TM, CM>, { | ||
| threadId: string; | ||
| commentId: string; | ||
| }>; | ||
| type FloatingComposerComponents = { | ||
| Composer: ComponentType<Omit<ComposerProps, "threadId" | "commentId">>; | ||
| Composer: ComponentType<ComposerPropsCreateThread<DTM, DCM>>; | ||
| }; | ||
| type FloatingComposerProps<M extends BaseMetadata$1 = DM> = Omit<ComposerProps<M>, "threadId" | "commentId"> & { | ||
| type FloatingComposerProps<TM extends BaseMetadata$1 = DTM, CM extends BaseMetadata$1 = DCM> = ComposerPropsCreateThread<TM, CM> & { | ||
| /** | ||
@@ -290,3 +295,3 @@ * Override the component's components. | ||
| }; | ||
| declare const FloatingComposer: react.ForwardRefExoticComponent<Omit<ComposerProps<BaseMetadata$1>, "threadId" | "commentId"> & { | ||
| declare const FloatingComposer: react.ForwardRefExoticComponent<ComposerPropsCreateThread<BaseMetadata$1, BaseMetadata$1> & { | ||
| /** | ||
@@ -305,7 +310,7 @@ * Override the component's components. | ||
| }; | ||
| interface FloatingThreadsProps<M extends BaseMetadata = DM> extends Omit<HTMLAttributes<HTMLDivElement>, "children"> { | ||
| interface FloatingThreadsProps<TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM> extends Omit<HTMLAttributes<HTMLDivElement>, "children"> { | ||
| /** | ||
| * The threads to display. | ||
| */ | ||
| threads: ThreadData<M>[]; | ||
| threads: ThreadData<TM, CM>[]; | ||
| /** | ||
@@ -312,0 +317,0 @@ * Override the component's components. |
+13
-8
@@ -1,2 +0,2 @@ | ||
| import { ContextualPromptContext, ContextualPromptResponse, ThreadData, Relax, MentionData, BaseMetadata, DM, HistoryVersion } from '@liveblocks/core'; | ||
| import { ContextualPromptContext, ContextualPromptResponse, ThreadData, Relax, MentionData, BaseMetadata, DTM, DCM, HistoryVersion } from '@liveblocks/core'; | ||
| import { LiveblocksYjsProvider } from '@liveblocks/yjs'; | ||
@@ -259,7 +259,7 @@ import { Content, Range, Extension, Node } from '@tiptap/core'; | ||
| }; | ||
| interface AnchoredThreadsProps<M extends BaseMetadata = DM> extends Omit<ComponentPropsWithoutRef<"div">, "children"> { | ||
| interface AnchoredThreadsProps<TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM> extends Omit<ComponentPropsWithoutRef<"div">, "children"> { | ||
| /** | ||
| * The threads to display. | ||
| */ | ||
| threads: ThreadData<M>[]; | ||
| threads: ThreadData<TM, CM>[]; | ||
| /** | ||
@@ -276,6 +276,11 @@ * Override the component's components. | ||
| type ExcludeProps<T, K extends Record<string, unknown>> = Omit<Exclude<T, T & K>, keyof K>; | ||
| type ComposerPropsCreateThread<TM extends BaseMetadata$1, CM extends BaseMetadata$1> = ExcludeProps<ComposerProps<TM, CM>, { | ||
| threadId: string; | ||
| commentId: string; | ||
| }>; | ||
| type FloatingComposerComponents = { | ||
| Composer: ComponentType<Omit<ComposerProps, "threadId" | "commentId">>; | ||
| Composer: ComponentType<ComposerPropsCreateThread<DTM, DCM>>; | ||
| }; | ||
| type FloatingComposerProps<M extends BaseMetadata$1 = DM> = Omit<ComposerProps<M>, "threadId" | "commentId"> & { | ||
| type FloatingComposerProps<TM extends BaseMetadata$1 = DTM, CM extends BaseMetadata$1 = DCM> = ComposerPropsCreateThread<TM, CM> & { | ||
| /** | ||
@@ -290,3 +295,3 @@ * Override the component's components. | ||
| }; | ||
| declare const FloatingComposer: react.ForwardRefExoticComponent<Omit<ComposerProps<BaseMetadata$1>, "threadId" | "commentId"> & { | ||
| declare const FloatingComposer: react.ForwardRefExoticComponent<ComposerPropsCreateThread<BaseMetadata$1, BaseMetadata$1> & { | ||
| /** | ||
@@ -305,7 +310,7 @@ * Override the component's components. | ||
| }; | ||
| interface FloatingThreadsProps<M extends BaseMetadata = DM> extends Omit<HTMLAttributes<HTMLDivElement>, "children"> { | ||
| interface FloatingThreadsProps<TM extends BaseMetadata = DTM, CM extends BaseMetadata = DCM> extends Omit<HTMLAttributes<HTMLDivElement>, "children"> { | ||
| /** | ||
| * The threads to display. | ||
| */ | ||
| threads: ThreadData<M>[]; | ||
| threads: ThreadData<TM, CM>[]; | ||
| /** | ||
@@ -312,0 +317,0 @@ * Override the component's components. |
@@ -7,2 +7,3 @@ 'use strict'; | ||
| var TogglePrimitive = require('@radix-ui/react-toggle'); | ||
| var react$1 = require('@tiptap/react'); | ||
| var react = require('react'); | ||
@@ -393,2 +394,7 @@ var context = require('../context.cjs'); | ||
| }, forwardedRef) => { | ||
| react$1.useEditorState({ | ||
| editor, | ||
| equalityFn: Object.is, | ||
| selector: (ctx) => ctx.editor?.state | ||
| }); | ||
| if (!editor) { | ||
@@ -395,0 +401,0 @@ return null; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"Toolbar.cjs","sources":["../../src/toolbar/Toolbar.tsx"],"sourcesContent":["import {\n BlockquoteIcon,\n BoldIcon,\n Button,\n CheckIcon,\n cn,\n CodeIcon,\n CommentIcon,\n H1Icon,\n H2Icon,\n H3Icon,\n ItalicIcon,\n ListOrderedIcon,\n ListUnorderedIcon,\n QuestionMarkIcon,\n RedoIcon,\n SelectButton,\n ShortcutTooltip,\n SparklesIcon,\n StrikethroughIcon,\n TextIcon,\n TooltipProvider,\n UnderlineIcon,\n UndoIcon,\n} from \"@liveblocks/react-ui/_private\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type { Editor } from \"@tiptap/react\";\nimport type {\n ComponentProps,\n ComponentType,\n KeyboardEvent,\n ReactNode,\n} from \"react\";\nimport { forwardRef, useCallback, useContext, useMemo } from \"react\";\n\nimport { EditorProvider, useCurrentEditor } from \"../context\";\nimport type { AiExtensionStorage, ExtendedChainedCommands } from \"../types\";\nimport { FloatingToolbarContext, FloatingToolbarExternal } from \"./shared\";\n\nexport const BLOCK_SELECT_SIDE_OFFSET = 10;\nexport const FLOATING_ELEMENT_COLLISION_PADDING = 10;\n\nexport interface ToolbarSlotProps {\n editor: Editor;\n}\n\nexport type ToolbarSlot = ReactNode | ComponentType<ToolbarSlotProps>;\n\nexport interface ToolbarProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n\n /**\n * The content of the toolbar, overriding the default content.\n * Use the `before` and `after` props if you want to keep and extend the default content.\n */\n children?: ToolbarSlot;\n\n /**\n * The content to display at the start of the toolbar.\n */\n before?: ToolbarSlot;\n\n /**\n * The content to display at the end of the toolbar.\n */\n after?: ToolbarSlot;\n}\n\nexport interface ToolbarButtonProps extends ComponentProps<\"button\"> {\n /**\n * The name of this button displayed in its tooltip.\n */\n name: string;\n\n /**\n * An optional icon displayed in this button.\n */\n icon?: ReactNode;\n\n /**\n * An optional keyboard shortcut displayed in this button's tooltip.\n *\n * @example\n * \"Mod-Alt-B\" → \"⌘⌥B\" in Apple environments, \"⌃⌥B\" otherwise\n * \"Ctrl-Shift-Escape\" → \"⌃⇧⎋\"\n * \"Space\" → \"␣\"\n */\n shortcut?: string;\n}\n\nexport interface ToolbarToggleProps extends ToolbarButtonProps {\n /**\n * Whether the button is toggled.\n */\n active: boolean;\n}\n\nexport interface ToolbarBlockSelectorItem {\n /**\n * The name of this block element, displayed as the label of this item.\n */\n name: string;\n\n /**\n * Optionally replace the name used as the label of this item by any content.\n */\n label?: ReactNode;\n\n /**\n * An optional icon displayed in this item.\n */\n icon?: ReactNode;\n\n /**\n * Whether this block element is currently active.\n * Set to `\"default\"` to display this item when no other item is active.\n */\n isActive: ((editor: Editor) => boolean) | \"default\";\n\n /**\n * A callback invoked when this item is selected.\n */\n setActive: (editor: Editor) => void;\n}\n\nexport interface ToolbarBlockSelectorProps extends ComponentProps<\"button\"> {\n /**\n * The items displayed in this block selector.\n * When provided as an array, the default items are overridden. To avoid this,\n * a function can be provided instead and it will receive the default items.\n *\n * @example\n * <Toolbar.BlockSelector\n * items={[\n * {\n * name: \"Text\",\n * isActive: \"default\",\n * setActive: () => { ... },\n * },\n * {\n * name: \"Heading 1\",\n * isActive: () => { ... },\n * setActive: () => { ... },\n * },\n * ]}\n * />\n *\n * @example\n * <Toolbar.BlockSelector\n * items={(defaultItems) => [\n * ...defaultItems,\n * {\n * name: \"Custom block\",\n * isActive: () => { ... },\n * setActive: () => { ... },\n * },\n * ]}\n * />\n */\n items?:\n | ToolbarBlockSelectorItem[]\n | ((\n defaultItems: ToolbarBlockSelectorItem[]\n ) => ToolbarBlockSelectorItem[]);\n}\n\nexport type ToolbarSeparatorProps = ComponentProps<\"div\">;\n\nexport function applyToolbarSlot(\n slot: ToolbarSlot,\n props: ToolbarSlotProps\n): ReactNode {\n if (typeof slot === \"function\") {\n const Component = slot;\n\n return <Component {...props} />;\n }\n\n return slot;\n}\n\nconst ToolbarButton = forwardRef<HTMLButtonElement, ToolbarButtonProps>(\n ({ icon, children, name, shortcut, onKeyDown, ...props }, forwardedRef) => {\n const floatingToolbarContext = useContext(FloatingToolbarContext);\n const closeFloatingToolbar = floatingToolbarContext?.close;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n\n if (\n !event.isDefaultPrevented() &&\n closeFloatingToolbar &&\n event.key === \"Escape\"\n ) {\n closeFloatingToolbar();\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [onKeyDown, closeFloatingToolbar]\n );\n\n return (\n <ShortcutTooltip content={name} shortcut={shortcut}>\n <Button\n type=\"button\"\n variant=\"toolbar\"\n ref={forwardedRef}\n icon={icon}\n aria-label={!children ? name : undefined}\n // Safari doesn't mark buttons as focusable, which breaks `relatedTarget`\n // in focus/blur events. https://bugs.webkit.org/show_bug.cgi?id=254655\n tabIndex={0}\n {...props}\n onKeyDown={handleKeyDown}\n >\n {!children && !icon ? name : children}\n </Button>\n </ShortcutTooltip>\n );\n }\n);\n\nconst ToolbarToggle = forwardRef<HTMLButtonElement, ToolbarToggleProps>(\n ({ active, ...props }, forwardedRef) => {\n return (\n <TogglePrimitive.Root asChild pressed={active}>\n <ToolbarButton ref={forwardedRef} {...props} />\n </TogglePrimitive.Root>\n );\n }\n);\n\nfunction createDefaultBlockSelectorItems(\n editor: Editor\n): ToolbarBlockSelectorItem[] {\n const items: (ToolbarBlockSelectorItem | null)[] = [\n {\n name: \"Text\",\n icon: <TextIcon />,\n isActive: \"default\",\n setActive: (editor) => editor.chain().focus().clearNodes().run(),\n },\n \"toggleHeading\" in editor.commands\n ? {\n name: \"Heading 1\",\n icon: <H1Icon />,\n isActive: (editor) => editor.isActive(\"heading\", { level: 1 }),\n setActive: (editor) =>\n (\n editor.chain().focus().clearNodes() as ExtendedChainedCommands<\n \"toggleHeading\",\n [{ level: number }]\n >\n )\n .toggleHeading({ level: 1 })\n .run(),\n }\n : null,\n \"toggleHeading\" in editor.commands\n ? {\n name: \"Heading 2\",\n icon: <H2Icon />,\n isActive: (editor) => editor.isActive(\"heading\", { level: 2 }),\n setActive: (editor) =>\n (\n editor.chain().focus().clearNodes() as ExtendedChainedCommands<\n \"toggleHeading\",\n [{ level: number }]\n >\n )\n .toggleHeading({ level: 2 })\n .run(),\n }\n : null,\n \"toggleHeading\" in editor.commands\n ? {\n name: \"Heading 3\",\n icon: <H3Icon />,\n isActive: (editor) => editor.isActive(\"heading\", { level: 3 }),\n setActive: (editor) =>\n (\n editor.chain().focus().clearNodes() as ExtendedChainedCommands<\n \"toggleHeading\",\n [{ level: number }]\n >\n )\n .toggleHeading({ level: 3 })\n .run(),\n }\n : null,\n \"toggleBulletList\" in editor.commands\n ? {\n name: \"Bullet list\",\n icon: <ListUnorderedIcon />,\n isActive: (editor) => editor.isActive(\"bulletList\"),\n setActive: (editor) =>\n (\n editor\n .chain()\n .focus()\n .clearNodes() as ExtendedChainedCommands<\"toggleBulletList\">\n )\n .toggleBulletList()\n .run(),\n }\n : null,\n \"toggleOrderedList\" in editor.commands\n ? {\n name: \"Numbered list\",\n icon: <ListOrderedIcon />,\n isActive: (editor) => editor.isActive(\"orderedList\"),\n setActive: (editor) =>\n (\n editor\n .chain()\n .focus()\n .clearNodes() as ExtendedChainedCommands<\"toggleOrderedList\">\n )\n .toggleOrderedList()\n .run(),\n }\n : null,\n \"toggleBlockquote\" in editor.commands\n ? {\n name: \"Blockquote\",\n icon: <BlockquoteIcon />,\n isActive: (editor) => editor.isActive(\"blockquote\"),\n setActive: (editor) =>\n (\n editor\n .chain()\n .focus()\n .clearNodes() as ExtendedChainedCommands<\"toggleBlockquote\">\n )\n .toggleBlockquote()\n .run(),\n }\n : null,\n ];\n\n return items.filter(Boolean) as ToolbarBlockSelectorItem[];\n}\n\nconst ToolbarBlockSelector = forwardRef<\n HTMLButtonElement,\n ToolbarBlockSelectorProps\n>(({ items, onKeyDown, ...props }, forwardedRef) => {\n const floatingToolbarContext = useContext(FloatingToolbarContext);\n const closeFloatingToolbar = floatingToolbarContext?.close;\n const editor = useCurrentEditor(\n \"BlockSelector\",\n \"Toolbar or FloatingToolbar\"\n );\n const resolvedItems = useMemo(() => {\n if (Array.isArray(items)) {\n return items;\n }\n\n const defaultItems = createDefaultBlockSelectorItems(editor);\n\n return items ? items(defaultItems) : defaultItems;\n }, [editor, items]);\n let defaultItem: ToolbarBlockSelectorItem | undefined;\n let activeItem = editor.isInitialized\n ? resolvedItems.find((item) => {\n if (item.isActive === \"default\") {\n defaultItem = item;\n return false;\n }\n\n return item.isActive(editor);\n })\n : undefined;\n\n if (!activeItem) {\n activeItem = defaultItem;\n }\n\n const handleItemChange = (name: string) => {\n const item = resolvedItems.find((item) => item.name === name);\n\n if (item) {\n item.setActive(editor);\n\n // If present in a floating toolbar, close it on change\n floatingToolbarContext?.close();\n }\n };\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n\n if (\n !event.isDefaultPrevented() &&\n closeFloatingToolbar &&\n event.key === \"Escape\"\n ) {\n closeFloatingToolbar();\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [onKeyDown, closeFloatingToolbar]\n );\n\n return (\n <SelectPrimitive.Root\n value={activeItem?.name}\n onValueChange={handleItemChange}\n >\n <ShortcutTooltip content=\"Turn into…\">\n <SelectPrimitive.Trigger\n asChild\n {...props}\n ref={forwardedRef}\n onKeyDown={handleKeyDown}\n disabled={resolvedItems.length === 0}\n >\n <SelectButton variant=\"toolbar\">\n {activeItem?.name ?? \"Turn into…\"}\n </SelectButton>\n </SelectPrimitive.Trigger>\n </ShortcutTooltip>\n <SelectPrimitive.Portal>\n <FloatingToolbarExternal>\n <SelectPrimitive.Content\n position=\"popper\"\n sideOffset={BLOCK_SELECT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n className=\"lb-root lb-portal lb-elevation lb-dropdown lb-select-dropdown lb-tiptap-block-selector-dropdown\"\n >\n {resolvedItems.map((item) => (\n <SelectPrimitive.Item\n key={item.name}\n value={item.name}\n className=\"lb-dropdown-item\"\n data-name={item.name}\n >\n {item.icon ? (\n <span className=\"lb-dropdown-item-icon lb-icon-container\">\n {item.icon}\n </span>\n ) : null}\n <span className=\"lb-dropdown-item-label\">\n {item.label ?? item.name}\n </span>\n {item.name === activeItem?.name ? (\n <span className=\"lb-dropdown-item-accessory lb-icon-container\">\n <CheckIcon />\n </span>\n ) : null}\n </SelectPrimitive.Item>\n ))}\n </SelectPrimitive.Content>\n </FloatingToolbarExternal>\n </SelectPrimitive.Portal>\n </SelectPrimitive.Root>\n );\n});\n\nconst ToolbarSeparator = forwardRef<HTMLDivElement, ToolbarSeparatorProps>(\n ({ className, ...props }, forwardedRef) => {\n return (\n <div\n ref={forwardedRef}\n role=\"separator\"\n aria-orientation=\"vertical\"\n className={cn(\"lb-tiptap-toolbar-separator\", className)}\n {...props}\n />\n );\n }\n);\n\nfunction ToolbarSectionHistory() {\n const editor = useCurrentEditor(\n \"SectionHistory\",\n \"Toolbar or FloatingToolbar\"\n );\n\n return (\n <>\n <ToolbarButton\n name=\"Undo\"\n icon={<UndoIcon />}\n shortcut=\"Mod-Z\"\n onClick={() => editor.chain().focus().undo().run()}\n disabled={!editor.can().chain().focus().undo().run()}\n />\n <ToolbarButton\n name=\"Redo\"\n icon={<RedoIcon />}\n shortcut=\"Mod-Shift-Z\"\n onClick={() => editor.chain().focus().redo().run()}\n disabled={!editor.can().chain().focus().redo().run()}\n />\n </>\n );\n}\n\nfunction ToolbarSectionInline() {\n const editor = useCurrentEditor(\n \"SectionInline\",\n \"Toolbar or FloatingToolbar\"\n );\n const supportsBold = \"toggleBold\" in editor.commands;\n const supportsItalic = \"toggleItalic\" in editor.commands;\n const supportsUnderline = \"toggleUnderline\" in editor.commands;\n const supportsStrike = \"toggleStrike\" in editor.commands;\n const supportsCode = \"toggleCode\" in editor.commands;\n\n return (\n <>\n {supportsBold && (\n <ToolbarToggle\n name=\"Bold\"\n icon={<BoldIcon />}\n shortcut=\"Mod-B\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleBold\">)\n .toggleBold()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleBold\">\n )\n .toggleBold()\n .run()\n }\n active={editor.isActive(\"bold\")}\n />\n )}\n {supportsItalic && (\n <ToolbarToggle\n name=\"Italic\"\n icon={<ItalicIcon />}\n shortcut=\"Mod-I\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleItalic\">)\n .toggleItalic()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleItalic\">\n )\n .toggleItalic()\n .run()\n }\n active={editor.isActive(\"italic\")}\n />\n )}\n {supportsUnderline && (\n <ToolbarToggle\n name=\"Underline\"\n icon={<UnderlineIcon />}\n shortcut=\"Mod-U\"\n onClick={() =>\n (\n editor\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleUnderline\">\n )\n .toggleUnderline()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleUnderline\">\n )\n .toggleUnderline()\n .run()\n }\n active={editor.isActive(\"underline\")}\n />\n )}\n {supportsStrike && (\n <ToolbarToggle\n name=\"Strikethrough\"\n icon={<StrikethroughIcon />}\n shortcut=\"Mod-U\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleStrike\">)\n .toggleStrike()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleStrike\">\n )\n .toggleStrike()\n .run()\n }\n active={editor.isActive(\"strike\")}\n />\n )}\n {supportsCode && (\n <ToolbarToggle\n name=\"Inline code\"\n icon={<CodeIcon />}\n shortcut=\"Mod-E\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleCode\">)\n .toggleCode()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleCode\">\n )\n .toggleCode()\n .run()\n }\n active={editor.isActive(\"code\")}\n />\n )}\n </>\n );\n}\n\nfunction ToolbarSectionCollaboration() {\n const editor = useCurrentEditor(\n \"SectionCollaboration\",\n \"Toolbar or FloatingToolbar\"\n );\n const supportsThread = \"addPendingComment\" in editor.commands;\n\n return (\n <>\n {supportsThread && (\n <ToolbarButton\n name=\"Add a comment\"\n icon={<CommentIcon />}\n onClick={() =>\n (\n editor\n .chain()\n .focus() as ExtendedChainedCommands<\"addPendingComment\">\n )\n .addPendingComment()\n .run()\n }\n >\n Comment\n </ToolbarButton>\n )}\n </>\n );\n}\n\nfunction ToolbarSectionAi() {\n const editor = useCurrentEditor(\"SectionAi\", \"Toolbar or FloatingToolbar\");\n const supportsAi = \"askAi\" in editor.commands;\n const aiName = (editor.storage.liveblocksAi as AiExtensionStorage | undefined)\n ?.name;\n\n return (\n <>\n {supportsAi && (\n <>\n <ToolbarButton\n name={`Ask ${aiName} anything…`}\n icon={<SparklesIcon />}\n onClick={() =>\n (\n editor.chain().focus() as ExtendedChainedCommands<\"askAi\">\n ).askAi()\n }\n >\n Ask {aiName}\n </ToolbarButton>\n <ToolbarButton\n name=\"Explain\"\n icon={<QuestionMarkIcon />}\n onClick={() =>\n (\n editor.chain().focus() as ExtendedChainedCommands<\"askAi\">\n ).askAi(\"Explain what the text is about\")\n }\n >\n Explain\n </ToolbarButton>\n </>\n )}\n </>\n );\n}\n\nfunction DefaultToolbarContent({ editor }: ToolbarSlotProps) {\n const supportsThread = \"addPendingComment\" in editor.commands;\n const supportsAi = \"askAi\" in editor.commands;\n\n return (\n <>\n <ToolbarSectionHistory />\n <ToolbarSeparator />\n {supportsAi ? (\n <>\n <ToolbarSectionAi />\n <ToolbarSeparator />\n </>\n ) : null}\n <ToolbarBlockSelector />\n <ToolbarSectionInline />\n {supportsThread ? (\n <>\n <ToolbarSeparator />\n <ToolbarSectionCollaboration />\n </>\n ) : null}\n </>\n );\n}\n\n/**\n * A static toolbar containing actions and values related to the editor.\n *\n * @example\n * <Toolbar editor={editor} />\n *\n * @example\n * <Toolbar editor={editor}>\n * <Toolbar.BlockSelector />\n * <Toolbar.Separator />\n * <Toolbar.SectionInline />\n * <Toolbar.Separator />\n * <Toolbar.Button name=\"Custom action\" onClick={() => { ... }} icon={<Icon.QuestionMark />} />\n * </Toolbar>\n */\nexport const Toolbar = Object.assign(\n forwardRef<HTMLDivElement, ToolbarProps>(\n (\n {\n before,\n after,\n children = DefaultToolbarContent,\n editor,\n className,\n ...props\n },\n forwardedRef\n ) => {\n if (!editor) {\n return null;\n }\n\n const slotProps: ToolbarSlotProps = { editor };\n\n return (\n <TooltipProvider>\n <EditorProvider editor={editor}>\n <div\n ref={forwardedRef}\n role=\"toolbar\"\n aria-label=\"Toolbar\"\n aria-orientation=\"horizontal\"\n className={cn(\"lb-root lb-tiptap-toolbar\", className)}\n {...props}\n >\n {applyToolbarSlot(before, slotProps)}\n {applyToolbarSlot(children, slotProps)}\n {applyToolbarSlot(after, slotProps)}\n </div>\n </EditorProvider>\n </TooltipProvider>\n );\n }\n ),\n {\n /**\n * A button for triggering actions.\n *\n * @example\n * <Toolbar.Button name=\"Comment\" shortcut=\"Mod-Shift-E\" onClick={() => { ... }} />\n *\n * @example\n * <Toolbar.Button name=\"Mention someone\" icon={<Icon.Mention />} onClick={() => { ... }} />\n */\n Button: ToolbarButton,\n\n /**\n * A toggle button for values that can be active or inactive.\n *\n * @example\n * <Toolbar.Toggle name=\"Bold\" active={isBold} />\n *\n * @example\n * <Toolbar.Toggle name=\"Italic\" icon={<Icon.Italic />} shortcut=\"Mod-I\" active={isItalic} onClick={() => { ... }} />\n */\n Toggle: ToolbarToggle,\n\n /**\n * A dropdown selector to switch between different block types.\n *\n * @example\n * <Toolbar.BlockSelector />\n */\n BlockSelector: ToolbarBlockSelector,\n\n /**\n * A visual (and accessible) separator to separate sections in a toolbar.\n */\n Separator: ToolbarSeparator,\n\n /**\n * A section containing history actions. (e.g. undo, redo)\n */\n SectionHistory: ToolbarSectionHistory,\n\n /**\n * A section containing inline formatting actions. (e.g. bold, italic, underline, ...)\n */\n SectionInline: ToolbarSectionInline,\n\n /**\n * A section containing collaborative actions. (e.g. adding a comment)\n */\n SectionCollaboration: ToolbarSectionCollaboration,\n\n /**\n * A section containing AI actions. (e.g. opening the AI toolbar)\n */\n SectionAi: ToolbarSectionAi,\n }\n);\n"],"names":["jsx","forwardRef","useContext","FloatingToolbarContext","useCallback","ShortcutTooltip","Button","TogglePrimitive","TextIcon","editor","H1Icon","H2Icon","H3Icon","ListUnorderedIcon","ListOrderedIcon","BlockquoteIcon","useCurrentEditor","useMemo","item","jsxs","SelectPrimitive","SelectButton","FloatingToolbarExternal","CheckIcon","cn","Fragment","UndoIcon","RedoIcon","BoldIcon","ItalicIcon","UnderlineIcon","StrikethroughIcon","CodeIcon","CommentIcon","SparklesIcon","QuestionMarkIcon","TooltipProvider","EditorProvider"],"mappings":"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"} | ||
| {"version":3,"file":"Toolbar.cjs","sources":["../../src/toolbar/Toolbar.tsx"],"sourcesContent":["import {\n BlockquoteIcon,\n BoldIcon,\n Button,\n CheckIcon,\n cn,\n CodeIcon,\n CommentIcon,\n H1Icon,\n H2Icon,\n H3Icon,\n ItalicIcon,\n ListOrderedIcon,\n ListUnorderedIcon,\n QuestionMarkIcon,\n RedoIcon,\n SelectButton,\n ShortcutTooltip,\n SparklesIcon,\n StrikethroughIcon,\n TextIcon,\n TooltipProvider,\n UnderlineIcon,\n UndoIcon,\n} from \"@liveblocks/react-ui/_private\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport type {\n ComponentProps,\n ComponentType,\n KeyboardEvent,\n ReactNode,\n} from \"react\";\nimport { forwardRef, useCallback, useContext, useMemo } from \"react\";\n\nimport { EditorProvider, useCurrentEditor } from \"../context\";\nimport type { AiExtensionStorage, ExtendedChainedCommands } from \"../types\";\nimport { FloatingToolbarContext, FloatingToolbarExternal } from \"./shared\";\n\nexport const BLOCK_SELECT_SIDE_OFFSET = 10;\nexport const FLOATING_ELEMENT_COLLISION_PADDING = 10;\n\nexport interface ToolbarSlotProps {\n editor: Editor;\n}\n\nexport type ToolbarSlot = ReactNode | ComponentType<ToolbarSlotProps>;\n\nexport interface ToolbarProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n\n /**\n * The content of the toolbar, overriding the default content.\n * Use the `before` and `after` props if you want to keep and extend the default content.\n */\n children?: ToolbarSlot;\n\n /**\n * The content to display at the start of the toolbar.\n */\n before?: ToolbarSlot;\n\n /**\n * The content to display at the end of the toolbar.\n */\n after?: ToolbarSlot;\n}\n\nexport interface ToolbarButtonProps extends ComponentProps<\"button\"> {\n /**\n * The name of this button displayed in its tooltip.\n */\n name: string;\n\n /**\n * An optional icon displayed in this button.\n */\n icon?: ReactNode;\n\n /**\n * An optional keyboard shortcut displayed in this button's tooltip.\n *\n * @example\n * \"Mod-Alt-B\" → \"⌘⌥B\" in Apple environments, \"⌃⌥B\" otherwise\n * \"Ctrl-Shift-Escape\" → \"⌃⇧⎋\"\n * \"Space\" → \"␣\"\n */\n shortcut?: string;\n}\n\nexport interface ToolbarToggleProps extends ToolbarButtonProps {\n /**\n * Whether the button is toggled.\n */\n active: boolean;\n}\n\nexport interface ToolbarBlockSelectorItem {\n /**\n * The name of this block element, displayed as the label of this item.\n */\n name: string;\n\n /**\n * Optionally replace the name used as the label of this item by any content.\n */\n label?: ReactNode;\n\n /**\n * An optional icon displayed in this item.\n */\n icon?: ReactNode;\n\n /**\n * Whether this block element is currently active.\n * Set to `\"default\"` to display this item when no other item is active.\n */\n isActive: ((editor: Editor) => boolean) | \"default\";\n\n /**\n * A callback invoked when this item is selected.\n */\n setActive: (editor: Editor) => void;\n}\n\nexport interface ToolbarBlockSelectorProps extends ComponentProps<\"button\"> {\n /**\n * The items displayed in this block selector.\n * When provided as an array, the default items are overridden. To avoid this,\n * a function can be provided instead and it will receive the default items.\n *\n * @example\n * <Toolbar.BlockSelector\n * items={[\n * {\n * name: \"Text\",\n * isActive: \"default\",\n * setActive: () => { ... },\n * },\n * {\n * name: \"Heading 1\",\n * isActive: () => { ... },\n * setActive: () => { ... },\n * },\n * ]}\n * />\n *\n * @example\n * <Toolbar.BlockSelector\n * items={(defaultItems) => [\n * ...defaultItems,\n * {\n * name: \"Custom block\",\n * isActive: () => { ... },\n * setActive: () => { ... },\n * },\n * ]}\n * />\n */\n items?:\n | ToolbarBlockSelectorItem[]\n | ((\n defaultItems: ToolbarBlockSelectorItem[]\n ) => ToolbarBlockSelectorItem[]);\n}\n\nexport type ToolbarSeparatorProps = ComponentProps<\"div\">;\n\nexport function applyToolbarSlot(\n slot: ToolbarSlot,\n props: ToolbarSlotProps\n): ReactNode {\n if (typeof slot === \"function\") {\n const Component = slot;\n\n return <Component {...props} />;\n }\n\n return slot;\n}\n\nconst ToolbarButton = forwardRef<HTMLButtonElement, ToolbarButtonProps>(\n ({ icon, children, name, shortcut, onKeyDown, ...props }, forwardedRef) => {\n const floatingToolbarContext = useContext(FloatingToolbarContext);\n const closeFloatingToolbar = floatingToolbarContext?.close;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n\n if (\n !event.isDefaultPrevented() &&\n closeFloatingToolbar &&\n event.key === \"Escape\"\n ) {\n closeFloatingToolbar();\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [onKeyDown, closeFloatingToolbar]\n );\n\n return (\n <ShortcutTooltip content={name} shortcut={shortcut}>\n <Button\n type=\"button\"\n variant=\"toolbar\"\n ref={forwardedRef}\n icon={icon}\n aria-label={!children ? name : undefined}\n // Safari doesn't mark buttons as focusable, which breaks `relatedTarget`\n // in focus/blur events. https://bugs.webkit.org/show_bug.cgi?id=254655\n tabIndex={0}\n {...props}\n onKeyDown={handleKeyDown}\n >\n {!children && !icon ? name : children}\n </Button>\n </ShortcutTooltip>\n );\n }\n);\n\nconst ToolbarToggle = forwardRef<HTMLButtonElement, ToolbarToggleProps>(\n ({ active, ...props }, forwardedRef) => {\n return (\n <TogglePrimitive.Root asChild pressed={active}>\n <ToolbarButton ref={forwardedRef} {...props} />\n </TogglePrimitive.Root>\n );\n }\n);\n\nfunction createDefaultBlockSelectorItems(\n editor: Editor\n): ToolbarBlockSelectorItem[] {\n const items: (ToolbarBlockSelectorItem | null)[] = [\n {\n name: \"Text\",\n icon: <TextIcon />,\n isActive: \"default\",\n setActive: (editor) => editor.chain().focus().clearNodes().run(),\n },\n \"toggleHeading\" in editor.commands\n ? {\n name: \"Heading 1\",\n icon: <H1Icon />,\n isActive: (editor) => editor.isActive(\"heading\", { level: 1 }),\n setActive: (editor) =>\n (\n editor.chain().focus().clearNodes() as ExtendedChainedCommands<\n \"toggleHeading\",\n [{ level: number }]\n >\n )\n .toggleHeading({ level: 1 })\n .run(),\n }\n : null,\n \"toggleHeading\" in editor.commands\n ? {\n name: \"Heading 2\",\n icon: <H2Icon />,\n isActive: (editor) => editor.isActive(\"heading\", { level: 2 }),\n setActive: (editor) =>\n (\n editor.chain().focus().clearNodes() as ExtendedChainedCommands<\n \"toggleHeading\",\n [{ level: number }]\n >\n )\n .toggleHeading({ level: 2 })\n .run(),\n }\n : null,\n \"toggleHeading\" in editor.commands\n ? {\n name: \"Heading 3\",\n icon: <H3Icon />,\n isActive: (editor) => editor.isActive(\"heading\", { level: 3 }),\n setActive: (editor) =>\n (\n editor.chain().focus().clearNodes() as ExtendedChainedCommands<\n \"toggleHeading\",\n [{ level: number }]\n >\n )\n .toggleHeading({ level: 3 })\n .run(),\n }\n : null,\n \"toggleBulletList\" in editor.commands\n ? {\n name: \"Bullet list\",\n icon: <ListUnorderedIcon />,\n isActive: (editor) => editor.isActive(\"bulletList\"),\n setActive: (editor) =>\n (\n editor\n .chain()\n .focus()\n .clearNodes() as ExtendedChainedCommands<\"toggleBulletList\">\n )\n .toggleBulletList()\n .run(),\n }\n : null,\n \"toggleOrderedList\" in editor.commands\n ? {\n name: \"Numbered list\",\n icon: <ListOrderedIcon />,\n isActive: (editor) => editor.isActive(\"orderedList\"),\n setActive: (editor) =>\n (\n editor\n .chain()\n .focus()\n .clearNodes() as ExtendedChainedCommands<\"toggleOrderedList\">\n )\n .toggleOrderedList()\n .run(),\n }\n : null,\n \"toggleBlockquote\" in editor.commands\n ? {\n name: \"Blockquote\",\n icon: <BlockquoteIcon />,\n isActive: (editor) => editor.isActive(\"blockquote\"),\n setActive: (editor) =>\n (\n editor\n .chain()\n .focus()\n .clearNodes() as ExtendedChainedCommands<\"toggleBlockquote\">\n )\n .toggleBlockquote()\n .run(),\n }\n : null,\n ];\n\n return items.filter(Boolean) as ToolbarBlockSelectorItem[];\n}\n\nconst ToolbarBlockSelector = forwardRef<\n HTMLButtonElement,\n ToolbarBlockSelectorProps\n>(({ items, onKeyDown, ...props }, forwardedRef) => {\n const floatingToolbarContext = useContext(FloatingToolbarContext);\n const closeFloatingToolbar = floatingToolbarContext?.close;\n const editor = useCurrentEditor(\n \"BlockSelector\",\n \"Toolbar or FloatingToolbar\"\n );\n const resolvedItems = useMemo(() => {\n if (Array.isArray(items)) {\n return items;\n }\n\n const defaultItems = createDefaultBlockSelectorItems(editor);\n\n return items ? items(defaultItems) : defaultItems;\n }, [editor, items]);\n let defaultItem: ToolbarBlockSelectorItem | undefined;\n let activeItem = editor.isInitialized\n ? resolvedItems.find((item) => {\n if (item.isActive === \"default\") {\n defaultItem = item;\n return false;\n }\n\n return item.isActive(editor);\n })\n : undefined;\n\n if (!activeItem) {\n activeItem = defaultItem;\n }\n\n const handleItemChange = (name: string) => {\n const item = resolvedItems.find((item) => item.name === name);\n\n if (item) {\n item.setActive(editor);\n\n // If present in a floating toolbar, close it on change\n floatingToolbarContext?.close();\n }\n };\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n\n if (\n !event.isDefaultPrevented() &&\n closeFloatingToolbar &&\n event.key === \"Escape\"\n ) {\n closeFloatingToolbar();\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [onKeyDown, closeFloatingToolbar]\n );\n\n return (\n <SelectPrimitive.Root\n value={activeItem?.name}\n onValueChange={handleItemChange}\n >\n <ShortcutTooltip content=\"Turn into…\">\n <SelectPrimitive.Trigger\n asChild\n {...props}\n ref={forwardedRef}\n onKeyDown={handleKeyDown}\n disabled={resolvedItems.length === 0}\n >\n <SelectButton variant=\"toolbar\">\n {activeItem?.name ?? \"Turn into…\"}\n </SelectButton>\n </SelectPrimitive.Trigger>\n </ShortcutTooltip>\n <SelectPrimitive.Portal>\n <FloatingToolbarExternal>\n <SelectPrimitive.Content\n position=\"popper\"\n sideOffset={BLOCK_SELECT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n className=\"lb-root lb-portal lb-elevation lb-dropdown lb-select-dropdown lb-tiptap-block-selector-dropdown\"\n >\n {resolvedItems.map((item) => (\n <SelectPrimitive.Item\n key={item.name}\n value={item.name}\n className=\"lb-dropdown-item\"\n data-name={item.name}\n >\n {item.icon ? (\n <span className=\"lb-dropdown-item-icon lb-icon-container\">\n {item.icon}\n </span>\n ) : null}\n <span className=\"lb-dropdown-item-label\">\n {item.label ?? item.name}\n </span>\n {item.name === activeItem?.name ? (\n <span className=\"lb-dropdown-item-accessory lb-icon-container\">\n <CheckIcon />\n </span>\n ) : null}\n </SelectPrimitive.Item>\n ))}\n </SelectPrimitive.Content>\n </FloatingToolbarExternal>\n </SelectPrimitive.Portal>\n </SelectPrimitive.Root>\n );\n});\n\nconst ToolbarSeparator = forwardRef<HTMLDivElement, ToolbarSeparatorProps>(\n ({ className, ...props }, forwardedRef) => {\n return (\n <div\n ref={forwardedRef}\n role=\"separator\"\n aria-orientation=\"vertical\"\n className={cn(\"lb-tiptap-toolbar-separator\", className)}\n {...props}\n />\n );\n }\n);\n\nfunction ToolbarSectionHistory() {\n const editor = useCurrentEditor(\n \"SectionHistory\",\n \"Toolbar or FloatingToolbar\"\n );\n\n return (\n <>\n <ToolbarButton\n name=\"Undo\"\n icon={<UndoIcon />}\n shortcut=\"Mod-Z\"\n onClick={() => editor.chain().focus().undo().run()}\n disabled={!editor.can().chain().focus().undo().run()}\n />\n <ToolbarButton\n name=\"Redo\"\n icon={<RedoIcon />}\n shortcut=\"Mod-Shift-Z\"\n onClick={() => editor.chain().focus().redo().run()}\n disabled={!editor.can().chain().focus().redo().run()}\n />\n </>\n );\n}\n\nfunction ToolbarSectionInline() {\n const editor = useCurrentEditor(\n \"SectionInline\",\n \"Toolbar or FloatingToolbar\"\n );\n const supportsBold = \"toggleBold\" in editor.commands;\n const supportsItalic = \"toggleItalic\" in editor.commands;\n const supportsUnderline = \"toggleUnderline\" in editor.commands;\n const supportsStrike = \"toggleStrike\" in editor.commands;\n const supportsCode = \"toggleCode\" in editor.commands;\n\n return (\n <>\n {supportsBold && (\n <ToolbarToggle\n name=\"Bold\"\n icon={<BoldIcon />}\n shortcut=\"Mod-B\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleBold\">)\n .toggleBold()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleBold\">\n )\n .toggleBold()\n .run()\n }\n active={editor.isActive(\"bold\")}\n />\n )}\n {supportsItalic && (\n <ToolbarToggle\n name=\"Italic\"\n icon={<ItalicIcon />}\n shortcut=\"Mod-I\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleItalic\">)\n .toggleItalic()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleItalic\">\n )\n .toggleItalic()\n .run()\n }\n active={editor.isActive(\"italic\")}\n />\n )}\n {supportsUnderline && (\n <ToolbarToggle\n name=\"Underline\"\n icon={<UnderlineIcon />}\n shortcut=\"Mod-U\"\n onClick={() =>\n (\n editor\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleUnderline\">\n )\n .toggleUnderline()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleUnderline\">\n )\n .toggleUnderline()\n .run()\n }\n active={editor.isActive(\"underline\")}\n />\n )}\n {supportsStrike && (\n <ToolbarToggle\n name=\"Strikethrough\"\n icon={<StrikethroughIcon />}\n shortcut=\"Mod-U\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleStrike\">)\n .toggleStrike()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleStrike\">\n )\n .toggleStrike()\n .run()\n }\n active={editor.isActive(\"strike\")}\n />\n )}\n {supportsCode && (\n <ToolbarToggle\n name=\"Inline code\"\n icon={<CodeIcon />}\n shortcut=\"Mod-E\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleCode\">)\n .toggleCode()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleCode\">\n )\n .toggleCode()\n .run()\n }\n active={editor.isActive(\"code\")}\n />\n )}\n </>\n );\n}\n\nfunction ToolbarSectionCollaboration() {\n const editor = useCurrentEditor(\n \"SectionCollaboration\",\n \"Toolbar or FloatingToolbar\"\n );\n const supportsThread = \"addPendingComment\" in editor.commands;\n\n return (\n <>\n {supportsThread && (\n <ToolbarButton\n name=\"Add a comment\"\n icon={<CommentIcon />}\n onClick={() =>\n (\n editor\n .chain()\n .focus() as ExtendedChainedCommands<\"addPendingComment\">\n )\n .addPendingComment()\n .run()\n }\n >\n Comment\n </ToolbarButton>\n )}\n </>\n );\n}\n\nfunction ToolbarSectionAi() {\n const editor = useCurrentEditor(\"SectionAi\", \"Toolbar or FloatingToolbar\");\n const supportsAi = \"askAi\" in editor.commands;\n const aiName = (editor.storage.liveblocksAi as AiExtensionStorage | undefined)\n ?.name;\n\n return (\n <>\n {supportsAi && (\n <>\n <ToolbarButton\n name={`Ask ${aiName} anything…`}\n icon={<SparklesIcon />}\n onClick={() =>\n (\n editor.chain().focus() as ExtendedChainedCommands<\"askAi\">\n ).askAi()\n }\n >\n Ask {aiName}\n </ToolbarButton>\n <ToolbarButton\n name=\"Explain\"\n icon={<QuestionMarkIcon />}\n onClick={() =>\n (\n editor.chain().focus() as ExtendedChainedCommands<\"askAi\">\n ).askAi(\"Explain what the text is about\")\n }\n >\n Explain\n </ToolbarButton>\n </>\n )}\n </>\n );\n}\n\nfunction DefaultToolbarContent({ editor }: ToolbarSlotProps) {\n const supportsThread = \"addPendingComment\" in editor.commands;\n const supportsAi = \"askAi\" in editor.commands;\n\n return (\n <>\n <ToolbarSectionHistory />\n <ToolbarSeparator />\n {supportsAi ? (\n <>\n <ToolbarSectionAi />\n <ToolbarSeparator />\n </>\n ) : null}\n <ToolbarBlockSelector />\n <ToolbarSectionInline />\n {supportsThread ? (\n <>\n <ToolbarSeparator />\n <ToolbarSectionCollaboration />\n </>\n ) : null}\n </>\n );\n}\n\n/**\n * A static toolbar containing actions and values related to the editor.\n *\n * @example\n * <Toolbar editor={editor} />\n *\n * @example\n * <Toolbar editor={editor}>\n * <Toolbar.BlockSelector />\n * <Toolbar.Separator />\n * <Toolbar.SectionInline />\n * <Toolbar.Separator />\n * <Toolbar.Button name=\"Custom action\" onClick={() => { ... }} icon={<Icon.QuestionMark />} />\n * </Toolbar>\n */\nexport const Toolbar = Object.assign(\n forwardRef<HTMLDivElement, ToolbarProps>(\n (\n {\n before,\n after,\n children = DefaultToolbarContent,\n editor,\n className,\n ...props\n },\n forwardedRef\n ) => {\n // Re-render the toolbar when the editor content and selection change.\n useEditorState({\n editor,\n equalityFn: Object.is,\n selector: (ctx) => ctx.editor?.state,\n });\n\n if (!editor) {\n return null;\n }\n\n const slotProps: ToolbarSlotProps = { editor };\n\n return (\n <TooltipProvider>\n <EditorProvider editor={editor}>\n <div\n ref={forwardedRef}\n role=\"toolbar\"\n aria-label=\"Toolbar\"\n aria-orientation=\"horizontal\"\n className={cn(\"lb-root lb-tiptap-toolbar\", className)}\n {...props}\n >\n {applyToolbarSlot(before, slotProps)}\n {applyToolbarSlot(children, slotProps)}\n {applyToolbarSlot(after, slotProps)}\n </div>\n </EditorProvider>\n </TooltipProvider>\n );\n }\n ),\n {\n /**\n * A button for triggering actions.\n *\n * @example\n * <Toolbar.Button name=\"Comment\" shortcut=\"Mod-Shift-E\" onClick={() => { ... }} />\n *\n * @example\n * <Toolbar.Button name=\"Mention someone\" icon={<Icon.Mention />} onClick={() => { ... }} />\n */\n Button: ToolbarButton,\n\n /**\n * A toggle button for values that can be active or inactive.\n *\n * @example\n * <Toolbar.Toggle name=\"Bold\" active={isBold} />\n *\n * @example\n * <Toolbar.Toggle name=\"Italic\" icon={<Icon.Italic />} shortcut=\"Mod-I\" active={isItalic} onClick={() => { ... }} />\n */\n Toggle: ToolbarToggle,\n\n /**\n * A dropdown selector to switch between different block types.\n *\n * @example\n * <Toolbar.BlockSelector />\n */\n BlockSelector: ToolbarBlockSelector,\n\n /**\n * A visual (and accessible) separator to separate sections in a toolbar.\n */\n Separator: ToolbarSeparator,\n\n /**\n * A section containing history actions. (e.g. undo, redo)\n */\n SectionHistory: ToolbarSectionHistory,\n\n /**\n * A section containing inline formatting actions. (e.g. bold, italic, underline, ...)\n */\n SectionInline: ToolbarSectionInline,\n\n /**\n * A section containing collaborative actions. (e.g. adding a comment)\n */\n SectionCollaboration: ToolbarSectionCollaboration,\n\n /**\n * A section containing AI actions. (e.g. opening the AI toolbar)\n */\n SectionAi: ToolbarSectionAi,\n }\n);\n"],"names":["jsx","forwardRef","useContext","FloatingToolbarContext","useCallback","ShortcutTooltip","Button","TogglePrimitive","TextIcon","editor","H1Icon","H2Icon","H3Icon","ListUnorderedIcon","ListOrderedIcon","BlockquoteIcon","useCurrentEditor","useMemo","item","jsxs","SelectPrimitive","SelectButton","FloatingToolbarExternal","CheckIcon","cn","Fragment","UndoIcon","RedoIcon","BoldIcon","ItalicIcon","UnderlineIcon","StrikethroughIcon","CodeIcon","CommentIcon","SparklesIcon","QuestionMarkIcon","useEditorState","TooltipProvider","EditorProvider"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCO,MAAM,wBAA2B,GAAA,GAAA;AACjC,MAAM,kCAAqC,GAAA,GAAA;AAmIlC,SAAA,gBAAA,CACd,MACA,KACW,EAAA;AACX,EAAI,IAAA,OAAO,SAAS,UAAY,EAAA;AAC9B,IAAA,MAAM,SAAY,GAAA,IAAA,CAAA;AAElB,IAAO,uBAAAA,cAAA,CAAC,SAAW,EAAA,EAAA,GAAG,KAAO,EAAA,CAAA,CAAA;AAAA,GAC/B;AAEA,EAAO,OAAA,IAAA,CAAA;AACT,CAAA;AAEA,MAAM,aAAgB,GAAAC,gBAAA;AAAA,EACpB,CAAC,EAAE,IAAA,EAAM,QAAU,EAAA,IAAA,EAAM,UAAU,SAAW,EAAA,GAAG,KAAM,EAAA,EAAG,YAAiB,KAAA;AACzE,IAAM,MAAA,sBAAA,GAAyBC,iBAAWC,6BAAsB,CAAA,CAAA;AAChE,IAAA,MAAM,uBAAuB,sBAAwB,EAAA,KAAA,CAAA;AAErD,IAAA,MAAM,aAAgB,GAAAC,iBAAA;AAAA,MACpB,CAAC,KAA4C,KAAA;AAC3C,QAAA,SAAA,GAAY,KAAK,CAAA,CAAA;AAEjB,QAAA,IACE,CAAC,KAAM,CAAA,kBAAA,MACP,oBACA,IAAA,KAAA,CAAM,QAAQ,QACd,EAAA;AACA,UAAqB,oBAAA,EAAA,CAAA;AACrB,UAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,UAAA,KAAA,CAAM,eAAgB,EAAA,CAAA;AAAA,SACxB;AAAA,OACF;AAAA,MACA,CAAC,WAAW,oBAAoB,CAAA;AAAA,KAClC,CAAA;AAEA,IAAA,uBACGJ,cAAA,CAAAK,wBAAA,EAAA,EAAgB,OAAS,EAAA,IAAA,EAAM,QAC9B,EAAA,QAAA,kBAAAL,cAAA;AAAA,MAACM,eAAA;AAAA,MAAA;AAAA,QACC,IAAK,EAAA,QAAA;AAAA,QACL,OAAQ,EAAA,SAAA;AAAA,QACR,GAAK,EAAA,YAAA;AAAA,QACL,IAAA;AAAA,QACA,YAAA,EAAY,CAAC,QAAA,GAAW,IAAO,GAAA,KAAA,CAAA;AAAA,QAG/B,QAAU,EAAA,CAAA;AAAA,QACT,GAAG,KAAA;AAAA,QACJ,SAAW,EAAA,aAAA;AAAA,QAEV,QAAC,EAAA,CAAA,QAAA,IAAY,CAAC,IAAA,GAAO,IAAO,GAAA,QAAA;AAAA,OAAA;AAAA,KAEjC,EAAA,CAAA,CAAA;AAAA,GAEJ;AACF,CAAA,CAAA;AAEA,MAAM,aAAgB,GAAAL,gBAAA;AAAA,EACpB,CAAC,EAAE,MAAA,EAAQ,GAAG,KAAA,IAAS,YAAiB,KAAA;AACtC,IAAA,uBACGD,cAAA,CAAAO,0BAAA,CAAgB,IAAhB,EAAA,EAAqB,SAAO,IAAC,EAAA,OAAA,EAAS,MACrC,EAAA,QAAA,kBAAAP,cAAA,CAAC,aAAc,EAAA,EAAA,GAAA,EAAK,YAAe,EAAA,GAAG,OAAO,CAC/C,EAAA,CAAA,CAAA;AAAA,GAEJ;AACF,CAAA,CAAA;AAEA,SAAS,gCACP,MAC4B,EAAA;AAC5B,EAAA,MAAM,KAA6C,GAAA;AAAA,IACjD;AAAA,MACE,IAAM,EAAA,MAAA;AAAA,MACN,IAAA,iCAAOQ,iBAAS,EAAA,EAAA,CAAA;AAAA,MAChB,QAAU,EAAA,SAAA;AAAA,MACV,SAAA,EAAW,CAACC,OAAAA,KAAWA,OAAO,CAAA,KAAA,GAAQ,KAAM,EAAA,CAAE,UAAW,EAAA,CAAE,GAAI,EAAA;AAAA,KACjE;AAAA,IACA,eAAA,IAAmB,OAAO,QACtB,GAAA;AAAA,MACE,IAAM,EAAA,WAAA;AAAA,MACN,IAAA,iCAAOC,eAAO,EAAA,EAAA,CAAA;AAAA,MACd,QAAA,EAAU,CAACD,OAAWA,KAAAA,OAAAA,CAAO,SAAS,SAAW,EAAA,EAAE,KAAO,EAAA,CAAA,EAAG,CAAA;AAAA,MAC7D,WAAW,CAACA,OAAAA,KAERA,OAAO,CAAA,KAAA,GAAQ,KAAM,EAAA,CAAE,UAAW,EAAA,CAKjC,cAAc,EAAE,KAAA,EAAO,CAAE,EAAC,EAC1B,GAAI,EAAA;AAAA,KAEX,GAAA,IAAA;AAAA,IACJ,eAAA,IAAmB,OAAO,QACtB,GAAA;AAAA,MACE,IAAM,EAAA,WAAA;AAAA,MACN,IAAA,iCAAOE,eAAO,EAAA,EAAA,CAAA;AAAA,MACd,QAAA,EAAU,CAACF,OAAWA,KAAAA,OAAAA,CAAO,SAAS,SAAW,EAAA,EAAE,KAAO,EAAA,CAAA,EAAG,CAAA;AAAA,MAC7D,WAAW,CAACA,OAAAA,KAERA,OAAO,CAAA,KAAA,GAAQ,KAAM,EAAA,CAAE,UAAW,EAAA,CAKjC,cAAc,EAAE,KAAA,EAAO,CAAE,EAAC,EAC1B,GAAI,EAAA;AAAA,KAEX,GAAA,IAAA;AAAA,IACJ,eAAA,IAAmB,OAAO,QACtB,GAAA;AAAA,MACE,IAAM,EAAA,WAAA;AAAA,MACN,IAAA,iCAAOG,eAAO,EAAA,EAAA,CAAA;AAAA,MACd,QAAA,EAAU,CAACH,OAAWA,KAAAA,OAAAA,CAAO,SAAS,SAAW,EAAA,EAAE,KAAO,EAAA,CAAA,EAAG,CAAA;AAAA,MAC7D,WAAW,CAACA,OAAAA,KAERA,OAAO,CAAA,KAAA,GAAQ,KAAM,EAAA,CAAE,UAAW,EAAA,CAKjC,cAAc,EAAE,KAAA,EAAO,CAAE,EAAC,EAC1B,GAAI,EAAA;AAAA,KAEX,GAAA,IAAA;AAAA,IACJ,kBAAA,IAAsB,OAAO,QACzB,GAAA;AAAA,MACE,IAAM,EAAA,aAAA;AAAA,MACN,IAAA,iCAAOI,0BAAkB,EAAA,EAAA,CAAA;AAAA,MACzB,QAAU,EAAA,CAACJ,OAAWA,KAAAA,OAAAA,CAAO,SAAS,YAAY,CAAA;AAAA,MAClD,SAAW,EAAA,CAACA,OAERA,KAAAA,OAAAA,CACG,KAAM,EAAA,CACN,KAAM,EAAA,CACN,UAAW,EAAA,CAEb,gBAAiB,EAAA,CACjB,GAAI,EAAA;AAAA,KAEX,GAAA,IAAA;AAAA,IACJ,mBAAA,IAAuB,OAAO,QAC1B,GAAA;AAAA,MACE,IAAM,EAAA,eAAA;AAAA,MACN,IAAA,iCAAOK,wBAAgB,EAAA,EAAA,CAAA;AAAA,MACvB,QAAU,EAAA,CAACL,OAAWA,KAAAA,OAAAA,CAAO,SAAS,aAAa,CAAA;AAAA,MACnD,SAAW,EAAA,CAACA,OAERA,KAAAA,OAAAA,CACG,KAAM,EAAA,CACN,KAAM,EAAA,CACN,UAAW,EAAA,CAEb,iBAAkB,EAAA,CAClB,GAAI,EAAA;AAAA,KAEX,GAAA,IAAA;AAAA,IACJ,kBAAA,IAAsB,OAAO,QACzB,GAAA;AAAA,MACE,IAAM,EAAA,YAAA;AAAA,MACN,IAAA,iCAAOM,uBAAe,EAAA,EAAA,CAAA;AAAA,MACtB,QAAU,EAAA,CAACN,OAAWA,KAAAA,OAAAA,CAAO,SAAS,YAAY,CAAA;AAAA,MAClD,SAAW,EAAA,CAACA,OAERA,KAAAA,OAAAA,CACG,KAAM,EAAA,CACN,KAAM,EAAA,CACN,UAAW,EAAA,CAEb,gBAAiB,EAAA,CACjB,GAAI,EAAA;AAAA,KAEX,GAAA,IAAA;AAAA,GACN,CAAA;AAEA,EAAO,OAAA,KAAA,CAAM,OAAO,OAAO,CAAA,CAAA;AAC7B,CAAA;AAEA,MAAM,oBAAA,GAAuBR,iBAG3B,CAAC,EAAE,OAAO,SAAW,EAAA,GAAG,KAAM,EAAA,EAAG,YAAiB,KAAA;AAClD,EAAM,MAAA,sBAAA,GAAyBC,iBAAWC,6BAAsB,CAAA,CAAA;AAChE,EAAA,MAAM,uBAAuB,sBAAwB,EAAA,KAAA,CAAA;AACrD,EAAA,MAAM,MAAS,GAAAa,wBAAA;AAAA,IACb,eAAA;AAAA,IACA,4BAAA;AAAA,GACF,CAAA;AACA,EAAM,MAAA,aAAA,GAAgBC,cAAQ,MAAM;AAClC,IAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,KAAK,CAAG,EAAA;AACxB,MAAO,OAAA,KAAA,CAAA;AAAA,KACT;AAEA,IAAM,MAAA,YAAA,GAAe,gCAAgC,MAAM,CAAA,CAAA;AAE3D,IAAO,OAAA,KAAA,GAAQ,KAAM,CAAA,YAAY,CAAI,GAAA,YAAA,CAAA;AAAA,GACpC,EAAA,CAAC,MAAQ,EAAA,KAAK,CAAC,CAAA,CAAA;AAClB,EAAI,IAAA,WAAA,CAAA;AACJ,EAAA,IAAI,aAAa,MAAO,CAAA,aAAA,GACpB,aAAc,CAAA,IAAA,CAAK,CAAC,IAAS,KAAA;AAC3B,IAAI,IAAA,IAAA,CAAK,aAAa,SAAW,EAAA;AAC/B,MAAc,WAAA,GAAA,IAAA,CAAA;AACd,MAAO,OAAA,KAAA,CAAA;AAAA,KACT;AAEA,IAAO,OAAA,IAAA,CAAK,SAAS,MAAM,CAAA,CAAA;AAAA,GAC5B,CACD,GAAA,KAAA,CAAA,CAAA;AAEJ,EAAA,IAAI,CAAC,UAAY,EAAA;AACf,IAAa,UAAA,GAAA,WAAA,CAAA;AAAA,GACf;AAEA,EAAM,MAAA,gBAAA,GAAmB,CAAC,IAAiB,KAAA;AACzC,IAAA,MAAM,OAAO,aAAc,CAAA,IAAA,CAAK,CAACC,KAASA,KAAAA,KAAAA,CAAK,SAAS,IAAI,CAAA,CAAA;AAE5D,IAAA,IAAI,IAAM,EAAA;AACR,MAAA,IAAA,CAAK,UAAU,MAAM,CAAA,CAAA;AAGrB,MAAA,sBAAA,EAAwB,KAAM,EAAA,CAAA;AAAA,KAChC;AAAA,GACF,CAAA;AAEA,EAAA,MAAM,aAAgB,GAAAd,iBAAA;AAAA,IACpB,CAAC,KAA4C,KAAA;AAC3C,MAAA,SAAA,GAAY,KAAK,CAAA,CAAA;AAEjB,MAAA,IACE,CAAC,KAAM,CAAA,kBAAA,MACP,oBACA,IAAA,KAAA,CAAM,QAAQ,QACd,EAAA;AACA,QAAqB,oBAAA,EAAA,CAAA;AACrB,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAA,KAAA,CAAM,eAAgB,EAAA,CAAA;AAAA,OACxB;AAAA,KACF;AAAA,IACA,CAAC,WAAW,oBAAoB,CAAA;AAAA,GAClC,CAAA;AAEA,EACE,uBAAAe,eAAA;AAAA,IAACC,0BAAgB,CAAA,IAAA;AAAA,IAAhB;AAAA,MACC,OAAO,UAAY,EAAA,IAAA;AAAA,MACnB,aAAe,EAAA,gBAAA;AAAA,MAEf,QAAA,EAAA;AAAA,wBAACpB,cAAA,CAAAK,wBAAA,EAAA,EAAgB,SAAQ,iBACvB,EAAA,QAAA,kBAAAL,cAAA;AAAA,UAACoB,0BAAgB,CAAA,OAAA;AAAA,UAAhB;AAAA,YACC,OAAO,EAAA,IAAA;AAAA,YACN,GAAG,KAAA;AAAA,YACJ,GAAK,EAAA,YAAA;AAAA,YACL,SAAW,EAAA,aAAA;AAAA,YACX,QAAA,EAAU,cAAc,MAAW,KAAA,CAAA;AAAA,YAEnC,yCAACC,qBAAa,EAAA,EAAA,OAAA,EAAQ,SACnB,EAAA,QAAA,EAAA,UAAA,EAAY,QAAQ,iBACvB,EAAA,CAAA;AAAA,WAAA;AAAA,SAEJ,EAAA,CAAA;AAAA,wBACCrB,cAAA,CAAAoB,0BAAA,CAAgB,MAAhB,EAAA,EACC,yCAACE,8BACC,EAAA,EAAA,QAAA,kBAAAtB,cAAA;AAAA,UAACoB,0BAAgB,CAAA,OAAA;AAAA,UAAhB;AAAA,YACC,QAAS,EAAA,QAAA;AAAA,YACT,UAAY,EAAA,wBAAA;AAAA,YACZ,gBAAkB,EAAA,kCAAA;AAAA,YAClB,SAAU,EAAA,iGAAA;AAAA,YAET,QAAA,EAAA,aAAA,CAAc,GAAI,CAAA,CAAC,IAClB,qBAAAD,eAAA;AAAA,cAACC,0BAAgB,CAAA,IAAA;AAAA,cAAhB;AAAA,gBAEC,OAAO,IAAK,CAAA,IAAA;AAAA,gBACZ,SAAU,EAAA,kBAAA;AAAA,gBACV,aAAW,IAAK,CAAA,IAAA;AAAA,gBAEf,QAAA,EAAA;AAAA,kBAAA,IAAA,CAAK,uBACHpB,cAAA,CAAA,MAAA,EAAA,EAAK,WAAU,yCACb,EAAA,QAAA,EAAA,IAAA,CAAK,MACR,CACE,GAAA,IAAA;AAAA,iDACH,MAAK,EAAA,EAAA,SAAA,EAAU,0BACb,QAAK,EAAA,IAAA,CAAA,KAAA,IAAS,KAAK,IACtB,EAAA,CAAA;AAAA,kBACC,IAAA,CAAK,IAAS,KAAA,UAAA,EAAY,IACzB,mBAAAA,cAAA,CAAC,MAAK,EAAA,EAAA,SAAA,EAAU,8CACd,EAAA,QAAA,kBAAAA,cAAA,CAACuB,kBAAU,EAAA,EAAA,CAAA,EACb,CACE,GAAA,IAAA;AAAA,iBAAA;AAAA,eAAA;AAAA,cAjBC,IAAK,CAAA,IAAA;AAAA,aAmBb,CAAA;AAAA,WAAA;AAAA,WAEL,CACF,EAAA,CAAA;AAAA,OAAA;AAAA,KAAA;AAAA,GACF,CAAA;AAEJ,CAAC,CAAA,CAAA;AAED,MAAM,gBAAmB,GAAAtB,gBAAA;AAAA,EACvB,CAAC,EAAE,SAAA,EAAW,GAAG,KAAA,IAAS,YAAiB,KAAA;AACzC,IACE,uBAAAD,cAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAK,EAAA,YAAA;AAAA,QACL,IAAK,EAAA,WAAA;AAAA,QACL,kBAAiB,EAAA,UAAA;AAAA,QACjB,SAAA,EAAWwB,WAAG,CAAA,6BAAA,EAA+B,SAAS,CAAA;AAAA,QACrD,GAAG,KAAA;AAAA,OAAA;AAAA,KACN,CAAA;AAAA,GAEJ;AACF,CAAA,CAAA;AAEA,SAAS,qBAAwB,GAAA;AAC/B,EAAA,MAAM,MAAS,GAAAR,wBAAA;AAAA,IACb,gBAAA;AAAA,IACA,4BAAA;AAAA,GACF,CAAA;AAEA,EAAA,uBAEIG,eAAA,CAAAM,mBAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAAzB,cAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,IAAK,EAAA,MAAA;AAAA,QACL,IAAA,iCAAO0B,iBAAS,EAAA,EAAA,CAAA;AAAA,QAChB,QAAS,EAAA,OAAA;AAAA,QACT,OAAA,EAAS,MAAM,MAAO,CAAA,KAAA,GAAQ,KAAM,EAAA,CAAE,IAAK,EAAA,CAAE,GAAI,EAAA;AAAA,QACjD,QAAA,EAAU,CAAC,MAAA,CAAO,GAAI,EAAA,CAAE,KAAM,EAAA,CAAE,KAAM,EAAA,CAAE,IAAK,EAAA,CAAE,GAAI,EAAA;AAAA,OAAA;AAAA,KACrD;AAAA,oBACA1B,cAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,IAAK,EAAA,MAAA;AAAA,QACL,IAAA,iCAAO2B,iBAAS,EAAA,EAAA,CAAA;AAAA,QAChB,QAAS,EAAA,aAAA;AAAA,QACT,OAAA,EAAS,MAAM,MAAO,CAAA,KAAA,GAAQ,KAAM,EAAA,CAAE,IAAK,EAAA,CAAE,GAAI,EAAA;AAAA,QACjD,QAAA,EAAU,CAAC,MAAA,CAAO,GAAI,EAAA,CAAE,KAAM,EAAA,CAAE,KAAM,EAAA,CAAE,IAAK,EAAA,CAAE,GAAI,EAAA;AAAA,OAAA;AAAA,KACrD;AAAA,GACF,EAAA,CAAA,CAAA;AAEJ,CAAA;AAEA,SAAS,oBAAuB,GAAA;AAC9B,EAAA,MAAM,MAAS,GAAAX,wBAAA;AAAA,IACb,eAAA;AAAA,IACA,4BAAA;AAAA,GACF,CAAA;AACA,EAAM,MAAA,YAAA,GAAe,gBAAgB,MAAO,CAAA,QAAA,CAAA;AAC5C,EAAM,MAAA,cAAA,GAAiB,kBAAkB,MAAO,CAAA,QAAA,CAAA;AAChD,EAAM,MAAA,iBAAA,GAAoB,qBAAqB,MAAO,CAAA,QAAA,CAAA;AACtD,EAAM,MAAA,cAAA,GAAiB,kBAAkB,MAAO,CAAA,QAAA,CAAA;AAChD,EAAM,MAAA,YAAA,GAAe,gBAAgB,MAAO,CAAA,QAAA,CAAA;AAE5C,EAAA,uBAEKG,eAAA,CAAAM,mBAAA,EAAA,EAAA,QAAA,EAAA;AAAA,IACC,YAAA,oBAAAzB,cAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,IAAK,EAAA,MAAA;AAAA,QACL,IAAA,iCAAO4B,iBAAS,EAAA,EAAA,CAAA;AAAA,QAChB,QAAS,EAAA,OAAA;AAAA,QACT,OAAA,EAAS,MACN,MAAO,CAAA,KAAA,GAAQ,KAAM,EAAA,CACnB,UAAW,EAAA,CACX,GAAI,EAAA;AAAA,QAET,QAAA,EACE,CACE,MAAA,CACG,GAAI,EAAA,CACJ,KAAM,EAAA,CACN,KAAM,EAAA,CAER,UAAW,EAAA,CACX,GAAI,EAAA;AAAA,QAET,MAAA,EAAQ,MAAO,CAAA,QAAA,CAAS,MAAM,CAAA;AAAA,OAAA;AAAA,KAChC;AAAA,IAED,cACC,oBAAA5B,cAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,IAAK,EAAA,QAAA;AAAA,QACL,IAAA,iCAAO6B,mBAAW,EAAA,EAAA,CAAA;AAAA,QAClB,QAAS,EAAA,OAAA;AAAA,QACT,OAAA,EAAS,MACN,MAAO,CAAA,KAAA,GAAQ,KAAM,EAAA,CACnB,YAAa,EAAA,CACb,GAAI,EAAA;AAAA,QAET,QAAA,EACE,CACE,MAAA,CACG,GAAI,EAAA,CACJ,KAAM,EAAA,CACN,KAAM,EAAA,CAER,YAAa,EAAA,CACb,GAAI,EAAA;AAAA,QAET,MAAA,EAAQ,MAAO,CAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,OAAA;AAAA,KAClC;AAAA,IAED,iBACC,oBAAA7B,cAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,IAAK,EAAA,WAAA;AAAA,QACL,IAAA,iCAAO8B,sBAAc,EAAA,EAAA,CAAA;AAAA,QACrB,QAAS,EAAA,OAAA;AAAA,QACT,OAAA,EAAS,MAEL,MACG,CAAA,KAAA,GACA,KAAM,EAAA,CAER,eAAgB,EAAA,CAChB,GAAI,EAAA;AAAA,QAET,QAAA,EACE,CACE,MAAA,CACG,GAAI,EAAA,CACJ,KAAM,EAAA,CACN,KAAM,EAAA,CAER,eAAgB,EAAA,CAChB,GAAI,EAAA;AAAA,QAET,MAAA,EAAQ,MAAO,CAAA,QAAA,CAAS,WAAW,CAAA;AAAA,OAAA;AAAA,KACrC;AAAA,IAED,cACC,oBAAA9B,cAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,IAAK,EAAA,eAAA;AAAA,QACL,IAAA,iCAAO+B,0BAAkB,EAAA,EAAA,CAAA;AAAA,QACzB,QAAS,EAAA,OAAA;AAAA,QACT,OAAA,EAAS,MACN,MAAO,CAAA,KAAA,GAAQ,KAAM,EAAA,CACnB,YAAa,EAAA,CACb,GAAI,EAAA;AAAA,QAET,QAAA,EACE,CACE,MAAA,CACG,GAAI,EAAA,CACJ,KAAM,EAAA,CACN,KAAM,EAAA,CAER,YAAa,EAAA,CACb,GAAI,EAAA;AAAA,QAET,MAAA,EAAQ,MAAO,CAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,OAAA;AAAA,KAClC;AAAA,IAED,YACC,oBAAA/B,cAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,IAAK,EAAA,aAAA;AAAA,QACL,IAAA,iCAAOgC,iBAAS,EAAA,EAAA,CAAA;AAAA,QAChB,QAAS,EAAA,OAAA;AAAA,QACT,OAAA,EAAS,MACN,MAAO,CAAA,KAAA,GAAQ,KAAM,EAAA,CACnB,UAAW,EAAA,CACX,GAAI,EAAA;AAAA,QAET,QAAA,EACE,CACE,MAAA,CACG,GAAI,EAAA,CACJ,KAAM,EAAA,CACN,KAAM,EAAA,CAER,UAAW,EAAA,CACX,GAAI,EAAA;AAAA,QAET,MAAA,EAAQ,MAAO,CAAA,QAAA,CAAS,MAAM,CAAA;AAAA,OAAA;AAAA,KAChC;AAAA,GAEJ,EAAA,CAAA,CAAA;AAEJ,CAAA;AAEA,SAAS,2BAA8B,GAAA;AACrC,EAAA,MAAM,MAAS,GAAAhB,wBAAA;AAAA,IACb,sBAAA;AAAA,IACA,4BAAA;AAAA,GACF,CAAA;AACA,EAAM,MAAA,cAAA,GAAiB,uBAAuB,MAAO,CAAA,QAAA,CAAA;AAErD,EAAA,6DAEK,QACC,EAAA,cAAA,oBAAAhB,cAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,IAAK,EAAA,eAAA;AAAA,MACL,IAAA,iCAAOiC,oBAAY,EAAA,EAAA,CAAA;AAAA,MACnB,OAAA,EAAS,MAEL,MACG,CAAA,KAAA,GACA,KAAM,EAAA,CAER,iBAAkB,EAAA,CAClB,GAAI,EAAA;AAAA,MAEV,QAAA,EAAA,SAAA;AAAA,KAAA;AAAA,GAIL,EAAA,CAAA,CAAA;AAEJ,CAAA;AAEA,SAAS,gBAAmB,GAAA;AAC1B,EAAM,MAAA,MAAA,GAASjB,wBAAiB,CAAA,WAAA,EAAa,4BAA4B,CAAA,CAAA;AACzE,EAAM,MAAA,UAAA,GAAa,WAAW,MAAO,CAAA,QAAA,CAAA;AACrC,EAAM,MAAA,MAAA,GAAU,MAAO,CAAA,OAAA,CAAQ,YAC3B,EAAA,IAAA,CAAA;AAEJ,EACE,uBAAAhB,cAAA,CAAAyB,mBAAA,EAAA,EACG,wCAEGN,eAAA,CAAAM,mBAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAAN,eAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,OAAO,MAAM,CAAA,eAAA,CAAA;AAAA,QACnB,IAAA,iCAAOe,qBAAa,EAAA,EAAA,CAAA;AAAA,QACpB,SAAS,MAEL,MAAA,CAAO,OAAQ,CAAA,KAAA,GACf,KAAM,EAAA;AAAA,QAEX,QAAA,EAAA;AAAA,UAAA,MAAA;AAAA,UACM,MAAA;AAAA,SAAA;AAAA,OAAA;AAAA,KACP;AAAA,oBACAlC,cAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,IAAK,EAAA,SAAA;AAAA,QACL,IAAA,iCAAOmC,yBAAiB,EAAA,EAAA,CAAA;AAAA,QACxB,OAAA,EAAS,MAEL,MAAO,CAAA,KAAA,GAAQ,KAAM,EAAA,CACrB,MAAM,gCAAgC,CAAA;AAAA,QAE3C,QAAA,EAAA,SAAA;AAAA,OAAA;AAAA,KAED;AAAA,GAAA,EACF,CAEJ,EAAA,CAAA,CAAA;AAEJ,CAAA;AAEA,SAAS,qBAAA,CAAsB,EAAE,MAAA,EAA4B,EAAA;AAC3D,EAAM,MAAA,cAAA,GAAiB,uBAAuB,MAAO,CAAA,QAAA,CAAA;AACrD,EAAM,MAAA,UAAA,GAAa,WAAW,MAAO,CAAA,QAAA,CAAA;AAErC,EAAA,uBAEIhB,eAAA,CAAAM,mBAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAAzB,cAAA,CAAC,qBAAsB,EAAA,EAAA,CAAA;AAAA,mCACtB,gBAAiB,EAAA,EAAA,CAAA;AAAA,IACjB,6BAEGmB,eAAA,CAAAM,mBAAA,EAAA,EAAA,QAAA,EAAA;AAAA,sBAAAzB,cAAA,CAAC,gBAAiB,EAAA,EAAA,CAAA;AAAA,qCACjB,gBAAiB,EAAA,EAAA,CAAA;AAAA,KAAA,EACpB,CACE,GAAA,IAAA;AAAA,mCACH,oBAAqB,EAAA,EAAA,CAAA;AAAA,mCACrB,oBAAqB,EAAA,EAAA,CAAA;AAAA,IACrB,iCAEGmB,eAAA,CAAAM,mBAAA,EAAA,EAAA,QAAA,EAAA;AAAA,sBAAAzB,cAAA,CAAC,gBAAiB,EAAA,EAAA,CAAA;AAAA,qCACjB,2BAA4B,EAAA,EAAA,CAAA;AAAA,KAAA,EAC/B,CACE,GAAA,IAAA;AAAA,GACN,EAAA,CAAA,CAAA;AAEJ,CAAA;AAiBO,MAAM,UAAU,MAAO,CAAA,MAAA;AAAA,EAC5BC,gBAAA;AAAA,IACE,CACE;AAAA,MACE,MAAA;AAAA,MACA,KAAA;AAAA,MACA,QAAW,GAAA,qBAAA;AAAA,MACX,MAAA;AAAA,MACA,SAAA;AAAA,MACA,GAAG,KAAA;AAAA,OAEL,YACG,KAAA;AAEH,MAAemC,sBAAA,CAAA;AAAA,QACb,MAAA;AAAA,QACA,YAAY,MAAO,CAAA,EAAA;AAAA,QACnB,QAAU,EAAA,CAAC,GAAQ,KAAA,GAAA,CAAI,MAAQ,EAAA,KAAA;AAAA,OAChC,CAAA,CAAA;AAED,MAAA,IAAI,CAAC,MAAQ,EAAA;AACX,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAEA,MAAM,MAAA,SAAA,GAA8B,EAAE,MAAO,EAAA,CAAA;AAE7C,MAAA,uBACGpC,cAAA,CAAAqC,wBAAA,EAAA,EACC,QAAC,kBAAArC,cAAA,CAAAsC,sBAAA,EAAA,EAAe,MACd,EAAA,QAAA,kBAAAnB,eAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAK,EAAA,YAAA;AAAA,UACL,IAAK,EAAA,SAAA;AAAA,UACL,YAAW,EAAA,SAAA;AAAA,UACX,kBAAiB,EAAA,YAAA;AAAA,UACjB,SAAA,EAAWK,WAAG,CAAA,2BAAA,EAA6B,SAAS,CAAA;AAAA,UACnD,GAAG,KAAA;AAAA,UAEH,QAAA,EAAA;AAAA,YAAA,gBAAA,CAAiB,QAAQ,SAAS,CAAA;AAAA,YAClC,gBAAA,CAAiB,UAAU,SAAS,CAAA;AAAA,YACpC,gBAAA,CAAiB,OAAO,SAAS,CAAA;AAAA,WAAA;AAAA,SAAA;AAAA,SAEtC,CACF,EAAA,CAAA,CAAA;AAAA,KAEJ;AAAA,GACF;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUE,MAAQ,EAAA,aAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWR,MAAQ,EAAA,aAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQR,aAAe,EAAA,oBAAA;AAAA;AAAA;AAAA;AAAA,IAKf,SAAW,EAAA,gBAAA;AAAA;AAAA;AAAA;AAAA,IAKX,cAAgB,EAAA,qBAAA;AAAA;AAAA;AAAA;AAAA,IAKhB,aAAe,EAAA,oBAAA;AAAA;AAAA;AAAA;AAAA,IAKf,oBAAsB,EAAA,2BAAA;AAAA;AAAA;AAAA;AAAA,IAKtB,SAAW,EAAA,gBAAA;AAAA,GACb;AACF;;;;;;;"} |
@@ -5,2 +5,3 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; | ||
| import * as TogglePrimitive from '@radix-ui/react-toggle'; | ||
| import { useEditorState } from '@tiptap/react'; | ||
| import { forwardRef, useContext, useCallback, useMemo } from 'react'; | ||
@@ -371,2 +372,7 @@ import { useCurrentEditor, EditorProvider } from '../context.js'; | ||
| }, forwardedRef) => { | ||
| useEditorState({ | ||
| editor, | ||
| equalityFn: Object.is, | ||
| selector: (ctx) => ctx.editor?.state | ||
| }); | ||
| if (!editor) { | ||
@@ -373,0 +379,0 @@ return null; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"Toolbar.js","sources":["../../src/toolbar/Toolbar.tsx"],"sourcesContent":["import {\n BlockquoteIcon,\n BoldIcon,\n Button,\n CheckIcon,\n cn,\n CodeIcon,\n CommentIcon,\n H1Icon,\n H2Icon,\n H3Icon,\n ItalicIcon,\n ListOrderedIcon,\n ListUnorderedIcon,\n QuestionMarkIcon,\n RedoIcon,\n SelectButton,\n ShortcutTooltip,\n SparklesIcon,\n StrikethroughIcon,\n TextIcon,\n TooltipProvider,\n UnderlineIcon,\n UndoIcon,\n} from \"@liveblocks/react-ui/_private\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type { Editor } from \"@tiptap/react\";\nimport type {\n ComponentProps,\n ComponentType,\n KeyboardEvent,\n ReactNode,\n} from \"react\";\nimport { forwardRef, useCallback, useContext, useMemo } from \"react\";\n\nimport { EditorProvider, useCurrentEditor } from \"../context\";\nimport type { AiExtensionStorage, ExtendedChainedCommands } from \"../types\";\nimport { FloatingToolbarContext, FloatingToolbarExternal } from \"./shared\";\n\nexport const BLOCK_SELECT_SIDE_OFFSET = 10;\nexport const FLOATING_ELEMENT_COLLISION_PADDING = 10;\n\nexport interface ToolbarSlotProps {\n editor: Editor;\n}\n\nexport type ToolbarSlot = ReactNode | ComponentType<ToolbarSlotProps>;\n\nexport interface ToolbarProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n\n /**\n * The content of the toolbar, overriding the default content.\n * Use the `before` and `after` props if you want to keep and extend the default content.\n */\n children?: ToolbarSlot;\n\n /**\n * The content to display at the start of the toolbar.\n */\n before?: ToolbarSlot;\n\n /**\n * The content to display at the end of the toolbar.\n */\n after?: ToolbarSlot;\n}\n\nexport interface ToolbarButtonProps extends ComponentProps<\"button\"> {\n /**\n * The name of this button displayed in its tooltip.\n */\n name: string;\n\n /**\n * An optional icon displayed in this button.\n */\n icon?: ReactNode;\n\n /**\n * An optional keyboard shortcut displayed in this button's tooltip.\n *\n * @example\n * \"Mod-Alt-B\" → \"⌘⌥B\" in Apple environments, \"⌃⌥B\" otherwise\n * \"Ctrl-Shift-Escape\" → \"⌃⇧⎋\"\n * \"Space\" → \"␣\"\n */\n shortcut?: string;\n}\n\nexport interface ToolbarToggleProps extends ToolbarButtonProps {\n /**\n * Whether the button is toggled.\n */\n active: boolean;\n}\n\nexport interface ToolbarBlockSelectorItem {\n /**\n * The name of this block element, displayed as the label of this item.\n */\n name: string;\n\n /**\n * Optionally replace the name used as the label of this item by any content.\n */\n label?: ReactNode;\n\n /**\n * An optional icon displayed in this item.\n */\n icon?: ReactNode;\n\n /**\n * Whether this block element is currently active.\n * Set to `\"default\"` to display this item when no other item is active.\n */\n isActive: ((editor: Editor) => boolean) | \"default\";\n\n /**\n * A callback invoked when this item is selected.\n */\n setActive: (editor: Editor) => void;\n}\n\nexport interface ToolbarBlockSelectorProps extends ComponentProps<\"button\"> {\n /**\n * The items displayed in this block selector.\n * When provided as an array, the default items are overridden. To avoid this,\n * a function can be provided instead and it will receive the default items.\n *\n * @example\n * <Toolbar.BlockSelector\n * items={[\n * {\n * name: \"Text\",\n * isActive: \"default\",\n * setActive: () => { ... },\n * },\n * {\n * name: \"Heading 1\",\n * isActive: () => { ... },\n * setActive: () => { ... },\n * },\n * ]}\n * />\n *\n * @example\n * <Toolbar.BlockSelector\n * items={(defaultItems) => [\n * ...defaultItems,\n * {\n * name: \"Custom block\",\n * isActive: () => { ... },\n * setActive: () => { ... },\n * },\n * ]}\n * />\n */\n items?:\n | ToolbarBlockSelectorItem[]\n | ((\n defaultItems: ToolbarBlockSelectorItem[]\n ) => ToolbarBlockSelectorItem[]);\n}\n\nexport type ToolbarSeparatorProps = ComponentProps<\"div\">;\n\nexport function applyToolbarSlot(\n slot: ToolbarSlot,\n props: ToolbarSlotProps\n): ReactNode {\n if (typeof slot === \"function\") {\n const Component = slot;\n\n return <Component {...props} />;\n }\n\n return slot;\n}\n\nconst ToolbarButton = forwardRef<HTMLButtonElement, ToolbarButtonProps>(\n ({ icon, children, name, shortcut, onKeyDown, ...props }, forwardedRef) => {\n const floatingToolbarContext = useContext(FloatingToolbarContext);\n const closeFloatingToolbar = floatingToolbarContext?.close;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n\n if (\n !event.isDefaultPrevented() &&\n closeFloatingToolbar &&\n event.key === \"Escape\"\n ) {\n closeFloatingToolbar();\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [onKeyDown, closeFloatingToolbar]\n );\n\n return (\n <ShortcutTooltip content={name} shortcut={shortcut}>\n <Button\n type=\"button\"\n variant=\"toolbar\"\n ref={forwardedRef}\n icon={icon}\n aria-label={!children ? name : undefined}\n // Safari doesn't mark buttons as focusable, which breaks `relatedTarget`\n // in focus/blur events. https://bugs.webkit.org/show_bug.cgi?id=254655\n tabIndex={0}\n {...props}\n onKeyDown={handleKeyDown}\n >\n {!children && !icon ? name : children}\n </Button>\n </ShortcutTooltip>\n );\n }\n);\n\nconst ToolbarToggle = forwardRef<HTMLButtonElement, ToolbarToggleProps>(\n ({ active, ...props }, forwardedRef) => {\n return (\n <TogglePrimitive.Root asChild pressed={active}>\n <ToolbarButton ref={forwardedRef} {...props} />\n </TogglePrimitive.Root>\n );\n }\n);\n\nfunction createDefaultBlockSelectorItems(\n editor: Editor\n): ToolbarBlockSelectorItem[] {\n const items: (ToolbarBlockSelectorItem | null)[] = [\n {\n name: \"Text\",\n icon: <TextIcon />,\n isActive: \"default\",\n setActive: (editor) => editor.chain().focus().clearNodes().run(),\n },\n \"toggleHeading\" in editor.commands\n ? {\n name: \"Heading 1\",\n icon: <H1Icon />,\n isActive: (editor) => editor.isActive(\"heading\", { level: 1 }),\n setActive: (editor) =>\n (\n editor.chain().focus().clearNodes() as ExtendedChainedCommands<\n \"toggleHeading\",\n [{ level: number }]\n >\n )\n .toggleHeading({ level: 1 })\n .run(),\n }\n : null,\n \"toggleHeading\" in editor.commands\n ? {\n name: \"Heading 2\",\n icon: <H2Icon />,\n isActive: (editor) => editor.isActive(\"heading\", { level: 2 }),\n setActive: (editor) =>\n (\n editor.chain().focus().clearNodes() as ExtendedChainedCommands<\n \"toggleHeading\",\n [{ level: number }]\n >\n )\n .toggleHeading({ level: 2 })\n .run(),\n }\n : null,\n \"toggleHeading\" in editor.commands\n ? {\n name: \"Heading 3\",\n icon: <H3Icon />,\n isActive: (editor) => editor.isActive(\"heading\", { level: 3 }),\n setActive: (editor) =>\n (\n editor.chain().focus().clearNodes() as ExtendedChainedCommands<\n \"toggleHeading\",\n [{ level: number }]\n >\n )\n .toggleHeading({ level: 3 })\n .run(),\n }\n : null,\n \"toggleBulletList\" in editor.commands\n ? {\n name: \"Bullet list\",\n icon: <ListUnorderedIcon />,\n isActive: (editor) => editor.isActive(\"bulletList\"),\n setActive: (editor) =>\n (\n editor\n .chain()\n .focus()\n .clearNodes() as ExtendedChainedCommands<\"toggleBulletList\">\n )\n .toggleBulletList()\n .run(),\n }\n : null,\n \"toggleOrderedList\" in editor.commands\n ? {\n name: \"Numbered list\",\n icon: <ListOrderedIcon />,\n isActive: (editor) => editor.isActive(\"orderedList\"),\n setActive: (editor) =>\n (\n editor\n .chain()\n .focus()\n .clearNodes() as ExtendedChainedCommands<\"toggleOrderedList\">\n )\n .toggleOrderedList()\n .run(),\n }\n : null,\n \"toggleBlockquote\" in editor.commands\n ? {\n name: \"Blockquote\",\n icon: <BlockquoteIcon />,\n isActive: (editor) => editor.isActive(\"blockquote\"),\n setActive: (editor) =>\n (\n editor\n .chain()\n .focus()\n .clearNodes() as ExtendedChainedCommands<\"toggleBlockquote\">\n )\n .toggleBlockquote()\n .run(),\n }\n : null,\n ];\n\n return items.filter(Boolean) as ToolbarBlockSelectorItem[];\n}\n\nconst ToolbarBlockSelector = forwardRef<\n HTMLButtonElement,\n ToolbarBlockSelectorProps\n>(({ items, onKeyDown, ...props }, forwardedRef) => {\n const floatingToolbarContext = useContext(FloatingToolbarContext);\n const closeFloatingToolbar = floatingToolbarContext?.close;\n const editor = useCurrentEditor(\n \"BlockSelector\",\n \"Toolbar or FloatingToolbar\"\n );\n const resolvedItems = useMemo(() => {\n if (Array.isArray(items)) {\n return items;\n }\n\n const defaultItems = createDefaultBlockSelectorItems(editor);\n\n return items ? items(defaultItems) : defaultItems;\n }, [editor, items]);\n let defaultItem: ToolbarBlockSelectorItem | undefined;\n let activeItem = editor.isInitialized\n ? resolvedItems.find((item) => {\n if (item.isActive === \"default\") {\n defaultItem = item;\n return false;\n }\n\n return item.isActive(editor);\n })\n : undefined;\n\n if (!activeItem) {\n activeItem = defaultItem;\n }\n\n const handleItemChange = (name: string) => {\n const item = resolvedItems.find((item) => item.name === name);\n\n if (item) {\n item.setActive(editor);\n\n // If present in a floating toolbar, close it on change\n floatingToolbarContext?.close();\n }\n };\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n\n if (\n !event.isDefaultPrevented() &&\n closeFloatingToolbar &&\n event.key === \"Escape\"\n ) {\n closeFloatingToolbar();\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [onKeyDown, closeFloatingToolbar]\n );\n\n return (\n <SelectPrimitive.Root\n value={activeItem?.name}\n onValueChange={handleItemChange}\n >\n <ShortcutTooltip content=\"Turn into…\">\n <SelectPrimitive.Trigger\n asChild\n {...props}\n ref={forwardedRef}\n onKeyDown={handleKeyDown}\n disabled={resolvedItems.length === 0}\n >\n <SelectButton variant=\"toolbar\">\n {activeItem?.name ?? \"Turn into…\"}\n </SelectButton>\n </SelectPrimitive.Trigger>\n </ShortcutTooltip>\n <SelectPrimitive.Portal>\n <FloatingToolbarExternal>\n <SelectPrimitive.Content\n position=\"popper\"\n sideOffset={BLOCK_SELECT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n className=\"lb-root lb-portal lb-elevation lb-dropdown lb-select-dropdown lb-tiptap-block-selector-dropdown\"\n >\n {resolvedItems.map((item) => (\n <SelectPrimitive.Item\n key={item.name}\n value={item.name}\n className=\"lb-dropdown-item\"\n data-name={item.name}\n >\n {item.icon ? (\n <span className=\"lb-dropdown-item-icon lb-icon-container\">\n {item.icon}\n </span>\n ) : null}\n <span className=\"lb-dropdown-item-label\">\n {item.label ?? item.name}\n </span>\n {item.name === activeItem?.name ? (\n <span className=\"lb-dropdown-item-accessory lb-icon-container\">\n <CheckIcon />\n </span>\n ) : null}\n </SelectPrimitive.Item>\n ))}\n </SelectPrimitive.Content>\n </FloatingToolbarExternal>\n </SelectPrimitive.Portal>\n </SelectPrimitive.Root>\n );\n});\n\nconst ToolbarSeparator = forwardRef<HTMLDivElement, ToolbarSeparatorProps>(\n ({ className, ...props }, forwardedRef) => {\n return (\n <div\n ref={forwardedRef}\n role=\"separator\"\n aria-orientation=\"vertical\"\n className={cn(\"lb-tiptap-toolbar-separator\", className)}\n {...props}\n />\n );\n }\n);\n\nfunction ToolbarSectionHistory() {\n const editor = useCurrentEditor(\n \"SectionHistory\",\n \"Toolbar or FloatingToolbar\"\n );\n\n return (\n <>\n <ToolbarButton\n name=\"Undo\"\n icon={<UndoIcon />}\n shortcut=\"Mod-Z\"\n onClick={() => editor.chain().focus().undo().run()}\n disabled={!editor.can().chain().focus().undo().run()}\n />\n <ToolbarButton\n name=\"Redo\"\n icon={<RedoIcon />}\n shortcut=\"Mod-Shift-Z\"\n onClick={() => editor.chain().focus().redo().run()}\n disabled={!editor.can().chain().focus().redo().run()}\n />\n </>\n );\n}\n\nfunction ToolbarSectionInline() {\n const editor = useCurrentEditor(\n \"SectionInline\",\n \"Toolbar or FloatingToolbar\"\n );\n const supportsBold = \"toggleBold\" in editor.commands;\n const supportsItalic = \"toggleItalic\" in editor.commands;\n const supportsUnderline = \"toggleUnderline\" in editor.commands;\n const supportsStrike = \"toggleStrike\" in editor.commands;\n const supportsCode = \"toggleCode\" in editor.commands;\n\n return (\n <>\n {supportsBold && (\n <ToolbarToggle\n name=\"Bold\"\n icon={<BoldIcon />}\n shortcut=\"Mod-B\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleBold\">)\n .toggleBold()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleBold\">\n )\n .toggleBold()\n .run()\n }\n active={editor.isActive(\"bold\")}\n />\n )}\n {supportsItalic && (\n <ToolbarToggle\n name=\"Italic\"\n icon={<ItalicIcon />}\n shortcut=\"Mod-I\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleItalic\">)\n .toggleItalic()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleItalic\">\n )\n .toggleItalic()\n .run()\n }\n active={editor.isActive(\"italic\")}\n />\n )}\n {supportsUnderline && (\n <ToolbarToggle\n name=\"Underline\"\n icon={<UnderlineIcon />}\n shortcut=\"Mod-U\"\n onClick={() =>\n (\n editor\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleUnderline\">\n )\n .toggleUnderline()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleUnderline\">\n )\n .toggleUnderline()\n .run()\n }\n active={editor.isActive(\"underline\")}\n />\n )}\n {supportsStrike && (\n <ToolbarToggle\n name=\"Strikethrough\"\n icon={<StrikethroughIcon />}\n shortcut=\"Mod-U\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleStrike\">)\n .toggleStrike()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleStrike\">\n )\n .toggleStrike()\n .run()\n }\n active={editor.isActive(\"strike\")}\n />\n )}\n {supportsCode && (\n <ToolbarToggle\n name=\"Inline code\"\n icon={<CodeIcon />}\n shortcut=\"Mod-E\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleCode\">)\n .toggleCode()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleCode\">\n )\n .toggleCode()\n .run()\n }\n active={editor.isActive(\"code\")}\n />\n )}\n </>\n );\n}\n\nfunction ToolbarSectionCollaboration() {\n const editor = useCurrentEditor(\n \"SectionCollaboration\",\n \"Toolbar or FloatingToolbar\"\n );\n const supportsThread = \"addPendingComment\" in editor.commands;\n\n return (\n <>\n {supportsThread && (\n <ToolbarButton\n name=\"Add a comment\"\n icon={<CommentIcon />}\n onClick={() =>\n (\n editor\n .chain()\n .focus() as ExtendedChainedCommands<\"addPendingComment\">\n )\n .addPendingComment()\n .run()\n }\n >\n Comment\n </ToolbarButton>\n )}\n </>\n );\n}\n\nfunction ToolbarSectionAi() {\n const editor = useCurrentEditor(\"SectionAi\", \"Toolbar or FloatingToolbar\");\n const supportsAi = \"askAi\" in editor.commands;\n const aiName = (editor.storage.liveblocksAi as AiExtensionStorage | undefined)\n ?.name;\n\n return (\n <>\n {supportsAi && (\n <>\n <ToolbarButton\n name={`Ask ${aiName} anything…`}\n icon={<SparklesIcon />}\n onClick={() =>\n (\n editor.chain().focus() as ExtendedChainedCommands<\"askAi\">\n ).askAi()\n }\n >\n Ask {aiName}\n </ToolbarButton>\n <ToolbarButton\n name=\"Explain\"\n icon={<QuestionMarkIcon />}\n onClick={() =>\n (\n editor.chain().focus() as ExtendedChainedCommands<\"askAi\">\n ).askAi(\"Explain what the text is about\")\n }\n >\n Explain\n </ToolbarButton>\n </>\n )}\n </>\n );\n}\n\nfunction DefaultToolbarContent({ editor }: ToolbarSlotProps) {\n const supportsThread = \"addPendingComment\" in editor.commands;\n const supportsAi = \"askAi\" in editor.commands;\n\n return (\n <>\n <ToolbarSectionHistory />\n <ToolbarSeparator />\n {supportsAi ? (\n <>\n <ToolbarSectionAi />\n <ToolbarSeparator />\n </>\n ) : null}\n <ToolbarBlockSelector />\n <ToolbarSectionInline />\n {supportsThread ? (\n <>\n <ToolbarSeparator />\n <ToolbarSectionCollaboration />\n </>\n ) : null}\n </>\n );\n}\n\n/**\n * A static toolbar containing actions and values related to the editor.\n *\n * @example\n * <Toolbar editor={editor} />\n *\n * @example\n * <Toolbar editor={editor}>\n * <Toolbar.BlockSelector />\n * <Toolbar.Separator />\n * <Toolbar.SectionInline />\n * <Toolbar.Separator />\n * <Toolbar.Button name=\"Custom action\" onClick={() => { ... }} icon={<Icon.QuestionMark />} />\n * </Toolbar>\n */\nexport const Toolbar = Object.assign(\n forwardRef<HTMLDivElement, ToolbarProps>(\n (\n {\n before,\n after,\n children = DefaultToolbarContent,\n editor,\n className,\n ...props\n },\n forwardedRef\n ) => {\n if (!editor) {\n return null;\n }\n\n const slotProps: ToolbarSlotProps = { editor };\n\n return (\n <TooltipProvider>\n <EditorProvider editor={editor}>\n <div\n ref={forwardedRef}\n role=\"toolbar\"\n aria-label=\"Toolbar\"\n aria-orientation=\"horizontal\"\n className={cn(\"lb-root lb-tiptap-toolbar\", className)}\n {...props}\n >\n {applyToolbarSlot(before, slotProps)}\n {applyToolbarSlot(children, slotProps)}\n {applyToolbarSlot(after, slotProps)}\n </div>\n </EditorProvider>\n </TooltipProvider>\n );\n }\n ),\n {\n /**\n * A button for triggering actions.\n *\n * @example\n * <Toolbar.Button name=\"Comment\" shortcut=\"Mod-Shift-E\" onClick={() => { ... }} />\n *\n * @example\n * <Toolbar.Button name=\"Mention someone\" icon={<Icon.Mention />} onClick={() => { ... }} />\n */\n Button: ToolbarButton,\n\n /**\n * A toggle button for values that can be active or inactive.\n *\n * @example\n * <Toolbar.Toggle name=\"Bold\" active={isBold} />\n *\n * @example\n * <Toolbar.Toggle name=\"Italic\" icon={<Icon.Italic />} shortcut=\"Mod-I\" active={isItalic} onClick={() => { ... }} />\n */\n Toggle: ToolbarToggle,\n\n /**\n * A dropdown selector to switch between different block types.\n *\n * @example\n * <Toolbar.BlockSelector />\n */\n BlockSelector: ToolbarBlockSelector,\n\n /**\n * A visual (and accessible) separator to separate sections in a toolbar.\n */\n Separator: ToolbarSeparator,\n\n /**\n * A section containing history actions. (e.g. undo, redo)\n */\n SectionHistory: ToolbarSectionHistory,\n\n /**\n * A section containing inline formatting actions. (e.g. bold, italic, underline, ...)\n */\n SectionInline: ToolbarSectionInline,\n\n /**\n * A section containing collaborative actions. (e.g. adding a comment)\n */\n SectionCollaboration: ToolbarSectionCollaboration,\n\n /**\n * A section containing AI actions. (e.g. opening the AI toolbar)\n */\n SectionAi: ToolbarSectionAi,\n }\n);\n"],"names":["editor","item"],"mappings":"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"} | ||
| {"version":3,"file":"Toolbar.js","sources":["../../src/toolbar/Toolbar.tsx"],"sourcesContent":["import {\n BlockquoteIcon,\n BoldIcon,\n Button,\n CheckIcon,\n cn,\n CodeIcon,\n CommentIcon,\n H1Icon,\n H2Icon,\n H3Icon,\n ItalicIcon,\n ListOrderedIcon,\n ListUnorderedIcon,\n QuestionMarkIcon,\n RedoIcon,\n SelectButton,\n ShortcutTooltip,\n SparklesIcon,\n StrikethroughIcon,\n TextIcon,\n TooltipProvider,\n UnderlineIcon,\n UndoIcon,\n} from \"@liveblocks/react-ui/_private\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport type {\n ComponentProps,\n ComponentType,\n KeyboardEvent,\n ReactNode,\n} from \"react\";\nimport { forwardRef, useCallback, useContext, useMemo } from \"react\";\n\nimport { EditorProvider, useCurrentEditor } from \"../context\";\nimport type { AiExtensionStorage, ExtendedChainedCommands } from \"../types\";\nimport { FloatingToolbarContext, FloatingToolbarExternal } from \"./shared\";\n\nexport const BLOCK_SELECT_SIDE_OFFSET = 10;\nexport const FLOATING_ELEMENT_COLLISION_PADDING = 10;\n\nexport interface ToolbarSlotProps {\n editor: Editor;\n}\n\nexport type ToolbarSlot = ReactNode | ComponentType<ToolbarSlotProps>;\n\nexport interface ToolbarProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n\n /**\n * The content of the toolbar, overriding the default content.\n * Use the `before` and `after` props if you want to keep and extend the default content.\n */\n children?: ToolbarSlot;\n\n /**\n * The content to display at the start of the toolbar.\n */\n before?: ToolbarSlot;\n\n /**\n * The content to display at the end of the toolbar.\n */\n after?: ToolbarSlot;\n}\n\nexport interface ToolbarButtonProps extends ComponentProps<\"button\"> {\n /**\n * The name of this button displayed in its tooltip.\n */\n name: string;\n\n /**\n * An optional icon displayed in this button.\n */\n icon?: ReactNode;\n\n /**\n * An optional keyboard shortcut displayed in this button's tooltip.\n *\n * @example\n * \"Mod-Alt-B\" → \"⌘⌥B\" in Apple environments, \"⌃⌥B\" otherwise\n * \"Ctrl-Shift-Escape\" → \"⌃⇧⎋\"\n * \"Space\" → \"␣\"\n */\n shortcut?: string;\n}\n\nexport interface ToolbarToggleProps extends ToolbarButtonProps {\n /**\n * Whether the button is toggled.\n */\n active: boolean;\n}\n\nexport interface ToolbarBlockSelectorItem {\n /**\n * The name of this block element, displayed as the label of this item.\n */\n name: string;\n\n /**\n * Optionally replace the name used as the label of this item by any content.\n */\n label?: ReactNode;\n\n /**\n * An optional icon displayed in this item.\n */\n icon?: ReactNode;\n\n /**\n * Whether this block element is currently active.\n * Set to `\"default\"` to display this item when no other item is active.\n */\n isActive: ((editor: Editor) => boolean) | \"default\";\n\n /**\n * A callback invoked when this item is selected.\n */\n setActive: (editor: Editor) => void;\n}\n\nexport interface ToolbarBlockSelectorProps extends ComponentProps<\"button\"> {\n /**\n * The items displayed in this block selector.\n * When provided as an array, the default items are overridden. To avoid this,\n * a function can be provided instead and it will receive the default items.\n *\n * @example\n * <Toolbar.BlockSelector\n * items={[\n * {\n * name: \"Text\",\n * isActive: \"default\",\n * setActive: () => { ... },\n * },\n * {\n * name: \"Heading 1\",\n * isActive: () => { ... },\n * setActive: () => { ... },\n * },\n * ]}\n * />\n *\n * @example\n * <Toolbar.BlockSelector\n * items={(defaultItems) => [\n * ...defaultItems,\n * {\n * name: \"Custom block\",\n * isActive: () => { ... },\n * setActive: () => { ... },\n * },\n * ]}\n * />\n */\n items?:\n | ToolbarBlockSelectorItem[]\n | ((\n defaultItems: ToolbarBlockSelectorItem[]\n ) => ToolbarBlockSelectorItem[]);\n}\n\nexport type ToolbarSeparatorProps = ComponentProps<\"div\">;\n\nexport function applyToolbarSlot(\n slot: ToolbarSlot,\n props: ToolbarSlotProps\n): ReactNode {\n if (typeof slot === \"function\") {\n const Component = slot;\n\n return <Component {...props} />;\n }\n\n return slot;\n}\n\nconst ToolbarButton = forwardRef<HTMLButtonElement, ToolbarButtonProps>(\n ({ icon, children, name, shortcut, onKeyDown, ...props }, forwardedRef) => {\n const floatingToolbarContext = useContext(FloatingToolbarContext);\n const closeFloatingToolbar = floatingToolbarContext?.close;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n\n if (\n !event.isDefaultPrevented() &&\n closeFloatingToolbar &&\n event.key === \"Escape\"\n ) {\n closeFloatingToolbar();\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [onKeyDown, closeFloatingToolbar]\n );\n\n return (\n <ShortcutTooltip content={name} shortcut={shortcut}>\n <Button\n type=\"button\"\n variant=\"toolbar\"\n ref={forwardedRef}\n icon={icon}\n aria-label={!children ? name : undefined}\n // Safari doesn't mark buttons as focusable, which breaks `relatedTarget`\n // in focus/blur events. https://bugs.webkit.org/show_bug.cgi?id=254655\n tabIndex={0}\n {...props}\n onKeyDown={handleKeyDown}\n >\n {!children && !icon ? name : children}\n </Button>\n </ShortcutTooltip>\n );\n }\n);\n\nconst ToolbarToggle = forwardRef<HTMLButtonElement, ToolbarToggleProps>(\n ({ active, ...props }, forwardedRef) => {\n return (\n <TogglePrimitive.Root asChild pressed={active}>\n <ToolbarButton ref={forwardedRef} {...props} />\n </TogglePrimitive.Root>\n );\n }\n);\n\nfunction createDefaultBlockSelectorItems(\n editor: Editor\n): ToolbarBlockSelectorItem[] {\n const items: (ToolbarBlockSelectorItem | null)[] = [\n {\n name: \"Text\",\n icon: <TextIcon />,\n isActive: \"default\",\n setActive: (editor) => editor.chain().focus().clearNodes().run(),\n },\n \"toggleHeading\" in editor.commands\n ? {\n name: \"Heading 1\",\n icon: <H1Icon />,\n isActive: (editor) => editor.isActive(\"heading\", { level: 1 }),\n setActive: (editor) =>\n (\n editor.chain().focus().clearNodes() as ExtendedChainedCommands<\n \"toggleHeading\",\n [{ level: number }]\n >\n )\n .toggleHeading({ level: 1 })\n .run(),\n }\n : null,\n \"toggleHeading\" in editor.commands\n ? {\n name: \"Heading 2\",\n icon: <H2Icon />,\n isActive: (editor) => editor.isActive(\"heading\", { level: 2 }),\n setActive: (editor) =>\n (\n editor.chain().focus().clearNodes() as ExtendedChainedCommands<\n \"toggleHeading\",\n [{ level: number }]\n >\n )\n .toggleHeading({ level: 2 })\n .run(),\n }\n : null,\n \"toggleHeading\" in editor.commands\n ? {\n name: \"Heading 3\",\n icon: <H3Icon />,\n isActive: (editor) => editor.isActive(\"heading\", { level: 3 }),\n setActive: (editor) =>\n (\n editor.chain().focus().clearNodes() as ExtendedChainedCommands<\n \"toggleHeading\",\n [{ level: number }]\n >\n )\n .toggleHeading({ level: 3 })\n .run(),\n }\n : null,\n \"toggleBulletList\" in editor.commands\n ? {\n name: \"Bullet list\",\n icon: <ListUnorderedIcon />,\n isActive: (editor) => editor.isActive(\"bulletList\"),\n setActive: (editor) =>\n (\n editor\n .chain()\n .focus()\n .clearNodes() as ExtendedChainedCommands<\"toggleBulletList\">\n )\n .toggleBulletList()\n .run(),\n }\n : null,\n \"toggleOrderedList\" in editor.commands\n ? {\n name: \"Numbered list\",\n icon: <ListOrderedIcon />,\n isActive: (editor) => editor.isActive(\"orderedList\"),\n setActive: (editor) =>\n (\n editor\n .chain()\n .focus()\n .clearNodes() as ExtendedChainedCommands<\"toggleOrderedList\">\n )\n .toggleOrderedList()\n .run(),\n }\n : null,\n \"toggleBlockquote\" in editor.commands\n ? {\n name: \"Blockquote\",\n icon: <BlockquoteIcon />,\n isActive: (editor) => editor.isActive(\"blockquote\"),\n setActive: (editor) =>\n (\n editor\n .chain()\n .focus()\n .clearNodes() as ExtendedChainedCommands<\"toggleBlockquote\">\n )\n .toggleBlockquote()\n .run(),\n }\n : null,\n ];\n\n return items.filter(Boolean) as ToolbarBlockSelectorItem[];\n}\n\nconst ToolbarBlockSelector = forwardRef<\n HTMLButtonElement,\n ToolbarBlockSelectorProps\n>(({ items, onKeyDown, ...props }, forwardedRef) => {\n const floatingToolbarContext = useContext(FloatingToolbarContext);\n const closeFloatingToolbar = floatingToolbarContext?.close;\n const editor = useCurrentEditor(\n \"BlockSelector\",\n \"Toolbar or FloatingToolbar\"\n );\n const resolvedItems = useMemo(() => {\n if (Array.isArray(items)) {\n return items;\n }\n\n const defaultItems = createDefaultBlockSelectorItems(editor);\n\n return items ? items(defaultItems) : defaultItems;\n }, [editor, items]);\n let defaultItem: ToolbarBlockSelectorItem | undefined;\n let activeItem = editor.isInitialized\n ? resolvedItems.find((item) => {\n if (item.isActive === \"default\") {\n defaultItem = item;\n return false;\n }\n\n return item.isActive(editor);\n })\n : undefined;\n\n if (!activeItem) {\n activeItem = defaultItem;\n }\n\n const handleItemChange = (name: string) => {\n const item = resolvedItems.find((item) => item.name === name);\n\n if (item) {\n item.setActive(editor);\n\n // If present in a floating toolbar, close it on change\n floatingToolbarContext?.close();\n }\n };\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n\n if (\n !event.isDefaultPrevented() &&\n closeFloatingToolbar &&\n event.key === \"Escape\"\n ) {\n closeFloatingToolbar();\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [onKeyDown, closeFloatingToolbar]\n );\n\n return (\n <SelectPrimitive.Root\n value={activeItem?.name}\n onValueChange={handleItemChange}\n >\n <ShortcutTooltip content=\"Turn into…\">\n <SelectPrimitive.Trigger\n asChild\n {...props}\n ref={forwardedRef}\n onKeyDown={handleKeyDown}\n disabled={resolvedItems.length === 0}\n >\n <SelectButton variant=\"toolbar\">\n {activeItem?.name ?? \"Turn into…\"}\n </SelectButton>\n </SelectPrimitive.Trigger>\n </ShortcutTooltip>\n <SelectPrimitive.Portal>\n <FloatingToolbarExternal>\n <SelectPrimitive.Content\n position=\"popper\"\n sideOffset={BLOCK_SELECT_SIDE_OFFSET}\n collisionPadding={FLOATING_ELEMENT_COLLISION_PADDING}\n className=\"lb-root lb-portal lb-elevation lb-dropdown lb-select-dropdown lb-tiptap-block-selector-dropdown\"\n >\n {resolvedItems.map((item) => (\n <SelectPrimitive.Item\n key={item.name}\n value={item.name}\n className=\"lb-dropdown-item\"\n data-name={item.name}\n >\n {item.icon ? (\n <span className=\"lb-dropdown-item-icon lb-icon-container\">\n {item.icon}\n </span>\n ) : null}\n <span className=\"lb-dropdown-item-label\">\n {item.label ?? item.name}\n </span>\n {item.name === activeItem?.name ? (\n <span className=\"lb-dropdown-item-accessory lb-icon-container\">\n <CheckIcon />\n </span>\n ) : null}\n </SelectPrimitive.Item>\n ))}\n </SelectPrimitive.Content>\n </FloatingToolbarExternal>\n </SelectPrimitive.Portal>\n </SelectPrimitive.Root>\n );\n});\n\nconst ToolbarSeparator = forwardRef<HTMLDivElement, ToolbarSeparatorProps>(\n ({ className, ...props }, forwardedRef) => {\n return (\n <div\n ref={forwardedRef}\n role=\"separator\"\n aria-orientation=\"vertical\"\n className={cn(\"lb-tiptap-toolbar-separator\", className)}\n {...props}\n />\n );\n }\n);\n\nfunction ToolbarSectionHistory() {\n const editor = useCurrentEditor(\n \"SectionHistory\",\n \"Toolbar or FloatingToolbar\"\n );\n\n return (\n <>\n <ToolbarButton\n name=\"Undo\"\n icon={<UndoIcon />}\n shortcut=\"Mod-Z\"\n onClick={() => editor.chain().focus().undo().run()}\n disabled={!editor.can().chain().focus().undo().run()}\n />\n <ToolbarButton\n name=\"Redo\"\n icon={<RedoIcon />}\n shortcut=\"Mod-Shift-Z\"\n onClick={() => editor.chain().focus().redo().run()}\n disabled={!editor.can().chain().focus().redo().run()}\n />\n </>\n );\n}\n\nfunction ToolbarSectionInline() {\n const editor = useCurrentEditor(\n \"SectionInline\",\n \"Toolbar or FloatingToolbar\"\n );\n const supportsBold = \"toggleBold\" in editor.commands;\n const supportsItalic = \"toggleItalic\" in editor.commands;\n const supportsUnderline = \"toggleUnderline\" in editor.commands;\n const supportsStrike = \"toggleStrike\" in editor.commands;\n const supportsCode = \"toggleCode\" in editor.commands;\n\n return (\n <>\n {supportsBold && (\n <ToolbarToggle\n name=\"Bold\"\n icon={<BoldIcon />}\n shortcut=\"Mod-B\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleBold\">)\n .toggleBold()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleBold\">\n )\n .toggleBold()\n .run()\n }\n active={editor.isActive(\"bold\")}\n />\n )}\n {supportsItalic && (\n <ToolbarToggle\n name=\"Italic\"\n icon={<ItalicIcon />}\n shortcut=\"Mod-I\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleItalic\">)\n .toggleItalic()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleItalic\">\n )\n .toggleItalic()\n .run()\n }\n active={editor.isActive(\"italic\")}\n />\n )}\n {supportsUnderline && (\n <ToolbarToggle\n name=\"Underline\"\n icon={<UnderlineIcon />}\n shortcut=\"Mod-U\"\n onClick={() =>\n (\n editor\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleUnderline\">\n )\n .toggleUnderline()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleUnderline\">\n )\n .toggleUnderline()\n .run()\n }\n active={editor.isActive(\"underline\")}\n />\n )}\n {supportsStrike && (\n <ToolbarToggle\n name=\"Strikethrough\"\n icon={<StrikethroughIcon />}\n shortcut=\"Mod-U\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleStrike\">)\n .toggleStrike()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleStrike\">\n )\n .toggleStrike()\n .run()\n }\n active={editor.isActive(\"strike\")}\n />\n )}\n {supportsCode && (\n <ToolbarToggle\n name=\"Inline code\"\n icon={<CodeIcon />}\n shortcut=\"Mod-E\"\n onClick={() =>\n (editor.chain().focus() as ExtendedChainedCommands<\"toggleCode\">)\n .toggleCode()\n .run()\n }\n disabled={\n !(\n editor\n .can()\n .chain()\n .focus() as ExtendedChainedCommands<\"toggleCode\">\n )\n .toggleCode()\n .run()\n }\n active={editor.isActive(\"code\")}\n />\n )}\n </>\n );\n}\n\nfunction ToolbarSectionCollaboration() {\n const editor = useCurrentEditor(\n \"SectionCollaboration\",\n \"Toolbar or FloatingToolbar\"\n );\n const supportsThread = \"addPendingComment\" in editor.commands;\n\n return (\n <>\n {supportsThread && (\n <ToolbarButton\n name=\"Add a comment\"\n icon={<CommentIcon />}\n onClick={() =>\n (\n editor\n .chain()\n .focus() as ExtendedChainedCommands<\"addPendingComment\">\n )\n .addPendingComment()\n .run()\n }\n >\n Comment\n </ToolbarButton>\n )}\n </>\n );\n}\n\nfunction ToolbarSectionAi() {\n const editor = useCurrentEditor(\"SectionAi\", \"Toolbar or FloatingToolbar\");\n const supportsAi = \"askAi\" in editor.commands;\n const aiName = (editor.storage.liveblocksAi as AiExtensionStorage | undefined)\n ?.name;\n\n return (\n <>\n {supportsAi && (\n <>\n <ToolbarButton\n name={`Ask ${aiName} anything…`}\n icon={<SparklesIcon />}\n onClick={() =>\n (\n editor.chain().focus() as ExtendedChainedCommands<\"askAi\">\n ).askAi()\n }\n >\n Ask {aiName}\n </ToolbarButton>\n <ToolbarButton\n name=\"Explain\"\n icon={<QuestionMarkIcon />}\n onClick={() =>\n (\n editor.chain().focus() as ExtendedChainedCommands<\"askAi\">\n ).askAi(\"Explain what the text is about\")\n }\n >\n Explain\n </ToolbarButton>\n </>\n )}\n </>\n );\n}\n\nfunction DefaultToolbarContent({ editor }: ToolbarSlotProps) {\n const supportsThread = \"addPendingComment\" in editor.commands;\n const supportsAi = \"askAi\" in editor.commands;\n\n return (\n <>\n <ToolbarSectionHistory />\n <ToolbarSeparator />\n {supportsAi ? (\n <>\n <ToolbarSectionAi />\n <ToolbarSeparator />\n </>\n ) : null}\n <ToolbarBlockSelector />\n <ToolbarSectionInline />\n {supportsThread ? (\n <>\n <ToolbarSeparator />\n <ToolbarSectionCollaboration />\n </>\n ) : null}\n </>\n );\n}\n\n/**\n * A static toolbar containing actions and values related to the editor.\n *\n * @example\n * <Toolbar editor={editor} />\n *\n * @example\n * <Toolbar editor={editor}>\n * <Toolbar.BlockSelector />\n * <Toolbar.Separator />\n * <Toolbar.SectionInline />\n * <Toolbar.Separator />\n * <Toolbar.Button name=\"Custom action\" onClick={() => { ... }} icon={<Icon.QuestionMark />} />\n * </Toolbar>\n */\nexport const Toolbar = Object.assign(\n forwardRef<HTMLDivElement, ToolbarProps>(\n (\n {\n before,\n after,\n children = DefaultToolbarContent,\n editor,\n className,\n ...props\n },\n forwardedRef\n ) => {\n // Re-render the toolbar when the editor content and selection change.\n useEditorState({\n editor,\n equalityFn: Object.is,\n selector: (ctx) => ctx.editor?.state,\n });\n\n if (!editor) {\n return null;\n }\n\n const slotProps: ToolbarSlotProps = { editor };\n\n return (\n <TooltipProvider>\n <EditorProvider editor={editor}>\n <div\n ref={forwardedRef}\n role=\"toolbar\"\n aria-label=\"Toolbar\"\n aria-orientation=\"horizontal\"\n className={cn(\"lb-root lb-tiptap-toolbar\", className)}\n {...props}\n >\n {applyToolbarSlot(before, slotProps)}\n {applyToolbarSlot(children, slotProps)}\n {applyToolbarSlot(after, slotProps)}\n </div>\n </EditorProvider>\n </TooltipProvider>\n );\n }\n ),\n {\n /**\n * A button for triggering actions.\n *\n * @example\n * <Toolbar.Button name=\"Comment\" shortcut=\"Mod-Shift-E\" onClick={() => { ... }} />\n *\n * @example\n * <Toolbar.Button name=\"Mention someone\" icon={<Icon.Mention />} onClick={() => { ... }} />\n */\n Button: ToolbarButton,\n\n /**\n * A toggle button for values that can be active or inactive.\n *\n * @example\n * <Toolbar.Toggle name=\"Bold\" active={isBold} />\n *\n * @example\n * <Toolbar.Toggle name=\"Italic\" icon={<Icon.Italic />} shortcut=\"Mod-I\" active={isItalic} onClick={() => { ... }} />\n */\n Toggle: ToolbarToggle,\n\n /**\n * A dropdown selector to switch between different block types.\n *\n * @example\n * <Toolbar.BlockSelector />\n */\n BlockSelector: ToolbarBlockSelector,\n\n /**\n * A visual (and accessible) separator to separate sections in a toolbar.\n */\n Separator: ToolbarSeparator,\n\n /**\n * A section containing history actions. (e.g. undo, redo)\n */\n SectionHistory: ToolbarSectionHistory,\n\n /**\n * A section containing inline formatting actions. (e.g. bold, italic, underline, ...)\n */\n SectionInline: ToolbarSectionInline,\n\n /**\n * A section containing collaborative actions. (e.g. adding a comment)\n */\n SectionCollaboration: ToolbarSectionCollaboration,\n\n /**\n * A section containing AI actions. (e.g. opening the AI toolbar)\n */\n SectionAi: ToolbarSectionAi,\n }\n);\n"],"names":["editor","item"],"mappings":"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"} |
+1
-1
| 'use strict'; | ||
| const PKG_NAME = "@liveblocks/react-tiptap"; | ||
| const PKG_VERSION = typeof "3.13.0-vincent3" === "string" && "3.13.0-vincent3"; | ||
| const PKG_VERSION = typeof "3.13.0" === "string" && "3.13.0"; | ||
| const PKG_FORMAT = typeof "cjs" === "string" && "cjs"; | ||
@@ -6,0 +6,0 @@ |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"version.cjs","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-tiptap\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":";;AAGO,MAAM,QAAW,GAAA,2BAAA;AACX,MAAA,WAAA,GAAc,OAAO,iBAAA,KAAgB,QAAY,IAAA,kBAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;;;"} | ||
| {"version":3,"file":"version.cjs","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-tiptap\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":";;AAGO,MAAM,QAAW,GAAA,2BAAA;AACX,MAAA,WAAA,GAAc,OAAO,QAAA,KAAgB,QAAY,IAAA,SAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;;;"} |
+1
-1
| const PKG_NAME = "@liveblocks/react-tiptap"; | ||
| const PKG_VERSION = typeof "3.13.0-vincent3" === "string" && "3.13.0-vincent3"; | ||
| const PKG_VERSION = typeof "3.13.0" === "string" && "3.13.0"; | ||
| const PKG_FORMAT = typeof "esm" === "string" && "esm"; | ||
@@ -4,0 +4,0 @@ |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"version.js","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-tiptap\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":"AAGO,MAAM,QAAW,GAAA,2BAAA;AACX,MAAA,WAAA,GAAc,OAAO,iBAAA,KAAgB,QAAY,IAAA,kBAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;"} | ||
| {"version":3,"file":"version.js","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-tiptap\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":"AAGO,MAAM,QAAW,GAAA,2BAAA;AACX,MAAA,WAAA,GAAc,OAAO,QAAA,KAAgB,QAAY,IAAA,SAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;"} |
+6
-6
| { | ||
| "name": "@liveblocks/react-tiptap", | ||
| "version": "3.13.0-vincent3", | ||
| "version": "3.13.0", | ||
| "description": "An integration of TipTap + React to enable collaboration, comments, live cursors, and more with Liveblocks.", | ||
@@ -46,7 +46,7 @@ "license": "Apache-2.0", | ||
| "@floating-ui/react-dom": "^2.1.2", | ||
| "@liveblocks/client": "3.13.0-vincent3", | ||
| "@liveblocks/core": "3.13.0-vincent3", | ||
| "@liveblocks/react": "3.13.0-vincent3", | ||
| "@liveblocks/react-ui": "3.13.0-vincent3", | ||
| "@liveblocks/yjs": "3.13.0-vincent3", | ||
| "@liveblocks/client": "3.13.0", | ||
| "@liveblocks/core": "3.13.0", | ||
| "@liveblocks/react": "3.13.0", | ||
| "@liveblocks/react-ui": "3.13.0", | ||
| "@liveblocks/yjs": "3.13.0", | ||
| "@radix-ui/react-select": "^2.1.2", | ||
@@ -53,0 +53,0 @@ "@radix-ui/react-toggle": "^1.1.0", |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
1016148
0.25%9475
0.18%0
-100%+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated