@liveblocks/react-lexical 2.18.3 → 2.18.4-uns2
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.mjs → classnames.cjs} +4 -2
- package/dist/{classnames.mjs.map → classnames.cjs.map} +1 -1
- package/dist/classnames.js +1 -3
- package/dist/classnames.js.map +1 -1
- package/dist/comments/{anchored-threads.mjs → anchored-threads.cjs} +44 -41
- package/dist/comments/{anchored-threads.mjs.map → anchored-threads.cjs.map} +1 -1
- package/dist/comments/anchored-threads.js +40 -43
- package/dist/comments/anchored-threads.js.map +1 -1
- package/dist/comments/{comment-plugin-provider.mjs → comment-plugin-provider.cjs} +62 -55
- package/dist/comments/{comment-plugin-provider.mjs.map → comment-plugin-provider.cjs.map} +1 -1
- package/dist/comments/comment-plugin-provider.js +54 -61
- package/dist/comments/comment-plugin-provider.js.map +1 -1
- package/dist/comments/{floating-composer.mjs → floating-composer.cjs} +68 -64
- package/dist/comments/{floating-composer.mjs.map → floating-composer.cjs.map} +1 -1
- package/dist/comments/floating-composer.js +63 -67
- package/dist/comments/floating-composer.js.map +1 -1
- package/dist/comments/{floating-threads.mjs → floating-threads.cjs} +51 -48
- package/dist/comments/{floating-threads.mjs.map → floating-threads.cjs.map} +1 -1
- package/dist/comments/floating-threads.js +47 -50
- package/dist/comments/floating-threads.js.map +1 -1
- package/dist/comments/get-thread-mark-ids.cjs +23 -0
- package/dist/comments/{get-thread-mark-ids.mjs.map → get-thread-mark-ids.cjs.map} +1 -1
- package/dist/comments/get-thread-mark-ids.js +6 -8
- package/dist/comments/get-thread-mark-ids.js.map +1 -1
- package/dist/comments/{thread-mark-node.mjs → thread-mark-node.cjs} +10 -6
- package/dist/comments/{thread-mark-node.mjs.map → thread-mark-node.cjs.map} +1 -1
- package/dist/comments/thread-mark-node.js +5 -9
- package/dist/comments/thread-mark-node.js.map +1 -1
- package/dist/comments/{unwrap-thread-mark-node.mjs → unwrap-thread-mark-node.cjs} +4 -2
- package/dist/comments/unwrap-thread-mark-node.cjs.map +1 -0
- package/dist/comments/unwrap-thread-mark-node.js +1 -3
- package/dist/comments/unwrap-thread-mark-node.js.map +1 -1
- package/dist/comments/{wrap-selection-in-thread-mark-node.mjs → wrap-selection-in-thread-mark-node.cjs} +12 -10
- package/dist/comments/{wrap-selection-in-thread-mark-node.mjs.map → wrap-selection-in-thread-mark-node.cjs.map} +1 -1
- package/dist/comments/wrap-selection-in-thread-mark-node.js +9 -11
- package/dist/comments/wrap-selection-in-thread-mark-node.js.map +1 -1
- package/dist/{create-dom-range.mjs → create-dom-range.cjs} +7 -5
- package/dist/{create-dom-range.mjs.map → create-dom-range.cjs.map} +1 -1
- package/dist/create-dom-range.js +4 -6
- package/dist/create-dom-range.js.map +1 -1
- package/dist/{create-rects-from-dom-range.mjs → create-rects-from-dom-range.cjs} +4 -2
- package/dist/{create-rects-from-dom-range.mjs.map → create-rects-from-dom-range.cjs.map} +1 -1
- package/dist/create-rects-from-dom-range.js +1 -3
- package/dist/create-rects-from-dom-range.js.map +1 -1
- package/dist/index.cjs +33 -0
- package/dist/{index.mjs.map → index.cjs.map} +1 -1
- package/dist/index.js +14 -31
- package/dist/index.js.map +1 -1
- package/dist/{is-block-node-active.mjs → is-block-node-active.cjs} +12 -10
- package/dist/{is-block-node-active.mjs.map → is-block-node-active.cjs.map} +1 -1
- package/dist/is-block-node-active.js +9 -11
- package/dist/is-block-node-active.js.map +1 -1
- package/dist/is-command-registered.cjs +11 -0
- package/dist/{is-command-registered.mjs.map → is-command-registered.cjs.map} +1 -1
- package/dist/is-command-registered.js +3 -5
- package/dist/is-command-registered.js.map +1 -1
- package/dist/is-text-format-active.cjs +16 -0
- package/dist/{is-text-format-active.mjs.map → is-text-format-active.cjs.map} +1 -1
- package/dist/is-text-format-active.js +4 -6
- package/dist/is-text-format-active.js.map +1 -1
- package/dist/liveblocks-config.cjs +17 -0
- package/dist/{liveblocks-config.mjs.map → liveblocks-config.cjs.map} +1 -1
- package/dist/liveblocks-config.js +4 -6
- package/dist/liveblocks-config.js.map +1 -1
- package/dist/liveblocks-plugin-provider.cjs +151 -0
- package/dist/liveblocks-plugin-provider.cjs.map +1 -0
- package/dist/liveblocks-plugin-provider.js +43 -47
- package/dist/liveblocks-plugin-provider.js.map +1 -1
- package/dist/mentions/{avatar.mjs → avatar.cjs} +16 -14
- package/dist/mentions/avatar.cjs.map +1 -0
- package/dist/mentions/avatar.js +13 -15
- package/dist/mentions/avatar.js.map +1 -1
- package/dist/mentions/mention-component.cjs +51 -0
- package/dist/mentions/{mention-component.mjs.map → mention-component.cjs.map} +1 -1
- package/dist/mentions/mention-component.js +14 -16
- package/dist/mentions/mention-component.js.map +1 -1
- package/dist/mentions/{mention-node.mjs → mention-node.cjs} +16 -12
- package/dist/mentions/{mention-node.mjs.map → mention-node.cjs.map} +1 -1
- package/dist/mentions/mention-node.js +11 -15
- package/dist/mentions/mention-node.js.map +1 -1
- package/dist/mentions/{mention-plugin.mjs → mention-plugin.cjs} +81 -78
- package/dist/mentions/{mention-plugin.mjs.map → mention-plugin.cjs.map} +1 -1
- package/dist/mentions/mention-plugin.js +77 -80
- package/dist/mentions/mention-plugin.js.map +1 -1
- package/dist/mentions/{suggestions.mjs → suggestions.cjs} +43 -37
- package/dist/mentions/{suggestions.mjs.map → suggestions.cjs.map} +1 -1
- package/dist/mentions/suggestions.js +36 -42
- package/dist/mentions/suggestions.js.map +1 -1
- package/dist/mentions/user.cjs +26 -0
- package/dist/mentions/{user.mjs.map → user.cjs.map} +1 -1
- package/dist/mentions/user.js +11 -13
- package/dist/mentions/user.js.map +1 -1
- package/dist/toolbar/{floating-toolbar.mjs → floating-toolbar.cjs} +73 -70
- package/dist/toolbar/{floating-toolbar.mjs.map → floating-toolbar.cjs.map} +1 -1
- package/dist/toolbar/floating-toolbar.js +69 -72
- package/dist/toolbar/floating-toolbar.js.map +1 -1
- package/dist/toolbar/shared.cjs +36 -0
- package/dist/toolbar/{shared.mjs.map → shared.cjs.map} +1 -1
- package/dist/toolbar/shared.js +12 -15
- package/dist/toolbar/shared.js.map +1 -1
- package/dist/toolbar/toolbar.cjs +433 -0
- package/dist/toolbar/{toolbar.mjs.map → toolbar.cjs.map} +1 -1
- package/dist/toolbar/toolbar.js +131 -156
- package/dist/toolbar/toolbar.js.map +1 -1
- package/dist/use-root-element.cjs +21 -0
- package/dist/use-root-element.cjs.map +1 -0
- package/dist/use-root-element.js +7 -9
- package/dist/use-root-element.js.map +1 -1
- package/dist/version-history/{history-version-preview.mjs → history-version-preview.cjs} +52 -50
- package/dist/version-history/{history-version-preview.mjs.map → history-version-preview.cjs.map} +1 -1
- package/dist/version-history/history-version-preview.js +49 -51
- package/dist/version-history/history-version-preview.js.map +1 -1
- package/dist/version.cjs +10 -0
- package/dist/{version.mjs.map → version.cjs.map} +1 -1
- package/dist/version.js +3 -7
- package/dist/version.js.map +1 -1
- package/package.json +18 -17
- package/styles.css.d.cts +1 -0
- package/dist/comments/get-thread-mark-ids.mjs +0 -21
- package/dist/comments/unwrap-thread-mark-node.mjs.map +0 -1
- package/dist/index.mjs +0 -16
- package/dist/is-command-registered.mjs +0 -9
- package/dist/is-text-format-active.mjs +0 -14
- package/dist/liveblocks-config.mjs +0 -15
- package/dist/liveblocks-plugin-provider.mjs +0 -147
- package/dist/liveblocks-plugin-provider.mjs.map +0 -1
- package/dist/mentions/avatar.mjs.map +0 -1
- package/dist/mentions/mention-component.mjs +0 -49
- package/dist/mentions/user.mjs +0 -24
- package/dist/toolbar/shared.mjs +0 -33
- package/dist/toolbar/toolbar.mjs +0 -408
- package/dist/use-root-element.mjs +0 -19
- package/dist/use-root-element.mjs.map +0 -1
- package/dist/version.mjs +0 -6
- /package/dist/{index.d.mts → index.d.cts} +0 -0
|
@@ -1,31 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
import { useFloating, offset, autoUpdate, inline, flip, hide, shift, limitShift, size } from '@floating-ui/react-dom';
|
|
3
|
-
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
4
|
-
import { useCreateThread } from '@liveblocks/react';
|
|
5
|
-
import { useLayoutEffect } from '@liveblocks/react/_private';
|
|
6
|
-
import { Composer } from '@liveblocks/react-ui';
|
|
7
|
-
import { createCommand, $getSelection, $isRangeSelection, COMMAND_PRIORITY_EDITOR, $setSelection } from 'lexical';
|
|
8
|
-
import { forwardRef, useState, useEffect, useCallback } from 'react';
|
|
9
|
-
import { createPortal } from 'react-dom';
|
|
10
|
-
import { createDOMRange } from '../create-dom-range.mjs';
|
|
11
|
-
import { createRectsFromDOMRange } from '../create-rects-from-dom-range.mjs';
|
|
12
|
-
import $wrapSelectionInThreadMarkNode from './wrap-selection-in-thread-mark-node.mjs';
|
|
1
|
+
'use strict';
|
|
13
2
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var reactDom = require('@floating-ui/react-dom');
|
|
5
|
+
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
6
|
+
var react$1 = require('@liveblocks/react');
|
|
7
|
+
var _private = require('@liveblocks/react/_private');
|
|
8
|
+
var reactUi = require('@liveblocks/react-ui');
|
|
9
|
+
var lexical = require('lexical');
|
|
10
|
+
var react = require('react');
|
|
11
|
+
var reactDom$1 = require('react-dom');
|
|
12
|
+
var createDomRange = require('../create-dom-range.cjs');
|
|
13
|
+
var createRectsFromDomRange = require('../create-rects-from-dom-range.cjs');
|
|
14
|
+
var wrapSelectionInThreadMarkNode = require('./wrap-selection-in-thread-mark-node.cjs');
|
|
15
|
+
|
|
16
|
+
const OPEN_FLOATING_COMPOSER_COMMAND = lexical.createCommand("OPEN_FLOATING_COMPOSER_COMMAND");
|
|
17
|
+
const FloatingComposer = react.forwardRef(function FloatingComposer2(props, forwardedRef) {
|
|
18
|
+
const [range, setRange] = react.useState(null);
|
|
19
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
20
|
+
react.useEffect(() => {
|
|
19
21
|
return editor.registerCommand(
|
|
20
22
|
OPEN_FLOATING_COMPOSER_COMMAND,
|
|
21
23
|
() => {
|
|
22
|
-
const selection =
|
|
23
|
-
if (
|
|
24
|
+
const selection = lexical.$getSelection();
|
|
25
|
+
if (!lexical.$isRangeSelection(selection))
|
|
24
26
|
return false;
|
|
25
27
|
if (selection.isCollapsed())
|
|
26
28
|
return false;
|
|
27
29
|
const { anchor, focus } = selection;
|
|
28
|
-
const range2 = createDOMRange(
|
|
30
|
+
const range2 = createDomRange.createDOMRange(
|
|
29
31
|
editor,
|
|
30
32
|
anchor.getNode(),
|
|
31
33
|
anchor.offset,
|
|
@@ -35,19 +37,19 @@ const FloatingComposer = forwardRef(function FloatingComposer2(props, forwardedR
|
|
|
35
37
|
setRange(range2);
|
|
36
38
|
return true;
|
|
37
39
|
},
|
|
38
|
-
COMMAND_PRIORITY_EDITOR
|
|
40
|
+
lexical.COMMAND_PRIORITY_EDITOR
|
|
39
41
|
);
|
|
40
42
|
}, [editor]);
|
|
41
43
|
if (range === null)
|
|
42
44
|
return null;
|
|
43
|
-
return /* @__PURE__ */ jsx(FloatingComposerImpl, {
|
|
45
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FloatingComposerImpl, {
|
|
44
46
|
ref: forwardedRef,
|
|
45
47
|
...props,
|
|
46
48
|
range,
|
|
47
49
|
onRangeChange: setRange
|
|
48
50
|
});
|
|
49
51
|
});
|
|
50
|
-
const FloatingComposerImpl = forwardRef(function FloatingComposer3(props, forwardedRef) {
|
|
52
|
+
const FloatingComposerImpl = react.forwardRef(function FloatingComposer3(props, forwardedRef) {
|
|
51
53
|
const {
|
|
52
54
|
range,
|
|
53
55
|
onRangeChange,
|
|
@@ -55,15 +57,15 @@ const FloatingComposerImpl = forwardRef(function FloatingComposer3(props, forwar
|
|
|
55
57
|
onComposerSubmit,
|
|
56
58
|
...composerProps
|
|
57
59
|
} = props;
|
|
58
|
-
const [editor] = useLexicalComposerContext();
|
|
59
|
-
const createThread = useCreateThread();
|
|
60
|
-
const $onStateRead = useCallback(() => {
|
|
61
|
-
const selection =
|
|
62
|
-
if (
|
|
60
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
61
|
+
const createThread = react$1.useCreateThread();
|
|
62
|
+
const $onStateRead = react.useCallback(() => {
|
|
63
|
+
const selection = lexical.$getSelection();
|
|
64
|
+
if (!lexical.$isRangeSelection(selection) || selection.isCollapsed()) {
|
|
63
65
|
return null;
|
|
64
66
|
}
|
|
65
67
|
const { anchor, focus } = selection;
|
|
66
|
-
const range2 = createDOMRange(
|
|
68
|
+
const range2 = createDomRange.createDOMRange(
|
|
67
69
|
editor,
|
|
68
70
|
anchor.getNode(),
|
|
69
71
|
anchor.offset,
|
|
@@ -72,7 +74,7 @@ const FloatingComposerImpl = forwardRef(function FloatingComposer3(props, forwar
|
|
|
72
74
|
);
|
|
73
75
|
return range2;
|
|
74
76
|
}, [editor]);
|
|
75
|
-
useEffect(() => {
|
|
77
|
+
react.useEffect(() => {
|
|
76
78
|
return editor.registerUpdateListener(({ editorState: state, tags }) => {
|
|
77
79
|
if (!tags.has("collaboration")) {
|
|
78
80
|
onRangeChange(null);
|
|
@@ -82,22 +84,22 @@ const FloatingComposerImpl = forwardRef(function FloatingComposer3(props, forwar
|
|
|
82
84
|
onRangeChange(range2);
|
|
83
85
|
});
|
|
84
86
|
}, [editor, range, onRangeChange, $onStateRead]);
|
|
85
|
-
const onThreadCreate = useCallback(
|
|
87
|
+
const onThreadCreate = react.useCallback(
|
|
86
88
|
(threadId) => {
|
|
87
89
|
editor.update(() => {
|
|
88
|
-
const selection =
|
|
89
|
-
if (
|
|
90
|
+
const selection = lexical.$getSelection();
|
|
91
|
+
if (!lexical.$isRangeSelection(selection))
|
|
90
92
|
return;
|
|
91
93
|
if (selection.isCollapsed())
|
|
92
94
|
return;
|
|
93
95
|
const isBackward = selection.isBackward();
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
wrapSelectionInThreadMarkNode(selection, isBackward, threadId);
|
|
97
|
+
lexical.$setSelection(null);
|
|
96
98
|
});
|
|
97
99
|
},
|
|
98
100
|
[editor]
|
|
99
101
|
);
|
|
100
|
-
const handleComposerSubmit = useCallback(
|
|
102
|
+
const handleComposerSubmit = react.useCallback(
|
|
101
103
|
(comment, event) => {
|
|
102
104
|
onComposerSubmit?.(comment, event);
|
|
103
105
|
if (event.defaultPrevented)
|
|
@@ -121,16 +123,16 @@ const FloatingComposerImpl = forwardRef(function FloatingComposer3(props, forwar
|
|
|
121
123
|
editor.focus();
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
|
-
return /* @__PURE__ */ jsxs(Fragment, {
|
|
126
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
125
127
|
children: [
|
|
126
|
-
/* @__PURE__ */ jsx(ActiveSelectionPortal, {
|
|
128
|
+
/* @__PURE__ */ jsxRuntime.jsx(ActiveSelectionPortal, {
|
|
127
129
|
range,
|
|
128
130
|
container: document.body
|
|
129
131
|
}),
|
|
130
|
-
/* @__PURE__ */ jsx(FloatingComposerPortal, {
|
|
132
|
+
/* @__PURE__ */ jsxRuntime.jsx(FloatingComposerPortal, {
|
|
131
133
|
range,
|
|
132
134
|
container: document.body,
|
|
133
|
-
children: /* @__PURE__ */ jsx(Composer, {
|
|
135
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactUi.Composer, {
|
|
134
136
|
autoFocus: true,
|
|
135
137
|
...composerProps,
|
|
136
138
|
onKeyDown: handleKeyDown,
|
|
@@ -150,24 +152,24 @@ function ActiveSelectionPortal({
|
|
|
150
152
|
strategy,
|
|
151
153
|
x,
|
|
152
154
|
y
|
|
153
|
-
} = useFloating({
|
|
155
|
+
} = reactDom.useFloating({
|
|
154
156
|
strategy: "fixed",
|
|
155
157
|
placement: "bottom",
|
|
156
|
-
middleware: [offset(-range.getBoundingClientRect().height)],
|
|
158
|
+
middleware: [reactDom.offset(-range.getBoundingClientRect().height)],
|
|
157
159
|
whileElementsMounted: (...args) => {
|
|
158
|
-
return autoUpdate(...args, {
|
|
160
|
+
return reactDom.autoUpdate(...args, {
|
|
159
161
|
animationFrame: true
|
|
160
162
|
});
|
|
161
163
|
}
|
|
162
164
|
});
|
|
163
|
-
useLayoutEffect(() => {
|
|
165
|
+
_private.useLayoutEffect(() => {
|
|
164
166
|
setReference(range);
|
|
165
167
|
}, [setReference, range]);
|
|
166
|
-
const [editor] = useLexicalComposerContext();
|
|
167
|
-
const rects = createRectsFromDOMRange(editor, range);
|
|
168
|
-
return createPortal(
|
|
169
|
-
/* @__PURE__ */ jsx(Fragment, {
|
|
170
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
168
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
169
|
+
const rects = createRectsFromDomRange.createRectsFromDOMRange(editor, range);
|
|
170
|
+
return reactDom$1.createPortal(
|
|
171
|
+
/* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
172
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", {
|
|
171
173
|
ref: setFloating,
|
|
172
174
|
style: {
|
|
173
175
|
position: strategy,
|
|
@@ -180,7 +182,7 @@ function ActiveSelectionPortal({
|
|
|
180
182
|
pointerEvents: "none"
|
|
181
183
|
},
|
|
182
184
|
className: "lb-root lb-portal",
|
|
183
|
-
children: rects.map((rect) => /* @__PURE__ */ jsx("span", {
|
|
185
|
+
children: rects.map((rect) => /* @__PURE__ */ jsxRuntime.jsx("span", {
|
|
184
186
|
style: {
|
|
185
187
|
position: "absolute",
|
|
186
188
|
top: rect.top - range.getBoundingClientRect().top,
|
|
@@ -208,31 +210,31 @@ function FloatingComposerPortal({
|
|
|
208
210
|
strategy,
|
|
209
211
|
x,
|
|
210
212
|
y
|
|
211
|
-
} = useFloating({
|
|
213
|
+
} = reactDom.useFloating({
|
|
212
214
|
strategy: "fixed",
|
|
213
215
|
placement: "bottom",
|
|
214
216
|
middleware: [
|
|
215
|
-
inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),
|
|
216
|
-
flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),
|
|
217
|
-
offset(10),
|
|
218
|
-
hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),
|
|
219
|
-
shift({
|
|
217
|
+
reactDom.inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),
|
|
218
|
+
reactDom.flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),
|
|
219
|
+
reactDom.offset(10),
|
|
220
|
+
reactDom.hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),
|
|
221
|
+
reactDom.shift({
|
|
220
222
|
padding: FLOATING_COMPOSER_COLLISION_PADDING,
|
|
221
|
-
limiter: limitShift()
|
|
223
|
+
limiter: reactDom.limitShift()
|
|
222
224
|
}),
|
|
223
|
-
size({ padding: FLOATING_COMPOSER_COLLISION_PADDING })
|
|
225
|
+
reactDom.size({ padding: FLOATING_COMPOSER_COLLISION_PADDING })
|
|
224
226
|
],
|
|
225
227
|
whileElementsMounted: (...args) => {
|
|
226
|
-
return autoUpdate(...args, {
|
|
228
|
+
return reactDom.autoUpdate(...args, {
|
|
227
229
|
animationFrame: true
|
|
228
230
|
});
|
|
229
231
|
}
|
|
230
232
|
});
|
|
231
|
-
useLayoutEffect(() => {
|
|
233
|
+
_private.useLayoutEffect(() => {
|
|
232
234
|
setReference(range);
|
|
233
235
|
}, [range, setReference]);
|
|
234
|
-
return createPortal(
|
|
235
|
-
/* @__PURE__ */ jsx("div", {
|
|
236
|
+
return reactDom$1.createPortal(
|
|
237
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
236
238
|
ref: setFloating,
|
|
237
239
|
style: {
|
|
238
240
|
position: strategy,
|
|
@@ -248,5 +250,7 @@ function FloatingComposerPortal({
|
|
|
248
250
|
);
|
|
249
251
|
}
|
|
250
252
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
+
exports.FLOATING_COMPOSER_COLLISION_PADDING = FLOATING_COMPOSER_COLLISION_PADDING;
|
|
254
|
+
exports.FloatingComposer = FloatingComposer;
|
|
255
|
+
exports.OPEN_FLOATING_COMPOSER_COMMAND = OPEN_FLOATING_COMPOSER_COMMAND;
|
|
256
|
+
//# sourceMappingURL=floating-composer.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floating-composer.mjs","sources":["../../src/comments/floating-composer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer } from \"@liveblocks/react-ui\";\nimport type { LexicalCommand } from \"lexical\";\nimport {\n $getSelection,\n $isRangeSelection,\n $setSelection,\n COMMAND_PRIORITY_EDITOR,\n createCommand,\n} from \"lexical\";\nimport type { ComponentRef, FormEvent, KeyboardEvent, ReactNode } from \"react\";\nimport { forwardRef, useCallback, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { createDOMRange } from \"../create-dom-range\";\nimport { createRectsFromDOMRange } from \"../create-rects-from-dom-range\";\nimport $wrapSelectionInThreadMarkNode from \"./wrap-selection-in-thread-mark-node\";\n\n/**\n * Dispatching OPEN_FLOATING_COMPOSER_COMMAND will display the FloatingComposer\n *\n * @example\n * import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\n * import { OPEN_FLOATING_COMPOSER_COMMAND } from \"@liveblocks/react-lexical\";\n *\n * function Toolbar() {\n * const [editor] = useLexicalComposerContext();\n *\n * return (\n * <button\n * onClick={() => {\n * editor.dispatchCommand(OPEN_FLOATING_COMPOSER_COMMAND);\n * }}\n * >\n * 💬 New comment\n * </button>\n * );\n * }\n */\nexport const OPEN_FLOATING_COMPOSER_COMMAND: LexicalCommand<void> =\n createCommand(\"OPEN_FLOATING_COMPOSER_COMMAND\");\n\ntype ComposerElement = ComponentRef<typeof Composer>;\n\nexport type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n>;\n\n/**\n * Displays a `Composer` near the current lexical selection.\n *\n * To open it, dispatch `OPEN_FLOATING_COMPOSER_COMMAND`.\n *\n * Submitting a comment will attach an annotation thread at the current selection.\n * Should be nested inside `LiveblocksPlugin`.\n */\nexport const FloatingComposer = forwardRef<\n ComposerElement,\n FloatingComposerProps\n>(function FloatingComposer(props, forwardedRef) {\n const [range, setRange] = useState<Range | null>(null);\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return editor.registerCommand(\n OPEN_FLOATING_COMPOSER_COMMAND,\n () => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return false;\n\n if (selection.isCollapsed()) return false;\n\n const { anchor, focus } = selection;\n\n const range = createDOMRange(\n editor,\n anchor.getNode(),\n anchor.offset,\n focus.getNode(),\n focus.offset\n );\n\n setRange(range);\n\n return true;\n },\n COMMAND_PRIORITY_EDITOR\n );\n }, [editor]);\n\n if (range === null) return null;\n\n return (\n <FloatingComposerImpl\n ref={forwardedRef}\n {...props}\n range={range}\n onRangeChange={setRange}\n />\n );\n});\n\ninterface FloatingComposerImplProps extends FloatingComposerProps {\n range: Range;\n onRangeChange: (range: Range | null) => void;\n}\n\nconst FloatingComposerImpl = forwardRef<\n ComposerElement,\n FloatingComposerImplProps\n>(function FloatingComposer(props, forwardedRef) {\n const {\n range,\n onRangeChange,\n onKeyDown,\n onComposerSubmit,\n ...composerProps\n } = props;\n\n const [editor] = useLexicalComposerContext();\n const createThread = useCreateThread();\n\n const $onStateRead = useCallback((): Range | null => {\n const selection = $getSelection();\n\n // If the selection is not a range selection or is collapsed, clear the range so the composer is no longer displayed.\n if (!$isRangeSelection(selection) || selection.isCollapsed()) {\n return null;\n }\n\n const { anchor, focus } = selection;\n const range = createDOMRange(\n editor,\n anchor.getNode(),\n anchor.offset,\n focus.getNode(),\n focus.offset\n );\n\n return range;\n }, [editor]);\n\n useEffect(() => {\n return editor.registerUpdateListener(({ editorState: state, tags }) => {\n // If the update is not related to collaboration, clear the range so the composer is no longer displayed.\n if (!tags.has(\"collaboration\")) {\n onRangeChange(null);\n return;\n }\n\n const range = state.read(() => $onStateRead());\n onRangeChange(range);\n });\n }, [editor, range, onRangeChange, $onStateRead]);\n\n /**\n * Create a new ThreadMarkNode and wrap the selected content in it.\n * @param threadId The id of the thread to associate with the selected content\n */\n const onThreadCreate = useCallback(\n (threadId: string) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n // If the selection is collapsed, we do not create a new thread node in the editor.\n if (selection.isCollapsed()) return;\n\n const isBackward = selection.isBackward();\n // Wrap content in a ThreadMarkNode\n $wrapSelectionInThreadMarkNode(selection, isBackward, threadId);\n\n // Clear the selection after wrapping\n $setSelection(null);\n });\n },\n [editor]\n );\n\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n\n onThreadCreate(thread.id);\n },\n [onThreadCreate, onComposerSubmit, props.metadata, createThread]\n );\n\n function handleKeyDown(event: KeyboardEvent<HTMLFormElement>) {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Escape\") {\n onRangeChange(null);\n editor.focus();\n }\n }\n\n return (\n <>\n <ActiveSelectionPortal range={range} container={document.body} />\n\n <FloatingComposerPortal range={range} container={document.body}>\n <Composer\n autoFocus\n {...composerProps}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n ref={forwardedRef}\n />\n </FloatingComposerPortal>\n </>\n );\n});\n\nfunction ActiveSelectionPortal({\n range,\n container,\n}: {\n range: Range;\n container: HTMLElement;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [offset(-range.getBoundingClientRect().height)],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference(range);\n }, [setReference, range]);\n\n const [editor] = useLexicalComposerContext();\n const rects = createRectsFromDOMRange(editor, range);\n\n return createPortal(\n <>\n <span\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n width: range.getBoundingClientRect().width,\n height: range.getBoundingClientRect().height,\n pointerEvents: \"none\",\n }}\n className=\"lb-root lb-portal\"\n >\n {rects.map((rect) => (\n <span\n key={JSON.stringify(rect)}\n style={{\n position: \"absolute\",\n top: rect.top - range.getBoundingClientRect().top,\n left: rect.left - range.getBoundingClientRect().left,\n width: rect.width,\n height: rect.height,\n backgroundColor: \"var(--lb-selection, rgba(0, 0, 255, 0.2))\",\n pointerEvents: \"none\",\n }}\n className=\"lb-selection lb-lexical-active-selection\"\n />\n ))}\n </span>\n </>,\n container\n );\n}\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nfunction FloatingComposerPortal({\n container,\n range,\n children,\n}: {\n container: HTMLElement;\n range: Range;\n children: ReactNode;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference(range);\n }, [range, setReference]);\n\n return createPortal(\n <div\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n className=\"lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-composer\"\n >\n {children}\n </div>,\n container\n );\n}\n"],"names":["FloatingComposer","range"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"floating-composer.cjs","sources":["../../src/comments/floating-composer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer } from \"@liveblocks/react-ui\";\nimport type { LexicalCommand } from \"lexical\";\nimport {\n $getSelection,\n $isRangeSelection,\n $setSelection,\n COMMAND_PRIORITY_EDITOR,\n createCommand,\n} from \"lexical\";\nimport type { ComponentRef, FormEvent, KeyboardEvent, ReactNode } from \"react\";\nimport { forwardRef, useCallback, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { createDOMRange } from \"../create-dom-range\";\nimport { createRectsFromDOMRange } from \"../create-rects-from-dom-range\";\nimport $wrapSelectionInThreadMarkNode from \"./wrap-selection-in-thread-mark-node\";\n\n/**\n * Dispatching OPEN_FLOATING_COMPOSER_COMMAND will display the FloatingComposer\n *\n * @example\n * import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\n * import { OPEN_FLOATING_COMPOSER_COMMAND } from \"@liveblocks/react-lexical\";\n *\n * function Toolbar() {\n * const [editor] = useLexicalComposerContext();\n *\n * return (\n * <button\n * onClick={() => {\n * editor.dispatchCommand(OPEN_FLOATING_COMPOSER_COMMAND);\n * }}\n * >\n * 💬 New comment\n * </button>\n * );\n * }\n */\nexport const OPEN_FLOATING_COMPOSER_COMMAND: LexicalCommand<void> =\n createCommand(\"OPEN_FLOATING_COMPOSER_COMMAND\");\n\ntype ComposerElement = ComponentRef<typeof Composer>;\n\nexport type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n>;\n\n/**\n * Displays a `Composer` near the current lexical selection.\n *\n * To open it, dispatch `OPEN_FLOATING_COMPOSER_COMMAND`.\n *\n * Submitting a comment will attach an annotation thread at the current selection.\n * Should be nested inside `LiveblocksPlugin`.\n */\nexport const FloatingComposer = forwardRef<\n ComposerElement,\n FloatingComposerProps\n>(function FloatingComposer(props, forwardedRef) {\n const [range, setRange] = useState<Range | null>(null);\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return editor.registerCommand(\n OPEN_FLOATING_COMPOSER_COMMAND,\n () => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return false;\n\n if (selection.isCollapsed()) return false;\n\n const { anchor, focus } = selection;\n\n const range = createDOMRange(\n editor,\n anchor.getNode(),\n anchor.offset,\n focus.getNode(),\n focus.offset\n );\n\n setRange(range);\n\n return true;\n },\n COMMAND_PRIORITY_EDITOR\n );\n }, [editor]);\n\n if (range === null) return null;\n\n return (\n <FloatingComposerImpl\n ref={forwardedRef}\n {...props}\n range={range}\n onRangeChange={setRange}\n />\n );\n});\n\ninterface FloatingComposerImplProps extends FloatingComposerProps {\n range: Range;\n onRangeChange: (range: Range | null) => void;\n}\n\nconst FloatingComposerImpl = forwardRef<\n ComposerElement,\n FloatingComposerImplProps\n>(function FloatingComposer(props, forwardedRef) {\n const {\n range,\n onRangeChange,\n onKeyDown,\n onComposerSubmit,\n ...composerProps\n } = props;\n\n const [editor] = useLexicalComposerContext();\n const createThread = useCreateThread();\n\n const $onStateRead = useCallback((): Range | null => {\n const selection = $getSelection();\n\n // If the selection is not a range selection or is collapsed, clear the range so the composer is no longer displayed.\n if (!$isRangeSelection(selection) || selection.isCollapsed()) {\n return null;\n }\n\n const { anchor, focus } = selection;\n const range = createDOMRange(\n editor,\n anchor.getNode(),\n anchor.offset,\n focus.getNode(),\n focus.offset\n );\n\n return range;\n }, [editor]);\n\n useEffect(() => {\n return editor.registerUpdateListener(({ editorState: state, tags }) => {\n // If the update is not related to collaboration, clear the range so the composer is no longer displayed.\n if (!tags.has(\"collaboration\")) {\n onRangeChange(null);\n return;\n }\n\n const range = state.read(() => $onStateRead());\n onRangeChange(range);\n });\n }, [editor, range, onRangeChange, $onStateRead]);\n\n /**\n * Create a new ThreadMarkNode and wrap the selected content in it.\n * @param threadId The id of the thread to associate with the selected content\n */\n const onThreadCreate = useCallback(\n (threadId: string) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n // If the selection is collapsed, we do not create a new thread node in the editor.\n if (selection.isCollapsed()) return;\n\n const isBackward = selection.isBackward();\n // Wrap content in a ThreadMarkNode\n $wrapSelectionInThreadMarkNode(selection, isBackward, threadId);\n\n // Clear the selection after wrapping\n $setSelection(null);\n });\n },\n [editor]\n );\n\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n\n onThreadCreate(thread.id);\n },\n [onThreadCreate, onComposerSubmit, props.metadata, createThread]\n );\n\n function handleKeyDown(event: KeyboardEvent<HTMLFormElement>) {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Escape\") {\n onRangeChange(null);\n editor.focus();\n }\n }\n\n return (\n <>\n <ActiveSelectionPortal range={range} container={document.body} />\n\n <FloatingComposerPortal range={range} container={document.body}>\n <Composer\n autoFocus\n {...composerProps}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n ref={forwardedRef}\n />\n </FloatingComposerPortal>\n </>\n );\n});\n\nfunction ActiveSelectionPortal({\n range,\n container,\n}: {\n range: Range;\n container: HTMLElement;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [offset(-range.getBoundingClientRect().height)],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference(range);\n }, [setReference, range]);\n\n const [editor] = useLexicalComposerContext();\n const rects = createRectsFromDOMRange(editor, range);\n\n return createPortal(\n <>\n <span\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n width: range.getBoundingClientRect().width,\n height: range.getBoundingClientRect().height,\n pointerEvents: \"none\",\n }}\n className=\"lb-root lb-portal\"\n >\n {rects.map((rect) => (\n <span\n key={JSON.stringify(rect)}\n style={{\n position: \"absolute\",\n top: rect.top - range.getBoundingClientRect().top,\n left: rect.left - range.getBoundingClientRect().left,\n width: rect.width,\n height: rect.height,\n backgroundColor: \"var(--lb-selection, rgba(0, 0, 255, 0.2))\",\n pointerEvents: \"none\",\n }}\n className=\"lb-selection lb-lexical-active-selection\"\n />\n ))}\n </span>\n </>,\n container\n );\n}\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nfunction FloatingComposerPortal({\n container,\n range,\n children,\n}: {\n container: HTMLElement;\n range: Range;\n children: ReactNode;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference(range);\n }, [range, setReference]);\n\n return createPortal(\n <div\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n className=\"lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-composer\"\n >\n {children}\n </div>,\n container\n );\n}\n"],"names":["createCommand","forwardRef","FloatingComposer","useState","useLexicalComposerContext","useEffect","$getSelection","$isRangeSelection","range","createDOMRange","COMMAND_PRIORITY_EDITOR","jsx","useCreateThread","useCallback","$wrapSelectionInThreadMarkNode","$setSelection","jsxs","Fragment","Composer","useFloating","offset","autoUpdate","useLayoutEffect","createRectsFromDOMRange","createPortal","inline","flip","hide","shift","limitShift","size"],"mappings":";;;;;;;;;;;;;;;AA0Da,MAAA,8BAAA,GACXA,sBAAc,gCAAgC,EAAA;AAiBzC,MAAM,gBAAmB,GAAAC,gBAAA,CAG9B,SAASC,iBAAAA,CAAiB,OAAO,YAAc,EAAA;AAC/C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIC,eAAuB,IAAI,CAAA,CAAA;AACrD,EAAM,MAAA,CAAC,MAAM,CAAA,GAAIC,gDAA0B,EAAA,CAAA;AAE3C,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,OAAO,MAAO,CAAA,eAAA;AAAA,MACZ,8BAAA;AAAA,MACA,MAAM;AACJ,QAAA,MAAM,YAAYC,qBAAc,EAAA,CAAA;AAChC,QAAI,IAAA,CAACC,0BAAkB,SAAS,CAAA;AAAG,UAAO,OAAA,KAAA,CAAA;AAE1C,QAAA,IAAI,UAAU,WAAY,EAAA;AAAG,UAAO,OAAA,KAAA,CAAA;AAEpC,QAAM,MAAA,EAAE,MAAQ,EAAA,KAAA,EAAU,GAAA,SAAA,CAAA;AAE1B,QAAA,MAAMC,MAAQ,GAAAC,6BAAA;AAAA,UACZ,MAAA;AAAA,UACA,OAAO,OAAQ,EAAA;AAAA,UACf,MAAO,CAAA,MAAA;AAAA,UACP,MAAM,OAAQ,EAAA;AAAA,UACd,KAAM,CAAA,MAAA;AAAA,SACR,CAAA;AAEA,QAAA,QAAA,CAASD,MAAK,CAAA,CAAA;AAEd,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAAA,MACAE,+BAAA;AAAA,KACF,CAAA;AAAA,GACF,EAAG,CAAC,MAAM,CAAC,CAAA,CAAA;AAEX,EAAA,IAAI,KAAU,KAAA,IAAA;AAAM,IAAO,OAAA,IAAA,CAAA;AAE3B,EAAA,uBACGC,cAAA,CAAA,oBAAA,EAAA;AAAA,IACC,GAAK,EAAA,YAAA;AAAA,IACJ,GAAG,KAAA;AAAA,IACJ,KAAA;AAAA,IACA,aAAe,EAAA,QAAA;AAAA,GACjB,CAAA,CAAA;AAEJ,CAAC,EAAA;AAOD,MAAM,oBAAuB,GAAAV,gBAAA,CAG3B,SAASC,iBAAAA,CAAiB,OAAO,YAAc,EAAA;AAC/C,EAAM,MAAA;AAAA,IACJ,KAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA,gBAAA;AAAA,IACG,GAAA,aAAA;AAAA,GACD,GAAA,KAAA,CAAA;AAEJ,EAAM,MAAA,CAAC,MAAM,CAAA,GAAIE,gDAA0B,EAAA,CAAA;AAC3C,EAAA,MAAM,eAAeQ,uBAAgB,EAAA,CAAA;AAErC,EAAM,MAAA,YAAA,GAAeC,kBAAY,MAAoB;AACnD,IAAA,MAAM,YAAYP,qBAAc,EAAA,CAAA;AAGhC,IAAA,IAAI,CAACC,yBAAkB,CAAA,SAAS,CAAK,IAAA,SAAA,CAAU,aAAe,EAAA;AAC5D,MAAO,OAAA,IAAA,CAAA;AAAA,KACT;AAEA,IAAM,MAAA,EAAE,MAAQ,EAAA,KAAA,EAAU,GAAA,SAAA,CAAA;AAC1B,IAAA,MAAMC,MAAQ,GAAAC,6BAAA;AAAA,MACZ,MAAA;AAAA,MACA,OAAO,OAAQ,EAAA;AAAA,MACf,MAAO,CAAA,MAAA;AAAA,MACP,MAAM,OAAQ,EAAA;AAAA,MACd,KAAM,CAAA,MAAA;AAAA,KACR,CAAA;AAEA,IAAOD,OAAAA,MAAAA,CAAAA;AAAA,GACT,EAAG,CAAC,MAAM,CAAC,CAAA,CAAA;AAEX,EAAAH,eAAA,CAAU,MAAM;AACd,IAAA,OAAO,OAAO,sBAAuB,CAAA,CAAC,EAAE,WAAa,EAAA,KAAA,EAAO,MAAW,KAAA;AAErE,MAAA,IAAI,CAAC,IAAA,CAAK,GAAI,CAAA,eAAe,CAAG,EAAA;AAC9B,QAAA,aAAA,CAAc,IAAI,CAAA,CAAA;AAClB,QAAA,OAAA;AAAA,OACF;AAEA,MAAA,MAAMG,MAAQ,GAAA,KAAA,CAAM,IAAK,CAAA,MAAM,cAAc,CAAA,CAAA;AAC7C,MAAA,aAAA,CAAcA,MAAK,CAAA,CAAA;AAAA,KACpB,CAAA,CAAA;AAAA,KACA,CAAC,MAAA,EAAQ,KAAO,EAAA,aAAA,EAAe,YAAY,CAAC,CAAA,CAAA;AAM/C,EAAA,MAAM,cAAiB,GAAAK,iBAAA;AAAA,IACrB,CAAC,QAAqB,KAAA;AACpB,MAAA,MAAA,CAAO,OAAO,MAAM;AAClB,QAAA,MAAM,YAAYP,qBAAc,EAAA,CAAA;AAChC,QAAI,IAAA,CAACC,0BAAkB,SAAS,CAAA;AAAG,UAAA,OAAA;AAGnC,QAAA,IAAI,UAAU,WAAY,EAAA;AAAG,UAAA,OAAA;AAE7B,QAAM,MAAA,UAAA,GAAa,UAAU,UAAW,EAAA,CAAA;AAExC,QAA+BO,6BAAA,CAAA,SAAA,EAAW,YAAY,QAAQ,CAAA,CAAA;AAG9D,QAAAC,qBAAA,CAAc,IAAI,CAAA,CAAA;AAAA,OACnB,CAAA,CAAA;AAAA,KACH;AAAA,IACA,CAAC,MAAM,CAAA;AAAA,GACT,CAAA;AAEA,EAAA,MAAM,oBAAuB,GAAAF,iBAAA;AAAA,IAC3B,CAAC,SAAgC,KAAsC,KAAA;AACrE,MAAA,gBAAA,GAAmB,SAAS,KAAK,CAAA,CAAA;AACjC,MAAA,IAAI,KAAM,CAAA,gBAAA;AAAkB,QAAA,OAAA;AAE5B,MAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AAErB,MAAA,MAAM,SAAS,YAAa,CAAA;AAAA,QAC1B,MAAM,OAAQ,CAAA,IAAA;AAAA,QACd,aAAa,OAAQ,CAAA,WAAA;AAAA,QACrB,QAAA,EAAU,KAAM,CAAA,QAAA,IAAY,EAAC;AAAA,OAC9B,CAAA,CAAA;AAED,MAAA,cAAA,CAAe,OAAO,EAAE,CAAA,CAAA;AAAA,KAC1B;AAAA,IACA,CAAC,cAAA,EAAgB,gBAAkB,EAAA,KAAA,CAAM,UAAU,YAAY,CAAA;AAAA,GACjE,CAAA;AAEA,EAAA,SAAS,cAAc,KAAuC,EAAA;AAC5D,IAAA,SAAA,GAAY,KAAK,CAAA,CAAA;AAEjB,IAAA,IAAI,MAAM,kBAAmB,EAAA;AAAG,MAAA,OAAA;AAEhC,IAAI,IAAA,KAAA,CAAM,QAAQ,QAAU,EAAA;AAC1B,MAAA,aAAA,CAAc,IAAI,CAAA,CAAA;AAClB,MAAA,MAAA,CAAO,KAAM,EAAA,CAAA;AAAA,KACf;AAAA,GACF;AAEA,EACE,uBAAAG,eAAA,CAAAC,mBAAA,EAAA;AAAA,IACE,QAAA,EAAA;AAAA,sBAACN,cAAA,CAAA,qBAAA,EAAA;AAAA,QAAsB,KAAA;AAAA,QAAc,WAAW,QAAS,CAAA,IAAA;AAAA,OAAM,CAAA;AAAA,sBAE9DA,cAAA,CAAA,sBAAA,EAAA;AAAA,QAAuB,KAAA;AAAA,QAAc,WAAW,QAAS,CAAA,IAAA;AAAA,QACxD,QAAC,kBAAAA,cAAA,CAAAO,gBAAA,EAAA;AAAA,UACC,SAAS,EAAA,IAAA;AAAA,UACR,GAAG,aAAA;AAAA,UACJ,SAAW,EAAA,aAAA;AAAA,UACX,gBAAkB,EAAA,oBAAA;AAAA,UAClB,GAAK,EAAA,YAAA;AAAA,SACP,CAAA;AAAA,OACF,CAAA;AAAA,KAAA;AAAA,GACF,CAAA,CAAA;AAEJ,CAAC,CAAA,CAAA;AAED,SAAS,qBAAsB,CAAA;AAAA,EAC7B,KAAA;AAAA,EACA,SAAA;AACF,CAGG,EAAA;AACD,EAAM,MAAA;AAAA,IACJ,IAAA,EAAM,EAAE,YAAA,EAAc,WAAY,EAAA;AAAA,IAClC,QAAA;AAAA,IACA,CAAA;AAAA,IACA,CAAA;AAAA,MACEC,oBAAY,CAAA;AAAA,IACd,QAAU,EAAA,OAAA;AAAA,IACV,SAAW,EAAA,QAAA;AAAA,IACX,UAAA,EAAY,CAACC,eAAO,CAAA,CAAC,MAAM,qBAAsB,EAAA,CAAE,MAAM,CAAC,CAAA;AAAA,IAC1D,oBAAA,EAAsB,IAAI,IAAS,KAAA;AACjC,MAAO,OAAAC,mBAAA,CAAW,GAAG,IAAM,EAAA;AAAA,QACzB,cAAgB,EAAA,IAAA;AAAA,OACjB,CAAA,CAAA;AAAA,KACH;AAAA,GACD,CAAA,CAAA;AAED,EAAAC,wBAAA,CAAgB,MAAM;AACpB,IAAA,YAAA,CAAa,KAAK,CAAA,CAAA;AAAA,GACjB,EAAA,CAAC,YAAc,EAAA,KAAK,CAAC,CAAA,CAAA;AAExB,EAAM,MAAA,CAAC,MAAM,CAAA,GAAIlB,gDAA0B,EAAA,CAAA;AAC3C,EAAM,MAAA,KAAA,GAAQmB,+CAAwB,CAAA,MAAA,EAAQ,KAAK,CAAA,CAAA;AAEnD,EAAO,OAAAC,uBAAA;AAAA,oBACLb,cAAA,CAAAM,mBAAA,EAAA;AAAA,MACE,QAAC,kBAAAN,cAAA,CAAA,MAAA,EAAA;AAAA,QACC,GAAK,EAAA,WAAA;AAAA,QACL,KAAO,EAAA;AAAA,UACL,QAAU,EAAA,QAAA;AAAA,UACV,GAAK,EAAA,CAAA;AAAA,UACL,IAAM,EAAA,CAAA;AAAA,UACN,SAAA,EAAW,eAAe,IAAK,CAAA,KAAA,CAAM,CAAC,CAAQ,CAAA,IAAA,EAAA,IAAA,CAAK,MAAM,CAAC,CAAA,CAAA,MAAA,CAAA;AAAA,UAC1D,QAAU,EAAA,aAAA;AAAA,UACV,KAAA,EAAO,KAAM,CAAA,qBAAA,EAAwB,CAAA,KAAA;AAAA,UACrC,MAAA,EAAQ,KAAM,CAAA,qBAAA,EAAwB,CAAA,MAAA;AAAA,UACtC,aAAe,EAAA,MAAA;AAAA,SACjB;AAAA,QACA,SAAU,EAAA,mBAAA;AAAA,QAET,QAAM,EAAA,KAAA,CAAA,GAAA,CAAI,CAAC,IAAA,qBACTA,cAAA,CAAA,MAAA,EAAA;AAAA,UAEC,KAAO,EAAA;AAAA,YACL,QAAU,EAAA,UAAA;AAAA,YACV,GAAK,EAAA,IAAA,CAAK,GAAM,GAAA,KAAA,CAAM,uBAAwB,CAAA,GAAA;AAAA,YAC9C,IAAM,EAAA,IAAA,CAAK,IAAO,GAAA,KAAA,CAAM,uBAAwB,CAAA,IAAA;AAAA,YAChD,OAAO,IAAK,CAAA,KAAA;AAAA,YACZ,QAAQ,IAAK,CAAA,MAAA;AAAA,YACb,eAAiB,EAAA,2CAAA;AAAA,YACjB,aAAe,EAAA,MAAA;AAAA,WACjB;AAAA,UACA,SAAU,EAAA,0CAAA;AAAA,SAAA,EAVL,IAAK,CAAA,SAAA,CAAU,IAAI,CAW1B,CACD,CAAA;AAAA,OACH,CAAA;AAAA,KACF,CAAA;AAAA,IACA,SAAA;AAAA,GACF,CAAA;AACF,CAAA;AAEO,MAAM,mCAAsC,GAAA,GAAA;AAEnD,SAAS,sBAAuB,CAAA;AAAA,EAC9B,SAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AACF,CAIG,EAAA;AACD,EAAM,MAAA;AAAA,IACJ,IAAA,EAAM,EAAE,YAAA,EAAc,WAAY,EAAA;AAAA,IAClC,QAAA;AAAA,IACA,CAAA;AAAA,IACA,CAAA;AAAA,MACEQ,oBAAY,CAAA;AAAA,IACd,QAAU,EAAA,OAAA;AAAA,IACV,SAAW,EAAA,QAAA;AAAA,IACX,UAAY,EAAA;AAAA,MACVM,eAAO,CAAA,EAAE,OAAS,EAAA,mCAAA,EAAqC,CAAA;AAAA,MACvDC,cAAK,EAAE,OAAA,EAAS,mCAAqC,EAAA,SAAA,EAAW,OAAO,CAAA;AAAA,MACvEN,gBAAO,EAAE,CAAA;AAAA,MACTO,aAAK,CAAA,EAAE,OAAS,EAAA,mCAAA,EAAqC,CAAA;AAAA,MACrDC,cAAM,CAAA;AAAA,QACJ,OAAS,EAAA,mCAAA;AAAA,QACT,SAASC,mBAAW,EAAA;AAAA,OACrB,CAAA;AAAA,MACDC,aAAK,CAAA,EAAE,OAAS,EAAA,mCAAA,EAAqC,CAAA;AAAA,KACvD;AAAA,IACA,oBAAA,EAAsB,IAAI,IAAS,KAAA;AACjC,MAAO,OAAAT,mBAAA,CAAW,GAAG,IAAM,EAAA;AAAA,QACzB,cAAgB,EAAA,IAAA;AAAA,OACjB,CAAA,CAAA;AAAA,KACH;AAAA,GACD,CAAA,CAAA;AAED,EAAAC,wBAAA,CAAgB,MAAM;AACpB,IAAA,YAAA,CAAa,KAAK,CAAA,CAAA;AAAA,GACjB,EAAA,CAAC,KAAO,EAAA,YAAY,CAAC,CAAA,CAAA;AAExB,EAAO,OAAAE,uBAAA;AAAA,oBACJb,cAAA,CAAA,KAAA,EAAA;AAAA,MACC,GAAK,EAAA,WAAA;AAAA,MACL,KAAO,EAAA;AAAA,QACL,QAAU,EAAA,QAAA;AAAA,QACV,GAAK,EAAA,CAAA;AAAA,QACL,IAAM,EAAA,CAAA;AAAA,QACN,SAAA,EAAW,eAAe,IAAK,CAAA,KAAA,CAAM,CAAC,CAAQ,CAAA,IAAA,EAAA,IAAA,CAAK,MAAM,CAAC,CAAA,CAAA,MAAA,CAAA;AAAA,QAC1D,QAAU,EAAA,aAAA;AAAA,OACZ;AAAA,MACA,SAAU,EAAA,iFAAA;AAAA,MAET,QAAA;AAAA,KACH,CAAA;AAAA,IACA,SAAA;AAAA,GACF,CAAA;AACF;;;;;;"}
|
|
@@ -1,33 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useFloating, offset, autoUpdate, inline, flip, hide, shift, limitShift, size } from '@floating-ui/react-dom';
|
|
3
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
4
|
+
import { useCreateThread } from '@liveblocks/react';
|
|
5
|
+
import { useLayoutEffect } from '@liveblocks/react/_private';
|
|
6
|
+
import { Composer } from '@liveblocks/react-ui';
|
|
7
|
+
import { createCommand, $getSelection, $isRangeSelection, COMMAND_PRIORITY_EDITOR, $setSelection } from 'lexical';
|
|
8
|
+
import { forwardRef, useState, useEffect, useCallback } from 'react';
|
|
9
|
+
import { createPortal } from 'react-dom';
|
|
10
|
+
import { createDOMRange } from '../create-dom-range.js';
|
|
11
|
+
import { createRectsFromDOMRange } from '../create-rects-from-dom-range.js';
|
|
12
|
+
import $wrapSelectionInThreadMarkNode from './wrap-selection-in-thread-mark-node.js';
|
|
2
13
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
var reactUi = require('@liveblocks/react-ui');
|
|
9
|
-
var lexical = require('lexical');
|
|
10
|
-
var react = require('react');
|
|
11
|
-
var reactDom$1 = require('react-dom');
|
|
12
|
-
var createDomRange = require('../create-dom-range.js');
|
|
13
|
-
var createRectsFromDomRange = require('../create-rects-from-dom-range.js');
|
|
14
|
-
var wrapSelectionInThreadMarkNode = require('./wrap-selection-in-thread-mark-node.js');
|
|
15
|
-
|
|
16
|
-
const OPEN_FLOATING_COMPOSER_COMMAND = lexical.createCommand("OPEN_FLOATING_COMPOSER_COMMAND");
|
|
17
|
-
const FloatingComposer = react.forwardRef(function FloatingComposer2(props, forwardedRef) {
|
|
18
|
-
const [range, setRange] = react.useState(null);
|
|
19
|
-
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
20
|
-
react.useEffect(() => {
|
|
14
|
+
const OPEN_FLOATING_COMPOSER_COMMAND = createCommand("OPEN_FLOATING_COMPOSER_COMMAND");
|
|
15
|
+
const FloatingComposer = forwardRef(function FloatingComposer2(props, forwardedRef) {
|
|
16
|
+
const [range, setRange] = useState(null);
|
|
17
|
+
const [editor] = useLexicalComposerContext();
|
|
18
|
+
useEffect(() => {
|
|
21
19
|
return editor.registerCommand(
|
|
22
20
|
OPEN_FLOATING_COMPOSER_COMMAND,
|
|
23
21
|
() => {
|
|
24
|
-
const selection =
|
|
25
|
-
if (
|
|
22
|
+
const selection = $getSelection();
|
|
23
|
+
if (!$isRangeSelection(selection))
|
|
26
24
|
return false;
|
|
27
25
|
if (selection.isCollapsed())
|
|
28
26
|
return false;
|
|
29
27
|
const { anchor, focus } = selection;
|
|
30
|
-
const range2 =
|
|
28
|
+
const range2 = createDOMRange(
|
|
31
29
|
editor,
|
|
32
30
|
anchor.getNode(),
|
|
33
31
|
anchor.offset,
|
|
@@ -37,19 +35,19 @@ const FloatingComposer = react.forwardRef(function FloatingComposer2(props, forw
|
|
|
37
35
|
setRange(range2);
|
|
38
36
|
return true;
|
|
39
37
|
},
|
|
40
|
-
|
|
38
|
+
COMMAND_PRIORITY_EDITOR
|
|
41
39
|
);
|
|
42
40
|
}, [editor]);
|
|
43
41
|
if (range === null)
|
|
44
42
|
return null;
|
|
45
|
-
return /* @__PURE__ */
|
|
43
|
+
return /* @__PURE__ */ jsx(FloatingComposerImpl, {
|
|
46
44
|
ref: forwardedRef,
|
|
47
45
|
...props,
|
|
48
46
|
range,
|
|
49
47
|
onRangeChange: setRange
|
|
50
48
|
});
|
|
51
49
|
});
|
|
52
|
-
const FloatingComposerImpl =
|
|
50
|
+
const FloatingComposerImpl = forwardRef(function FloatingComposer3(props, forwardedRef) {
|
|
53
51
|
const {
|
|
54
52
|
range,
|
|
55
53
|
onRangeChange,
|
|
@@ -57,15 +55,15 @@ const FloatingComposerImpl = react.forwardRef(function FloatingComposer3(props,
|
|
|
57
55
|
onComposerSubmit,
|
|
58
56
|
...composerProps
|
|
59
57
|
} = props;
|
|
60
|
-
const [editor] =
|
|
61
|
-
const createThread =
|
|
62
|
-
const $onStateRead =
|
|
63
|
-
const selection =
|
|
64
|
-
if (
|
|
58
|
+
const [editor] = useLexicalComposerContext();
|
|
59
|
+
const createThread = useCreateThread();
|
|
60
|
+
const $onStateRead = useCallback(() => {
|
|
61
|
+
const selection = $getSelection();
|
|
62
|
+
if (!$isRangeSelection(selection) || selection.isCollapsed()) {
|
|
65
63
|
return null;
|
|
66
64
|
}
|
|
67
65
|
const { anchor, focus } = selection;
|
|
68
|
-
const range2 =
|
|
66
|
+
const range2 = createDOMRange(
|
|
69
67
|
editor,
|
|
70
68
|
anchor.getNode(),
|
|
71
69
|
anchor.offset,
|
|
@@ -74,7 +72,7 @@ const FloatingComposerImpl = react.forwardRef(function FloatingComposer3(props,
|
|
|
74
72
|
);
|
|
75
73
|
return range2;
|
|
76
74
|
}, [editor]);
|
|
77
|
-
|
|
75
|
+
useEffect(() => {
|
|
78
76
|
return editor.registerUpdateListener(({ editorState: state, tags }) => {
|
|
79
77
|
if (!tags.has("collaboration")) {
|
|
80
78
|
onRangeChange(null);
|
|
@@ -84,22 +82,22 @@ const FloatingComposerImpl = react.forwardRef(function FloatingComposer3(props,
|
|
|
84
82
|
onRangeChange(range2);
|
|
85
83
|
});
|
|
86
84
|
}, [editor, range, onRangeChange, $onStateRead]);
|
|
87
|
-
const onThreadCreate =
|
|
85
|
+
const onThreadCreate = useCallback(
|
|
88
86
|
(threadId) => {
|
|
89
87
|
editor.update(() => {
|
|
90
|
-
const selection =
|
|
91
|
-
if (
|
|
88
|
+
const selection = $getSelection();
|
|
89
|
+
if (!$isRangeSelection(selection))
|
|
92
90
|
return;
|
|
93
91
|
if (selection.isCollapsed())
|
|
94
92
|
return;
|
|
95
93
|
const isBackward = selection.isBackward();
|
|
96
|
-
wrapSelectionInThreadMarkNode(selection, isBackward, threadId);
|
|
97
|
-
|
|
94
|
+
$wrapSelectionInThreadMarkNode(selection, isBackward, threadId);
|
|
95
|
+
$setSelection(null);
|
|
98
96
|
});
|
|
99
97
|
},
|
|
100
98
|
[editor]
|
|
101
99
|
);
|
|
102
|
-
const handleComposerSubmit =
|
|
100
|
+
const handleComposerSubmit = useCallback(
|
|
103
101
|
(comment, event) => {
|
|
104
102
|
onComposerSubmit?.(comment, event);
|
|
105
103
|
if (event.defaultPrevented)
|
|
@@ -123,16 +121,16 @@ const FloatingComposerImpl = react.forwardRef(function FloatingComposer3(props,
|
|
|
123
121
|
editor.focus();
|
|
124
122
|
}
|
|
125
123
|
}
|
|
126
|
-
return /* @__PURE__ */
|
|
124
|
+
return /* @__PURE__ */ jsxs(Fragment, {
|
|
127
125
|
children: [
|
|
128
|
-
/* @__PURE__ */
|
|
126
|
+
/* @__PURE__ */ jsx(ActiveSelectionPortal, {
|
|
129
127
|
range,
|
|
130
128
|
container: document.body
|
|
131
129
|
}),
|
|
132
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ jsx(FloatingComposerPortal, {
|
|
133
131
|
range,
|
|
134
132
|
container: document.body,
|
|
135
|
-
children: /* @__PURE__ */
|
|
133
|
+
children: /* @__PURE__ */ jsx(Composer, {
|
|
136
134
|
autoFocus: true,
|
|
137
135
|
...composerProps,
|
|
138
136
|
onKeyDown: handleKeyDown,
|
|
@@ -152,24 +150,24 @@ function ActiveSelectionPortal({
|
|
|
152
150
|
strategy,
|
|
153
151
|
x,
|
|
154
152
|
y
|
|
155
|
-
} =
|
|
153
|
+
} = useFloating({
|
|
156
154
|
strategy: "fixed",
|
|
157
155
|
placement: "bottom",
|
|
158
|
-
middleware: [
|
|
156
|
+
middleware: [offset(-range.getBoundingClientRect().height)],
|
|
159
157
|
whileElementsMounted: (...args) => {
|
|
160
|
-
return
|
|
158
|
+
return autoUpdate(...args, {
|
|
161
159
|
animationFrame: true
|
|
162
160
|
});
|
|
163
161
|
}
|
|
164
162
|
});
|
|
165
|
-
|
|
163
|
+
useLayoutEffect(() => {
|
|
166
164
|
setReference(range);
|
|
167
165
|
}, [setReference, range]);
|
|
168
|
-
const [editor] =
|
|
169
|
-
const rects =
|
|
170
|
-
return
|
|
171
|
-
/* @__PURE__ */
|
|
172
|
-
children: /* @__PURE__ */
|
|
166
|
+
const [editor] = useLexicalComposerContext();
|
|
167
|
+
const rects = createRectsFromDOMRange(editor, range);
|
|
168
|
+
return createPortal(
|
|
169
|
+
/* @__PURE__ */ jsx(Fragment, {
|
|
170
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
173
171
|
ref: setFloating,
|
|
174
172
|
style: {
|
|
175
173
|
position: strategy,
|
|
@@ -182,7 +180,7 @@ function ActiveSelectionPortal({
|
|
|
182
180
|
pointerEvents: "none"
|
|
183
181
|
},
|
|
184
182
|
className: "lb-root lb-portal",
|
|
185
|
-
children: rects.map((rect) => /* @__PURE__ */
|
|
183
|
+
children: rects.map((rect) => /* @__PURE__ */ jsx("span", {
|
|
186
184
|
style: {
|
|
187
185
|
position: "absolute",
|
|
188
186
|
top: rect.top - range.getBoundingClientRect().top,
|
|
@@ -210,31 +208,31 @@ function FloatingComposerPortal({
|
|
|
210
208
|
strategy,
|
|
211
209
|
x,
|
|
212
210
|
y
|
|
213
|
-
} =
|
|
211
|
+
} = useFloating({
|
|
214
212
|
strategy: "fixed",
|
|
215
213
|
placement: "bottom",
|
|
216
214
|
middleware: [
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
215
|
+
inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),
|
|
216
|
+
flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),
|
|
217
|
+
offset(10),
|
|
218
|
+
hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),
|
|
219
|
+
shift({
|
|
222
220
|
padding: FLOATING_COMPOSER_COLLISION_PADDING,
|
|
223
|
-
limiter:
|
|
221
|
+
limiter: limitShift()
|
|
224
222
|
}),
|
|
225
|
-
|
|
223
|
+
size({ padding: FLOATING_COMPOSER_COLLISION_PADDING })
|
|
226
224
|
],
|
|
227
225
|
whileElementsMounted: (...args) => {
|
|
228
|
-
return
|
|
226
|
+
return autoUpdate(...args, {
|
|
229
227
|
animationFrame: true
|
|
230
228
|
});
|
|
231
229
|
}
|
|
232
230
|
});
|
|
233
|
-
|
|
231
|
+
useLayoutEffect(() => {
|
|
234
232
|
setReference(range);
|
|
235
233
|
}, [range, setReference]);
|
|
236
|
-
return
|
|
237
|
-
/* @__PURE__ */
|
|
234
|
+
return createPortal(
|
|
235
|
+
/* @__PURE__ */ jsx("div", {
|
|
238
236
|
ref: setFloating,
|
|
239
237
|
style: {
|
|
240
238
|
position: strategy,
|
|
@@ -250,7 +248,5 @@ function FloatingComposerPortal({
|
|
|
250
248
|
);
|
|
251
249
|
}
|
|
252
250
|
|
|
253
|
-
|
|
254
|
-
exports.FloatingComposer = FloatingComposer;
|
|
255
|
-
exports.OPEN_FLOATING_COMPOSER_COMMAND = OPEN_FLOATING_COMPOSER_COMMAND;
|
|
251
|
+
export { FLOATING_COMPOSER_COLLISION_PADDING, FloatingComposer, OPEN_FLOATING_COMPOSER_COMMAND };
|
|
256
252
|
//# sourceMappingURL=floating-composer.js.map
|