@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.
- package/dist/active-selection.js +143 -0
- package/dist/active-selection.js.map +1 -0
- package/dist/active-selection.mjs +123 -0
- package/dist/active-selection.mjs.map +1 -0
- package/dist/comments/ThreadPanel.js +26 -0
- package/dist/comments/ThreadPanel.js.map +1 -0
- package/dist/comments/ThreadPanel.mjs +24 -0
- package/dist/comments/ThreadPanel.mjs.map +1 -0
- package/dist/comments/comment-plugin-provider.js +322 -0
- package/dist/comments/comment-plugin-provider.js.map +1 -0
- package/dist/comments/comment-plugin-provider.mjs +299 -0
- package/dist/comments/comment-plugin-provider.mjs.map +1 -0
- package/dist/comments/floating-composer.js +34 -0
- package/dist/comments/floating-composer.js.map +1 -0
- package/dist/comments/floating-composer.mjs +32 -0
- package/dist/comments/floating-composer.mjs.map +1 -0
- package/dist/comments/get-thread-mark-ids.js +23 -0
- package/dist/comments/get-thread-mark-ids.js.map +1 -0
- package/dist/comments/get-thread-mark-ids.mjs +21 -0
- package/dist/comments/get-thread-mark-ids.mjs.map +1 -0
- package/dist/comments/thread-mark-node.js +138 -0
- package/dist/comments/thread-mark-node.js.map +1 -0
- package/dist/comments/thread-mark-node.mjs +134 -0
- package/dist/comments/thread-mark-node.mjs.map +1 -0
- package/dist/comments/unwrap-thread-mark-node.js +19 -0
- package/dist/comments/unwrap-thread-mark-node.js.map +1 -0
- package/dist/comments/unwrap-thread-mark-node.mjs +17 -0
- package/dist/comments/unwrap-thread-mark-node.mjs.map +1 -0
- package/dist/comments/wrap-selection-in-thread-mark-node.js +63 -0
- package/dist/comments/wrap-selection-in-thread-mark-node.js.map +1 -0
- package/dist/comments/wrap-selection-in-thread-mark-node.mjs +61 -0
- package/dist/comments/wrap-selection-in-thread-mark-node.mjs.map +1 -0
- package/dist/floating-selection-container.js +157 -0
- package/dist/floating-selection-container.js.map +1 -0
- package/dist/floating-selection-container.mjs +155 -0
- package/dist/floating-selection-container.mjs.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +11 -0
- package/dist/index.mjs.map +1 -0
- package/dist/liveblocks-config.js +89 -0
- package/dist/liveblocks-config.js.map +1 -0
- package/dist/liveblocks-config.mjs +67 -0
- package/dist/liveblocks-config.mjs.map +1 -0
- package/dist/liveblocks-plugin-provider.js +79 -0
- package/dist/liveblocks-plugin-provider.js.map +1 -0
- package/dist/liveblocks-plugin-provider.mjs +76 -0
- package/dist/liveblocks-plugin-provider.mjs.map +1 -0
- package/dist/mentions/avatar.js +49 -0
- package/dist/mentions/avatar.js.map +1 -0
- package/dist/mentions/avatar.mjs +47 -0
- package/dist/mentions/avatar.mjs.map +1 -0
- package/dist/mentions/mention-component.js +63 -0
- package/dist/mentions/mention-component.js.map +1 -0
- package/dist/mentions/mention-component.mjs +60 -0
- package/dist/mentions/mention-component.mjs.map +1 -0
- package/dist/mentions/mention-node.js +105 -0
- package/dist/mentions/mention-node.js.map +1 -0
- package/dist/mentions/mention-node.mjs +84 -0
- package/dist/mentions/mention-node.mjs.map +1 -0
- package/dist/mentions/mention-plugin.js +291 -0
- package/dist/mentions/mention-plugin.js.map +1 -0
- package/dist/mentions/mention-plugin.mjs +284 -0
- package/dist/mentions/mention-plugin.mjs.map +1 -0
- package/dist/mentions/suggestions.js +161 -0
- package/dist/mentions/suggestions.js.map +1 -0
- package/dist/mentions/suggestions.mjs +158 -0
- package/dist/mentions/suggestions.mjs.map +1 -0
- package/dist/mentions/user.js +21 -0
- package/dist/mentions/user.js.map +1 -0
- package/dist/mentions/user.mjs +19 -0
- package/dist/mentions/user.mjs.map +1 -0
- package/dist/version.js +10 -0
- package/dist/version.js.map +1 -0
- package/dist/version.mjs +6 -0
- package/dist/version.mjs.map +1 -0
- 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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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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;;;;"}
|