@liveblocks/react-lexical 2.2.2-test2 → 2.2.3-alpha1

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 (35) hide show
  1. package/dist/comments/anchored-threads.js +247 -0
  2. package/dist/comments/anchored-threads.js.map +1 -0
  3. package/dist/comments/anchored-threads.mjs +244 -0
  4. package/dist/comments/anchored-threads.mjs.map +1 -0
  5. package/dist/comments/comment-plugin-provider.js +11 -6
  6. package/dist/comments/comment-plugin-provider.js.map +1 -1
  7. package/dist/comments/comment-plugin-provider.mjs +12 -8
  8. package/dist/comments/comment-plugin-provider.mjs.map +1 -1
  9. package/dist/comments/floating-composer.js +2 -2
  10. package/dist/comments/floating-composer.js.map +1 -1
  11. package/dist/comments/floating-composer.mjs +2 -2
  12. package/dist/comments/floating-composer.mjs.map +1 -1
  13. package/dist/comments/floating-threads.js +219 -0
  14. package/dist/comments/floating-threads.js.map +1 -0
  15. package/dist/comments/floating-threads.mjs +216 -0
  16. package/dist/comments/floating-threads.mjs.map +1 -0
  17. package/dist/index.d.mts +34 -4
  18. package/dist/index.d.ts +34 -4
  19. package/dist/index.js +4 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +2 -0
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/liveblocks-plugin-provider.js +1 -0
  24. package/dist/liveblocks-plugin-provider.js.map +1 -1
  25. package/dist/liveblocks-plugin-provider.mjs +1 -1
  26. package/dist/liveblocks-plugin-provider.mjs.map +1 -1
  27. package/dist/version.js +1 -1
  28. package/dist/version.js.map +1 -1
  29. package/dist/version.mjs +1 -1
  30. package/dist/version.mjs.map +1 -1
  31. package/package.json +6 -6
  32. package/src/styles/constants.css +8 -0
  33. package/src/styles/index.css +76 -13
  34. package/styles.css +1 -1
  35. package/styles.css.map +1 -1
@@ -0,0 +1,219 @@
1
+ 'use strict';
2
+
3
+ var reactDom = require('@floating-ui/react-dom');
4
+ var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
5
+ var reactUi = require('@liveblocks/react-ui');
6
+ var lexical = require('lexical');
7
+ var React = require('react');
8
+ var reactDom$1 = require('react-dom');
9
+ var index_js = require('use-sync-external-store/shim/index.js');
10
+ var classnames = require('../classnames.js');
11
+ var anchoredThreads = require('./anchored-threads.js');
12
+ var commentPluginProvider = require('./comment-plugin-provider.js');
13
+
14
+ function FloatingThreads({
15
+ threads,
16
+ components,
17
+ ...divProps
18
+ }) {
19
+ const activeThreads = useActiveThreads();
20
+ const Thread = components?.Thread ?? reactUi.Thread;
21
+ const [editor] = LexicalComposerContext.useLexicalComposerContext();
22
+ const nodes = useThreadToNodes();
23
+ const [range, setRange] = React.useState(null);
24
+ const handleUpdateRange = React.useCallback(() => {
25
+ function getActiveRange() {
26
+ function getActiveElements() {
27
+ const activeElements2 = /* @__PURE__ */ new Set();
28
+ for (const thread of activeThreads) {
29
+ const keys = nodes.get(thread);
30
+ if (keys === void 0)
31
+ continue;
32
+ for (const key of keys) {
33
+ const element = editor.getElementByKey(key);
34
+ if (element === null)
35
+ continue;
36
+ activeElements2.add(element);
37
+ }
38
+ }
39
+ return activeElements2;
40
+ }
41
+ const activeElements = getActiveElements();
42
+ const sortedElements = Array.from(activeElements).sort(anchoredThreads.compareNodes);
43
+ if (sortedElements.length === 0)
44
+ return null;
45
+ const range3 = document.createRange();
46
+ range3.setStartBefore(sortedElements[0]);
47
+ range3.setEndAfter(sortedElements[sortedElements.length - 1]);
48
+ return range3;
49
+ }
50
+ const active = (threads ?? []).filter(
51
+ (thread) => activeThreads.includes(thread.id)
52
+ );
53
+ const range2 = getActiveRange();
54
+ if (range2 === null) {
55
+ setRange(null);
56
+ return;
57
+ }
58
+ setRange({ range: range2, threads: active });
59
+ }, [activeThreads, nodes, editor, threads]);
60
+ React.useEffect(() => {
61
+ handleUpdateRange();
62
+ }, [handleUpdateRange]);
63
+ React.useEffect(() => {
64
+ return editor.registerUpdateListener(handleUpdateRange);
65
+ }, [editor, handleUpdateRange]);
66
+ const handleEscapeKeydown = React.useCallback(() => {
67
+ if (range === null)
68
+ return false;
69
+ setRange(null);
70
+ return true;
71
+ }, [range]);
72
+ React.useEffect(() => {
73
+ return editor.registerCommand(
74
+ lexical.KEY_ESCAPE_COMMAND,
75
+ handleEscapeKeydown,
76
+ lexical.COMMAND_PRIORITY_HIGH
77
+ );
78
+ }, [editor, handleEscapeKeydown]);
79
+ const isCollapsed = useIsSelectionCollapsed();
80
+ if (range === null || isCollapsed === null || !isCollapsed)
81
+ return null;
82
+ return /* @__PURE__ */ React.createElement(FloatingThreadPortal, {
83
+ range: range.range,
84
+ container: document.body,
85
+ ...divProps
86
+ }, range.threads.map((thread) => /* @__PURE__ */ React.createElement(ThreadWrapper, {
87
+ key: thread.id,
88
+ thread,
89
+ Thread,
90
+ onEscapeKeydown: handleEscapeKeydown,
91
+ className: "lb-lexical-floating-threads-thread"
92
+ })));
93
+ }
94
+ const FLOATING_THREAD_COLLISION_PADDING = 10;
95
+ function FloatingThreadPortal(props) {
96
+ const { container, range, children, className, style, ...divProps } = props;
97
+ const {
98
+ refs: { setReference, setFloating },
99
+ strategy,
100
+ x,
101
+ y
102
+ } = reactDom.useFloating({
103
+ strategy: "absolute",
104
+ placement: "bottom",
105
+ middleware: [
106
+ reactDom.flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),
107
+ reactDom.offset(10),
108
+ reactDom.hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),
109
+ reactDom.shift({
110
+ padding: FLOATING_THREAD_COLLISION_PADDING,
111
+ limiter: reactDom.limitShift()
112
+ }),
113
+ reactDom.size({
114
+ padding: FLOATING_THREAD_COLLISION_PADDING,
115
+ apply({ availableWidth, availableHeight, elements }) {
116
+ elements.floating.style.setProperty(
117
+ "--lb-lexical-floating-threads-available-width",
118
+ `${availableWidth}px`
119
+ );
120
+ elements.floating.style.setProperty(
121
+ "--lb-lexical-floating-threads-available-height",
122
+ `${availableHeight}px`
123
+ );
124
+ }
125
+ })
126
+ ],
127
+ whileElementsMounted: (...args) => {
128
+ return reactDom.autoUpdate(...args, {
129
+ animationFrame: true
130
+ });
131
+ }
132
+ });
133
+ React.useLayoutEffect(() => {
134
+ setReference({
135
+ getBoundingClientRect: () => range.getBoundingClientRect()
136
+ });
137
+ }, [setReference, range]);
138
+ return reactDom$1.createPortal(
139
+ /* @__PURE__ */ React.createElement("div", {
140
+ ref: setFloating,
141
+ ...divProps,
142
+ style: {
143
+ ...style,
144
+ position: strategy,
145
+ top: 0,
146
+ left: 0,
147
+ transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
148
+ minWidth: "max-content"
149
+ },
150
+ className: classnames.classNames(
151
+ "lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-threads",
152
+ className
153
+ )
154
+ }, children),
155
+ container
156
+ );
157
+ }
158
+ function ThreadWrapper({
159
+ thread,
160
+ Thread,
161
+ onEscapeKeydown,
162
+ onKeyDown,
163
+ ...threadProps
164
+ }) {
165
+ const handleKeyDown = React.useCallback(
166
+ (event) => {
167
+ onKeyDown?.(event);
168
+ if (event.key === "Escape") {
169
+ onEscapeKeydown();
170
+ }
171
+ },
172
+ [onEscapeKeydown, onKeyDown]
173
+ );
174
+ return /* @__PURE__ */ React.createElement(Thread, {
175
+ thread,
176
+ onKeyDown: handleKeyDown,
177
+ ...threadProps
178
+ });
179
+ }
180
+ function useThreadToNodes() {
181
+ const threadToNodes = React.useContext(commentPluginProvider.ThreadToNodesContext);
182
+ if (threadToNodes === null) {
183
+ throw new Error(
184
+ "FloatingThreads component must be used within a LiveblocksPlugin component."
185
+ );
186
+ }
187
+ return threadToNodes;
188
+ }
189
+ function useIsSelectionCollapsed() {
190
+ const [editor] = LexicalComposerContext.useLexicalComposerContext();
191
+ const subscribe = React.useCallback(
192
+ (onStoreChange) => {
193
+ return editor.registerUpdateListener(onStoreChange);
194
+ },
195
+ [editor]
196
+ );
197
+ const getSnapshot = React.useCallback(() => {
198
+ return editor.getEditorState().read(() => {
199
+ const selection = lexical.$getSelection();
200
+ if (selection === null)
201
+ return null;
202
+ return selection.isCollapsed();
203
+ });
204
+ }, [editor]);
205
+ return index_js.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
206
+ }
207
+ function useActiveThreads() {
208
+ const activeThreads = React.useContext(commentPluginProvider.ActiveThreadsContext);
209
+ if (activeThreads === null) {
210
+ throw new Error(
211
+ "FloatingThreads component must be used within LiveblocksPlugin."
212
+ );
213
+ }
214
+ return activeThreads;
215
+ }
216
+
217
+ exports.FLOATING_THREAD_COLLISION_PADDING = FLOATING_THREAD_COLLISION_PADDING;
218
+ exports.FloatingThreads = FloatingThreads;
219
+ //# sourceMappingURL=floating-threads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floating-threads.js","sources":["../../src/comments/floating-threads.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 { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { BaseMetadata, DM, ThreadData } from \"@liveblocks/core\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport {\n $getSelection,\n COMMAND_PRIORITY_HIGH,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport React, {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n\nimport { classNames } from \"../classnames\";\nimport { compareNodes } from \"./anchored-threads\";\nimport {\n ActiveThreadsContext,\n type ThreadToNodesMap,\n} from \"./comment-plugin-provider\";\nimport { ThreadToNodesContext } from \"./comment-plugin-provider\";\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\nexport function FloatingThreads({\n threads,\n components,\n ...divProps\n}: FloatingThreadsProps) {\n const activeThreads = useActiveThreads();\n\n const Thread = components?.Thread ?? DefaultThread;\n\n const [editor] = useLexicalComposerContext();\n const nodes = useThreadToNodes(); // A map of thread ids to a set of thread mark nodes associated with the thread\n\n const [range, setRange] = useState<{\n range: Range;\n threads: ThreadData[];\n } | null>(null);\n\n const handleUpdateRange = useCallback(() => {\n function getActiveRange(): Range | null {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = nodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n const sortedElements = Array.from(activeElements).sort(compareNodes);\n if (sortedElements.length === 0) return null;\n\n const range = document.createRange();\n range.setStartBefore(sortedElements[0]);\n range.setEndAfter(sortedElements[sortedElements.length - 1]);\n\n return range;\n }\n\n const active = (threads ?? []).filter((thread) =>\n activeThreads.includes(thread.id)\n );\n\n const range = getActiveRange();\n if (range === null) {\n setRange(null);\n return;\n }\n\n setRange({ range, threads: active });\n }, [activeThreads, nodes, editor, threads]);\n\n useEffect(() => {\n handleUpdateRange();\n }, [handleUpdateRange]);\n\n useEffect(() => {\n return editor.registerUpdateListener(handleUpdateRange);\n }, [editor, handleUpdateRange]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (range === null) return false;\n setRange(null);\n return true;\n }, [range]);\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n handleEscapeKeydown,\n COMMAND_PRIORITY_HIGH\n );\n }, [editor, handleEscapeKeydown]);\n\n const isCollapsed = useIsSelectionCollapsed();\n\n if (range === null || isCollapsed === null || !isCollapsed) return null;\n\n return (\n <FloatingThreadPortal\n range={range.range}\n container={document.body}\n {...divProps}\n >\n {range.threads.map((thread) => (\n <ThreadWrapper\n key={thread.id}\n thread={thread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-lexical-floating-threads-thread\"\n />\n ))}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n range: Range;\n container: HTMLElement;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal(props: FloatingThreadPortalProps) {\n const { container, range, children, className, style, ...divProps } = props;\n\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-lexical-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-lexical-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 useLayoutEffect(() => {\n setReference({\n getBoundingClientRect: () => range.getBoundingClientRect(),\n });\n }, [setReference, range]);\n\n return createPortal(\n <div\n ref={setFloating}\n {...divProps}\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-lexical-floating lb-lexical-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\nfunction useThreadToNodes(): ThreadToNodesMap {\n const threadToNodes = useContext(ThreadToNodesContext);\n if (threadToNodes === null) {\n throw new Error(\n \"FloatingThreads component must be used within a LiveblocksPlugin component.\"\n );\n }\n return threadToNodes;\n}\n\nfunction useIsSelectionCollapsed(): boolean | null {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerUpdateListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (selection === null) return null;\n return selection.isCollapsed();\n });\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nfunction useActiveThreads() {\n const activeThreads = useContext(ActiveThreadsContext);\n if (activeThreads === null) {\n throw new Error(\n \"FloatingThreads component must be used within LiveblocksPlugin.\"\n );\n }\n\n return activeThreads;\n}\n"],"names":["DefaultThread","useLexicalComposerContext","useState","useCallback","activeElements","compareNodes","range","useEffect","KEY_ESCAPE_COMMAND","COMMAND_PRIORITY_HIGH","useFloating","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","createPortal","classNames","useContext","ThreadToNodesContext","$getSelection","useSyncExternalStore","ActiveThreadsContext"],"mappings":"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"}
@@ -0,0 +1,216 @@
1
+ import { useFloating, flip, offset, hide, shift, limitShift, size, autoUpdate } from '@floating-ui/react-dom';
2
+ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
3
+ import { Thread } from '@liveblocks/react-ui';
4
+ import { KEY_ESCAPE_COMMAND, COMMAND_PRIORITY_HIGH, $getSelection } from 'lexical';
5
+ import React__default, { useState, useCallback, useEffect, useLayoutEffect, useContext } from 'react';
6
+ import { createPortal } from 'react-dom';
7
+ import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js';
8
+ import { classNames } from '../classnames.mjs';
9
+ import { compareNodes } from './anchored-threads.mjs';
10
+ import { ThreadToNodesContext, ActiveThreadsContext } from './comment-plugin-provider.mjs';
11
+
12
+ function FloatingThreads({
13
+ threads,
14
+ components,
15
+ ...divProps
16
+ }) {
17
+ const activeThreads = useActiveThreads();
18
+ const Thread$1 = components?.Thread ?? Thread;
19
+ const [editor] = useLexicalComposerContext();
20
+ const nodes = useThreadToNodes();
21
+ const [range, setRange] = useState(null);
22
+ const handleUpdateRange = useCallback(() => {
23
+ function getActiveRange() {
24
+ function getActiveElements() {
25
+ const activeElements2 = /* @__PURE__ */ new Set();
26
+ for (const thread of activeThreads) {
27
+ const keys = nodes.get(thread);
28
+ if (keys === void 0)
29
+ continue;
30
+ for (const key of keys) {
31
+ const element = editor.getElementByKey(key);
32
+ if (element === null)
33
+ continue;
34
+ activeElements2.add(element);
35
+ }
36
+ }
37
+ return activeElements2;
38
+ }
39
+ const activeElements = getActiveElements();
40
+ const sortedElements = Array.from(activeElements).sort(compareNodes);
41
+ if (sortedElements.length === 0)
42
+ return null;
43
+ const range3 = document.createRange();
44
+ range3.setStartBefore(sortedElements[0]);
45
+ range3.setEndAfter(sortedElements[sortedElements.length - 1]);
46
+ return range3;
47
+ }
48
+ const active = (threads ?? []).filter(
49
+ (thread) => activeThreads.includes(thread.id)
50
+ );
51
+ const range2 = getActiveRange();
52
+ if (range2 === null) {
53
+ setRange(null);
54
+ return;
55
+ }
56
+ setRange({ range: range2, threads: active });
57
+ }, [activeThreads, nodes, editor, threads]);
58
+ useEffect(() => {
59
+ handleUpdateRange();
60
+ }, [handleUpdateRange]);
61
+ useEffect(() => {
62
+ return editor.registerUpdateListener(handleUpdateRange);
63
+ }, [editor, handleUpdateRange]);
64
+ const handleEscapeKeydown = useCallback(() => {
65
+ if (range === null)
66
+ return false;
67
+ setRange(null);
68
+ return true;
69
+ }, [range]);
70
+ useEffect(() => {
71
+ return editor.registerCommand(
72
+ KEY_ESCAPE_COMMAND,
73
+ handleEscapeKeydown,
74
+ COMMAND_PRIORITY_HIGH
75
+ );
76
+ }, [editor, handleEscapeKeydown]);
77
+ const isCollapsed = useIsSelectionCollapsed();
78
+ if (range === null || isCollapsed === null || !isCollapsed)
79
+ return null;
80
+ return /* @__PURE__ */ React__default.createElement(FloatingThreadPortal, {
81
+ range: range.range,
82
+ container: document.body,
83
+ ...divProps
84
+ }, range.threads.map((thread) => /* @__PURE__ */ React__default.createElement(ThreadWrapper, {
85
+ key: thread.id,
86
+ thread,
87
+ Thread: Thread$1,
88
+ onEscapeKeydown: handleEscapeKeydown,
89
+ className: "lb-lexical-floating-threads-thread"
90
+ })));
91
+ }
92
+ const FLOATING_THREAD_COLLISION_PADDING = 10;
93
+ function FloatingThreadPortal(props) {
94
+ const { container, range, children, className, style, ...divProps } = props;
95
+ const {
96
+ refs: { setReference, setFloating },
97
+ strategy,
98
+ x,
99
+ y
100
+ } = useFloating({
101
+ strategy: "absolute",
102
+ placement: "bottom",
103
+ middleware: [
104
+ flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),
105
+ offset(10),
106
+ hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),
107
+ shift({
108
+ padding: FLOATING_THREAD_COLLISION_PADDING,
109
+ limiter: limitShift()
110
+ }),
111
+ size({
112
+ padding: FLOATING_THREAD_COLLISION_PADDING,
113
+ apply({ availableWidth, availableHeight, elements }) {
114
+ elements.floating.style.setProperty(
115
+ "--lb-lexical-floating-threads-available-width",
116
+ `${availableWidth}px`
117
+ );
118
+ elements.floating.style.setProperty(
119
+ "--lb-lexical-floating-threads-available-height",
120
+ `${availableHeight}px`
121
+ );
122
+ }
123
+ })
124
+ ],
125
+ whileElementsMounted: (...args) => {
126
+ return autoUpdate(...args, {
127
+ animationFrame: true
128
+ });
129
+ }
130
+ });
131
+ useLayoutEffect(() => {
132
+ setReference({
133
+ getBoundingClientRect: () => range.getBoundingClientRect()
134
+ });
135
+ }, [setReference, range]);
136
+ return createPortal(
137
+ /* @__PURE__ */ React__default.createElement("div", {
138
+ ref: setFloating,
139
+ ...divProps,
140
+ style: {
141
+ ...style,
142
+ position: strategy,
143
+ top: 0,
144
+ left: 0,
145
+ transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
146
+ minWidth: "max-content"
147
+ },
148
+ className: classNames(
149
+ "lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-threads",
150
+ className
151
+ )
152
+ }, children),
153
+ container
154
+ );
155
+ }
156
+ function ThreadWrapper({
157
+ thread,
158
+ Thread,
159
+ onEscapeKeydown,
160
+ onKeyDown,
161
+ ...threadProps
162
+ }) {
163
+ const handleKeyDown = useCallback(
164
+ (event) => {
165
+ onKeyDown?.(event);
166
+ if (event.key === "Escape") {
167
+ onEscapeKeydown();
168
+ }
169
+ },
170
+ [onEscapeKeydown, onKeyDown]
171
+ );
172
+ return /* @__PURE__ */ React__default.createElement(Thread, {
173
+ thread,
174
+ onKeyDown: handleKeyDown,
175
+ ...threadProps
176
+ });
177
+ }
178
+ function useThreadToNodes() {
179
+ const threadToNodes = useContext(ThreadToNodesContext);
180
+ if (threadToNodes === null) {
181
+ throw new Error(
182
+ "FloatingThreads component must be used within a LiveblocksPlugin component."
183
+ );
184
+ }
185
+ return threadToNodes;
186
+ }
187
+ function useIsSelectionCollapsed() {
188
+ const [editor] = useLexicalComposerContext();
189
+ const subscribe = useCallback(
190
+ (onStoreChange) => {
191
+ return editor.registerUpdateListener(onStoreChange);
192
+ },
193
+ [editor]
194
+ );
195
+ const getSnapshot = useCallback(() => {
196
+ return editor.getEditorState().read(() => {
197
+ const selection = $getSelection();
198
+ if (selection === null)
199
+ return null;
200
+ return selection.isCollapsed();
201
+ });
202
+ }, [editor]);
203
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
204
+ }
205
+ function useActiveThreads() {
206
+ const activeThreads = useContext(ActiveThreadsContext);
207
+ if (activeThreads === null) {
208
+ throw new Error(
209
+ "FloatingThreads component must be used within LiveblocksPlugin."
210
+ );
211
+ }
212
+ return activeThreads;
213
+ }
214
+
215
+ export { FLOATING_THREAD_COLLISION_PADDING, FloatingThreads };
216
+ //# sourceMappingURL=floating-threads.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floating-threads.mjs","sources":["../../src/comments/floating-threads.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 { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { BaseMetadata, DM, ThreadData } from \"@liveblocks/core\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport {\n $getSelection,\n COMMAND_PRIORITY_HIGH,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport React, {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n\nimport { classNames } from \"../classnames\";\nimport { compareNodes } from \"./anchored-threads\";\nimport {\n ActiveThreadsContext,\n type ThreadToNodesMap,\n} from \"./comment-plugin-provider\";\nimport { ThreadToNodesContext } from \"./comment-plugin-provider\";\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\nexport function FloatingThreads({\n threads,\n components,\n ...divProps\n}: FloatingThreadsProps) {\n const activeThreads = useActiveThreads();\n\n const Thread = components?.Thread ?? DefaultThread;\n\n const [editor] = useLexicalComposerContext();\n const nodes = useThreadToNodes(); // A map of thread ids to a set of thread mark nodes associated with the thread\n\n const [range, setRange] = useState<{\n range: Range;\n threads: ThreadData[];\n } | null>(null);\n\n const handleUpdateRange = useCallback(() => {\n function getActiveRange(): Range | null {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = nodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n const sortedElements = Array.from(activeElements).sort(compareNodes);\n if (sortedElements.length === 0) return null;\n\n const range = document.createRange();\n range.setStartBefore(sortedElements[0]);\n range.setEndAfter(sortedElements[sortedElements.length - 1]);\n\n return range;\n }\n\n const active = (threads ?? []).filter((thread) =>\n activeThreads.includes(thread.id)\n );\n\n const range = getActiveRange();\n if (range === null) {\n setRange(null);\n return;\n }\n\n setRange({ range, threads: active });\n }, [activeThreads, nodes, editor, threads]);\n\n useEffect(() => {\n handleUpdateRange();\n }, [handleUpdateRange]);\n\n useEffect(() => {\n return editor.registerUpdateListener(handleUpdateRange);\n }, [editor, handleUpdateRange]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (range === null) return false;\n setRange(null);\n return true;\n }, [range]);\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n handleEscapeKeydown,\n COMMAND_PRIORITY_HIGH\n );\n }, [editor, handleEscapeKeydown]);\n\n const isCollapsed = useIsSelectionCollapsed();\n\n if (range === null || isCollapsed === null || !isCollapsed) return null;\n\n return (\n <FloatingThreadPortal\n range={range.range}\n container={document.body}\n {...divProps}\n >\n {range.threads.map((thread) => (\n <ThreadWrapper\n key={thread.id}\n thread={thread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-lexical-floating-threads-thread\"\n />\n ))}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n range: Range;\n container: HTMLElement;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal(props: FloatingThreadPortalProps) {\n const { container, range, children, className, style, ...divProps } = props;\n\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-lexical-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-lexical-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 useLayoutEffect(() => {\n setReference({\n getBoundingClientRect: () => range.getBoundingClientRect(),\n });\n }, [setReference, range]);\n\n return createPortal(\n <div\n ref={setFloating}\n {...divProps}\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-lexical-floating lb-lexical-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\nfunction useThreadToNodes(): ThreadToNodesMap {\n const threadToNodes = useContext(ThreadToNodesContext);\n if (threadToNodes === null) {\n throw new Error(\n \"FloatingThreads component must be used within a LiveblocksPlugin component.\"\n );\n }\n return threadToNodes;\n}\n\nfunction useIsSelectionCollapsed(): boolean | null {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerUpdateListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (selection === null) return null;\n return selection.isCollapsed();\n });\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nfunction useActiveThreads() {\n const activeThreads = useContext(ActiveThreadsContext);\n if (activeThreads === null) {\n throw new Error(\n \"FloatingThreads component must be used within LiveblocksPlugin.\"\n );\n }\n\n return activeThreads;\n}\n"],"names":["Thread","DefaultThread","activeElements","range","React"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,10 +1,25 @@
1
- import { BaseMetadata, DM } from '@liveblocks/core';
2
- import { ComposerProps } from '@liveblocks/react-ui';
1
+ import { BaseMetadata, DM, ThreadData } from '@liveblocks/core';
2
+ import { ThreadProps, ComposerProps } from '@liveblocks/react-ui';
3
+ import React, { ComponentPropsWithoutRef, ComponentType, HTMLAttributes } from 'react';
3
4
  import * as lexical from 'lexical';
4
5
  import { LexicalCommand } from 'lexical';
5
- import React from 'react';
6
6
  import { InitialConfigType } from '@lexical/react/LexicalComposer';
7
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
+ declare function AnchoredThreads({ threads, components, className, style, ...divProps }: AnchoredThreadsProps): React.JSX.Element | undefined;
22
+
8
23
  /**
9
24
  * Returns whether the associated thread annotation for the given thread id is selected or not in the editor.
10
25
  * @param threadId The id of the thread to check if the associated annotation is selected or not.
@@ -45,6 +60,21 @@ declare type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<ComposerP
45
60
  */
46
61
  declare const FloatingComposer: React.ForwardRefExoticComponent<FloatingComposerProps<BaseMetadata> & React.RefAttributes<HTMLFormElement>>;
47
62
 
63
+ declare type ThreadPanelComponents = {
64
+ Thread: ComponentType<ThreadProps>;
65
+ };
66
+ interface FloatingThreadsProps<M extends BaseMetadata = DM> extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
67
+ /**
68
+ * The threads to display.
69
+ */
70
+ threads: ThreadData<M>[];
71
+ /**
72
+ * Override the component's components.
73
+ */
74
+ components?: Partial<ThreadPanelComponents>;
75
+ }
76
+ declare function FloatingThreads({ threads, components, ...divProps }: FloatingThreadsProps): React.JSX.Element | null;
77
+
48
78
  /**
49
79
  * Function that takes a Lexical editor config and modifies it to add the necessary
50
80
  * `nodes` and `theme` to make `LiveblocksPlugin` works correctly.
@@ -140,4 +170,4 @@ declare type LiveblocksPluginProps = {
140
170
  */
141
171
  declare const LiveblocksPlugin: ({ children, }: LiveblocksPluginProps) => JSX.Element;
142
172
 
143
- export { FloatingComposer, LiveblocksPlugin, OPEN_FLOATING_COMPOSER_COMMAND, liveblocksConfig, useEditorStatus, useIsThreadActive };
173
+ export { AnchoredThreads, AnchoredThreadsProps, FloatingComposer, FloatingComposerProps, FloatingThreads, FloatingThreadsProps, LiveblocksPlugin, OPEN_FLOATING_COMPOSER_COMMAND, liveblocksConfig, useEditorStatus, useIsThreadActive };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,25 @@
1
- import { BaseMetadata, DM } from '@liveblocks/core';
2
- import { ComposerProps } from '@liveblocks/react-ui';
1
+ import { BaseMetadata, DM, ThreadData } from '@liveblocks/core';
2
+ import { ThreadProps, ComposerProps } from '@liveblocks/react-ui';
3
+ import React, { ComponentPropsWithoutRef, ComponentType, HTMLAttributes } from 'react';
3
4
  import * as lexical from 'lexical';
4
5
  import { LexicalCommand } from 'lexical';
5
- import React from 'react';
6
6
  import { InitialConfigType } from '@lexical/react/LexicalComposer';
7
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
+ declare function AnchoredThreads({ threads, components, className, style, ...divProps }: AnchoredThreadsProps): React.JSX.Element | undefined;
22
+
8
23
  /**
9
24
  * Returns whether the associated thread annotation for the given thread id is selected or not in the editor.
10
25
  * @param threadId The id of the thread to check if the associated annotation is selected or not.
@@ -45,6 +60,21 @@ declare type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<ComposerP
45
60
  */
46
61
  declare const FloatingComposer: React.ForwardRefExoticComponent<FloatingComposerProps<BaseMetadata> & React.RefAttributes<HTMLFormElement>>;
47
62
 
63
+ declare type ThreadPanelComponents = {
64
+ Thread: ComponentType<ThreadProps>;
65
+ };
66
+ interface FloatingThreadsProps<M extends BaseMetadata = DM> extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
67
+ /**
68
+ * The threads to display.
69
+ */
70
+ threads: ThreadData<M>[];
71
+ /**
72
+ * Override the component's components.
73
+ */
74
+ components?: Partial<ThreadPanelComponents>;
75
+ }
76
+ declare function FloatingThreads({ threads, components, ...divProps }: FloatingThreadsProps): React.JSX.Element | null;
77
+
48
78
  /**
49
79
  * Function that takes a Lexical editor config and modifies it to add the necessary
50
80
  * `nodes` and `theme` to make `LiveblocksPlugin` works correctly.
@@ -140,4 +170,4 @@ declare type LiveblocksPluginProps = {
140
170
  */
141
171
  declare const LiveblocksPlugin: ({ children, }: LiveblocksPluginProps) => JSX.Element;
142
172
 
143
- export { FloatingComposer, LiveblocksPlugin, OPEN_FLOATING_COMPOSER_COMMAND, liveblocksConfig, useEditorStatus, useIsThreadActive };
173
+ export { AnchoredThreads, AnchoredThreadsProps, FloatingComposer, FloatingComposerProps, FloatingThreads, FloatingThreadsProps, LiveblocksPlugin, OPEN_FLOATING_COMPOSER_COMMAND, liveblocksConfig, useEditorStatus, useIsThreadActive };
package/dist/index.js CHANGED
@@ -2,16 +2,20 @@
2
2
 
3
3
  var core = require('@liveblocks/core');
4
4
  var version = require('./version.js');
5
+ var anchoredThreads = require('./comments/anchored-threads.js');
5
6
  var commentPluginProvider = require('./comments/comment-plugin-provider.js');
6
7
  var floatingComposer = require('./comments/floating-composer.js');
8
+ var floatingThreads = require('./comments/floating-threads.js');
7
9
  var liveblocksConfig = require('./liveblocks-config.js');
8
10
  var liveblocksPluginProvider = require('./liveblocks-plugin-provider.js');
9
11
 
10
12
  core.detectDupes(version.PKG_NAME, version.PKG_VERSION, version.PKG_FORMAT);
11
13
 
14
+ exports.AnchoredThreads = anchoredThreads.AnchoredThreads;
12
15
  exports.useIsThreadActive = commentPluginProvider.useIsThreadActive;
13
16
  exports.FloatingComposer = floatingComposer.FloatingComposer;
14
17
  exports.OPEN_FLOATING_COMPOSER_COMMAND = floatingComposer.OPEN_FLOATING_COMPOSER_COMMAND;
18
+ exports.FloatingThreads = floatingThreads.FloatingThreads;
15
19
  exports.liveblocksConfig = liveblocksConfig.liveblocksConfig;
16
20
  exports.LiveblocksPlugin = liveblocksPluginProvider.LiveblocksPlugin;
17
21
  exports.useEditorStatus = liveblocksPluginProvider.useEditorStatus;
package/dist/index.js.map CHANGED
@@ -1 +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 { useIsThreadActive } from \"./comments/comment-plugin-provider\";\nexport {\n FloatingComposer,\n OPEN_FLOATING_COMPOSER_COMMAND,\n} from \"./comments/floating-composer\";\nexport { liveblocksConfig } from \"./liveblocks-config\";\nexport {\n LiveblocksPlugin,\n useEditorStatus,\n} from \"./liveblocks-plugin-provider\";\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;;;AAIAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;;;;;"}
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 type { AnchoredThreadsProps } from \"./comments/anchored-threads\";\nexport { AnchoredThreads } from \"./comments/anchored-threads\";\nexport { useIsThreadActive } from \"./comments/comment-plugin-provider\";\nexport type { FloatingComposerProps } from \"./comments/floating-composer\";\nexport {\n FloatingComposer,\n OPEN_FLOATING_COMPOSER_COMMAND,\n} from \"./comments/floating-composer\";\nexport type { FloatingThreadsProps } from \"./comments/floating-threads\";\nexport { FloatingThreads } from \"./comments/floating-threads\";\nexport { liveblocksConfig } from \"./liveblocks-config\";\nexport {\n LiveblocksPlugin,\n useEditorStatus,\n} from \"./liveblocks-plugin-provider\";\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;;;;;AAIAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;;;;;;;"}
package/dist/index.mjs CHANGED
@@ -1,7 +1,9 @@
1
1
  import { detectDupes } from '@liveblocks/core';
2
2
  import { PKG_NAME, PKG_VERSION, PKG_FORMAT } from './version.mjs';
3
+ export { AnchoredThreads } from './comments/anchored-threads.mjs';
3
4
  export { useIsThreadActive } from './comments/comment-plugin-provider.mjs';
4
5
  export { FloatingComposer, OPEN_FLOATING_COMPOSER_COMMAND } from './comments/floating-composer.mjs';
6
+ export { FloatingThreads } from './comments/floating-threads.mjs';
5
7
  export { liveblocksConfig } from './liveblocks-config.mjs';
6
8
  export { LiveblocksPlugin, useEditorStatus } from './liveblocks-plugin-provider.mjs';
7
9
 
@@ -1 +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 { useIsThreadActive } from \"./comments/comment-plugin-provider\";\nexport {\n FloatingComposer,\n OPEN_FLOATING_COMPOSER_COMMAND,\n} from \"./comments/floating-composer\";\nexport { liveblocksConfig } from \"./liveblocks-config\";\nexport {\n LiveblocksPlugin,\n useEditorStatus,\n} from \"./liveblocks-plugin-provider\";\n"],"names":[],"mappings":";;;;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
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 type { AnchoredThreadsProps } from \"./comments/anchored-threads\";\nexport { AnchoredThreads } from \"./comments/anchored-threads\";\nexport { useIsThreadActive } from \"./comments/comment-plugin-provider\";\nexport type { FloatingComposerProps } from \"./comments/floating-composer\";\nexport {\n FloatingComposer,\n OPEN_FLOATING_COMPOSER_COMMAND,\n} from \"./comments/floating-composer\";\nexport type { FloatingThreadsProps } from \"./comments/floating-threads\";\nexport { FloatingThreads } from \"./comments/floating-threads\";\nexport { liveblocksConfig } from \"./liveblocks-config\";\nexport {\n LiveblocksPlugin,\n useEditorStatus,\n} from \"./liveblocks-plugin-provider\";\n"],"names":[],"mappings":";;;;;;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}