@liveblocks/react-lexical 1.12.0-lexical4 → 2.0.0-alpha2
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/classnames.js +8 -0
- package/dist/classnames.js.map +1 -0
- package/dist/classnames.mjs +6 -0
- package/dist/classnames.mjs.map +1 -0
- package/dist/comments/ThreadPanel.js +27 -7
- package/dist/comments/ThreadPanel.js.map +1 -1
- package/dist/comments/ThreadPanel.mjs +28 -8
- package/dist/comments/ThreadPanel.mjs.map +1 -1
- package/dist/comments/comment-plugin-provider.js +18 -106
- package/dist/comments/comment-plugin-provider.js.map +1 -1
- package/dist/comments/comment-plugin-provider.mjs +17 -104
- package/dist/comments/comment-plugin-provider.mjs.map +1 -1
- package/dist/comments/floating-composer.js +226 -15
- package/dist/comments/floating-composer.js.map +1 -1
- package/dist/comments/floating-composer.mjs +224 -15
- package/dist/comments/floating-composer.mjs.map +1 -1
- package/dist/comments/thread-mark-node.js +1 -16
- package/dist/comments/thread-mark-node.js.map +1 -1
- package/dist/comments/thread-mark-node.mjs +1 -16
- package/dist/comments/thread-mark-node.mjs.map +1 -1
- package/dist/create-dom-range.js +63 -0
- package/dist/create-dom-range.js.map +1 -0
- package/dist/create-dom-range.mjs +61 -0
- package/dist/create-dom-range.mjs.map +1 -0
- package/dist/create-rects-from-dom-range.js +36 -0
- package/dist/create-rects-from-dom-range.js.map +1 -0
- package/dist/create-rects-from-dom-range.mjs +34 -0
- package/dist/create-rects-from-dom-range.mjs.map +1 -0
- package/dist/index.d.mts +113 -0
- package/dist/index.d.ts +96 -44
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -4
- package/dist/index.mjs.map +1 -1
- package/dist/liveblocks-config.js +3 -75
- package/dist/liveblocks-config.js.map +1 -1
- package/dist/liveblocks-config.mjs +4 -56
- package/dist/liveblocks-config.mjs.map +1 -1
- package/dist/liveblocks-plugin-provider.js +12 -29
- package/dist/liveblocks-plugin-provider.js.map +1 -1
- package/dist/liveblocks-plugin-provider.mjs +13 -29
- package/dist/liveblocks-plugin-provider.mjs.map +1 -1
- package/dist/mentions/avatar.js +11 -7
- package/dist/mentions/avatar.js.map +1 -1
- package/dist/mentions/avatar.mjs +11 -7
- package/dist/mentions/avatar.mjs.map +1 -1
- package/dist/mentions/mention-component.js +5 -18
- package/dist/mentions/mention-component.js.map +1 -1
- package/dist/mentions/mention-component.mjs +7 -19
- package/dist/mentions/mention-component.mjs.map +1 -1
- package/dist/mentions/mention-node.js +77 -74
- package/dist/mentions/mention-node.js.map +1 -1
- package/dist/mentions/mention-node.mjs +76 -75
- package/dist/mentions/mention-node.mjs.map +1 -1
- package/dist/mentions/mention-plugin.js +130 -91
- package/dist/mentions/mention-plugin.js.map +1 -1
- package/dist/mentions/mention-plugin.mjs +119 -76
- package/dist/mentions/mention-plugin.mjs.map +1 -1
- package/dist/mentions/suggestions.js +34 -6
- package/dist/mentions/suggestions.js.map +1 -1
- package/dist/mentions/suggestions.mjs +28 -3
- package/dist/mentions/suggestions.mjs.map +1 -1
- package/dist/mentions/user.js +9 -6
- package/dist/mentions/user.js.map +1 -1
- package/dist/mentions/user.mjs +9 -6
- package/dist/mentions/user.mjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/version.mjs +1 -1
- package/dist/version.mjs.map +1 -1
- package/package.json +23 -15
- package/src/styles/constants.css +1 -0
- package/src/styles/index.css +154 -0
- package/src/styles/utils.css +6 -0
- package/styles.css +1 -0
- package/styles.css.d.ts +1 -0
- package/styles.css.map +1 -0
- package/dist/active-selection.js +0 -143
- package/dist/active-selection.js.map +0 -1
- package/dist/active-selection.mjs +0 -123
- package/dist/active-selection.mjs.map +0 -1
- package/dist/floating-selection-container.js +0 -157
- package/dist/floating-selection-container.js.map +0 -1
- package/dist/floating-selection-container.mjs +0 -155
- package/dist/floating-selection-container.mjs.map +0 -1
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
2
|
-
import { createDOMRange, createRectsFromDOMRange } from '@lexical/selection';
|
|
3
|
-
import { $getSelection, $isRangeSelection } from 'lexical';
|
|
4
|
-
import * as React from 'react';
|
|
5
|
-
import { useRef, useLayoutEffect, useCallback } from 'react';
|
|
6
|
-
import { createPortal } from 'react-dom';
|
|
7
|
-
import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js';
|
|
8
|
-
|
|
9
|
-
function ActiveSelection({ styles }) {
|
|
10
|
-
const [editor] = useLexicalComposerContext();
|
|
11
|
-
const selection = useSelection();
|
|
12
|
-
if (selection === null)
|
|
13
|
-
return null;
|
|
14
|
-
const info = editor.getEditorState().read(() => {
|
|
15
|
-
return {
|
|
16
|
-
anchor: {
|
|
17
|
-
node: selection.anchor.getNode(),
|
|
18
|
-
offset: selection.anchor.offset
|
|
19
|
-
},
|
|
20
|
-
focus: {
|
|
21
|
-
node: selection.focus.getNode(),
|
|
22
|
-
offset: selection.focus.offset
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
});
|
|
26
|
-
const root = editor.getRootElement();
|
|
27
|
-
if (root === null)
|
|
28
|
-
return null;
|
|
29
|
-
const rootContainer = root.parentElement;
|
|
30
|
-
if (rootContainer === null)
|
|
31
|
-
return null;
|
|
32
|
-
return createPortal(
|
|
33
|
-
/* @__PURE__ */ React.createElement(SelectionRects, {
|
|
34
|
-
selection: info,
|
|
35
|
-
styles
|
|
36
|
-
}),
|
|
37
|
-
rootContainer
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
function SelectionRects({
|
|
41
|
-
selection,
|
|
42
|
-
styles = {}
|
|
43
|
-
}) {
|
|
44
|
-
const [editor] = useLexicalComposerContext();
|
|
45
|
-
const divRef = useRef(null);
|
|
46
|
-
useLayoutEffect(() => {
|
|
47
|
-
const container = divRef.current;
|
|
48
|
-
if (container === null)
|
|
49
|
-
return;
|
|
50
|
-
function drawSelectionRects() {
|
|
51
|
-
if (container === null)
|
|
52
|
-
return;
|
|
53
|
-
while (container.firstChild) {
|
|
54
|
-
container.removeChild(container.firstChild);
|
|
55
|
-
}
|
|
56
|
-
const range = createDOMRange(
|
|
57
|
-
editor,
|
|
58
|
-
selection.anchor.node,
|
|
59
|
-
selection.anchor.offset,
|
|
60
|
-
selection.focus.node,
|
|
61
|
-
selection.focus.offset
|
|
62
|
-
);
|
|
63
|
-
if (range === null)
|
|
64
|
-
return;
|
|
65
|
-
const rects = createRectsFromDOMRange(editor, range);
|
|
66
|
-
for (const rect of rects) {
|
|
67
|
-
const div = document.createElement("div");
|
|
68
|
-
Object.assign(div.style, {
|
|
69
|
-
backgroundColor: "rgba(255, 212, 0, 0.14)",
|
|
70
|
-
...styles,
|
|
71
|
-
position: "absolute",
|
|
72
|
-
top: `${rect.top - container.getBoundingClientRect().top}px`,
|
|
73
|
-
left: `${rect.left - container.getBoundingClientRect().left}px`,
|
|
74
|
-
width: `${rect.width}px`,
|
|
75
|
-
height: `${rect.height}px`,
|
|
76
|
-
pointerEvents: "none"
|
|
77
|
-
});
|
|
78
|
-
container.appendChild(div);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
const observer = new ResizeObserver(drawSelectionRects);
|
|
82
|
-
observer.observe(container);
|
|
83
|
-
const unsubscribeFromUpdates = editor.registerUpdateListener(drawSelectionRects);
|
|
84
|
-
return () => {
|
|
85
|
-
observer.disconnect();
|
|
86
|
-
unsubscribeFromUpdates();
|
|
87
|
-
};
|
|
88
|
-
}, [selection, editor, styles]);
|
|
89
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
90
|
-
ref: divRef,
|
|
91
|
-
style: {
|
|
92
|
-
position: "absolute",
|
|
93
|
-
top: 0,
|
|
94
|
-
left: 0,
|
|
95
|
-
width: "100%",
|
|
96
|
-
height: "100%",
|
|
97
|
-
pointerEvents: "none"
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
function useSelection() {
|
|
102
|
-
const [editor] = useLexicalComposerContext();
|
|
103
|
-
const subscribe = useCallback(
|
|
104
|
-
(onStoreChange) => {
|
|
105
|
-
return editor.registerUpdateListener(onStoreChange);
|
|
106
|
-
},
|
|
107
|
-
[editor]
|
|
108
|
-
);
|
|
109
|
-
const getSnapshot = useCallback(() => {
|
|
110
|
-
return editor.getEditorState().read(() => {
|
|
111
|
-
const selection = $getSelection();
|
|
112
|
-
if (!$isRangeSelection(selection))
|
|
113
|
-
return null;
|
|
114
|
-
if (selection.isCollapsed())
|
|
115
|
-
return null;
|
|
116
|
-
return selection;
|
|
117
|
-
});
|
|
118
|
-
}, [editor]);
|
|
119
|
-
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export { ActiveSelection };
|
|
123
|
-
//# sourceMappingURL=active-selection.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"active-selection.mjs","sources":["../src/active-selection.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { createDOMRange, createRectsFromDOMRange } from \"@lexical/selection\";\nimport type { LexicalNode, RangeSelection } from \"lexical\";\nimport { $getSelection, $isRangeSelection } from \"lexical\";\nimport * as React from \"react\";\nimport { useCallback, useLayoutEffect, useRef } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n\ninterface ActiveSelectionProps {\n styles?: Partial<CSSStyleDeclaration>;\n}\n\nexport function ActiveSelection({ styles }: ActiveSelectionProps) {\n const [editor] = useLexicalComposerContext();\n const selection = useSelection();\n if (selection === null) 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 <SelectionRects selection={info} styles={styles} />,\n rootContainer\n );\n}\n\nfunction SelectionRects({\n selection,\n styles = {},\n}: {\n selection: SelectionInfo;\n styles?: Partial<CSSStyleDeclaration>;\n}) {\n const [editor] = useLexicalComposerContext();\n\n const divRef = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n const container = divRef.current;\n if (container === null) return;\n\n function drawSelectionRects() {\n if (container === null) return;\n\n // Remove all existing children of the container\n while (container.firstChild) {\n container.removeChild(container.firstChild);\n }\n\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 const rects = createRectsFromDOMRange(editor, range);\n\n for (const rect of rects) {\n const div = document.createElement(\"div\");\n\n Object.assign(div.style, {\n backgroundColor: \"rgba(255, 212, 0, 0.14)\",\n ...styles,\n position: \"absolute\",\n top: `${rect.top - container.getBoundingClientRect().top}px`,\n left: `${rect.left - container.getBoundingClientRect().left}px`,\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n pointerEvents: \"none\",\n });\n\n container.appendChild(div);\n }\n }\n\n // Observe resizes of the container element to redraw the selection\n const observer = new ResizeObserver(drawSelectionRects);\n\n observer.observe(container);\n\n // Listen to updates in the editor to redraw the selection\n const unsubscribeFromUpdates =\n editor.registerUpdateListener(drawSelectionRects);\n\n return () => {\n observer.disconnect();\n unsubscribeFromUpdates();\n };\n }, [selection, editor, styles]);\n\n return (\n <div\n ref={divRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n }}\n />\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\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 if (selection.isCollapsed()) return null;\n\n return selection;\n });\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,157 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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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"}
|
|
@@ -1,155 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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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"}
|