@liveblocks/react-tiptap 3.9.1-tiptap1 → 3.9.2-tiptap1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LiveblocksExtension.cjs +4 -0
- package/dist/LiveblocksExtension.cjs.map +1 -1
- package/dist/LiveblocksExtension.js +4 -0
- package/dist/LiveblocksExtension.js.map +1 -1
- package/dist/ai/AiExtension.cjs +8 -0
- package/dist/ai/AiExtension.cjs.map +1 -1
- package/dist/ai/AiExtension.js +8 -0
- package/dist/ai/AiExtension.js.map +1 -1
- package/dist/ai/AiToolbar.cjs +256 -235
- package/dist/ai/AiToolbar.cjs.map +1 -1
- package/dist/ai/AiToolbar.js +256 -235
- package/dist/ai/AiToolbar.js.map +1 -1
- package/dist/comments/AnchoredThreads.cjs +63 -50
- package/dist/comments/AnchoredThreads.cjs.map +1 -1
- package/dist/comments/AnchoredThreads.js +63 -50
- package/dist/comments/AnchoredThreads.js.map +1 -1
- package/dist/comments/CommentsExtension.cjs +3 -0
- package/dist/comments/CommentsExtension.cjs.map +1 -1
- package/dist/comments/CommentsExtension.js +3 -0
- package/dist/comments/CommentsExtension.js.map +1 -1
- package/dist/comments/FloatingComposer.cjs +25 -19
- package/dist/comments/FloatingComposer.cjs.map +1 -1
- package/dist/comments/FloatingComposer.js +25 -19
- package/dist/comments/FloatingComposer.js.map +1 -1
- package/dist/comments/FloatingThreads.cjs +39 -33
- package/dist/comments/FloatingThreads.cjs.map +1 -1
- package/dist/comments/FloatingThreads.js +39 -33
- package/dist/comments/FloatingThreads.js.map +1 -1
- package/dist/context.cjs +1 -4
- package/dist/context.cjs.map +1 -1
- package/dist/context.js +1 -4
- package/dist/context.js.map +1 -1
- package/dist/mentions/GroupMentionNode.cjs +2 -0
- package/dist/mentions/GroupMentionNode.cjs.map +1 -1
- package/dist/mentions/GroupMentionNode.js +2 -0
- package/dist/mentions/GroupMentionNode.js.map +1 -1
- package/dist/mentions/Mention.cjs +42 -40
- package/dist/mentions/Mention.cjs.map +1 -1
- package/dist/mentions/Mention.js +42 -40
- package/dist/mentions/Mention.js.map +1 -1
- package/dist/mentions/MentionExtension.cjs +1 -0
- package/dist/mentions/MentionExtension.cjs.map +1 -1
- package/dist/mentions/MentionExtension.js +1 -0
- package/dist/mentions/MentionExtension.js.map +1 -1
- package/dist/mentions/MentionNode.cjs +2 -0
- package/dist/mentions/MentionNode.cjs.map +1 -1
- package/dist/mentions/MentionNode.js +2 -0
- package/dist/mentions/MentionNode.js.map +1 -1
- package/dist/mentions/MentionsList.cjs +66 -51
- package/dist/mentions/MentionsList.cjs.map +1 -1
- package/dist/mentions/MentionsList.js +66 -51
- package/dist/mentions/MentionsList.js.map +1 -1
- package/dist/toolbar/FloatingToolbar.cjs +43 -28
- package/dist/toolbar/FloatingToolbar.cjs.map +1 -1
- package/dist/toolbar/FloatingToolbar.js +43 -28
- package/dist/toolbar/FloatingToolbar.js.map +1 -1
- package/dist/toolbar/Toolbar.cjs +191 -153
- package/dist/toolbar/Toolbar.cjs.map +1 -1
- package/dist/toolbar/Toolbar.js +191 -153
- package/dist/toolbar/Toolbar.js.map +1 -1
- package/dist/toolbar/shared.cjs +12 -11
- package/dist/toolbar/shared.cjs.map +1 -1
- package/dist/toolbar/shared.js +12 -11
- package/dist/toolbar/shared.js.map +1 -1
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.js.map +1 -1
- package/dist/version-history/HistoryVersionPreview.cjs +29 -42
- package/dist/version-history/HistoryVersionPreview.cjs.map +1 -1
- package/dist/version-history/HistoryVersionPreview.js +29 -42
- package/dist/version-history/HistoryVersionPreview.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -6
- package/src/styles/index.css +3 -2
- package/styles.css +1 -1
- package/styles.css.map +1 -1
|
@@ -57,18 +57,25 @@ function FloatingThreads({
|
|
|
57
57
|
}, [activeThread, editor]);
|
|
58
58
|
if (!activeThread || !editor || activeThread.resolved)
|
|
59
59
|
return null;
|
|
60
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
container: document.body,
|
|
64
|
-
...props,
|
|
65
|
-
children: activeThread && /* @__PURE__ */ jsxRuntime.jsx(ThreadWrapper, {
|
|
60
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
61
|
+
FloatingThreadPortal,
|
|
62
|
+
{
|
|
66
63
|
thread: activeThread,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
64
|
+
editor,
|
|
65
|
+
container: document.body,
|
|
66
|
+
...props,
|
|
67
|
+
children: activeThread && /* @__PURE__ */ jsxRuntime.jsx(
|
|
68
|
+
ThreadWrapper,
|
|
69
|
+
{
|
|
70
|
+
thread: activeThread,
|
|
71
|
+
Thread,
|
|
72
|
+
onEscapeKeydown: handleEscapeKeydown,
|
|
73
|
+
className: "lb-tiptap-floating-threads-thread"
|
|
74
|
+
},
|
|
75
|
+
activeThread.id
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
);
|
|
72
79
|
}
|
|
73
80
|
const FLOATING_THREAD_COLLISION_PADDING = 10;
|
|
74
81
|
function FloatingThreadPortal({
|
|
@@ -132,23 +139,26 @@ function FloatingThreadPortal({
|
|
|
132
139
|
}, [editor, updateRef]);
|
|
133
140
|
_private.useLayoutEffect(updateRef, [updateRef]);
|
|
134
141
|
return reactDom$1.createPortal(
|
|
135
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
...
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
className
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
142
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
143
|
+
"div",
|
|
144
|
+
{
|
|
145
|
+
ref: setFloating,
|
|
146
|
+
...props,
|
|
147
|
+
style: {
|
|
148
|
+
...style,
|
|
149
|
+
position: strategy,
|
|
150
|
+
top: 0,
|
|
151
|
+
left: 0,
|
|
152
|
+
transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
|
|
153
|
+
minWidth: "max-content"
|
|
154
|
+
},
|
|
155
|
+
className: _private$1.cn(
|
|
156
|
+
"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-threads",
|
|
157
|
+
className
|
|
158
|
+
),
|
|
159
|
+
children
|
|
160
|
+
}
|
|
161
|
+
),
|
|
152
162
|
container
|
|
153
163
|
);
|
|
154
164
|
}
|
|
@@ -168,11 +178,7 @@ function ThreadWrapper({
|
|
|
168
178
|
},
|
|
169
179
|
[onEscapeKeydown, onKeyDown]
|
|
170
180
|
);
|
|
171
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Thread, {
|
|
172
|
-
thread,
|
|
173
|
-
onKeyDown: handleKeyDown,
|
|
174
|
-
...threadProps
|
|
175
|
-
});
|
|
181
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Thread, { thread, onKeyDown: handleKeyDown, ...threadProps });
|
|
176
182
|
}
|
|
177
183
|
|
|
178
184
|
exports.FLOATING_THREAD_COLLISION_PADDING = FLOATING_THREAD_COLLISION_PADDING;
|
|
@@ -1 +1 @@
|
|
|
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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"}
|
|
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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"}
|
|
@@ -55,18 +55,25 @@ function FloatingThreads({
|
|
|
55
55
|
}, [activeThread, editor]);
|
|
56
56
|
if (!activeThread || !editor || activeThread.resolved)
|
|
57
57
|
return null;
|
|
58
|
-
return /* @__PURE__ */ jsx(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
container: document.body,
|
|
62
|
-
...props,
|
|
63
|
-
children: activeThread && /* @__PURE__ */ jsx(ThreadWrapper, {
|
|
58
|
+
return /* @__PURE__ */ jsx(
|
|
59
|
+
FloatingThreadPortal,
|
|
60
|
+
{
|
|
64
61
|
thread: activeThread,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
62
|
+
editor,
|
|
63
|
+
container: document.body,
|
|
64
|
+
...props,
|
|
65
|
+
children: activeThread && /* @__PURE__ */ jsx(
|
|
66
|
+
ThreadWrapper,
|
|
67
|
+
{
|
|
68
|
+
thread: activeThread,
|
|
69
|
+
Thread: Thread$1,
|
|
70
|
+
onEscapeKeydown: handleEscapeKeydown,
|
|
71
|
+
className: "lb-tiptap-floating-threads-thread"
|
|
72
|
+
},
|
|
73
|
+
activeThread.id
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
);
|
|
70
77
|
}
|
|
71
78
|
const FLOATING_THREAD_COLLISION_PADDING = 10;
|
|
72
79
|
function FloatingThreadPortal({
|
|
@@ -130,23 +137,26 @@ function FloatingThreadPortal({
|
|
|
130
137
|
}, [editor, updateRef]);
|
|
131
138
|
useLayoutEffect(updateRef, [updateRef]);
|
|
132
139
|
return createPortal(
|
|
133
|
-
/* @__PURE__ */ jsx(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
...
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
className
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
140
|
+
/* @__PURE__ */ jsx(
|
|
141
|
+
"div",
|
|
142
|
+
{
|
|
143
|
+
ref: setFloating,
|
|
144
|
+
...props,
|
|
145
|
+
style: {
|
|
146
|
+
...style,
|
|
147
|
+
position: strategy,
|
|
148
|
+
top: 0,
|
|
149
|
+
left: 0,
|
|
150
|
+
transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
|
|
151
|
+
minWidth: "max-content"
|
|
152
|
+
},
|
|
153
|
+
className: cn(
|
|
154
|
+
"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-threads",
|
|
155
|
+
className
|
|
156
|
+
),
|
|
157
|
+
children
|
|
158
|
+
}
|
|
159
|
+
),
|
|
150
160
|
container
|
|
151
161
|
);
|
|
152
162
|
}
|
|
@@ -166,11 +176,7 @@ function ThreadWrapper({
|
|
|
166
176
|
},
|
|
167
177
|
[onEscapeKeydown, onKeyDown]
|
|
168
178
|
);
|
|
169
|
-
return /* @__PURE__ */ jsx(Thread, {
|
|
170
|
-
thread,
|
|
171
|
-
onKeyDown: handleKeyDown,
|
|
172
|
-
...threadProps
|
|
173
|
-
});
|
|
179
|
+
return /* @__PURE__ */ jsx(Thread, { thread, onKeyDown: handleKeyDown, ...threadProps });
|
|
174
180
|
}
|
|
175
181
|
|
|
176
182
|
export { FLOATING_THREAD_COLLISION_PADDING, FloatingThreads };
|
|
@@ -1 +1 @@
|
|
|
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":"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"}
|
|
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":"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"}
|
package/dist/context.cjs
CHANGED
|
@@ -9,10 +9,7 @@ function EditorProvider({
|
|
|
9
9
|
editor,
|
|
10
10
|
children
|
|
11
11
|
}) {
|
|
12
|
-
return /* @__PURE__ */ jsxRuntime.jsx(EditorContext.Provider, {
|
|
13
|
-
value: editor,
|
|
14
|
-
children
|
|
15
|
-
});
|
|
12
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EditorContext.Provider, { value: editor, children });
|
|
16
13
|
}
|
|
17
14
|
function useCurrentEditor(source, parent) {
|
|
18
15
|
const currentEditor = react.useContext(EditorContext);
|
package/dist/context.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.cjs","sources":["../src/context.tsx"],"sourcesContent":["import { nn } from \"@liveblocks/core\";\nimport type { Editor } from \"@tiptap/react\";\nimport type { PropsWithChildren } from \"react\";\nimport { createContext, useContext } from \"react\";\n\nconst EditorContext = createContext<Editor | null>(null);\n\nexport function EditorProvider({\n editor,\n children,\n}: PropsWithChildren<{ editor: Editor }>) {\n return (\n <EditorContext.Provider value={editor}>{children}</EditorContext.Provider>\n );\n}\n\n/**\n * @tiptap/react already offers a `useCurrentEditor` hook but our components might\n * not live under `EditorProvider` or `EditorContent` so we create our own to reduce\n * repetition within our own nested components.\n *\n * @example\n * <Toolbar editor={editor}> // `editor` is required here\n * <ToolbarSectionInline /> // But it isn't there, because `Toolbar` uses our own `EditorProvider`\n * </Toolbar>\n */\nexport function useCurrentEditor(source: string, parent: string) {\n const currentEditor = useContext(EditorContext);\n\n return nn(currentEditor, `${source} can’t be used outside of ${parent}.`);\n}\n"],"names":["createContext","
|
|
1
|
+
{"version":3,"file":"context.cjs","sources":["../src/context.tsx"],"sourcesContent":["import { nn } from \"@liveblocks/core\";\nimport type { Editor } from \"@tiptap/react\";\nimport type { PropsWithChildren } from \"react\";\nimport { createContext, useContext } from \"react\";\n\nconst EditorContext = createContext<Editor | null>(null);\n\nexport function EditorProvider({\n editor,\n children,\n}: PropsWithChildren<{ editor: Editor }>) {\n return (\n <EditorContext.Provider value={editor}>{children}</EditorContext.Provider>\n );\n}\n\n/**\n * @tiptap/react already offers a `useCurrentEditor` hook but our components might\n * not live under `EditorProvider` or `EditorContent` so we create our own to reduce\n * repetition within our own nested components.\n *\n * @example\n * <Toolbar editor={editor}> // `editor` is required here\n * <ToolbarSectionInline /> // But it isn't there, because `Toolbar` uses our own `EditorProvider`\n * </Toolbar>\n */\nexport function useCurrentEditor(source: string, parent: string) {\n const currentEditor = useContext(EditorContext);\n\n return nn(currentEditor, `${source} can’t be used outside of ${parent}.`);\n}\n"],"names":["createContext","useContext","nn"],"mappings":";;;;;;AAKA,MAAM,aAAA,GAAgBA,oBAA6B,IAAI,CAAA,CAAA;AAEhD,SAAS,cAAe,CAAA;AAAA,EAC7B,MAAA;AAAA,EACA,QAAA;AACF,CAA0C,EAAA;AACxC,EAAA,sCACG,aAAc,CAAA,QAAA,EAAd,EAAuB,KAAA,EAAO,QAAS,QAAS,EAAA,CAAA,CAAA;AAErD,CAAA;AAYgB,SAAA,gBAAA,CAAiB,QAAgB,MAAgB,EAAA;AAC/D,EAAM,MAAA,aAAA,GAAgBC,iBAAW,aAAa,CAAA,CAAA;AAE9C,EAAA,OAAOC,QAAG,aAAe,EAAA,CAAA,EAAG,MAAM,CAAA,+BAAA,EAA6B,MAAM,CAAG,CAAA,CAAA,CAAA,CAAA;AAC1E;;;;;"}
|
package/dist/context.js
CHANGED
|
@@ -7,10 +7,7 @@ function EditorProvider({
|
|
|
7
7
|
editor,
|
|
8
8
|
children
|
|
9
9
|
}) {
|
|
10
|
-
return /* @__PURE__ */ jsx(EditorContext.Provider, {
|
|
11
|
-
value: editor,
|
|
12
|
-
children
|
|
13
|
-
});
|
|
10
|
+
return /* @__PURE__ */ jsx(EditorContext.Provider, { value: editor, children });
|
|
14
11
|
}
|
|
15
12
|
function useCurrentEditor(source, parent) {
|
|
16
13
|
const currentEditor = useContext(EditorContext);
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sources":["../src/context.tsx"],"sourcesContent":["import { nn } from \"@liveblocks/core\";\nimport type { Editor } from \"@tiptap/react\";\nimport type { PropsWithChildren } from \"react\";\nimport { createContext, useContext } from \"react\";\n\nconst EditorContext = createContext<Editor | null>(null);\n\nexport function EditorProvider({\n editor,\n children,\n}: PropsWithChildren<{ editor: Editor }>) {\n return (\n <EditorContext.Provider value={editor}>{children}</EditorContext.Provider>\n );\n}\n\n/**\n * @tiptap/react already offers a `useCurrentEditor` hook but our components might\n * not live under `EditorProvider` or `EditorContent` so we create our own to reduce\n * repetition within our own nested components.\n *\n * @example\n * <Toolbar editor={editor}> // `editor` is required here\n * <ToolbarSectionInline /> // But it isn't there, because `Toolbar` uses our own `EditorProvider`\n * </Toolbar>\n */\nexport function useCurrentEditor(source: string, parent: string) {\n const currentEditor = useContext(EditorContext);\n\n return nn(currentEditor, `${source} can’t be used outside of ${parent}.`);\n}\n"],"names":[],"mappings":";;;;AAKA,MAAM,aAAA,GAAgB,cAA6B,IAAI,CAAA,CAAA;AAEhD,SAAS,cAAe,CAAA;AAAA,EAC7B,MAAA;AAAA,EACA,QAAA;AACF,CAA0C,EAAA;AACxC,
|
|
1
|
+
{"version":3,"file":"context.js","sources":["../src/context.tsx"],"sourcesContent":["import { nn } from \"@liveblocks/core\";\nimport type { Editor } from \"@tiptap/react\";\nimport type { PropsWithChildren } from \"react\";\nimport { createContext, useContext } from \"react\";\n\nconst EditorContext = createContext<Editor | null>(null);\n\nexport function EditorProvider({\n editor,\n children,\n}: PropsWithChildren<{ editor: Editor }>) {\n return (\n <EditorContext.Provider value={editor}>{children}</EditorContext.Provider>\n );\n}\n\n/**\n * @tiptap/react already offers a `useCurrentEditor` hook but our components might\n * not live under `EditorProvider` or `EditorContent` so we create our own to reduce\n * repetition within our own nested components.\n *\n * @example\n * <Toolbar editor={editor}> // `editor` is required here\n * <ToolbarSectionInline /> // But it isn't there, because `Toolbar` uses our own `EditorProvider`\n * </Toolbar>\n */\nexport function useCurrentEditor(source: string, parent: string) {\n const currentEditor = useContext(EditorContext);\n\n return nn(currentEditor, `${source} can’t be used outside of ${parent}.`);\n}\n"],"names":[],"mappings":";;;;AAKA,MAAM,aAAA,GAAgB,cAA6B,IAAI,CAAA,CAAA;AAEhD,SAAS,cAAe,CAAA;AAAA,EAC7B,MAAA;AAAA,EACA,QAAA;AACF,CAA0C,EAAA;AACxC,EAAA,2BACG,aAAc,CAAA,QAAA,EAAd,EAAuB,KAAA,EAAO,QAAS,QAAS,EAAA,CAAA,CAAA;AAErD,CAAA;AAYgB,SAAA,gBAAA,CAAiB,QAAgB,MAAgB,EAAA;AAC/D,EAAM,MAAA,aAAA,GAAgB,WAAW,aAAa,CAAA,CAAA;AAE9C,EAAA,OAAO,GAAG,aAAe,EAAA,CAAA,EAAG,MAAM,CAAA,+BAAA,EAA6B,MAAM,CAAG,CAAA,CAAA,CAAA,CAAA;AAC1E;;;;"}
|
|
@@ -38,6 +38,7 @@ const GroupMentionNode = core.Node.create({
|
|
|
38
38
|
}
|
|
39
39
|
return {
|
|
40
40
|
"data-id": attributes.id
|
|
41
|
+
// "as" typing because TipTap doesn't have a way to type attributes
|
|
41
42
|
};
|
|
42
43
|
}
|
|
43
44
|
},
|
|
@@ -73,6 +74,7 @@ const GroupMentionNode = core.Node.create({
|
|
|
73
74
|
}
|
|
74
75
|
return {
|
|
75
76
|
"data-notification-id": attributes.notificationId
|
|
77
|
+
// "as" typing because TipTap doesn't have a way to type attributes
|
|
76
78
|
};
|
|
77
79
|
}
|
|
78
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupMentionNode.cjs","sources":["../../src/mentions/GroupMentionNode.ts"],"sourcesContent":["import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\n\nimport { LIVEBLOCKS_GROUP_MENTION_TYPE } from \"../types\";\nimport { Mention } from \"./Mention\";\n\nexport const GroupMentionNode = Node.create({\n name: LIVEBLOCKS_GROUP_MENTION_TYPE,\n group: \"inline\",\n inline: true,\n selectable: true,\n atom: true,\n\n priority: 101,\n parseHTML() {\n return [\n {\n tag: \"liveblocks-group-mention\",\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\"liveblocks-group-mention\", mergeAttributes(HTMLAttributes)];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(Mention, {\n contentDOMElementTag: \"span\",\n });\n },\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-id\"),\n renderHTML: (attributes) => {\n if (!attributes.id) {\n return {};\n }\n\n return {\n \"data-id\": attributes.id as string, // \"as\" typing because TipTap doesn't have a way to type attributes\n };\n },\n },\n userIds: {\n default: undefined,\n parseHTML: (element) => {\n const userIdsAttribute = element.getAttribute(\"data-user-ids\");\n\n if (!userIdsAttribute) {\n return undefined;\n }\n\n try {\n const userIds = JSON.parse(userIdsAttribute) as string[];\n\n return Array.isArray(userIds) ? userIds : undefined;\n } catch {\n return undefined;\n }\n },\n renderHTML: (attributes) => {\n if (!attributes.userIds || !Array.isArray(attributes.userIds)) {\n return {};\n }\n\n return {\n \"data-user-ids\": JSON.stringify(attributes.userIds),\n };\n },\n },\n notificationId: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-notification-id\"),\n renderHTML: (attributes) => {\n if (!attributes.notificationId) {\n return {};\n }\n\n return {\n \"data-notification-id\": attributes.notificationId as string, // \"as\" typing because TipTap doesn't have a way to type attributes\n };\n },\n },\n };\n },\n addKeyboardShortcuts() {\n return {\n Backspace: () =>\n this.editor.commands.command(({ tr, state }) => {\n let isMention = false;\n const { selection } = state;\n const { empty, anchor } = selection;\n\n if (!empty) {\n return false;\n }\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true;\n tr.insertText(\"\", pos, pos + node.nodeSize);\n }\n });\n\n return isMention;\n }),\n };\n },\n});\n"],"names":["Node","LIVEBLOCKS_GROUP_MENTION_TYPE","mergeAttributes","ReactNodeViewRenderer","Mention"],"mappings":";;;;;;;AAMa,MAAA,gBAAA,GAAmBA,UAAK,MAAO,CAAA;AAAA,EAC1C,IAAM,EAAAC,mCAAA;AAAA,EACN,KAAO,EAAA,QAAA;AAAA,EACP,MAAQ,EAAA,IAAA;AAAA,EACR,UAAY,EAAA,IAAA;AAAA,EACZ,IAAM,EAAA,IAAA;AAAA,EAEN,QAAU,EAAA,GAAA;AAAA,EACV,SAAY,GAAA;AACV,IAAO,OAAA;AAAA,MACL;AAAA,QACE,GAAK,EAAA,0BAAA;AAAA,OACP;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAEA,UAAA,CAAW,EAAE,cAAA,EAAkB,EAAA;AAC7B,IAAA,OAAO,CAAC,0BAAA,EAA4BC,oBAAgB,CAAA,cAAc,CAAC,CAAA,CAAA;AAAA,GACrE;AAAA,EAEA,WAAc,GAAA;AACZ,IAAA,OAAOC,4BAAsBC,eAAS,EAAA;AAAA,MACpC,oBAAsB,EAAA,MAAA;AAAA,KACvB,CAAA,CAAA;AAAA,GACH;AAAA,EAEA,aAAgB,GAAA;AACd,IAAO,OAAA;AAAA,MACL,EAAI,EAAA;AAAA,QACF,OAAS,EAAA,IAAA;AAAA,QACT,SAAW,EAAA,CAAC,OAAY,KAAA,OAAA,CAAQ,aAAa,SAAS,CAAA;AAAA,QACtD,UAAA,EAAY,CAAC,UAAe,KAAA;AAC1B,UAAI,IAAA,CAAC,WAAW,EAAI,EAAA;AAClB,YAAA,OAAO,EAAC,CAAA;AAAA,WACV;AAEA,UAAO,OAAA;AAAA,YACL,WAAW,UAAW,CAAA,EAAA;AAAA,WACxB,CAAA;AAAA,SACF;AAAA,OACF;AAAA,MACA,OAAS,EAAA;AAAA,QACP,OAAS,EAAA,KAAA,CAAA;AAAA,QACT,SAAA,EAAW,CAAC,OAAY,KAAA;AACtB,UAAM,MAAA,gBAAA,GAAmB,OAAQ,CAAA,YAAA,CAAa,eAAe,CAAA,CAAA;AAE7D,UAAA,IAAI,CAAC,gBAAkB,EAAA;AACrB,YAAO,OAAA,KAAA,CAAA,CAAA;AAAA,WACT;AAEA,UAAI,IAAA;AACF,YAAM,MAAA,OAAA,GAAU,IAAK,CAAA,KAAA,CAAM,gBAAgB,CAAA,CAAA;AAE3C,YAAA,OAAO,KAAM,CAAA,OAAA,CAAQ,OAAO,CAAA,GAAI,OAAU,GAAA,KAAA,CAAA,CAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"GroupMentionNode.cjs","sources":["../../src/mentions/GroupMentionNode.ts"],"sourcesContent":["import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\n\nimport { LIVEBLOCKS_GROUP_MENTION_TYPE } from \"../types\";\nimport { Mention } from \"./Mention\";\n\nexport const GroupMentionNode = Node.create({\n name: LIVEBLOCKS_GROUP_MENTION_TYPE,\n group: \"inline\",\n inline: true,\n selectable: true,\n atom: true,\n\n priority: 101,\n parseHTML() {\n return [\n {\n tag: \"liveblocks-group-mention\",\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\"liveblocks-group-mention\", mergeAttributes(HTMLAttributes)];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(Mention, {\n contentDOMElementTag: \"span\",\n });\n },\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-id\"),\n renderHTML: (attributes) => {\n if (!attributes.id) {\n return {};\n }\n\n return {\n \"data-id\": attributes.id as string, // \"as\" typing because TipTap doesn't have a way to type attributes\n };\n },\n },\n userIds: {\n default: undefined,\n parseHTML: (element) => {\n const userIdsAttribute = element.getAttribute(\"data-user-ids\");\n\n if (!userIdsAttribute) {\n return undefined;\n }\n\n try {\n const userIds = JSON.parse(userIdsAttribute) as string[];\n\n return Array.isArray(userIds) ? userIds : undefined;\n } catch {\n return undefined;\n }\n },\n renderHTML: (attributes) => {\n if (!attributes.userIds || !Array.isArray(attributes.userIds)) {\n return {};\n }\n\n return {\n \"data-user-ids\": JSON.stringify(attributes.userIds),\n };\n },\n },\n notificationId: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-notification-id\"),\n renderHTML: (attributes) => {\n if (!attributes.notificationId) {\n return {};\n }\n\n return {\n \"data-notification-id\": attributes.notificationId as string, // \"as\" typing because TipTap doesn't have a way to type attributes\n };\n },\n },\n };\n },\n addKeyboardShortcuts() {\n return {\n Backspace: () =>\n this.editor.commands.command(({ tr, state }) => {\n let isMention = false;\n const { selection } = state;\n const { empty, anchor } = selection;\n\n if (!empty) {\n return false;\n }\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true;\n tr.insertText(\"\", pos, pos + node.nodeSize);\n }\n });\n\n return isMention;\n }),\n };\n },\n});\n"],"names":["Node","LIVEBLOCKS_GROUP_MENTION_TYPE","mergeAttributes","ReactNodeViewRenderer","Mention"],"mappings":"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"}
|
|
@@ -36,6 +36,7 @@ const GroupMentionNode = Node.create({
|
|
|
36
36
|
}
|
|
37
37
|
return {
|
|
38
38
|
"data-id": attributes.id
|
|
39
|
+
// "as" typing because TipTap doesn't have a way to type attributes
|
|
39
40
|
};
|
|
40
41
|
}
|
|
41
42
|
},
|
|
@@ -71,6 +72,7 @@ const GroupMentionNode = Node.create({
|
|
|
71
72
|
}
|
|
72
73
|
return {
|
|
73
74
|
"data-notification-id": attributes.notificationId
|
|
75
|
+
// "as" typing because TipTap doesn't have a way to type attributes
|
|
74
76
|
};
|
|
75
77
|
}
|
|
76
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupMentionNode.js","sources":["../../src/mentions/GroupMentionNode.ts"],"sourcesContent":["import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\n\nimport { LIVEBLOCKS_GROUP_MENTION_TYPE } from \"../types\";\nimport { Mention } from \"./Mention\";\n\nexport const GroupMentionNode = Node.create({\n name: LIVEBLOCKS_GROUP_MENTION_TYPE,\n group: \"inline\",\n inline: true,\n selectable: true,\n atom: true,\n\n priority: 101,\n parseHTML() {\n return [\n {\n tag: \"liveblocks-group-mention\",\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\"liveblocks-group-mention\", mergeAttributes(HTMLAttributes)];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(Mention, {\n contentDOMElementTag: \"span\",\n });\n },\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-id\"),\n renderHTML: (attributes) => {\n if (!attributes.id) {\n return {};\n }\n\n return {\n \"data-id\": attributes.id as string, // \"as\" typing because TipTap doesn't have a way to type attributes\n };\n },\n },\n userIds: {\n default: undefined,\n parseHTML: (element) => {\n const userIdsAttribute = element.getAttribute(\"data-user-ids\");\n\n if (!userIdsAttribute) {\n return undefined;\n }\n\n try {\n const userIds = JSON.parse(userIdsAttribute) as string[];\n\n return Array.isArray(userIds) ? userIds : undefined;\n } catch {\n return undefined;\n }\n },\n renderHTML: (attributes) => {\n if (!attributes.userIds || !Array.isArray(attributes.userIds)) {\n return {};\n }\n\n return {\n \"data-user-ids\": JSON.stringify(attributes.userIds),\n };\n },\n },\n notificationId: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-notification-id\"),\n renderHTML: (attributes) => {\n if (!attributes.notificationId) {\n return {};\n }\n\n return {\n \"data-notification-id\": attributes.notificationId as string, // \"as\" typing because TipTap doesn't have a way to type attributes\n };\n },\n },\n };\n },\n addKeyboardShortcuts() {\n return {\n Backspace: () =>\n this.editor.commands.command(({ tr, state }) => {\n let isMention = false;\n const { selection } = state;\n const { empty, anchor } = selection;\n\n if (!empty) {\n return false;\n }\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true;\n tr.insertText(\"\", pos, pos + node.nodeSize);\n }\n });\n\n return isMention;\n }),\n };\n },\n});\n"],"names":[],"mappings":";;;;;AAMa,MAAA,gBAAA,GAAmB,KAAK,MAAO,CAAA;AAAA,EAC1C,IAAM,EAAA,6BAAA;AAAA,EACN,KAAO,EAAA,QAAA;AAAA,EACP,MAAQ,EAAA,IAAA;AAAA,EACR,UAAY,EAAA,IAAA;AAAA,EACZ,IAAM,EAAA,IAAA;AAAA,EAEN,QAAU,EAAA,GAAA;AAAA,EACV,SAAY,GAAA;AACV,IAAO,OAAA;AAAA,MACL;AAAA,QACE,GAAK,EAAA,0BAAA;AAAA,OACP;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAEA,UAAA,CAAW,EAAE,cAAA,EAAkB,EAAA;AAC7B,IAAA,OAAO,CAAC,0BAAA,EAA4B,eAAgB,CAAA,cAAc,CAAC,CAAA,CAAA;AAAA,GACrE;AAAA,EAEA,WAAc,GAAA;AACZ,IAAA,OAAO,sBAAsB,OAAS,EAAA;AAAA,MACpC,oBAAsB,EAAA,MAAA;AAAA,KACvB,CAAA,CAAA;AAAA,GACH;AAAA,EAEA,aAAgB,GAAA;AACd,IAAO,OAAA;AAAA,MACL,EAAI,EAAA;AAAA,QACF,OAAS,EAAA,IAAA;AAAA,QACT,SAAW,EAAA,CAAC,OAAY,KAAA,OAAA,CAAQ,aAAa,SAAS,CAAA;AAAA,QACtD,UAAA,EAAY,CAAC,UAAe,KAAA;AAC1B,UAAI,IAAA,CAAC,WAAW,EAAI,EAAA;AAClB,YAAA,OAAO,EAAC,CAAA;AAAA,WACV;AAEA,UAAO,OAAA;AAAA,YACL,WAAW,UAAW,CAAA,EAAA;AAAA,WACxB,CAAA;AAAA,SACF;AAAA,OACF;AAAA,MACA,OAAS,EAAA;AAAA,QACP,OAAS,EAAA,KAAA,CAAA;AAAA,QACT,SAAA,EAAW,CAAC,OAAY,KAAA;AACtB,UAAM,MAAA,gBAAA,GAAmB,OAAQ,CAAA,YAAA,CAAa,eAAe,CAAA,CAAA;AAE7D,UAAA,IAAI,CAAC,gBAAkB,EAAA;AACrB,YAAO,OAAA,KAAA,CAAA,CAAA;AAAA,WACT;AAEA,UAAI,IAAA;AACF,YAAM,MAAA,OAAA,GAAU,IAAK,CAAA,KAAA,CAAM,gBAAgB,CAAA,CAAA;AAE3C,YAAA,OAAO,KAAM,CAAA,OAAA,CAAQ,OAAO,CAAA,GAAI,OAAU,GAAA,KAAA,CAAA,CAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"GroupMentionNode.js","sources":["../../src/mentions/GroupMentionNode.ts"],"sourcesContent":["import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\n\nimport { LIVEBLOCKS_GROUP_MENTION_TYPE } from \"../types\";\nimport { Mention } from \"./Mention\";\n\nexport const GroupMentionNode = Node.create({\n name: LIVEBLOCKS_GROUP_MENTION_TYPE,\n group: \"inline\",\n inline: true,\n selectable: true,\n atom: true,\n\n priority: 101,\n parseHTML() {\n return [\n {\n tag: \"liveblocks-group-mention\",\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\"liveblocks-group-mention\", mergeAttributes(HTMLAttributes)];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(Mention, {\n contentDOMElementTag: \"span\",\n });\n },\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-id\"),\n renderHTML: (attributes) => {\n if (!attributes.id) {\n return {};\n }\n\n return {\n \"data-id\": attributes.id as string, // \"as\" typing because TipTap doesn't have a way to type attributes\n };\n },\n },\n userIds: {\n default: undefined,\n parseHTML: (element) => {\n const userIdsAttribute = element.getAttribute(\"data-user-ids\");\n\n if (!userIdsAttribute) {\n return undefined;\n }\n\n try {\n const userIds = JSON.parse(userIdsAttribute) as string[];\n\n return Array.isArray(userIds) ? userIds : undefined;\n } catch {\n return undefined;\n }\n },\n renderHTML: (attributes) => {\n if (!attributes.userIds || !Array.isArray(attributes.userIds)) {\n return {};\n }\n\n return {\n \"data-user-ids\": JSON.stringify(attributes.userIds),\n };\n },\n },\n notificationId: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-notification-id\"),\n renderHTML: (attributes) => {\n if (!attributes.notificationId) {\n return {};\n }\n\n return {\n \"data-notification-id\": attributes.notificationId as string, // \"as\" typing because TipTap doesn't have a way to type attributes\n };\n },\n },\n };\n },\n addKeyboardShortcuts() {\n return {\n Backspace: () =>\n this.editor.commands.command(({ tr, state }) => {\n let isMention = false;\n const { selection } = state;\n const { empty, anchor } = selection;\n\n if (!empty) {\n return false;\n }\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true;\n tr.insertText(\"\", pos, pos + node.nodeSize);\n }\n });\n\n return isMention;\n }),\n };\n },\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -7,40 +7,36 @@ var react = require('@tiptap/react');
|
|
|
7
7
|
var types = require('../types.cjs');
|
|
8
8
|
|
|
9
9
|
const UserMention = ({ isSelected, mention }) => {
|
|
10
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
children: core.MENTION_CHARACTER
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
]
|
|
25
|
-
});
|
|
10
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11
|
+
react.NodeViewWrapper,
|
|
12
|
+
{
|
|
13
|
+
className: _private.cn(
|
|
14
|
+
"lb-root lb-mention lb-tiptap-mention",
|
|
15
|
+
isSelected && "lb-mention-selected"
|
|
16
|
+
),
|
|
17
|
+
as: "span",
|
|
18
|
+
children: [
|
|
19
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "lb-mention-symbol", children: core.MENTION_CHARACTER }),
|
|
20
|
+
/* @__PURE__ */ jsxRuntime.jsx(_private.User, { userId: mention.id })
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
);
|
|
26
24
|
};
|
|
27
25
|
const GroupMention = ({ isSelected, mention }) => {
|
|
28
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
children: core.MENTION_CHARACTER
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
]
|
|
43
|
-
});
|
|
26
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
27
|
+
react.NodeViewWrapper,
|
|
28
|
+
{
|
|
29
|
+
className: _private.cn(
|
|
30
|
+
"lb-root lb-mention lb-tiptap-mention",
|
|
31
|
+
isSelected && "lb-mention-selected"
|
|
32
|
+
),
|
|
33
|
+
as: "span",
|
|
34
|
+
children: [
|
|
35
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "lb-mention-symbol", children: core.MENTION_CHARACTER }),
|
|
36
|
+
/* @__PURE__ */ jsxRuntime.jsx(_private.Group, { groupId: mention.id })
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
);
|
|
44
40
|
};
|
|
45
41
|
function deserializeGroupUserIds(userIds) {
|
|
46
42
|
if (typeof userIds !== "string") {
|
|
@@ -63,10 +59,13 @@ const Mention = ({ node, selected: isSelected }) => {
|
|
|
63
59
|
kind: "user",
|
|
64
60
|
id: attrs.id
|
|
65
61
|
};
|
|
66
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
62
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
63
|
+
UserMention,
|
|
64
|
+
{
|
|
65
|
+
mention,
|
|
66
|
+
isSelected
|
|
67
|
+
}
|
|
68
|
+
);
|
|
70
69
|
}
|
|
71
70
|
if (node.type.name === types.LIVEBLOCKS_GROUP_MENTION_TYPE) {
|
|
72
71
|
const mention = {
|
|
@@ -74,10 +73,13 @@ const Mention = ({ node, selected: isSelected }) => {
|
|
|
74
73
|
id: attrs.id,
|
|
75
74
|
userIds: deserializeGroupUserIds(attrs.userIds)
|
|
76
75
|
};
|
|
77
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
77
|
+
GroupMention,
|
|
78
|
+
{
|
|
79
|
+
mention,
|
|
80
|
+
isSelected
|
|
81
|
+
}
|
|
82
|
+
);
|
|
81
83
|
}
|
|
82
84
|
return null;
|
|
83
85
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Mention.cjs","sources":["../../src/mentions/Mention.tsx"],"sourcesContent":["import {\n type GroupMentionData,\n MENTION_CHARACTER,\n type MentionData,\n type UserMentionData,\n} from \"@liveblocks/core\";\nimport { cn, Group, User } from \"@liveblocks/react-ui/_private\";\nimport { NodeViewWrapper, type ReactNodeViewProps } from \"@tiptap/react\";\n\nimport {\n LIVEBLOCKS_GROUP_MENTION_TYPE,\n LIVEBLOCKS_MENTION_TYPE,\n type SerializedTiptapMentionData,\n} from \"../types\";\n\ninterface MentionProps {\n mention: MentionData;\n isSelected: boolean;\n}\ninterface GroupMentionProps {\n mention: GroupMentionData;\n isSelected: boolean;\n}\n\nconst UserMention = ({ isSelected, mention }: MentionProps) => {\n\n return (\n <NodeViewWrapper\n className={cn(\n \"lb-root lb-mention lb-tiptap-mention\",\n isSelected && \"lb-mention-selected\"\n )}\n as=\"span\"\n >\n <span className=\"lb-mention-symbol\">{MENTION_CHARACTER}</span>\n <User userId={mention.id} />\n </NodeViewWrapper>\n );\n};\n\nconst GroupMention = ({ isSelected, mention }: GroupMentionProps) => {\n return (\n <NodeViewWrapper\n className={cn(\n \"lb-root lb-mention lb-tiptap-mention\",\n isSelected && \"lb-mention-selected\"\n )}\n as=\"span\"\n >\n <span className=\"lb-mention-symbol\">{MENTION_CHARACTER}</span>\n <Group groupId={mention.id} />\n </NodeViewWrapper>\n );\n};\n\nfunction deserializeGroupUserIds(\n userIds: string | undefined\n): string[] | undefined {\n if (typeof userIds !== \"string\") {\n return undefined;\n }\n\n try {\n const parsedUserIds = JSON.parse(userIds) as string[];\n\n if (Array.isArray(parsedUserIds)) {\n return parsedUserIds;\n }\n\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nexport const Mention = ({ node, selected: isSelected }: ReactNodeViewProps<HTMLSpanElement>) => {\n const attrs = node.attrs as Omit<SerializedTiptapMentionData, \"kind\">;\n\n if (node.type.name === LIVEBLOCKS_MENTION_TYPE) {\n const mention: UserMentionData = {\n kind: \"user\",\n id: attrs.id,\n };\n\n return (\n <UserMention\n mention={mention}\n isSelected={isSelected}\n />\n );\n }\n if (node.type.name === LIVEBLOCKS_GROUP_MENTION_TYPE) {\n const mention: GroupMentionData = {\n kind: \"group\",\n id: attrs.id,\n userIds: deserializeGroupUserIds(attrs.userIds),\n };\n\n return (\n <GroupMention\n mention={mention}\n isSelected={isSelected}\n />\n );\n }\n\n return null;\n};\n"],"names":["jsxs","NodeViewWrapper","cn","jsx","MENTION_CHARACTER","User","Group","LIVEBLOCKS_MENTION_TYPE","LIVEBLOCKS_GROUP_MENTION_TYPE"],"mappings":";;;;;;;;AAwBA,MAAM,WAAc,GAAA,CAAC,EAAE,UAAA,EAAY,SAA4B,KAAA;AAE7D,
|
|
1
|
+
{"version":3,"file":"Mention.cjs","sources":["../../src/mentions/Mention.tsx"],"sourcesContent":["import {\n type GroupMentionData,\n MENTION_CHARACTER,\n type MentionData,\n type UserMentionData,\n} from \"@liveblocks/core\";\nimport { cn, Group, User } from \"@liveblocks/react-ui/_private\";\nimport { NodeViewWrapper, type ReactNodeViewProps } from \"@tiptap/react\";\n\nimport {\n LIVEBLOCKS_GROUP_MENTION_TYPE,\n LIVEBLOCKS_MENTION_TYPE,\n type SerializedTiptapMentionData,\n} from \"../types\";\n\ninterface MentionProps {\n mention: MentionData;\n isSelected: boolean;\n}\ninterface GroupMentionProps {\n mention: GroupMentionData;\n isSelected: boolean;\n}\n\nconst UserMention = ({ isSelected, mention }: MentionProps) => {\n\n return (\n <NodeViewWrapper\n className={cn(\n \"lb-root lb-mention lb-tiptap-mention\",\n isSelected && \"lb-mention-selected\"\n )}\n as=\"span\"\n >\n <span className=\"lb-mention-symbol\">{MENTION_CHARACTER}</span>\n <User userId={mention.id} />\n </NodeViewWrapper>\n );\n};\n\nconst GroupMention = ({ isSelected, mention }: GroupMentionProps) => {\n return (\n <NodeViewWrapper\n className={cn(\n \"lb-root lb-mention lb-tiptap-mention\",\n isSelected && \"lb-mention-selected\"\n )}\n as=\"span\"\n >\n <span className=\"lb-mention-symbol\">{MENTION_CHARACTER}</span>\n <Group groupId={mention.id} />\n </NodeViewWrapper>\n );\n};\n\nfunction deserializeGroupUserIds(\n userIds: string | undefined\n): string[] | undefined {\n if (typeof userIds !== \"string\") {\n return undefined;\n }\n\n try {\n const parsedUserIds = JSON.parse(userIds) as string[];\n\n if (Array.isArray(parsedUserIds)) {\n return parsedUserIds;\n }\n\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nexport const Mention = ({ node, selected: isSelected }: ReactNodeViewProps<HTMLSpanElement>) => {\n const attrs = node.attrs as Omit<SerializedTiptapMentionData, \"kind\">;\n\n if (node.type.name === LIVEBLOCKS_MENTION_TYPE) {\n const mention: UserMentionData = {\n kind: \"user\",\n id: attrs.id,\n };\n\n return (\n <UserMention\n mention={mention}\n isSelected={isSelected}\n />\n );\n }\n if (node.type.name === LIVEBLOCKS_GROUP_MENTION_TYPE) {\n const mention: GroupMentionData = {\n kind: \"group\",\n id: attrs.id,\n userIds: deserializeGroupUserIds(attrs.userIds),\n };\n\n return (\n <GroupMention\n mention={mention}\n isSelected={isSelected}\n />\n );\n }\n\n return null;\n};\n"],"names":["jsxs","NodeViewWrapper","cn","jsx","MENTION_CHARACTER","User","Group","LIVEBLOCKS_MENTION_TYPE","LIVEBLOCKS_GROUP_MENTION_TYPE"],"mappings":";;;;;;;;AAwBA,MAAM,WAAc,GAAA,CAAC,EAAE,UAAA,EAAY,SAA4B,KAAA;AAE7D,EACE,uBAAAA,eAAA;AAAA,IAACC,qBAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAAC,WAAA;AAAA,QACT,sCAAA;AAAA,QACA,UAAc,IAAA,qBAAA;AAAA,OAChB;AAAA,MACA,EAAG,EAAA,MAAA;AAAA,MAEH,QAAA,EAAA;AAAA,wBAACC,cAAA,CAAA,MAAA,EAAA,EAAK,SAAU,EAAA,mBAAA,EAAqB,QAAkB,EAAAC,sBAAA,EAAA,CAAA;AAAA,wBACtDD,cAAA,CAAAE,aAAA,EAAA,EAAK,MAAQ,EAAA,OAAA,CAAQ,EAAI,EAAA,CAAA;AAAA,OAAA;AAAA,KAAA;AAAA,GAC5B,CAAA;AAEJ,CAAA,CAAA;AAEA,MAAM,YAAe,GAAA,CAAC,EAAE,UAAA,EAAY,SAAiC,KAAA;AACnE,EACE,uBAAAL,eAAA;AAAA,IAACC,qBAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAAC,WAAA;AAAA,QACT,sCAAA;AAAA,QACA,UAAc,IAAA,qBAAA;AAAA,OAChB;AAAA,MACA,EAAG,EAAA,MAAA;AAAA,MAEH,QAAA,EAAA;AAAA,wBAACC,cAAA,CAAA,MAAA,EAAA,EAAK,SAAU,EAAA,mBAAA,EAAqB,QAAkB,EAAAC,sBAAA,EAAA,CAAA;AAAA,wBACtDD,cAAA,CAAAG,cAAA,EAAA,EAAM,OAAS,EAAA,OAAA,CAAQ,EAAI,EAAA,CAAA;AAAA,OAAA;AAAA,KAAA;AAAA,GAC9B,CAAA;AAEJ,CAAA,CAAA;AAEA,SAAS,wBACP,OACsB,EAAA;AACtB,EAAI,IAAA,OAAO,YAAY,QAAU,EAAA;AAC/B,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT;AAEA,EAAI,IAAA;AACF,IAAM,MAAA,aAAA,GAAgB,IAAK,CAAA,KAAA,CAAM,OAAO,CAAA,CAAA;AAExC,IAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,aAAa,CAAG,EAAA;AAChC,MAAO,OAAA,aAAA,CAAA;AAAA,KACT;AAEA,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACD,CAAA,MAAA;AACN,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT;AACF,CAAA;AAEO,MAAM,UAAU,CAAC,EAAE,IAAM,EAAA,QAAA,EAAU,YAAsD,KAAA;AAC9F,EAAA,MAAM,QAAQ,IAAK,CAAA,KAAA,CAAA;AAEnB,EAAI,IAAA,IAAA,CAAK,IAAK,CAAA,IAAA,KAASC,6BAAyB,EAAA;AAC9C,IAAA,MAAM,OAA2B,GAAA;AAAA,MAC/B,IAAM,EAAA,MAAA;AAAA,MACN,IAAI,KAAM,CAAA,EAAA;AAAA,KACZ,CAAA;AAEA,IACE,uBAAAJ,cAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,OAAA;AAAA,QACA,UAAA;AAAA,OAAA;AAAA,KACF,CAAA;AAAA,GAEJ;AACA,EAAI,IAAA,IAAA,CAAK,IAAK,CAAA,IAAA,KAASK,mCAA+B,EAAA;AACpD,IAAA,MAAM,OAA4B,GAAA;AAAA,MAChC,IAAM,EAAA,OAAA;AAAA,MACN,IAAI,KAAM,CAAA,EAAA;AAAA,MACV,OAAA,EAAS,uBAAwB,CAAA,KAAA,CAAM,OAAO,CAAA;AAAA,KAChD,CAAA;AAEA,IACE,uBAAAL,cAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,OAAA;AAAA,QACA,UAAA;AAAA,OAAA;AAAA,KACF,CAAA;AAAA,GAEJ;AAEA,EAAO,OAAA,IAAA,CAAA;AACT;;;;"}
|