@liveblocks/react-lexical 1.12.0-lexical3

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 (78) hide show
  1. package/dist/active-selection.js +143 -0
  2. package/dist/active-selection.js.map +1 -0
  3. package/dist/active-selection.mjs +123 -0
  4. package/dist/active-selection.mjs.map +1 -0
  5. package/dist/comments/ThreadPanel.js +26 -0
  6. package/dist/comments/ThreadPanel.js.map +1 -0
  7. package/dist/comments/ThreadPanel.mjs +24 -0
  8. package/dist/comments/ThreadPanel.mjs.map +1 -0
  9. package/dist/comments/comment-plugin-provider.js +322 -0
  10. package/dist/comments/comment-plugin-provider.js.map +1 -0
  11. package/dist/comments/comment-plugin-provider.mjs +299 -0
  12. package/dist/comments/comment-plugin-provider.mjs.map +1 -0
  13. package/dist/comments/floating-composer.js +34 -0
  14. package/dist/comments/floating-composer.js.map +1 -0
  15. package/dist/comments/floating-composer.mjs +32 -0
  16. package/dist/comments/floating-composer.mjs.map +1 -0
  17. package/dist/comments/get-thread-mark-ids.js +23 -0
  18. package/dist/comments/get-thread-mark-ids.js.map +1 -0
  19. package/dist/comments/get-thread-mark-ids.mjs +21 -0
  20. package/dist/comments/get-thread-mark-ids.mjs.map +1 -0
  21. package/dist/comments/thread-mark-node.js +138 -0
  22. package/dist/comments/thread-mark-node.js.map +1 -0
  23. package/dist/comments/thread-mark-node.mjs +134 -0
  24. package/dist/comments/thread-mark-node.mjs.map +1 -0
  25. package/dist/comments/unwrap-thread-mark-node.js +19 -0
  26. package/dist/comments/unwrap-thread-mark-node.js.map +1 -0
  27. package/dist/comments/unwrap-thread-mark-node.mjs +17 -0
  28. package/dist/comments/unwrap-thread-mark-node.mjs.map +1 -0
  29. package/dist/comments/wrap-selection-in-thread-mark-node.js +63 -0
  30. package/dist/comments/wrap-selection-in-thread-mark-node.js.map +1 -0
  31. package/dist/comments/wrap-selection-in-thread-mark-node.mjs +61 -0
  32. package/dist/comments/wrap-selection-in-thread-mark-node.mjs.map +1 -0
  33. package/dist/floating-selection-container.js +157 -0
  34. package/dist/floating-selection-container.js.map +1 -0
  35. package/dist/floating-selection-container.mjs +155 -0
  36. package/dist/floating-selection-container.mjs.map +1 -0
  37. package/dist/index.d.ts +61 -0
  38. package/dist/index.js +20 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/index.mjs +11 -0
  41. package/dist/index.mjs.map +1 -0
  42. package/dist/liveblocks-config.js +89 -0
  43. package/dist/liveblocks-config.js.map +1 -0
  44. package/dist/liveblocks-config.mjs +67 -0
  45. package/dist/liveblocks-config.mjs.map +1 -0
  46. package/dist/liveblocks-plugin-provider.js +79 -0
  47. package/dist/liveblocks-plugin-provider.js.map +1 -0
  48. package/dist/liveblocks-plugin-provider.mjs +76 -0
  49. package/dist/liveblocks-plugin-provider.mjs.map +1 -0
  50. package/dist/mentions/avatar.js +49 -0
  51. package/dist/mentions/avatar.js.map +1 -0
  52. package/dist/mentions/avatar.mjs +47 -0
  53. package/dist/mentions/avatar.mjs.map +1 -0
  54. package/dist/mentions/mention-component.js +63 -0
  55. package/dist/mentions/mention-component.js.map +1 -0
  56. package/dist/mentions/mention-component.mjs +60 -0
  57. package/dist/mentions/mention-component.mjs.map +1 -0
  58. package/dist/mentions/mention-node.js +105 -0
  59. package/dist/mentions/mention-node.js.map +1 -0
  60. package/dist/mentions/mention-node.mjs +84 -0
  61. package/dist/mentions/mention-node.mjs.map +1 -0
  62. package/dist/mentions/mention-plugin.js +291 -0
  63. package/dist/mentions/mention-plugin.js.map +1 -0
  64. package/dist/mentions/mention-plugin.mjs +284 -0
  65. package/dist/mentions/mention-plugin.mjs.map +1 -0
  66. package/dist/mentions/suggestions.js +161 -0
  67. package/dist/mentions/suggestions.js.map +1 -0
  68. package/dist/mentions/suggestions.mjs +158 -0
  69. package/dist/mentions/suggestions.mjs.map +1 -0
  70. package/dist/mentions/user.js +21 -0
  71. package/dist/mentions/user.js.map +1 -0
  72. package/dist/mentions/user.mjs +19 -0
  73. package/dist/mentions/user.mjs.map +1 -0
  74. package/dist/version.js +10 -0
  75. package/dist/version.js.map +1 -0
  76. package/dist/version.mjs +6 -0
  77. package/dist/version.mjs.map +1 -0
  78. package/package.json +102 -0
@@ -0,0 +1,157 @@
1
+ 'use strict';
2
+
3
+ var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
4
+ var lexical = require('lexical');
5
+ var React = require('react');
6
+ var index_js = require('use-sync-external-store/shim/index.js');
7
+ var reactDom = require('react-dom');
8
+ var selection = require('@lexical/selection');
9
+ var commentPluginProvider = require('./comments/comment-plugin-provider.js');
10
+
11
+ const FloatingSelectionContainer = React.forwardRef(function FloatingSelectionContainer2(props, forwardedRef) {
12
+ const [editor] = LexicalComposerContext.useLexicalComposerContext();
13
+ const selection = useSelection();
14
+ if (selection === null)
15
+ return null;
16
+ if (selection.isCollapsed())
17
+ return null;
18
+ const info = editor.getEditorState().read(() => {
19
+ return {
20
+ anchor: {
21
+ node: selection.anchor.getNode(),
22
+ offset: selection.anchor.offset
23
+ },
24
+ focus: {
25
+ node: selection.focus.getNode(),
26
+ offset: selection.focus.offset
27
+ }
28
+ };
29
+ });
30
+ const root = editor.getRootElement();
31
+ if (root === null)
32
+ return null;
33
+ const rootContainer = root.parentElement;
34
+ if (rootContainer === null)
35
+ return null;
36
+ return reactDom.createPortal(
37
+ /* @__PURE__ */ React.createElement(FloatingSelectionContainerImpl, {
38
+ ...props,
39
+ selection: info,
40
+ ref: forwardedRef
41
+ }),
42
+ rootContainer
43
+ );
44
+ });
45
+ const FloatingSelectionContainerImpl = React.forwardRef(function FloatingSelectionContainer3(props, forwardedRef) {
46
+ const {
47
+ children,
48
+ selection: selection$1,
49
+ sideOffset = 0,
50
+ alignOffset = 0,
51
+ collisionPadding = 0
52
+ } = props;
53
+ const hideFloatingComposer = commentPluginProvider.useHideFloatingComposer();
54
+ const containerRef = React.useRef(null);
55
+ const divRef = React.useRef(null);
56
+ const [editor] = LexicalComposerContext.useLexicalComposerContext();
57
+ React.useImperativeHandle(
58
+ forwardedRef,
59
+ () => divRef.current
60
+ );
61
+ React.useEffect(() => {
62
+ return editor.registerUpdateListener(({ editorState: state, tags }) => {
63
+ if (tags.has("collaboration"))
64
+ return;
65
+ state.read(() => hideFloatingComposer());
66
+ });
67
+ }, [editor, hideFloatingComposer]);
68
+ React.useLayoutEffect(() => {
69
+ const content = divRef.current;
70
+ if (content === null)
71
+ return;
72
+ const parent = containerRef.current;
73
+ if (parent === null)
74
+ return;
75
+ function positionContent() {
76
+ const content2 = divRef.current;
77
+ if (content2 === null)
78
+ return;
79
+ const parent2 = content2.parentElement;
80
+ if (parent2 === null)
81
+ return;
82
+ const range = selection.createDOMRange(
83
+ editor,
84
+ selection$1.anchor.node,
85
+ selection$1.anchor.offset,
86
+ selection$1.focus.node,
87
+ selection$1.focus.offset
88
+ );
89
+ if (range === null)
90
+ return;
91
+ const rect = range.getBoundingClientRect();
92
+ let left = rect.left - parent2.getBoundingClientRect().left;
93
+ let top = rect.bottom - parent2.getBoundingClientRect().top;
94
+ left += alignOffset;
95
+ const width = content2.getBoundingClientRect().width;
96
+ left = left + rect.width / 2 - width / 2;
97
+ if (left < collisionPadding) {
98
+ left = collisionPadding;
99
+ } else if (left + width > parent2.getBoundingClientRect().right - parent2.getBoundingClientRect().left - collisionPadding) {
100
+ left = parent2.getBoundingClientRect().right - parent2.getBoundingClientRect().left - width - collisionPadding;
101
+ }
102
+ top += sideOffset;
103
+ const height = content2.getBoundingClientRect().height;
104
+ if (top + height > parent2.getBoundingClientRect().height - parent2.getBoundingClientRect().top + collisionPadding) {
105
+ top = rect.top - parent2.getBoundingClientRect().top - height;
106
+ top -= sideOffset;
107
+ }
108
+ content2.style.left = `${left}px`;
109
+ content2.style.top = `${top}px`;
110
+ }
111
+ const observer = new ResizeObserver(positionContent);
112
+ observer.observe(parent);
113
+ const unsubscribeFromUpdates = editor.registerUpdateListener(positionContent);
114
+ return () => {
115
+ observer.disconnect();
116
+ unsubscribeFromUpdates();
117
+ };
118
+ }, [selection$1, editor]);
119
+ return /* @__PURE__ */ React.createElement("div", {
120
+ ref: containerRef,
121
+ style: {
122
+ position: "absolute",
123
+ top: 0,
124
+ left: 0,
125
+ width: "100%",
126
+ height: "100%",
127
+ pointerEvents: "none"
128
+ }
129
+ }, /* @__PURE__ */ React.createElement("div", {
130
+ ref: divRef,
131
+ style: {
132
+ position: "absolute",
133
+ pointerEvents: "auto"
134
+ }
135
+ }, children));
136
+ });
137
+ function useSelection() {
138
+ const [editor] = LexicalComposerContext.useLexicalComposerContext();
139
+ const subscribe = React.useCallback(
140
+ (onStoreChange) => {
141
+ return editor.registerUpdateListener(onStoreChange);
142
+ },
143
+ [editor]
144
+ );
145
+ const getSnapshot = React.useCallback(() => {
146
+ return editor.getEditorState().read(() => {
147
+ const selection = lexical.$getSelection();
148
+ if (!lexical.$isRangeSelection(selection))
149
+ return null;
150
+ return selection;
151
+ });
152
+ }, [editor]);
153
+ return index_js.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
154
+ }
155
+
156
+ exports.FloatingSelectionContainer = FloatingSelectionContainer;
157
+ //# sourceMappingURL=floating-selection-container.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floating-selection-container.js","sources":["../src/floating-selection-container.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n RangeSelection,\n $getSelection,\n $isRangeSelection,\n LexicalNode,\n} from \"lexical\";\nimport React, {\n forwardRef,\n PropsWithChildren,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport { createPortal } from \"react-dom\";\nimport { createDOMRange } from \"@lexical/selection\";\nimport { useHideFloatingComposer } from \"./comments/comment-plugin-provider\";\n\nexport interface FloatingSelectionContainerProps {\n sideOffset?: number;\n alignOffset?: number;\n collisionPadding?: number;\n}\n\nexport const FloatingSelectionContainer = forwardRef<\n HTMLDivElement | null,\n PropsWithChildren<FloatingSelectionContainerProps>\n>(function FloatingSelectionContainer(props, forwardedRef) {\n const [editor] = useLexicalComposerContext();\n const selection = useSelection();\n\n if (selection === null) return null;\n\n if (selection.isCollapsed()) return null;\n\n const info = editor.getEditorState().read(() => {\n return {\n anchor: {\n node: selection.anchor.getNode(),\n offset: selection.anchor.offset,\n },\n focus: {\n node: selection.focus.getNode(),\n offset: selection.focus.offset,\n },\n };\n });\n\n const root = editor.getRootElement();\n if (root === null) return null;\n\n const rootContainer = root.parentElement;\n if (rootContainer === null) return null;\n\n return createPortal(\n <FloatingSelectionContainerImpl\n {...props}\n selection={info}\n ref={forwardedRef}\n />,\n rootContainer\n );\n});\n\ntype SelectionInfo = {\n anchor: {\n node: LexicalNode;\n offset: number;\n };\n focus: {\n node: LexicalNode;\n offset: number;\n };\n};\n\ninterface FloatingSelectionContainerImplProps\n extends FloatingSelectionContainerProps {\n selection: SelectionInfo;\n}\n\nconst FloatingSelectionContainerImpl = forwardRef<\n HTMLDivElement | null,\n PropsWithChildren<FloatingSelectionContainerImplProps>\n>(function FloatingSelectionContainer(props, forwardedRef) {\n const {\n children,\n selection,\n sideOffset = 0,\n alignOffset = 0,\n collisionPadding = 0,\n } = props;\n\n const hideFloatingComposer = useHideFloatingComposer();\n\n const containerRef = useRef<HTMLDivElement>(null);\n const divRef = useRef<HTMLDivElement>(null);\n\n const [editor] = useLexicalComposerContext();\n\n useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(\n forwardedRef,\n () => divRef.current\n );\n\n useEffect(() => {\n return editor.registerUpdateListener(({ editorState: state, tags }) => {\n // Ignore selection updates related to collaboration\n if (tags.has(\"collaboration\")) return;\n state.read(() => hideFloatingComposer());\n });\n }, [editor, hideFloatingComposer]);\n\n useLayoutEffect(() => {\n const content = divRef.current;\n if (content === null) return;\n\n const parent = containerRef.current;\n if (parent === null) return;\n\n function positionContent() {\n const content = divRef.current;\n if (content === null) return;\n\n const parent = content.parentElement;\n if (parent === null) return;\n\n // Create a DOM range from the selection\n const range = createDOMRange(\n editor,\n selection.anchor.node,\n selection.anchor.offset,\n selection.focus.node,\n selection.focus.offset\n );\n\n if (range === null) return;\n\n // Get the bounding client rect of the DOM (selection) range\n const rect = range.getBoundingClientRect();\n\n // Set the position of the floating container\n let left = rect.left - parent.getBoundingClientRect().left;\n let top = rect.bottom - parent.getBoundingClientRect().top;\n\n // Apply the align offset\n left += alignOffset;\n\n // Get the width and height of the content\n const width = content.getBoundingClientRect().width;\n left = left + rect.width / 2 - width / 2;\n\n // Ensure content does not overflow the container\n if (left < collisionPadding) {\n left = collisionPadding;\n } else if (\n left + width >\n parent.getBoundingClientRect().right -\n parent.getBoundingClientRect().left -\n collisionPadding\n ) {\n left =\n parent.getBoundingClientRect().right -\n parent.getBoundingClientRect().left -\n width -\n collisionPadding;\n }\n\n // Apply the side offset\n top += sideOffset;\n\n const height = content.getBoundingClientRect().height;\n\n if (\n top + height >\n parent.getBoundingClientRect().height -\n parent.getBoundingClientRect().top +\n collisionPadding\n ) {\n top = rect.top - parent.getBoundingClientRect().top - height;\n top -= sideOffset;\n }\n\n content.style.left = `${left}px`;\n content.style.top = `${top}px`;\n }\n\n // Observe resizes of the container element to redraw the selection\n const observer = new ResizeObserver(positionContent);\n observer.observe(parent);\n\n // Listen to updates in the editor to redraw the selection\n const unsubscribeFromUpdates =\n editor.registerUpdateListener(positionContent);\n\n return () => {\n observer.disconnect();\n unsubscribeFromUpdates();\n };\n }, [selection, editor]);\n\n return (\n <div\n ref={containerRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n }}\n >\n <div\n ref={divRef}\n style={{\n position: \"absolute\",\n pointerEvents: \"auto\",\n }}\n >\n {children}\n </div>\n </div>\n );\n});\n\nfunction useSelection(): RangeSelection | 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 (!$isRangeSelection(selection)) return null;\n\n return selection;\n });\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n"],"names":["forwardRef","FloatingSelectionContainer","useLexicalComposerContext","createPortal","selection","useHideFloatingComposer","useRef","useImperativeHandle","useEffect","useLayoutEffect","content","parent","createDOMRange","useCallback","$getSelection","$isRangeSelection","useSyncExternalStore"],"mappings":"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"}
@@ -0,0 +1,155 @@
1
+ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
2
+ import { $getSelection, $isRangeSelection } from 'lexical';
3
+ import React__default, { forwardRef, useRef, useImperativeHandle, useEffect, useLayoutEffect, useCallback } from 'react';
4
+ import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js';
5
+ import { createPortal } from 'react-dom';
6
+ import { createDOMRange } from '@lexical/selection';
7
+ import { useHideFloatingComposer } from './comments/comment-plugin-provider.mjs';
8
+
9
+ const FloatingSelectionContainer = forwardRef(function FloatingSelectionContainer2(props, forwardedRef) {
10
+ const [editor] = useLexicalComposerContext();
11
+ const selection = useSelection();
12
+ if (selection === null)
13
+ return null;
14
+ if (selection.isCollapsed())
15
+ return null;
16
+ const info = editor.getEditorState().read(() => {
17
+ return {
18
+ anchor: {
19
+ node: selection.anchor.getNode(),
20
+ offset: selection.anchor.offset
21
+ },
22
+ focus: {
23
+ node: selection.focus.getNode(),
24
+ offset: selection.focus.offset
25
+ }
26
+ };
27
+ });
28
+ const root = editor.getRootElement();
29
+ if (root === null)
30
+ return null;
31
+ const rootContainer = root.parentElement;
32
+ if (rootContainer === null)
33
+ return null;
34
+ return createPortal(
35
+ /* @__PURE__ */ React__default.createElement(FloatingSelectionContainerImpl, {
36
+ ...props,
37
+ selection: info,
38
+ ref: forwardedRef
39
+ }),
40
+ rootContainer
41
+ );
42
+ });
43
+ const FloatingSelectionContainerImpl = forwardRef(function FloatingSelectionContainer3(props, forwardedRef) {
44
+ const {
45
+ children,
46
+ selection,
47
+ sideOffset = 0,
48
+ alignOffset = 0,
49
+ collisionPadding = 0
50
+ } = props;
51
+ const hideFloatingComposer = useHideFloatingComposer();
52
+ const containerRef = useRef(null);
53
+ const divRef = useRef(null);
54
+ const [editor] = useLexicalComposerContext();
55
+ useImperativeHandle(
56
+ forwardedRef,
57
+ () => divRef.current
58
+ );
59
+ useEffect(() => {
60
+ return editor.registerUpdateListener(({ editorState: state, tags }) => {
61
+ if (tags.has("collaboration"))
62
+ return;
63
+ state.read(() => hideFloatingComposer());
64
+ });
65
+ }, [editor, hideFloatingComposer]);
66
+ useLayoutEffect(() => {
67
+ const content = divRef.current;
68
+ if (content === null)
69
+ return;
70
+ const parent = containerRef.current;
71
+ if (parent === null)
72
+ return;
73
+ function positionContent() {
74
+ const content2 = divRef.current;
75
+ if (content2 === null)
76
+ return;
77
+ const parent2 = content2.parentElement;
78
+ if (parent2 === null)
79
+ return;
80
+ const range = createDOMRange(
81
+ editor,
82
+ selection.anchor.node,
83
+ selection.anchor.offset,
84
+ selection.focus.node,
85
+ selection.focus.offset
86
+ );
87
+ if (range === null)
88
+ return;
89
+ const rect = range.getBoundingClientRect();
90
+ let left = rect.left - parent2.getBoundingClientRect().left;
91
+ let top = rect.bottom - parent2.getBoundingClientRect().top;
92
+ left += alignOffset;
93
+ const width = content2.getBoundingClientRect().width;
94
+ left = left + rect.width / 2 - width / 2;
95
+ if (left < collisionPadding) {
96
+ left = collisionPadding;
97
+ } else if (left + width > parent2.getBoundingClientRect().right - parent2.getBoundingClientRect().left - collisionPadding) {
98
+ left = parent2.getBoundingClientRect().right - parent2.getBoundingClientRect().left - width - collisionPadding;
99
+ }
100
+ top += sideOffset;
101
+ const height = content2.getBoundingClientRect().height;
102
+ if (top + height > parent2.getBoundingClientRect().height - parent2.getBoundingClientRect().top + collisionPadding) {
103
+ top = rect.top - parent2.getBoundingClientRect().top - height;
104
+ top -= sideOffset;
105
+ }
106
+ content2.style.left = `${left}px`;
107
+ content2.style.top = `${top}px`;
108
+ }
109
+ const observer = new ResizeObserver(positionContent);
110
+ observer.observe(parent);
111
+ const unsubscribeFromUpdates = editor.registerUpdateListener(positionContent);
112
+ return () => {
113
+ observer.disconnect();
114
+ unsubscribeFromUpdates();
115
+ };
116
+ }, [selection, editor]);
117
+ return /* @__PURE__ */ React__default.createElement("div", {
118
+ ref: containerRef,
119
+ style: {
120
+ position: "absolute",
121
+ top: 0,
122
+ left: 0,
123
+ width: "100%",
124
+ height: "100%",
125
+ pointerEvents: "none"
126
+ }
127
+ }, /* @__PURE__ */ React__default.createElement("div", {
128
+ ref: divRef,
129
+ style: {
130
+ position: "absolute",
131
+ pointerEvents: "auto"
132
+ }
133
+ }, children));
134
+ });
135
+ function useSelection() {
136
+ const [editor] = useLexicalComposerContext();
137
+ const subscribe = useCallback(
138
+ (onStoreChange) => {
139
+ return editor.registerUpdateListener(onStoreChange);
140
+ },
141
+ [editor]
142
+ );
143
+ const getSnapshot = useCallback(() => {
144
+ return editor.getEditorState().read(() => {
145
+ const selection = $getSelection();
146
+ if (!$isRangeSelection(selection))
147
+ return null;
148
+ return selection;
149
+ });
150
+ }, [editor]);
151
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
152
+ }
153
+
154
+ export { FloatingSelectionContainer };
155
+ //# sourceMappingURL=floating-selection-container.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floating-selection-container.mjs","sources":["../src/floating-selection-container.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n RangeSelection,\n $getSelection,\n $isRangeSelection,\n LexicalNode,\n} from \"lexical\";\nimport React, {\n forwardRef,\n PropsWithChildren,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport { createPortal } from \"react-dom\";\nimport { createDOMRange } from \"@lexical/selection\";\nimport { useHideFloatingComposer } from \"./comments/comment-plugin-provider\";\n\nexport interface FloatingSelectionContainerProps {\n sideOffset?: number;\n alignOffset?: number;\n collisionPadding?: number;\n}\n\nexport const FloatingSelectionContainer = forwardRef<\n HTMLDivElement | null,\n PropsWithChildren<FloatingSelectionContainerProps>\n>(function FloatingSelectionContainer(props, forwardedRef) {\n const [editor] = useLexicalComposerContext();\n const selection = useSelection();\n\n if (selection === null) return null;\n\n if (selection.isCollapsed()) return null;\n\n const info = editor.getEditorState().read(() => {\n return {\n anchor: {\n node: selection.anchor.getNode(),\n offset: selection.anchor.offset,\n },\n focus: {\n node: selection.focus.getNode(),\n offset: selection.focus.offset,\n },\n };\n });\n\n const root = editor.getRootElement();\n if (root === null) return null;\n\n const rootContainer = root.parentElement;\n if (rootContainer === null) return null;\n\n return createPortal(\n <FloatingSelectionContainerImpl\n {...props}\n selection={info}\n ref={forwardedRef}\n />,\n rootContainer\n );\n});\n\ntype SelectionInfo = {\n anchor: {\n node: LexicalNode;\n offset: number;\n };\n focus: {\n node: LexicalNode;\n offset: number;\n };\n};\n\ninterface FloatingSelectionContainerImplProps\n extends FloatingSelectionContainerProps {\n selection: SelectionInfo;\n}\n\nconst FloatingSelectionContainerImpl = forwardRef<\n HTMLDivElement | null,\n PropsWithChildren<FloatingSelectionContainerImplProps>\n>(function FloatingSelectionContainer(props, forwardedRef) {\n const {\n children,\n selection,\n sideOffset = 0,\n alignOffset = 0,\n collisionPadding = 0,\n } = props;\n\n const hideFloatingComposer = useHideFloatingComposer();\n\n const containerRef = useRef<HTMLDivElement>(null);\n const divRef = useRef<HTMLDivElement>(null);\n\n const [editor] = useLexicalComposerContext();\n\n useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(\n forwardedRef,\n () => divRef.current\n );\n\n useEffect(() => {\n return editor.registerUpdateListener(({ editorState: state, tags }) => {\n // Ignore selection updates related to collaboration\n if (tags.has(\"collaboration\")) return;\n state.read(() => hideFloatingComposer());\n });\n }, [editor, hideFloatingComposer]);\n\n useLayoutEffect(() => {\n const content = divRef.current;\n if (content === null) return;\n\n const parent = containerRef.current;\n if (parent === null) return;\n\n function positionContent() {\n const content = divRef.current;\n if (content === null) return;\n\n const parent = content.parentElement;\n if (parent === null) return;\n\n // Create a DOM range from the selection\n const range = createDOMRange(\n editor,\n selection.anchor.node,\n selection.anchor.offset,\n selection.focus.node,\n selection.focus.offset\n );\n\n if (range === null) return;\n\n // Get the bounding client rect of the DOM (selection) range\n const rect = range.getBoundingClientRect();\n\n // Set the position of the floating container\n let left = rect.left - parent.getBoundingClientRect().left;\n let top = rect.bottom - parent.getBoundingClientRect().top;\n\n // Apply the align offset\n left += alignOffset;\n\n // Get the width and height of the content\n const width = content.getBoundingClientRect().width;\n left = left + rect.width / 2 - width / 2;\n\n // Ensure content does not overflow the container\n if (left < collisionPadding) {\n left = collisionPadding;\n } else if (\n left + width >\n parent.getBoundingClientRect().right -\n parent.getBoundingClientRect().left -\n collisionPadding\n ) {\n left =\n parent.getBoundingClientRect().right -\n parent.getBoundingClientRect().left -\n width -\n collisionPadding;\n }\n\n // Apply the side offset\n top += sideOffset;\n\n const height = content.getBoundingClientRect().height;\n\n if (\n top + height >\n parent.getBoundingClientRect().height -\n parent.getBoundingClientRect().top +\n collisionPadding\n ) {\n top = rect.top - parent.getBoundingClientRect().top - height;\n top -= sideOffset;\n }\n\n content.style.left = `${left}px`;\n content.style.top = `${top}px`;\n }\n\n // Observe resizes of the container element to redraw the selection\n const observer = new ResizeObserver(positionContent);\n observer.observe(parent);\n\n // Listen to updates in the editor to redraw the selection\n const unsubscribeFromUpdates =\n editor.registerUpdateListener(positionContent);\n\n return () => {\n observer.disconnect();\n unsubscribeFromUpdates();\n };\n }, [selection, editor]);\n\n return (\n <div\n ref={containerRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n }}\n >\n <div\n ref={divRef}\n style={{\n position: \"absolute\",\n pointerEvents: \"auto\",\n }}\n >\n {children}\n </div>\n </div>\n );\n});\n\nfunction useSelection(): RangeSelection | 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 (!$isRangeSelection(selection)) return null;\n\n return selection;\n });\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n"],"names":["FloatingSelectionContainer","React","content","parent"],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import React, { ComponentType, HTMLAttributes } from 'react';
2
+ import * as lexical from 'lexical';
3
+ import { InitialConfigType } from '@lexical/react/LexicalComposer';
4
+ import { ComposerProps } from '@liveblocks/react-comments';
5
+ import { BaseMetadata } from '@liveblocks/core';
6
+
7
+ declare const ThreadPanel: () => React.JSX.Element;
8
+
9
+ declare type LiveblocksPluginProviderProps = {
10
+ children?: React.ReactNode;
11
+ };
12
+ declare const LiveblocksPluginProvider: ({ children, }: LiveblocksPluginProviderProps) => JSX.Element;
13
+
14
+ interface MentionProps {
15
+ /**
16
+ * The mention's user ID.
17
+ */
18
+ userId: string;
19
+ }
20
+ interface MentionSuggestionsProps {
21
+ /**
22
+ * The list of suggested user IDs.
23
+ */
24
+ userIds: string[];
25
+ }
26
+ interface EditorComponents {
27
+ Mention: ComponentType<MentionProps>;
28
+ MentionSuggestions: ComponentType<MentionSuggestionsProps>;
29
+ }
30
+ interface LiveblocksConfig {
31
+ /**
32
+ * Whether comments are enabled. Defaults to true.
33
+ */
34
+ comments?: boolean;
35
+ /**
36
+ * The components displayed within the editor.
37
+ */
38
+ components?: Partial<EditorComponents>;
39
+ }
40
+ declare function liveblocksLexicalConfig(editorConfig: InitialConfigType, config?: LiveblocksConfig): {
41
+ nodes: (lexical.KlassConstructor<typeof lexical.LexicalNode> | lexical.LexicalNodeReplacement)[];
42
+ editorState: null;
43
+ editor__DEPRECATED?: lexical.LexicalEditor | null | undefined;
44
+ namespace: string;
45
+ onError: (error: Error, editor: lexical.LexicalEditor) => void;
46
+ editable?: boolean | undefined;
47
+ theme?: lexical.EditorThemeClasses | undefined;
48
+ html?: lexical.HTMLConfig | undefined;
49
+ };
50
+
51
+ declare const Mention: React.ForwardRefExoticComponent<HTMLAttributes<HTMLSpanElement> & React.RefAttributes<HTMLSpanElement>>;
52
+
53
+ declare type ThreadMetadata = {
54
+ resolved?: boolean;
55
+ };
56
+ declare type FloatingComposerProps<M extends BaseMetadata = ThreadMetadata> = Omit<ComposerProps<M>, "threadId" | "commentId">;
57
+ declare const FloatingComposer: React.ForwardRefExoticComponent<FloatingComposerProps<ThreadMetadata> & React.RefAttributes<HTMLFormElement>>;
58
+
59
+ declare function useCreateThread(): () => void;
60
+
61
+ export { FloatingComposer, LiveblocksPluginProvider, Mention, ThreadPanel, liveblocksLexicalConfig, useCreateThread };
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ var core = require('@liveblocks/core');
4
+ var version = require('./version.js');
5
+ var ThreadPanel = require('./comments/ThreadPanel.js');
6
+ var liveblocksConfig = require('./liveblocks-config.js');
7
+ var liveblocksPluginProvider = require('./liveblocks-plugin-provider.js');
8
+ var mentionComponent = require('./mentions/mention-component.js');
9
+ var floatingComposer = require('./comments/floating-composer.js');
10
+ var commentPluginProvider = require('./comments/comment-plugin-provider.js');
11
+
12
+ core.detectDupes(version.PKG_NAME, version.PKG_VERSION, version.PKG_FORMAT);
13
+
14
+ exports.ThreadPanel = ThreadPanel.ThreadPanel;
15
+ exports.liveblocksLexicalConfig = liveblocksConfig.liveblocksLexicalConfig;
16
+ exports.LiveblocksPluginProvider = liveblocksPluginProvider.LiveblocksPluginProvider;
17
+ exports.Mention = mentionComponent.Mention;
18
+ exports.FloatingComposer = floatingComposer.FloatingComposer;
19
+ exports.useCreateThread = commentPluginProvider.useCreateThread;
20
+ //# 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 { ThreadPanel } from \"./comments/ThreadPanel\";\nexport { liveblocksLexicalConfig } from \"./liveblocks-config\";\nexport { LiveblocksPluginProvider } from \"./liveblocks-plugin-provider\";\nexport { Mention } from \"./mentions/mention-component\";\nexport { FloatingComposer } from \"./comments/floating-composer\";\nexport { useCreateThread } from \"./comments/comment-plugin-provider\";\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,11 @@
1
+ import { detectDupes } from '@liveblocks/core';
2
+ import { PKG_NAME, PKG_VERSION, PKG_FORMAT } from './version.mjs';
3
+ export { ThreadPanel } from './comments/ThreadPanel.mjs';
4
+ export { liveblocksLexicalConfig } from './liveblocks-config.mjs';
5
+ export { LiveblocksPluginProvider } from './liveblocks-plugin-provider.mjs';
6
+ export { Mention } from './mentions/mention-component.mjs';
7
+ export { FloatingComposer } from './comments/floating-composer.mjs';
8
+ export { useCreateThread } from './comments/comment-plugin-provider.mjs';
9
+
10
+ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
11
+ //# 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 { ThreadPanel } from \"./comments/ThreadPanel\";\nexport { liveblocksLexicalConfig } from \"./liveblocks-config\";\nexport { LiveblocksPluginProvider } from \"./liveblocks-plugin-provider\";\nexport { Mention } from \"./mentions/mention-component\";\nexport { FloatingComposer } from \"./comments/floating-composer\";\nexport { useCreateThread } from \"./comments/comment-plugin-provider\";\n"],"names":[],"mappings":";;;;;;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
@@ -0,0 +1,89 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var threadMarkNode = require('./comments/thread-mark-node.js');
5
+ var avatar = require('./mentions/avatar.js');
6
+ var mentionComponent = require('./mentions/mention-component.js');
7
+ var mentionNode = require('./mentions/mention-node.js');
8
+ var suggestions = require('./mentions/suggestions.js');
9
+ var user = require('./mentions/user.js');
10
+
11
+ function _interopNamespaceDefault(e) {
12
+ var n = Object.create(null);
13
+ if (e) {
14
+ Object.keys(e).forEach(function (k) {
15
+ if (k !== 'default') {
16
+ var d = Object.getOwnPropertyDescriptor(e, k);
17
+ Object.defineProperty(n, k, d.get ? d : {
18
+ enumerable: true,
19
+ get: function () { return e[k]; }
20
+ });
21
+ }
22
+ });
23
+ }
24
+ n.default = e;
25
+ return Object.freeze(n);
26
+ }
27
+
28
+ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
29
+
30
+ let liveblocksConfig = null;
31
+ const MENTION_CHARACTER = "@";
32
+ const defaultComponents = {
33
+ Mention: ({ userId }) => {
34
+ return /* @__PURE__ */ React__namespace.createElement(mentionComponent.Mention, {
35
+ className: "lb-lexical-mention"
36
+ }, MENTION_CHARACTER, /* @__PURE__ */ React__namespace.createElement(user, {
37
+ userId
38
+ }));
39
+ },
40
+ MentionSuggestions: ({ userIds }) => {
41
+ return /* @__PURE__ */ React__namespace.createElement(suggestions.List, {
42
+ className: "lb-lexical-suggestions-list"
43
+ }, userIds.map((userId) => /* @__PURE__ */ React__namespace.createElement(suggestions.Item, {
44
+ key: userId,
45
+ value: userId,
46
+ className: "lb-lexical-suggestions-list-item"
47
+ }, /* @__PURE__ */ React__namespace.createElement(avatar, {
48
+ userId,
49
+ className: "lb-lexical-mention-suggestion-avatar"
50
+ }), /* @__PURE__ */ React__namespace.createElement(user, {
51
+ userId,
52
+ className: "lb-lexical-mention-suggestion-user"
53
+ }))));
54
+ }
55
+ };
56
+ function liveblocksLexicalConfig(editorConfig, config = {}) {
57
+ const { comments = true, components = {} } = config;
58
+ const nodes = [...editorConfig.nodes ?? []];
59
+ const Mention2 = components.Mention ?? defaultComponents.Mention;
60
+ const MentionSuggestions = components.MentionSuggestions ?? defaultComponents.MentionSuggestions;
61
+ const mentionFactory = mentionNode.createMentionNodeFactory(Mention2);
62
+ nodes.push(threadMarkNode.ThreadMarkNode, mentionFactory.MentionNode);
63
+ liveblocksConfig = {
64
+ comments,
65
+ mentions: {
66
+ factory: mentionFactory,
67
+ components: {
68
+ MentionSuggestions
69
+ }
70
+ }
71
+ };
72
+ return {
73
+ ...editorConfig,
74
+ nodes,
75
+ editorState: null
76
+ };
77
+ }
78
+ function getLiveblocksLexicalConfig() {
79
+ if (liveblocksConfig === null) {
80
+ throw new Error("Liveblocks config is not initialized.");
81
+ }
82
+ return {
83
+ ...liveblocksConfig
84
+ };
85
+ }
86
+
87
+ exports.getLiveblocksLexicalConfig = getLiveblocksLexicalConfig;
88
+ exports.liveblocksLexicalConfig = liveblocksLexicalConfig;
89
+ //# sourceMappingURL=liveblocks-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveblocks-config.js","sources":["../src/liveblocks-config.tsx"],"sourcesContent":["import type { InitialConfigType } from \"@lexical/react/LexicalComposer\";\nimport type { ComponentType } from \"react\";\nimport * as React from \"react\";\n\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport type { LiveblocksLexicalInternalConfig } from \"./liveblocks-plugin-provider\";\nimport Avatar from \"./mentions/avatar\";\nimport { Mention } from \"./mentions/mention-component\";\nimport { createMentionNodeFactory } from \"./mentions/mention-node\";\nimport * as Suggestions from \"./mentions/suggestions\";\nimport User from \"./mentions/user\";\n\nlet liveblocksConfig: LiveblocksLexicalInternalConfig | null = null;\n\nexport interface MentionProps {\n /**\n * The mention's user ID.\n */\n userId: string;\n}\n\nexport interface MentionSuggestionsProps {\n /**\n * The list of suggested user IDs.\n */\n userIds: string[];\n}\n\ninterface EditorComponents {\n Mention: ComponentType<MentionProps>;\n MentionSuggestions: ComponentType<MentionSuggestionsProps>;\n}\n\nexport interface LiveblocksConfig {\n /**\n * Whether comments are enabled. Defaults to true.\n */\n comments?: boolean;\n /**\n * The components displayed within the editor.\n */\n components?: Partial<EditorComponents>;\n}\n\nconst MENTION_CHARACTER = \"@\";\nconst defaultComponents: EditorComponents = {\n Mention: ({ userId }) => {\n return (\n <Mention className=\"lb-lexical-mention\">\n {MENTION_CHARACTER}\n <User userId={userId} />\n </Mention>\n );\n },\n MentionSuggestions: ({ userIds }) => {\n return (\n <Suggestions.List className=\"lb-lexical-suggestions-list\">\n {userIds.map((userId) => (\n <Suggestions.Item\n key={userId}\n value={userId}\n className=\"lb-lexical-suggestions-list-item\"\n >\n <Avatar\n userId={userId}\n className=\"lb-lexical-mention-suggestion-avatar\"\n />\n <User\n userId={userId}\n className=\"lb-lexical-mention-suggestion-user\"\n />\n </Suggestions.Item>\n ))}\n </Suggestions.List>\n );\n },\n};\n\nexport function liveblocksLexicalConfig(\n editorConfig: InitialConfigType,\n config: LiveblocksConfig = {}\n) {\n const { comments = true, components = {} } = config;\n\n const nodes = [...(editorConfig.nodes ?? [])];\n\n const Mention = components.Mention ?? defaultComponents.Mention;\n const MentionSuggestions =\n components.MentionSuggestions ?? defaultComponents.MentionSuggestions;\n\n const mentionFactory = createMentionNodeFactory(Mention);\n\n nodes.push(ThreadMarkNode, mentionFactory.MentionNode);\n\n liveblocksConfig = {\n comments,\n mentions: {\n factory: mentionFactory,\n components: {\n MentionSuggestions,\n },\n },\n };\n\n return {\n ...editorConfig,\n nodes,\n editorState: null, // explicitly null because CollabProvider requires it\n };\n}\n\nexport function getLiveblocksLexicalConfig(): LiveblocksLexicalInternalConfig {\n if (liveblocksConfig === null) {\n throw new Error(\"Liveblocks config is not initialized.\");\n }\n return {\n ...liveblocksConfig,\n };\n}\n"],"names":["React","Mention","User","Suggestions.List","Suggestions.Item","Avatar","createMentionNodeFactory","ThreadMarkNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,IAAI,gBAA2D,GAAA,IAAA,CAAA;AAgC/D,MAAM,iBAAoB,GAAA,GAAA,CAAA;AAC1B,MAAM,iBAAsC,GAAA;AAAA,EAC1C,OAAS,EAAA,CAAC,EAAE,MAAA,EAAa,KAAA;AACvB,IAAA,uBACGA,gBAAA,CAAA,aAAA,CAAAC,wBAAA,EAAA;AAAA,MAAQ,SAAU,EAAA,oBAAA;AAAA,KAAA,EAChB,mCACAD,gBAAA,CAAA,aAAA,CAAAE,IAAA,EAAA;AAAA,MAAK,MAAA;AAAA,KAAgB,CACxB,CAAA,CAAA;AAAA,GAEJ;AAAA,EACA,kBAAoB,EAAA,CAAC,EAAE,OAAA,EAAc,KAAA;AACnC,IACE,uBAAAF,gBAAA,CAAA,aAAA,CAACG,gBAAA,EAAA;AAAA,MAAiB,SAAU,EAAA,6BAAA;AAAA,KAAA,EACzB,QAAQ,GAAI,CAAA,CAAC,MACZ,qBAAAH,gBAAA,CAAA,aAAA,CAACI,gBAAA,EAAA;AAAA,MACC,GAAK,EAAA,MAAA;AAAA,MACL,KAAO,EAAA,MAAA;AAAA,MACP,SAAU,EAAA,kCAAA;AAAA,KAAA,kBAETJ,gBAAA,CAAA,aAAA,CAAAK,MAAA,EAAA;AAAA,MACC,MAAA;AAAA,MACA,SAAU,EAAA,sCAAA;AAAA,KACZ,mBACCL,gBAAA,CAAA,aAAA,CAAAE,IAAA,EAAA;AAAA,MACC,MAAA;AAAA,MACA,SAAU,EAAA,oCAAA;AAAA,KACZ,CACF,CACD,CACH,CAAA,CAAA;AAAA,GAEJ;AACF,CAAA,CAAA;AAEO,SAAS,uBACd,CAAA,YAAA,EACA,MAA2B,GAAA,EAC3B,EAAA;AACA,EAAA,MAAM,EAAE,QAAW,GAAA,IAAA,EAAM,UAAa,GAAA,IAAO,GAAA,MAAA,CAAA;AAE7C,EAAA,MAAM,QAAQ,CAAC,GAAI,YAAa,CAAA,KAAA,IAAS,EAAG,CAAA,CAAA;AAE5C,EAAMD,MAAAA,QAAAA,GAAU,UAAW,CAAA,OAAA,IAAW,iBAAkB,CAAA,OAAA,CAAA;AACxD,EAAM,MAAA,kBAAA,GACJ,UAAW,CAAA,kBAAA,IAAsB,iBAAkB,CAAA,kBAAA,CAAA;AAErD,EAAM,MAAA,cAAA,GAAiBK,qCAAyBL,QAAO,CAAA,CAAA;AAEvD,EAAM,KAAA,CAAA,IAAA,CAAKM,6BAAgB,EAAA,cAAA,CAAe,WAAW,CAAA,CAAA;AAErD,EAAmB,gBAAA,GAAA;AAAA,IACjB,QAAA;AAAA,IACA,QAAU,EAAA;AAAA,MACR,OAAS,EAAA,cAAA;AAAA,MACT,UAAY,EAAA;AAAA,QACV,kBAAA;AAAA,OACF;AAAA,KACF;AAAA,GACF,CAAA;AAEA,EAAO,OAAA;AAAA,IACL,GAAG,YAAA;AAAA,IACH,KAAA;AAAA,IACA,WAAa,EAAA,IAAA;AAAA,GACf,CAAA;AACF,CAAA;AAEO,SAAS,0BAA8D,GAAA;AAC5E,EAAA,IAAI,qBAAqB,IAAM,EAAA;AAC7B,IAAM,MAAA,IAAI,MAAM,uCAAuC,CAAA,CAAA;AAAA,GACzD;AACA,EAAO,OAAA;AAAA,IACL,GAAG,gBAAA;AAAA,GACL,CAAA;AACF;;;;;"}
@@ -0,0 +1,67 @@
1
+ import * as React from 'react';
2
+ import { ThreadMarkNode } from './comments/thread-mark-node.mjs';
3
+ import Avatar from './mentions/avatar.mjs';
4
+ import { Mention } from './mentions/mention-component.mjs';
5
+ import { createMentionNodeFactory } from './mentions/mention-node.mjs';
6
+ import { List, Item } from './mentions/suggestions.mjs';
7
+ import User from './mentions/user.mjs';
8
+
9
+ let liveblocksConfig = null;
10
+ const MENTION_CHARACTER = "@";
11
+ const defaultComponents = {
12
+ Mention: ({ userId }) => {
13
+ return /* @__PURE__ */ React.createElement(Mention, {
14
+ className: "lb-lexical-mention"
15
+ }, MENTION_CHARACTER, /* @__PURE__ */ React.createElement(User, {
16
+ userId
17
+ }));
18
+ },
19
+ MentionSuggestions: ({ userIds }) => {
20
+ return /* @__PURE__ */ React.createElement(List, {
21
+ className: "lb-lexical-suggestions-list"
22
+ }, userIds.map((userId) => /* @__PURE__ */ React.createElement(Item, {
23
+ key: userId,
24
+ value: userId,
25
+ className: "lb-lexical-suggestions-list-item"
26
+ }, /* @__PURE__ */ React.createElement(Avatar, {
27
+ userId,
28
+ className: "lb-lexical-mention-suggestion-avatar"
29
+ }), /* @__PURE__ */ React.createElement(User, {
30
+ userId,
31
+ className: "lb-lexical-mention-suggestion-user"
32
+ }))));
33
+ }
34
+ };
35
+ function liveblocksLexicalConfig(editorConfig, config = {}) {
36
+ const { comments = true, components = {} } = config;
37
+ const nodes = [...editorConfig.nodes ?? []];
38
+ const Mention2 = components.Mention ?? defaultComponents.Mention;
39
+ const MentionSuggestions = components.MentionSuggestions ?? defaultComponents.MentionSuggestions;
40
+ const mentionFactory = createMentionNodeFactory(Mention2);
41
+ nodes.push(ThreadMarkNode, mentionFactory.MentionNode);
42
+ liveblocksConfig = {
43
+ comments,
44
+ mentions: {
45
+ factory: mentionFactory,
46
+ components: {
47
+ MentionSuggestions
48
+ }
49
+ }
50
+ };
51
+ return {
52
+ ...editorConfig,
53
+ nodes,
54
+ editorState: null
55
+ };
56
+ }
57
+ function getLiveblocksLexicalConfig() {
58
+ if (liveblocksConfig === null) {
59
+ throw new Error("Liveblocks config is not initialized.");
60
+ }
61
+ return {
62
+ ...liveblocksConfig
63
+ };
64
+ }
65
+
66
+ export { getLiveblocksLexicalConfig, liveblocksLexicalConfig };
67
+ //# sourceMappingURL=liveblocks-config.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveblocks-config.mjs","sources":["../src/liveblocks-config.tsx"],"sourcesContent":["import type { InitialConfigType } from \"@lexical/react/LexicalComposer\";\nimport type { ComponentType } from \"react\";\nimport * as React from \"react\";\n\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport type { LiveblocksLexicalInternalConfig } from \"./liveblocks-plugin-provider\";\nimport Avatar from \"./mentions/avatar\";\nimport { Mention } from \"./mentions/mention-component\";\nimport { createMentionNodeFactory } from \"./mentions/mention-node\";\nimport * as Suggestions from \"./mentions/suggestions\";\nimport User from \"./mentions/user\";\n\nlet liveblocksConfig: LiveblocksLexicalInternalConfig | null = null;\n\nexport interface MentionProps {\n /**\n * The mention's user ID.\n */\n userId: string;\n}\n\nexport interface MentionSuggestionsProps {\n /**\n * The list of suggested user IDs.\n */\n userIds: string[];\n}\n\ninterface EditorComponents {\n Mention: ComponentType<MentionProps>;\n MentionSuggestions: ComponentType<MentionSuggestionsProps>;\n}\n\nexport interface LiveblocksConfig {\n /**\n * Whether comments are enabled. Defaults to true.\n */\n comments?: boolean;\n /**\n * The components displayed within the editor.\n */\n components?: Partial<EditorComponents>;\n}\n\nconst MENTION_CHARACTER = \"@\";\nconst defaultComponents: EditorComponents = {\n Mention: ({ userId }) => {\n return (\n <Mention className=\"lb-lexical-mention\">\n {MENTION_CHARACTER}\n <User userId={userId} />\n </Mention>\n );\n },\n MentionSuggestions: ({ userIds }) => {\n return (\n <Suggestions.List className=\"lb-lexical-suggestions-list\">\n {userIds.map((userId) => (\n <Suggestions.Item\n key={userId}\n value={userId}\n className=\"lb-lexical-suggestions-list-item\"\n >\n <Avatar\n userId={userId}\n className=\"lb-lexical-mention-suggestion-avatar\"\n />\n <User\n userId={userId}\n className=\"lb-lexical-mention-suggestion-user\"\n />\n </Suggestions.Item>\n ))}\n </Suggestions.List>\n );\n },\n};\n\nexport function liveblocksLexicalConfig(\n editorConfig: InitialConfigType,\n config: LiveblocksConfig = {}\n) {\n const { comments = true, components = {} } = config;\n\n const nodes = [...(editorConfig.nodes ?? [])];\n\n const Mention = components.Mention ?? defaultComponents.Mention;\n const MentionSuggestions =\n components.MentionSuggestions ?? defaultComponents.MentionSuggestions;\n\n const mentionFactory = createMentionNodeFactory(Mention);\n\n nodes.push(ThreadMarkNode, mentionFactory.MentionNode);\n\n liveblocksConfig = {\n comments,\n mentions: {\n factory: mentionFactory,\n components: {\n MentionSuggestions,\n },\n },\n };\n\n return {\n ...editorConfig,\n nodes,\n editorState: null, // explicitly null because CollabProvider requires it\n };\n}\n\nexport function getLiveblocksLexicalConfig(): LiveblocksLexicalInternalConfig {\n if (liveblocksConfig === null) {\n throw new Error(\"Liveblocks config is not initialized.\");\n }\n return {\n ...liveblocksConfig,\n };\n}\n"],"names":["Suggestions.List","Suggestions.Item","Mention"],"mappings":";;;;;;;;AAYA,IAAI,gBAA2D,GAAA,IAAA,CAAA;AAgC/D,MAAM,iBAAoB,GAAA,GAAA,CAAA;AAC1B,MAAM,iBAAsC,GAAA;AAAA,EAC1C,OAAS,EAAA,CAAC,EAAE,MAAA,EAAa,KAAA;AACvB,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA;AAAA,MAAQ,SAAU,EAAA,oBAAA;AAAA,KAAA,EAChB,mCACA,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,MAAK,MAAA;AAAA,KAAgB,CACxB,CAAA,CAAA;AAAA,GAEJ;AAAA,EACA,kBAAoB,EAAA,CAAC,EAAE,OAAA,EAAc,KAAA;AACnC,IACE,uBAAA,KAAA,CAAA,aAAA,CAACA,IAAA,EAAA;AAAA,MAAiB,SAAU,EAAA,6BAAA;AAAA,KAAA,EACzB,QAAQ,GAAI,CAAA,CAAC,MACZ,qBAAA,KAAA,CAAA,aAAA,CAACC,IAAA,EAAA;AAAA,MACC,GAAK,EAAA,MAAA;AAAA,MACL,KAAO,EAAA,MAAA;AAAA,MACP,SAAU,EAAA,kCAAA;AAAA,KAAA,kBAET,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,MACC,MAAA;AAAA,MACA,SAAU,EAAA,sCAAA;AAAA,KACZ,mBACC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,MACC,MAAA;AAAA,MACA,SAAU,EAAA,oCAAA;AAAA,KACZ,CACF,CACD,CACH,CAAA,CAAA;AAAA,GAEJ;AACF,CAAA,CAAA;AAEO,SAAS,uBACd,CAAA,YAAA,EACA,MAA2B,GAAA,EAC3B,EAAA;AACA,EAAA,MAAM,EAAE,QAAW,GAAA,IAAA,EAAM,UAAa,GAAA,IAAO,GAAA,MAAA,CAAA;AAE7C,EAAA,MAAM,QAAQ,CAAC,GAAI,YAAa,CAAA,KAAA,IAAS,EAAG,CAAA,CAAA;AAE5C,EAAMC,MAAAA,QAAAA,GAAU,UAAW,CAAA,OAAA,IAAW,iBAAkB,CAAA,OAAA,CAAA;AACxD,EAAM,MAAA,kBAAA,GACJ,UAAW,CAAA,kBAAA,IAAsB,iBAAkB,CAAA,kBAAA,CAAA;AAErD,EAAM,MAAA,cAAA,GAAiB,yBAAyBA,QAAO,CAAA,CAAA;AAEvD,EAAM,KAAA,CAAA,IAAA,CAAK,cAAgB,EAAA,cAAA,CAAe,WAAW,CAAA,CAAA;AAErD,EAAmB,gBAAA,GAAA;AAAA,IACjB,QAAA;AAAA,IACA,QAAU,EAAA;AAAA,MACR,OAAS,EAAA,cAAA;AAAA,MACT,UAAY,EAAA;AAAA,QACV,kBAAA;AAAA,OACF;AAAA,KACF;AAAA,GACF,CAAA;AAEA,EAAO,OAAA;AAAA,IACL,GAAG,YAAA;AAAA,IACH,KAAA;AAAA,IACA,WAAa,EAAA,IAAA;AAAA,GACf,CAAA;AACF,CAAA;AAEO,SAAS,0BAA8D,GAAA;AAC5E,EAAA,IAAI,qBAAqB,IAAM,EAAA;AAC7B,IAAM,MAAA,IAAI,MAAM,uCAAuC,CAAA,CAAA;AAAA,GACzD;AACA,EAAO,OAAA;AAAA,IACL,GAAG,gBAAA;AAAA,GACL,CAAA;AACF;;;;"}