@liveblocks/react-lexical 1.12.0-lexical6 → 2.0.0-alpha3

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 (80) hide show
  1. package/dist/classnames.js +8 -0
  2. package/dist/classnames.js.map +1 -0
  3. package/dist/classnames.mjs +6 -0
  4. package/dist/classnames.mjs.map +1 -0
  5. package/dist/comments/ThreadPanel.js +41 -16
  6. package/dist/comments/ThreadPanel.js.map +1 -1
  7. package/dist/comments/ThreadPanel.mjs +43 -18
  8. package/dist/comments/ThreadPanel.mjs.map +1 -1
  9. package/dist/comments/comment-plugin-provider.js +18 -106
  10. package/dist/comments/comment-plugin-provider.js.map +1 -1
  11. package/dist/comments/comment-plugin-provider.mjs +17 -104
  12. package/dist/comments/comment-plugin-provider.mjs.map +1 -1
  13. package/dist/comments/floating-composer.js +226 -15
  14. package/dist/comments/floating-composer.js.map +1 -1
  15. package/dist/comments/floating-composer.mjs +224 -15
  16. package/dist/comments/floating-composer.mjs.map +1 -1
  17. package/dist/create-dom-range.js +63 -0
  18. package/dist/create-dom-range.js.map +1 -0
  19. package/dist/create-dom-range.mjs +61 -0
  20. package/dist/create-dom-range.mjs.map +1 -0
  21. package/dist/create-rects-from-dom-range.js +36 -0
  22. package/dist/create-rects-from-dom-range.js.map +1 -0
  23. package/dist/create-rects-from-dom-range.mjs +34 -0
  24. package/dist/create-rects-from-dom-range.mjs.map +1 -0
  25. package/dist/index.d.mts +30 -40
  26. package/dist/index.d.ts +30 -40
  27. package/dist/index.js +5 -6
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +3 -4
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/liveblocks-config.js +3 -75
  32. package/dist/liveblocks-config.js.map +1 -1
  33. package/dist/liveblocks-config.mjs +4 -56
  34. package/dist/liveblocks-config.mjs.map +1 -1
  35. package/dist/liveblocks-plugin-provider.js +39 -43
  36. package/dist/liveblocks-plugin-provider.js.map +1 -1
  37. package/dist/liveblocks-plugin-provider.mjs +41 -44
  38. package/dist/liveblocks-plugin-provider.mjs.map +1 -1
  39. package/dist/mentions/avatar.js +10 -6
  40. package/dist/mentions/avatar.js.map +1 -1
  41. package/dist/mentions/avatar.mjs +10 -6
  42. package/dist/mentions/avatar.mjs.map +1 -1
  43. package/dist/mentions/mention-component.js +5 -18
  44. package/dist/mentions/mention-component.js.map +1 -1
  45. package/dist/mentions/mention-component.mjs +7 -19
  46. package/dist/mentions/mention-component.mjs.map +1 -1
  47. package/dist/mentions/mention-node.js +76 -80
  48. package/dist/mentions/mention-node.js.map +1 -1
  49. package/dist/mentions/mention-node.mjs +75 -81
  50. package/dist/mentions/mention-node.mjs.map +1 -1
  51. package/dist/mentions/mention-plugin.js +102 -90
  52. package/dist/mentions/mention-plugin.js.map +1 -1
  53. package/dist/mentions/mention-plugin.mjs +87 -71
  54. package/dist/mentions/mention-plugin.mjs.map +1 -1
  55. package/dist/mentions/suggestions.js +34 -6
  56. package/dist/mentions/suggestions.js.map +1 -1
  57. package/dist/mentions/suggestions.mjs +28 -3
  58. package/dist/mentions/suggestions.mjs.map +1 -1
  59. package/dist/mentions/user.js +8 -5
  60. package/dist/mentions/user.js.map +1 -1
  61. package/dist/mentions/user.mjs +8 -5
  62. package/dist/mentions/user.mjs.map +1 -1
  63. package/dist/version.js +1 -1
  64. package/dist/version.js.map +1 -1
  65. package/dist/version.mjs +1 -1
  66. package/dist/version.mjs.map +1 -1
  67. package/package.json +13 -13
  68. package/src/styles/constants.css +1 -0
  69. package/src/styles/index.css +158 -5
  70. package/src/styles/utils.css +6 -0
  71. package/styles.css +1 -1
  72. package/styles.css.map +1 -1
  73. package/dist/active-selection.js +0 -143
  74. package/dist/active-selection.js.map +0 -1
  75. package/dist/active-selection.mjs +0 -123
  76. package/dist/active-selection.mjs.map +0 -1
  77. package/dist/floating-selection-container.js +0 -157
  78. package/dist/floating-selection-container.js.map +0 -1
  79. package/dist/floating-selection-container.mjs +0 -155
  80. 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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"}