@liveblocks/react-tiptap 0.0.1 → 2.8.3-tiptap2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/LiveblocksExtension.js +206 -0
  2. package/dist/LiveblocksExtension.js.map +1 -0
  3. package/dist/LiveblocksExtension.mjs +204 -0
  4. package/dist/LiveblocksExtension.mjs.map +1 -0
  5. package/dist/classnames.js +8 -0
  6. package/dist/classnames.js.map +1 -0
  7. package/dist/classnames.mjs +6 -0
  8. package/dist/classnames.mjs.map +1 -0
  9. package/dist/comments/AnchoredThreads.js +178 -0
  10. package/dist/comments/AnchoredThreads.js.map +1 -0
  11. package/dist/comments/AnchoredThreads.mjs +176 -0
  12. package/dist/comments/AnchoredThreads.mjs.map +1 -0
  13. package/dist/comments/CommentsExtension.js +224 -0
  14. package/dist/comments/CommentsExtension.js.map +1 -0
  15. package/dist/comments/CommentsExtension.mjs +222 -0
  16. package/dist/comments/CommentsExtension.mjs.map +1 -0
  17. package/dist/comments/FloatingComposer.js +100 -0
  18. package/dist/comments/FloatingComposer.js.map +1 -0
  19. package/dist/comments/FloatingComposer.mjs +97 -0
  20. package/dist/comments/FloatingComposer.mjs.map +1 -0
  21. package/dist/comments/FloatingThreads.js +159 -0
  22. package/dist/comments/FloatingThreads.js.map +1 -0
  23. package/dist/comments/FloatingThreads.mjs +156 -0
  24. package/dist/comments/FloatingThreads.mjs.map +1 -0
  25. package/dist/index.d.mts +78 -0
  26. package/dist/index.d.ts +78 -0
  27. package/dist/index.js +18 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/index.mjs +10 -0
  30. package/dist/index.mjs.map +1 -0
  31. package/dist/mentions/Avatar.js +53 -0
  32. package/dist/mentions/Avatar.js.map +1 -0
  33. package/dist/mentions/Avatar.mjs +51 -0
  34. package/dist/mentions/Avatar.mjs.map +1 -0
  35. package/dist/mentions/Mention.js +24 -0
  36. package/dist/mentions/Mention.js.map +1 -0
  37. package/dist/mentions/Mention.mjs +22 -0
  38. package/dist/mentions/Mention.mjs.map +1 -0
  39. package/dist/mentions/MentionExtension.js +222 -0
  40. package/dist/mentions/MentionExtension.js.map +1 -0
  41. package/dist/mentions/MentionExtension.mjs +220 -0
  42. package/dist/mentions/MentionExtension.mjs.map +1 -0
  43. package/dist/mentions/MentionsList.js +123 -0
  44. package/dist/mentions/MentionsList.js.map +1 -0
  45. package/dist/mentions/MentionsList.mjs +119 -0
  46. package/dist/mentions/MentionsList.mjs.map +1 -0
  47. package/dist/types.js +33 -0
  48. package/dist/types.js.map +1 -0
  49. package/dist/types.mjs +24 -0
  50. package/dist/types.mjs.map +1 -0
  51. package/dist/utils.js +47 -0
  52. package/dist/utils.js.map +1 -0
  53. package/dist/utils.mjs +43 -0
  54. package/dist/utils.mjs.map +1 -0
  55. package/dist/version-history/HistoryVersionPreview.js +79 -0
  56. package/dist/version-history/HistoryVersionPreview.js.map +1 -0
  57. package/dist/version-history/HistoryVersionPreview.mjs +77 -0
  58. package/dist/version-history/HistoryVersionPreview.mjs.map +1 -0
  59. package/dist/version.js +10 -0
  60. package/dist/version.js.map +1 -0
  61. package/dist/version.mjs +6 -0
  62. package/dist/version.mjs.map +1 -0
  63. package/package.json +77 -1
  64. package/src/styles/constants.css +9 -0
  65. package/src/styles/index.css +250 -0
  66. package/src/styles/utils.css +6 -0
  67. package/styles.css +1 -0
  68. package/styles.css.d.ts +1 -0
  69. package/styles.css.map +1 -0
@@ -0,0 +1,159 @@
1
+ 'use strict';
2
+
3
+ var reactDom = require('@floating-ui/react-dom');
4
+ var reactUi = require('@liveblocks/react-ui');
5
+ var React = require('react');
6
+ var reactDom$1 = require('react-dom');
7
+ var classnames = require('../classnames.js');
8
+ var types = require('../types.js');
9
+
10
+ function FloatingThreads({
11
+ threads,
12
+ components,
13
+ editor,
14
+ ...props
15
+ }) {
16
+ const Thread = components?.Thread ?? reactUi.Thread;
17
+ const pluginState = editor ? types.THREADS_PLUGIN_KEY.getState(editor.state) : null;
18
+ const [activeThread, setActiveThread] = React.useState(null);
19
+ React.useEffect(() => {
20
+ if (!editor || !pluginState) {
21
+ setActiveThread(null);
22
+ return;
23
+ }
24
+ const { selectedThreadId, selectedThreadPos } = pluginState;
25
+ if (selectedThreadId === null || selectedThreadPos === null) {
26
+ setActiveThread(null);
27
+ return;
28
+ }
29
+ const active = (threads ?? []).find(
30
+ (thread) => selectedThreadId === thread.id
31
+ );
32
+ setActiveThread(active ?? null);
33
+ }, [editor, pluginState, threads]);
34
+ const handleEscapeKeydown = React.useCallback(() => {
35
+ if (!editor || activeThread === null)
36
+ return false;
37
+ editor.commands.selectThread(null);
38
+ return true;
39
+ }, [activeThread, editor]);
40
+ if (!activeThread || !editor || activeThread.resolved)
41
+ return null;
42
+ return /* @__PURE__ */ React.createElement(FloatingThreadPortal, {
43
+ thread: activeThread,
44
+ editor,
45
+ container: document.body,
46
+ ...props
47
+ }, activeThread && /* @__PURE__ */ React.createElement(ThreadWrapper, {
48
+ key: activeThread.id,
49
+ thread: activeThread,
50
+ Thread,
51
+ onEscapeKeydown: handleEscapeKeydown,
52
+ className: "lb-tiptap-floating-threads-thread"
53
+ }));
54
+ }
55
+ const FLOATING_THREAD_COLLISION_PADDING = 10;
56
+ function FloatingThreadPortal({
57
+ container,
58
+ editor,
59
+ thread,
60
+ children,
61
+ className,
62
+ style,
63
+ ...props
64
+ }) {
65
+ const {
66
+ refs: { setReference, setFloating },
67
+ strategy,
68
+ x,
69
+ y
70
+ } = reactDom.useFloating({
71
+ strategy: "absolute",
72
+ placement: "bottom",
73
+ middleware: [
74
+ reactDom.flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),
75
+ reactDom.offset(10),
76
+ reactDom.hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),
77
+ reactDom.shift({
78
+ padding: FLOATING_THREAD_COLLISION_PADDING,
79
+ limiter: reactDom.limitShift()
80
+ }),
81
+ reactDom.size({
82
+ padding: FLOATING_THREAD_COLLISION_PADDING,
83
+ apply({ availableWidth, availableHeight, elements }) {
84
+ elements.floating.style.setProperty(
85
+ "--lb-tiptap-floating-threads-available-width",
86
+ `${availableWidth}px`
87
+ );
88
+ elements.floating.style.setProperty(
89
+ "--lb-tiptap-floating-threads-available-height",
90
+ `${availableHeight}px`
91
+ );
92
+ }
93
+ })
94
+ ],
95
+ whileElementsMounted: (...args) => {
96
+ return reactDom.autoUpdate(...args, {
97
+ animationFrame: true
98
+ });
99
+ }
100
+ });
101
+ const updateRef = React.useCallback(() => {
102
+ const el = editor.view.dom.querySelector(`[data-lb-thread-id="${thread.id}"]`);
103
+ if (el) {
104
+ setReference(el);
105
+ }
106
+ }, [setReference, editor, thread.id]);
107
+ React.useEffect(() => {
108
+ editor.on("transaction", updateRef);
109
+ return () => {
110
+ editor.off("transaction", updateRef);
111
+ };
112
+ }, [editor, updateRef]);
113
+ React.useLayoutEffect(updateRef, [updateRef]);
114
+ return reactDom$1.createPortal(
115
+ /* @__PURE__ */ React.createElement("div", {
116
+ ref: setFloating,
117
+ ...props,
118
+ style: {
119
+ ...style,
120
+ position: strategy,
121
+ top: 0,
122
+ left: 0,
123
+ transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
124
+ minWidth: "max-content"
125
+ },
126
+ className: classnames.classNames(
127
+ "lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-threads",
128
+ className
129
+ )
130
+ }, children),
131
+ container
132
+ );
133
+ }
134
+ function ThreadWrapper({
135
+ thread,
136
+ Thread,
137
+ onEscapeKeydown,
138
+ onKeyDown,
139
+ ...threadProps
140
+ }) {
141
+ const handleKeyDown = React.useCallback(
142
+ (event) => {
143
+ onKeyDown?.(event);
144
+ if (event.key === "Escape") {
145
+ onEscapeKeydown();
146
+ }
147
+ },
148
+ [onEscapeKeydown, onKeyDown]
149
+ );
150
+ return /* @__PURE__ */ React.createElement(Thread, {
151
+ thread,
152
+ onKeyDown: handleKeyDown,
153
+ ...threadProps
154
+ });
155
+ }
156
+
157
+ exports.FLOATING_THREAD_COLLISION_PADDING = FLOATING_THREAD_COLLISION_PADDING;
158
+ exports.FloatingThreads = FloatingThreads;
159
+ //# sourceMappingURL=FloatingThreads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloatingThreads.js","sources":["../../src/comments/FloatingThreads.tsx"],"sourcesContent":["\nimport {\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 {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport type { Editor } from \"@tiptap/react\";\nimport React, {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useLayoutEffect,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport type { ThreadPluginState } from \"../types\";\nimport { THREADS_PLUGIN_KEY } from \"../types\";\n\ntype ThreadPanelComponents = {\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<ThreadPanelComponents>;\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\n const Thread = components?.Thread ?? DefaultThread;\n const pluginState = editor ? THREADS_PLUGIN_KEY.getState(editor.state) as ThreadPluginState : null;\n\n const [activeThread, setActiveThread] = useState<ThreadData | null>(null);\n\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((thread) =>\n 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(`[data-lb-thread-id=\"${thread.id}\"]`);\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={classNames(\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\n"],"names":["DefaultThread","THREADS_PLUGIN_KEY","useState","useEffect","useCallback","useFloating","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","createPortal","classNames"],"mappings":"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"}
@@ -0,0 +1,156 @@
1
+ import { useFloating, flip, offset, hide, shift, limitShift, size, autoUpdate } from '@floating-ui/react-dom';
2
+ import { Thread } from '@liveblocks/react-ui';
3
+ import React, { useState, useEffect, useCallback, useLayoutEffect } from 'react';
4
+ import { createPortal } from 'react-dom';
5
+ import { classNames } from '../classnames.mjs';
6
+ import { THREADS_PLUGIN_KEY } from '../types.mjs';
7
+
8
+ function FloatingThreads({
9
+ threads,
10
+ components,
11
+ editor,
12
+ ...props
13
+ }) {
14
+ const Thread$1 = components?.Thread ?? Thread;
15
+ const pluginState = editor ? THREADS_PLUGIN_KEY.getState(editor.state) : null;
16
+ const [activeThread, setActiveThread] = useState(null);
17
+ useEffect(() => {
18
+ if (!editor || !pluginState) {
19
+ setActiveThread(null);
20
+ return;
21
+ }
22
+ const { selectedThreadId, selectedThreadPos } = pluginState;
23
+ if (selectedThreadId === null || selectedThreadPos === null) {
24
+ setActiveThread(null);
25
+ return;
26
+ }
27
+ const active = (threads ?? []).find(
28
+ (thread) => selectedThreadId === thread.id
29
+ );
30
+ setActiveThread(active ?? null);
31
+ }, [editor, pluginState, threads]);
32
+ const handleEscapeKeydown = useCallback(() => {
33
+ if (!editor || activeThread === null)
34
+ return false;
35
+ editor.commands.selectThread(null);
36
+ return true;
37
+ }, [activeThread, editor]);
38
+ if (!activeThread || !editor || activeThread.resolved)
39
+ return null;
40
+ return /* @__PURE__ */ React.createElement(FloatingThreadPortal, {
41
+ thread: activeThread,
42
+ editor,
43
+ container: document.body,
44
+ ...props
45
+ }, activeThread && /* @__PURE__ */ React.createElement(ThreadWrapper, {
46
+ key: activeThread.id,
47
+ thread: activeThread,
48
+ Thread: Thread$1,
49
+ onEscapeKeydown: handleEscapeKeydown,
50
+ className: "lb-tiptap-floating-threads-thread"
51
+ }));
52
+ }
53
+ const FLOATING_THREAD_COLLISION_PADDING = 10;
54
+ function FloatingThreadPortal({
55
+ container,
56
+ editor,
57
+ thread,
58
+ children,
59
+ className,
60
+ style,
61
+ ...props
62
+ }) {
63
+ const {
64
+ refs: { setReference, setFloating },
65
+ strategy,
66
+ x,
67
+ y
68
+ } = useFloating({
69
+ strategy: "absolute",
70
+ placement: "bottom",
71
+ middleware: [
72
+ flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),
73
+ offset(10),
74
+ hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),
75
+ shift({
76
+ padding: FLOATING_THREAD_COLLISION_PADDING,
77
+ limiter: limitShift()
78
+ }),
79
+ size({
80
+ padding: FLOATING_THREAD_COLLISION_PADDING,
81
+ apply({ availableWidth, availableHeight, elements }) {
82
+ elements.floating.style.setProperty(
83
+ "--lb-tiptap-floating-threads-available-width",
84
+ `${availableWidth}px`
85
+ );
86
+ elements.floating.style.setProperty(
87
+ "--lb-tiptap-floating-threads-available-height",
88
+ `${availableHeight}px`
89
+ );
90
+ }
91
+ })
92
+ ],
93
+ whileElementsMounted: (...args) => {
94
+ return autoUpdate(...args, {
95
+ animationFrame: true
96
+ });
97
+ }
98
+ });
99
+ const updateRef = useCallback(() => {
100
+ const el = editor.view.dom.querySelector(`[data-lb-thread-id="${thread.id}"]`);
101
+ if (el) {
102
+ setReference(el);
103
+ }
104
+ }, [setReference, editor, thread.id]);
105
+ useEffect(() => {
106
+ editor.on("transaction", updateRef);
107
+ return () => {
108
+ editor.off("transaction", updateRef);
109
+ };
110
+ }, [editor, updateRef]);
111
+ useLayoutEffect(updateRef, [updateRef]);
112
+ return createPortal(
113
+ /* @__PURE__ */ React.createElement("div", {
114
+ ref: setFloating,
115
+ ...props,
116
+ style: {
117
+ ...style,
118
+ position: strategy,
119
+ top: 0,
120
+ left: 0,
121
+ transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
122
+ minWidth: "max-content"
123
+ },
124
+ className: classNames(
125
+ "lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-threads",
126
+ className
127
+ )
128
+ }, children),
129
+ container
130
+ );
131
+ }
132
+ function ThreadWrapper({
133
+ thread,
134
+ Thread,
135
+ onEscapeKeydown,
136
+ onKeyDown,
137
+ ...threadProps
138
+ }) {
139
+ const handleKeyDown = useCallback(
140
+ (event) => {
141
+ onKeyDown?.(event);
142
+ if (event.key === "Escape") {
143
+ onEscapeKeydown();
144
+ }
145
+ },
146
+ [onEscapeKeydown, onKeyDown]
147
+ );
148
+ return /* @__PURE__ */ React.createElement(Thread, {
149
+ thread,
150
+ onKeyDown: handleKeyDown,
151
+ ...threadProps
152
+ });
153
+ }
154
+
155
+ export { FLOATING_THREAD_COLLISION_PADDING, FloatingThreads };
156
+ //# sourceMappingURL=FloatingThreads.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FloatingThreads.mjs","sources":["../../src/comments/FloatingThreads.tsx"],"sourcesContent":["\nimport {\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 {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport type { Editor } from \"@tiptap/react\";\nimport React, {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useLayoutEffect,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport type { ThreadPluginState } from \"../types\";\nimport { THREADS_PLUGIN_KEY } from \"../types\";\n\ntype ThreadPanelComponents = {\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<ThreadPanelComponents>;\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\n const Thread = components?.Thread ?? DefaultThread;\n const pluginState = editor ? THREADS_PLUGIN_KEY.getState(editor.state) as ThreadPluginState : null;\n\n const [activeThread, setActiveThread] = useState<ThreadData | null>(null);\n\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((thread) =>\n 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(`[data-lb-thread-id=\"${thread.id}\"]`);\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={classNames(\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\n"],"names":["Thread","DefaultThread"],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import { BaseMetadata, DM, ThreadData, HistoryVersion } from '@liveblocks/core';
2
+ import { ThreadProps, ComposerProps } from '@liveblocks/react-ui';
3
+ import { Editor } from '@tiptap/react';
4
+ import React, { ComponentPropsWithoutRef, ComponentType, HTMLAttributes } from 'react';
5
+ import { BaseMetadata as BaseMetadata$1 } from '@liveblocks/client';
6
+ import { Extension } from '@tiptap/core';
7
+
8
+ declare type AnchoredThreadsComponents = {
9
+ Thread: ComponentType<ThreadProps>;
10
+ };
11
+ interface AnchoredThreadsProps<M extends BaseMetadata = DM> extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
12
+ /**
13
+ * The threads to display.
14
+ */
15
+ threads: ThreadData<M>[];
16
+ /**
17
+ * Override the component's components.
18
+ */
19
+ components?: Partial<AnchoredThreadsComponents>;
20
+ /**
21
+ * The tiptap editor
22
+ */
23
+ editor: Editor | null;
24
+ }
25
+ declare function AnchoredThreads({ threads, components, className, style, editor, ...props }: AnchoredThreadsProps): React.JSX.Element | null;
26
+
27
+ declare const FloatingComposer: React.ForwardRefExoticComponent<Omit<ComposerProps<BaseMetadata$1>, "threadId" | "commentId"> & {
28
+ editor: Editor | null;
29
+ } & React.RefAttributes<HTMLFormElement>>;
30
+
31
+ declare type ThreadPanelComponents = {
32
+ Thread: ComponentType<ThreadProps>;
33
+ };
34
+ interface FloatingThreadsProps<M extends BaseMetadata = DM> extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
35
+ /**
36
+ * The threads to display.
37
+ */
38
+ threads: ThreadData<M>[];
39
+ /**
40
+ * Override the component's components.
41
+ */
42
+ components?: Partial<ThreadPanelComponents>;
43
+ /**
44
+ * The tiptap editor
45
+ */
46
+ editor: Editor | null;
47
+ }
48
+ declare function FloatingThreads({ threads, components, editor, ...props }: FloatingThreadsProps): React.JSX.Element | null;
49
+
50
+ declare const useLiveblocksExtension: () => Extension;
51
+
52
+ interface HistoryVersionPreviewProps extends ComponentPropsWithoutRef<"div"> {
53
+ version: HistoryVersion;
54
+ editor: Editor;
55
+ onVersionRestore?: (version: HistoryVersion) => void;
56
+ }
57
+ /**
58
+ * Displays a specific version of the current TipTap document.
59
+ *
60
+ * @example
61
+ * <HistoryVersionPreview version={version} />
62
+ */
63
+ declare const HistoryVersionPreview: React.ForwardRefExoticComponent<HistoryVersionPreviewProps & React.RefAttributes<HTMLDivElement>>;
64
+
65
+ declare module "@tiptap/core" {
66
+ interface Commands<ReturnType> {
67
+ comments: {
68
+ /**
69
+ * Add a comment
70
+ */
71
+ addComment: (id: string) => ReturnType;
72
+ selectThread: (id: string | null) => ReturnType;
73
+ addPendingComment: () => ReturnType;
74
+ };
75
+ }
76
+ }
77
+
78
+ export { AnchoredThreads, FloatingComposer, FloatingThreads, HistoryVersionPreview, useLiveblocksExtension };
@@ -0,0 +1,78 @@
1
+ import { BaseMetadata, DM, ThreadData, HistoryVersion } from '@liveblocks/core';
2
+ import { ThreadProps, ComposerProps } from '@liveblocks/react-ui';
3
+ import { Editor } from '@tiptap/react';
4
+ import React, { ComponentPropsWithoutRef, ComponentType, HTMLAttributes } from 'react';
5
+ import { BaseMetadata as BaseMetadata$1 } from '@liveblocks/client';
6
+ import { Extension } from '@tiptap/core';
7
+
8
+ declare type AnchoredThreadsComponents = {
9
+ Thread: ComponentType<ThreadProps>;
10
+ };
11
+ interface AnchoredThreadsProps<M extends BaseMetadata = DM> extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
12
+ /**
13
+ * The threads to display.
14
+ */
15
+ threads: ThreadData<M>[];
16
+ /**
17
+ * Override the component's components.
18
+ */
19
+ components?: Partial<AnchoredThreadsComponents>;
20
+ /**
21
+ * The tiptap editor
22
+ */
23
+ editor: Editor | null;
24
+ }
25
+ declare function AnchoredThreads({ threads, components, className, style, editor, ...props }: AnchoredThreadsProps): React.JSX.Element | null;
26
+
27
+ declare const FloatingComposer: React.ForwardRefExoticComponent<Omit<ComposerProps<BaseMetadata$1>, "threadId" | "commentId"> & {
28
+ editor: Editor | null;
29
+ } & React.RefAttributes<HTMLFormElement>>;
30
+
31
+ declare type ThreadPanelComponents = {
32
+ Thread: ComponentType<ThreadProps>;
33
+ };
34
+ interface FloatingThreadsProps<M extends BaseMetadata = DM> extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
35
+ /**
36
+ * The threads to display.
37
+ */
38
+ threads: ThreadData<M>[];
39
+ /**
40
+ * Override the component's components.
41
+ */
42
+ components?: Partial<ThreadPanelComponents>;
43
+ /**
44
+ * The tiptap editor
45
+ */
46
+ editor: Editor | null;
47
+ }
48
+ declare function FloatingThreads({ threads, components, editor, ...props }: FloatingThreadsProps): React.JSX.Element | null;
49
+
50
+ declare const useLiveblocksExtension: () => Extension;
51
+
52
+ interface HistoryVersionPreviewProps extends ComponentPropsWithoutRef<"div"> {
53
+ version: HistoryVersion;
54
+ editor: Editor;
55
+ onVersionRestore?: (version: HistoryVersion) => void;
56
+ }
57
+ /**
58
+ * Displays a specific version of the current TipTap document.
59
+ *
60
+ * @example
61
+ * <HistoryVersionPreview version={version} />
62
+ */
63
+ declare const HistoryVersionPreview: React.ForwardRefExoticComponent<HistoryVersionPreviewProps & React.RefAttributes<HTMLDivElement>>;
64
+
65
+ declare module "@tiptap/core" {
66
+ interface Commands<ReturnType> {
67
+ comments: {
68
+ /**
69
+ * Add a comment
70
+ */
71
+ addComment: (id: string) => ReturnType;
72
+ selectThread: (id: string | null) => ReturnType;
73
+ addPendingComment: () => ReturnType;
74
+ };
75
+ }
76
+ }
77
+
78
+ export { AnchoredThreads, FloatingComposer, FloatingThreads, HistoryVersionPreview, useLiveblocksExtension };
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var core = require('@liveblocks/core');
4
+ var version = require('./version.js');
5
+ var AnchoredThreads = require('./comments/AnchoredThreads.js');
6
+ var FloatingComposer = require('./comments/FloatingComposer.js');
7
+ var FloatingThreads = require('./comments/FloatingThreads.js');
8
+ var LiveblocksExtension = require('./LiveblocksExtension.js');
9
+ var HistoryVersionPreview = require('./version-history/HistoryVersionPreview.js');
10
+
11
+ core.detectDupes(version.PKG_NAME, version.PKG_VERSION, version.PKG_FORMAT);
12
+
13
+ exports.AnchoredThreads = AnchoredThreads.AnchoredThreads;
14
+ exports.FloatingComposer = FloatingComposer.FloatingComposer;
15
+ exports.FloatingThreads = FloatingThreads.FloatingThreads;
16
+ exports.useLiveblocksExtension = LiveblocksExtension.useLiveblocksExtension;
17
+ exports.HistoryVersionPreview = HistoryVersionPreview.HistoryVersionPreview;
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport { AnchoredThreads } from \"./comments/AnchoredThreads\";\nexport { FloatingComposer } from \"./comments/FloatingComposer\";\nexport { FloatingThreads } from \"./comments/FloatingThreads\";\nexport { useLiveblocksExtension } from \"./LiveblocksExtension\";\nexport { HistoryVersionPreview } from \"./version-history/HistoryVersionPreview\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n comments: {\n /**\n * Add a comment\n */\n addComment: (id: string) => ReturnType;\n selectThread: (id: string | null) => ReturnType;\n addPendingComment: () => ReturnType;\n };\n }\n}\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;;;;AAIAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;;;;"}
package/dist/index.mjs ADDED
@@ -0,0 +1,10 @@
1
+ import { detectDupes } from '@liveblocks/core';
2
+ import { PKG_NAME, PKG_VERSION, PKG_FORMAT } from './version.mjs';
3
+ export { AnchoredThreads } from './comments/AnchoredThreads.mjs';
4
+ export { FloatingComposer } from './comments/FloatingComposer.mjs';
5
+ export { FloatingThreads } from './comments/FloatingThreads.mjs';
6
+ export { useLiveblocksExtension } from './LiveblocksExtension.mjs';
7
+ export { HistoryVersionPreview } from './version-history/HistoryVersionPreview.mjs';
8
+
9
+ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
10
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport { AnchoredThreads } from \"./comments/AnchoredThreads\";\nexport { FloatingComposer } from \"./comments/FloatingComposer\";\nexport { FloatingThreads } from \"./comments/FloatingThreads\";\nexport { useLiveblocksExtension } from \"./LiveblocksExtension\";\nexport { HistoryVersionPreview } from \"./version-history/HistoryVersionPreview\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n comments: {\n /**\n * Add a comment\n */\n addComment: (id: string) => ReturnType;\n selectThread: (id: string | null) => ReturnType;\n addPendingComment: () => ReturnType;\n };\n }\n}\n"],"names":[],"mappings":";;;;;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ var react = require('@liveblocks/react');
4
+ var React = require('react');
5
+ var classnames = require('../classnames.js');
6
+
7
+ const Avatar = React.forwardRef(
8
+ function Avatar2(props, forwardedRef) {
9
+ const { userId, className, ...spanProps } = props;
10
+ const { user, isLoading } = react.useUser(userId);
11
+ const avatar = user ? user.avatar : void 0;
12
+ const name = user ? user.name : void 0;
13
+ function Initials() {
14
+ const initials = name ? getInitials(name) : void 0;
15
+ if (initials) {
16
+ return /* @__PURE__ */ React.createElement("span", {
17
+ "aria-hidden": true,
18
+ className: "lb-avatar-fallback"
19
+ }, initials);
20
+ }
21
+ if (isLoading)
22
+ return null;
23
+ if (user === void 0)
24
+ return null;
25
+ return /* @__PURE__ */ React.createElement("span", {
26
+ "aria-label": userId,
27
+ title: userId,
28
+ className: "lb-avatar-fallback"
29
+ }, getInitials(userId));
30
+ }
31
+ return /* @__PURE__ */ React.createElement("span", {
32
+ "data-loading": isLoading ? "" : void 0,
33
+ ...spanProps,
34
+ className: classnames.classNames("lb-avatar", className),
35
+ ref: forwardedRef
36
+ }, avatar && /* @__PURE__ */ React.createElement("img", {
37
+ src: avatar,
38
+ alt: name,
39
+ className: "lb-avatar-image"
40
+ }), /* @__PURE__ */ React.createElement(Initials, null));
41
+ }
42
+ );
43
+ function getInitials(name) {
44
+ return name.trim().split(" ").reduce((initials, name2, index, array) => {
45
+ if (index === 0 || index === array.length - 1) {
46
+ initials += name2.charAt(0).toLocaleUpperCase();
47
+ }
48
+ return initials;
49
+ }, "");
50
+ }
51
+
52
+ exports.Avatar = Avatar;
53
+ //# sourceMappingURL=Avatar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Avatar.js","sources":["../../src/mentions/Avatar.tsx"],"sourcesContent":["import { useUser } from \"@liveblocks/react\";\nimport type { HTMLAttributes } from \"react\";\nimport React, { forwardRef } from \"react\";\n\nimport { classNames } from \"../classnames\";\n\nexport interface AvatarProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n userId: string;\n}\n\nexport const Avatar = forwardRef<HTMLSpanElement, AvatarProps>(\n function Avatar(props, forwardedRef) {\n const { userId, className, ...spanProps } = props;\n\n const { user, isLoading } = useUser(userId);\n\n const avatar = user ? user.avatar : undefined;\n\n const name = user ? user.name : undefined;\n\n function Initials() {\n const initials = name ? getInitials(name) : undefined;\n if (initials) {\n return (\n <span aria-hidden className=\"lb-avatar-fallback\">\n {initials}\n </span>\n );\n }\n\n if (isLoading) return null;\n\n if (user === undefined) return null;\n\n return (\n <span aria-label={userId} title={userId} className=\"lb-avatar-fallback\">\n {getInitials(userId)}\n </span>\n );\n }\n\n return (\n <span\n data-loading={isLoading ? \"\" : undefined}\n {...spanProps}\n className={classNames(\"lb-avatar\", className)}\n ref={forwardedRef}\n >\n {avatar && <img src={avatar} alt={name} className=\"lb-avatar-image\" />}\n\n <Initials />\n </span>\n );\n }\n);\n\nfunction getInitials(name: string) {\n return name\n .trim()\n .split(\" \")\n .reduce((initials, name, index, array) => {\n if (index === 0 || index === array.length - 1) {\n initials += name.charAt(0).toLocaleUpperCase();\n }\n\n return initials;\n }, \"\");\n}\n"],"names":["forwardRef","Avatar","useUser","classNames","name"],"mappings":";;;;;;AAWO,MAAM,MAAS,GAAAA,gBAAA;AAAA,EACpB,SAASC,OAAO,CAAA,KAAA,EAAO,YAAc,EAAA;AACnC,IAAA,MAAM,EAAE,MAAA,EAAQ,SAAc,EAAA,GAAA,SAAA,EAAc,GAAA,KAAA,CAAA;AAE5C,IAAA,MAAM,EAAE,IAAA,EAAM,SAAU,EAAA,GAAIC,cAAQ,MAAM,CAAA,CAAA;AAE1C,IAAM,MAAA,MAAA,GAAS,IAAO,GAAA,IAAA,CAAK,MAAS,GAAA,KAAA,CAAA,CAAA;AAEpC,IAAM,MAAA,IAAA,GAAO,IAAO,GAAA,IAAA,CAAK,IAAO,GAAA,KAAA,CAAA,CAAA;AAEhC,IAAA,SAAS,QAAW,GAAA;AAClB,MAAA,MAAM,QAAW,GAAA,IAAA,GAAO,WAAY,CAAA,IAAI,CAAI,GAAA,KAAA,CAAA,CAAA;AAC5C,MAAA,IAAI,QAAU,EAAA;AACZ,QAAA,uBACG,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,UAAK,aAAW,EAAA,IAAA;AAAA,UAAC,SAAU,EAAA,oBAAA;AAAA,SAAA,EACzB,QACH,CAAA,CAAA;AAAA,OAEJ;AAEA,MAAI,IAAA,SAAA;AAAW,QAAO,OAAA,IAAA,CAAA;AAEtB,MAAA,IAAI,IAAS,KAAA,KAAA,CAAA;AAAW,QAAO,OAAA,IAAA,CAAA;AAE/B,MAAA,uBACG,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,QAAK,YAAY,EAAA,MAAA;AAAA,QAAQ,KAAO,EAAA,MAAA;AAAA,QAAQ,SAAU,EAAA,oBAAA;AAAA,OAChD,EAAA,WAAA,CAAY,MAAM,CACrB,CAAA,CAAA;AAAA,KAEJ;AAEA,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,MACC,cAAA,EAAc,YAAY,EAAK,GAAA,KAAA,CAAA;AAAA,MAC9B,GAAG,SAAA;AAAA,MACJ,SAAA,EAAWC,qBAAW,CAAA,WAAA,EAAa,SAAS,CAAA;AAAA,MAC5C,GAAK,EAAA,YAAA;AAAA,KAAA,EAEJ,0BAAW,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,MAAI,GAAK,EAAA,MAAA;AAAA,MAAQ,GAAK,EAAA,IAAA;AAAA,MAAM,SAAU,EAAA,iBAAA;AAAA,KAAkB,CAAA,kBAEnE,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,IAAS,CACZ,CAAA,CAAA;AAAA,GAEJ;AACF,EAAA;AAEA,SAAS,YAAY,IAAc,EAAA;AACjC,EAAO,OAAA,IAAA,CACJ,IAAK,EAAA,CACL,KAAM,CAAA,GAAG,CACT,CAAA,MAAA,CAAO,CAAC,QAAA,EAAUC,KAAM,EAAA,KAAA,EAAO,KAAU,KAAA;AACxC,IAAA,IAAI,KAAU,KAAA,CAAA,IAAK,KAAU,KAAA,KAAA,CAAM,SAAS,CAAG,EAAA;AAC7C,MAAA,QAAA,IAAYA,KAAK,CAAA,MAAA,CAAO,CAAC,CAAA,CAAE,iBAAkB,EAAA,CAAA;AAAA,KAC/C;AAEA,IAAO,OAAA,QAAA,CAAA;AAAA,KACN,EAAE,CAAA,CAAA;AACT;;;;"}