@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classnames.js","sources":["../src/classnames.ts"],"sourcesContent":["export function classNames(\n ...args: (string | number | boolean | undefined | null)[]\n) {\n return args\n .filter((arg) => typeof arg === \"string\" || typeof arg === \"number\")\n .join(\" \");\n}\n"],"names":[],"mappings":";;AAAO,SAAS,cACX,IACH,EAAA;AACA,EAAA,OAAO,IACJ,CAAA,MAAA,CAAO,CAAC,GAAA,KAAQ,OAAO,GAAA,KAAQ,QAAY,IAAA,OAAO,GAAQ,KAAA,QAAQ,CAClE,CAAA,IAAA,CAAK,GAAG,CAAA,CAAA;AACb;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classnames.mjs","sources":["../src/classnames.ts"],"sourcesContent":["export function classNames(\n ...args: (string | number | boolean | undefined | null)[]\n) {\n return args\n .filter((arg) => typeof arg === \"string\" || typeof arg === \"number\")\n .join(\" \");\n}\n"],"names":[],"mappings":"AAAO,SAAS,cACX,IACH,EAAA;AACA,EAAA,OAAO,IACJ,CAAA,MAAA,CAAO,CAAC,GAAA,KAAQ,OAAO,GAAA,KAAQ,QAAY,IAAA,OAAO,GAAQ,KAAA,QAAQ,CAClE,CAAA,IAAA,CAAK,GAAG,CAAA,CAAA;AACb;;;;"}
|
|
@@ -1,21 +1,41 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var react = require('@liveblocks/react');
|
|
4
|
-
var
|
|
4
|
+
var reactUi = require('@liveblocks/react-ui');
|
|
5
5
|
var React = require('react');
|
|
6
|
+
var commentPluginProvider = require('./comment-plugin-provider.js');
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
8
|
+
const DefaultThread = ({ thread, isActive }) => {
|
|
9
|
+
const onDeleteThread = React.useContext(commentPluginProvider.OnDeleteThreadCallback);
|
|
10
|
+
if (onDeleteThread === null) {
|
|
11
|
+
throw new Error("OnDeleteThreadCallback not provided");
|
|
12
|
+
}
|
|
13
|
+
const handleThreadDelete = React.useCallback(
|
|
14
|
+
(thread2) => {
|
|
15
|
+
onDeleteThread(thread2.id);
|
|
16
|
+
},
|
|
17
|
+
[onDeleteThread]
|
|
18
|
+
);
|
|
19
|
+
return /* @__PURE__ */ React.createElement(reactUi.Thread, {
|
|
20
|
+
thread,
|
|
21
|
+
"data-state": isActive ? "active" : null,
|
|
22
|
+
onThreadDelete: handleThreadDelete
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
const ThreadPanel = ({ renderThread }) => {
|
|
26
|
+
const { threads } = react.useThreads();
|
|
27
|
+
const isThreadActive = React.useContext(commentPluginProvider.IsActiveThreadContext);
|
|
28
|
+
const ThreadComponent = renderThread ?? DefaultThread;
|
|
10
29
|
if (!threads || threads.length === 0) {
|
|
11
30
|
return /* @__PURE__ */ React.createElement("div", {
|
|
12
|
-
className: "lb-lexical-threads-empty"
|
|
31
|
+
className: "lb-root lb-lexical-threads-empty"
|
|
13
32
|
}, "No threads yet");
|
|
14
33
|
}
|
|
15
34
|
return /* @__PURE__ */ React.createElement("div", {
|
|
16
|
-
className: "lb-lexical-threads"
|
|
35
|
+
className: "lb-lexical-threads lb-root"
|
|
17
36
|
}, threads.map((thread) => {
|
|
18
|
-
return /* @__PURE__ */ React.createElement(
|
|
37
|
+
return /* @__PURE__ */ React.createElement(ThreadComponent, {
|
|
38
|
+
isActive: isThreadActive(thread.id),
|
|
19
39
|
key: thread.id,
|
|
20
40
|
thread
|
|
21
41
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThreadPanel.js","sources":["../../src/comments/ThreadPanel.tsx"],"sourcesContent":["\nimport {
|
|
1
|
+
{"version":3,"file":"ThreadPanel.js","sources":["../../src/comments/ThreadPanel.tsx"],"sourcesContent":["import type { BaseMetadata, ThreadData } from \"@liveblocks/core\";\nimport { useThreads } from \"@liveblocks/react\";\nimport { Thread } from \"@liveblocks/react-ui\";\nimport type { ComponentType } from \"react\";\nimport React, { useCallback, useContext } from \"react\";\n\nimport {\n IsActiveThreadContext,\n OnDeleteThreadCallback,\n} from \"./comment-plugin-provider\";\n\ntype ThreadProps = {\n thread: ThreadData<BaseMetadata>;\n isActive: boolean;\n};\n\ntype ThreadPanelProps = {\n renderThread?: ComponentType<ThreadProps>;\n};\n\nconst DefaultThread = ({ thread, isActive }: ThreadProps) => {\n const onDeleteThread = useContext(OnDeleteThreadCallback);\n if (onDeleteThread === null) {\n throw new Error(\"OnDeleteThreadCallback not provided\");\n }\n const handleThreadDelete = useCallback(\n (thread: ThreadData<BaseMetadata>) => {\n onDeleteThread(thread.id);\n },\n [onDeleteThread]\n );\n\n return (\n <Thread\n thread={thread}\n data-state={isActive ? \"active\" : null}\n onThreadDelete={handleThreadDelete}\n />\n );\n};\n\nconst ThreadPanel = ({ renderThread }: ThreadPanelProps) => {\n const { threads } = useThreads();\n const isThreadActive = useContext(IsActiveThreadContext);\n const ThreadComponent = renderThread ?? DefaultThread;\n\n if (!threads || threads.length === 0) {\n return (\n <div className=\"lb-root lb-lexical-threads-empty\">No threads yet</div>\n );\n }\n\n return (\n <div className=\"lb-lexical-threads lb-root\">\n {threads.map((thread) => {\n return (\n <ThreadComponent\n isActive={isThreadActive(thread.id)}\n key={thread.id}\n thread={thread}\n />\n );\n })}\n </div>\n );\n};\n\nexport { ThreadPanel };\n"],"names":["useContext","OnDeleteThreadCallback","useCallback","thread","Thread","useThreads","IsActiveThreadContext"],"mappings":";;;;;;;AAoBA,MAAM,aAAgB,GAAA,CAAC,EAAE,MAAA,EAAQ,UAA4B,KAAA;AAC3D,EAAM,MAAA,cAAA,GAAiBA,iBAAWC,4CAAsB,CAAA,CAAA;AACxD,EAAA,IAAI,mBAAmB,IAAM,EAAA;AAC3B,IAAM,MAAA,IAAI,MAAM,qCAAqC,CAAA,CAAA;AAAA,GACvD;AACA,EAAA,MAAM,kBAAqB,GAAAC,iBAAA;AAAA,IACzB,CAACC,OAAqC,KAAA;AACpC,MAAA,cAAA,CAAeA,QAAO,EAAE,CAAA,CAAA;AAAA,KAC1B;AAAA,IACA,CAAC,cAAc,CAAA;AAAA,GACjB,CAAA;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAAC,cAAA,EAAA;AAAA,IACC,MAAA;AAAA,IACA,YAAA,EAAY,WAAW,QAAW,GAAA,IAAA;AAAA,IAClC,cAAgB,EAAA,kBAAA;AAAA,GAClB,CAAA,CAAA;AAEJ,CAAA,CAAA;AAEA,MAAM,WAAc,GAAA,CAAC,EAAE,YAAA,EAAqC,KAAA;AAC1D,EAAM,MAAA,EAAE,OAAQ,EAAA,GAAIC,gBAAW,EAAA,CAAA;AAC/B,EAAM,MAAA,cAAA,GAAiBL,iBAAWM,2CAAqB,CAAA,CAAA;AACvD,EAAA,MAAM,kBAAkB,YAAgB,IAAA,aAAA,CAAA;AAExC,EAAA,IAAI,CAAC,OAAA,IAAW,OAAQ,CAAA,MAAA,KAAW,CAAG,EAAA;AACpC,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,MAAI,SAAU,EAAA,kCAAA;AAAA,KAAA,EAAmC,gBAAc,CAAA,CAAA;AAAA,GAEpE;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IAAI,SAAU,EAAA,4BAAA;AAAA,GACZ,EAAA,OAAA,CAAQ,GAAI,CAAA,CAAC,MAAW,KAAA;AACvB,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,eAAA,EAAA;AAAA,MACC,QAAA,EAAU,cAAe,CAAA,MAAA,CAAO,EAAE,CAAA;AAAA,MAClC,KAAK,MAAO,CAAA,EAAA;AAAA,MACZ,MAAA;AAAA,KACF,CAAA,CAAA;AAAA,GAEH,CACH,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1,19 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Thread } from '@liveblocks/react-
|
|
3
|
-
import React__default from 'react';
|
|
1
|
+
import { useThreads } from '@liveblocks/react';
|
|
2
|
+
import { Thread } from '@liveblocks/react-ui';
|
|
3
|
+
import React__default, { useContext, useCallback } from 'react';
|
|
4
|
+
import { OnDeleteThreadCallback, IsActiveThreadContext } from './comment-plugin-provider.mjs';
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
6
|
+
const DefaultThread = ({ thread, isActive }) => {
|
|
7
|
+
const onDeleteThread = useContext(OnDeleteThreadCallback);
|
|
8
|
+
if (onDeleteThread === null) {
|
|
9
|
+
throw new Error("OnDeleteThreadCallback not provided");
|
|
10
|
+
}
|
|
11
|
+
const handleThreadDelete = useCallback(
|
|
12
|
+
(thread2) => {
|
|
13
|
+
onDeleteThread(thread2.id);
|
|
14
|
+
},
|
|
15
|
+
[onDeleteThread]
|
|
16
|
+
);
|
|
17
|
+
return /* @__PURE__ */ React__default.createElement(Thread, {
|
|
18
|
+
thread,
|
|
19
|
+
"data-state": isActive ? "active" : null,
|
|
20
|
+
onThreadDelete: handleThreadDelete
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
const ThreadPanel = ({ renderThread }) => {
|
|
7
24
|
const { threads } = useThreads();
|
|
25
|
+
const isThreadActive = useContext(IsActiveThreadContext);
|
|
26
|
+
const ThreadComponent = renderThread ?? DefaultThread;
|
|
8
27
|
if (!threads || threads.length === 0) {
|
|
9
28
|
return /* @__PURE__ */ React__default.createElement("div", {
|
|
10
|
-
className: "lb-lexical-threads-empty"
|
|
29
|
+
className: "lb-root lb-lexical-threads-empty"
|
|
11
30
|
}, "No threads yet");
|
|
12
31
|
}
|
|
13
32
|
return /* @__PURE__ */ React__default.createElement("div", {
|
|
14
|
-
className: "lb-lexical-threads"
|
|
33
|
+
className: "lb-lexical-threads lb-root"
|
|
15
34
|
}, threads.map((thread) => {
|
|
16
|
-
return /* @__PURE__ */ React__default.createElement(
|
|
35
|
+
return /* @__PURE__ */ React__default.createElement(ThreadComponent, {
|
|
36
|
+
isActive: isThreadActive(thread.id),
|
|
17
37
|
key: thread.id,
|
|
18
38
|
thread
|
|
19
39
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThreadPanel.mjs","sources":["../../src/comments/ThreadPanel.tsx"],"sourcesContent":["\nimport {
|
|
1
|
+
{"version":3,"file":"ThreadPanel.mjs","sources":["../../src/comments/ThreadPanel.tsx"],"sourcesContent":["import type { BaseMetadata, ThreadData } from \"@liveblocks/core\";\nimport { useThreads } from \"@liveblocks/react\";\nimport { Thread } from \"@liveblocks/react-ui\";\nimport type { ComponentType } from \"react\";\nimport React, { useCallback, useContext } from \"react\";\n\nimport {\n IsActiveThreadContext,\n OnDeleteThreadCallback,\n} from \"./comment-plugin-provider\";\n\ntype ThreadProps = {\n thread: ThreadData<BaseMetadata>;\n isActive: boolean;\n};\n\ntype ThreadPanelProps = {\n renderThread?: ComponentType<ThreadProps>;\n};\n\nconst DefaultThread = ({ thread, isActive }: ThreadProps) => {\n const onDeleteThread = useContext(OnDeleteThreadCallback);\n if (onDeleteThread === null) {\n throw new Error(\"OnDeleteThreadCallback not provided\");\n }\n const handleThreadDelete = useCallback(\n (thread: ThreadData<BaseMetadata>) => {\n onDeleteThread(thread.id);\n },\n [onDeleteThread]\n );\n\n return (\n <Thread\n thread={thread}\n data-state={isActive ? \"active\" : null}\n onThreadDelete={handleThreadDelete}\n />\n );\n};\n\nconst ThreadPanel = ({ renderThread }: ThreadPanelProps) => {\n const { threads } = useThreads();\n const isThreadActive = useContext(IsActiveThreadContext);\n const ThreadComponent = renderThread ?? DefaultThread;\n\n if (!threads || threads.length === 0) {\n return (\n <div className=\"lb-root lb-lexical-threads-empty\">No threads yet</div>\n );\n }\n\n return (\n <div className=\"lb-lexical-threads lb-root\">\n {threads.map((thread) => {\n return (\n <ThreadComponent\n isActive={isThreadActive(thread.id)}\n key={thread.id}\n thread={thread}\n />\n );\n })}\n </div>\n );\n};\n\nexport { ThreadPanel };\n"],"names":["thread","React"],"mappings":";;;;;AAoBA,MAAM,aAAgB,GAAA,CAAC,EAAE,MAAA,EAAQ,UAA4B,KAAA;AAC3D,EAAM,MAAA,cAAA,GAAiB,WAAW,sBAAsB,CAAA,CAAA;AACxD,EAAA,IAAI,mBAAmB,IAAM,EAAA;AAC3B,IAAM,MAAA,IAAI,MAAM,qCAAqC,CAAA,CAAA;AAAA,GACvD;AACA,EAAA,MAAM,kBAAqB,GAAA,WAAA;AAAA,IACzB,CAACA,OAAqC,KAAA;AACpC,MAAA,cAAA,CAAeA,QAAO,EAAE,CAAA,CAAA;AAAA,KAC1B;AAAA,IACA,CAAC,cAAc,CAAA;AAAA,GACjB,CAAA;AAEA,EAAA,uBACGC,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IACC,MAAA;AAAA,IACA,YAAA,EAAY,WAAW,QAAW,GAAA,IAAA;AAAA,IAClC,cAAgB,EAAA,kBAAA;AAAA,GAClB,CAAA,CAAA;AAEJ,CAAA,CAAA;AAEA,MAAM,WAAc,GAAA,CAAC,EAAE,YAAA,EAAqC,KAAA;AAC1D,EAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,UAAW,EAAA,CAAA;AAC/B,EAAM,MAAA,cAAA,GAAiB,WAAW,qBAAqB,CAAA,CAAA;AACvD,EAAA,MAAM,kBAAkB,YAAgB,IAAA,aAAA,CAAA;AAExC,EAAA,IAAI,CAAC,OAAA,IAAW,OAAQ,CAAA,MAAA,KAAW,CAAG,EAAA;AACpC,IAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,MAAI,SAAU,EAAA,kCAAA;AAAA,KAAA,EAAmC,gBAAc,CAAA,CAAA;AAAA,GAEpE;AAEA,EAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IAAI,SAAU,EAAA,4BAAA;AAAA,GACZ,EAAA,OAAA,CAAQ,GAAI,CAAA,CAAC,MAAW,KAAA;AACvB,IAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,eAAA,EAAA;AAAA,MACC,QAAA,EAAU,cAAe,CAAA,MAAA,CAAO,EAAE,CAAA;AAAA,MAClC,KAAK,MAAO,CAAA,EAAA;AAAA,MACZ,MAAA;AAAA,KACF,CAAA,CAAA;AAAA,GAEH,CACH,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -7,11 +7,9 @@ var react = require('@liveblocks/react');
|
|
|
7
7
|
var lexical = require('lexical');
|
|
8
8
|
var React = require('react');
|
|
9
9
|
var withSelector_js = require('use-sync-external-store/shim/with-selector.js');
|
|
10
|
-
var activeSelection = require('../active-selection.js');
|
|
11
10
|
var getThreadMarkIds = require('./get-thread-mark-ids.js');
|
|
12
11
|
var threadMarkNode = require('./thread-mark-node.js');
|
|
13
12
|
var unwrapThreadMarkNode = require('./unwrap-thread-mark-node.js');
|
|
14
|
-
var wrapSelectionInThreadMarkNode = require('./wrap-selection-in-thread-mark-node.js');
|
|
15
13
|
|
|
16
14
|
function _interopNamespaceDefault(e) {
|
|
17
15
|
var n = Object.create(null);
|
|
@@ -32,66 +30,16 @@ function _interopNamespaceDefault(e) {
|
|
|
32
30
|
|
|
33
31
|
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
34
32
|
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const [showFloatingComposer, setShowFloatingComposer] = React.useState(false);
|
|
38
|
-
return /* @__PURE__ */ React__namespace.createElement(ShowFloatingComposerContext.Provider, {
|
|
39
|
-
value: {
|
|
40
|
-
setShowFloatingComposer,
|
|
41
|
-
showFloatingComposer
|
|
42
|
-
}
|
|
43
|
-
}, children);
|
|
44
|
-
};
|
|
45
|
-
function useCreateThread() {
|
|
46
|
-
const context = React__namespace.useContext(ShowFloatingComposerContext);
|
|
47
|
-
if (context === null) {
|
|
48
|
-
throw new Error(
|
|
49
|
-
"useCreateThread must be used within a LiveblocksPluginProvider with comments enabled"
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
return () => {
|
|
53
|
-
context.setShowFloatingComposer(true);
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
function useShowFloatingComposer() {
|
|
57
|
-
const context = React__namespace.useContext(ShowFloatingComposerContext);
|
|
58
|
-
if (context === null) {
|
|
59
|
-
throw new Error(
|
|
60
|
-
"useShowFloatingComposer must be used within a LiveblocksPluginProvider with comments enabled"
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
return context.showFloatingComposer;
|
|
64
|
-
}
|
|
65
|
-
function useHideFloatingComposer() {
|
|
66
|
-
const context = React__namespace.useContext(ShowFloatingComposerContext);
|
|
67
|
-
if (context === null) {
|
|
68
|
-
throw new Error(
|
|
69
|
-
"useHideFloatingComposer must be used within a LiveblocksPluginProvider with comments enabled"
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
return () => {
|
|
73
|
-
context.setShowFloatingComposer(false);
|
|
74
|
-
};
|
|
75
|
-
}
|
|
33
|
+
const OnDeleteThreadCallback = React.createContext(null);
|
|
34
|
+
const IsActiveThreadContext = React.createContext((_) => false);
|
|
76
35
|
function CommentPluginProvider({ children }) {
|
|
77
36
|
const [editor, context] = LexicalComposerContext.useLexicalComposerContext();
|
|
78
37
|
const [threadToNodes, setThreadToNodes] = React.useState(
|
|
79
38
|
/* @__PURE__ */ new Map()
|
|
80
39
|
);
|
|
81
40
|
const [activeThreads, setActiveThreads] = React.useState([]);
|
|
82
|
-
const [showActiveSelection, setShowActiveSelection] = React.useState(false);
|
|
83
41
|
const client = react.useClient();
|
|
84
|
-
const
|
|
85
|
-
useRoom,
|
|
86
|
-
[core.kInternal]: {
|
|
87
|
-
useCommentsErrorListener,
|
|
88
|
-
ThreadCreateCallbackProvider,
|
|
89
|
-
ThreadDeleteCallbackProvider,
|
|
90
|
-
ComposerFocusCallbackProvider,
|
|
91
|
-
IsThreadActiveCallbackProvider
|
|
92
|
-
}
|
|
93
|
-
} = react.useRoomContextBundle();
|
|
94
|
-
const room = useRoom();
|
|
42
|
+
const room = react.useRoom();
|
|
95
43
|
React.useEffect(() => {
|
|
96
44
|
if (!editor.hasNodes([threadMarkNode.ThreadMarkNode])) {
|
|
97
45
|
throw new Error(
|
|
@@ -105,21 +53,6 @@ function CommentPluginProvider({ children }) {
|
|
|
105
53
|
},
|
|
106
54
|
[activeThreads]
|
|
107
55
|
);
|
|
108
|
-
const handleThreadCreate = React.useCallback(
|
|
109
|
-
(threadId) => {
|
|
110
|
-
editor.update(() => {
|
|
111
|
-
const selection = lexical.$getSelection();
|
|
112
|
-
if (!lexical.$isRangeSelection(selection))
|
|
113
|
-
return;
|
|
114
|
-
if (selection.isCollapsed())
|
|
115
|
-
return;
|
|
116
|
-
const isBackward = selection.isBackward();
|
|
117
|
-
wrapSelectionInThreadMarkNode(selection, isBackward, threadId);
|
|
118
|
-
lexical.$setSelection(null);
|
|
119
|
-
});
|
|
120
|
-
},
|
|
121
|
-
[editor]
|
|
122
|
-
);
|
|
123
56
|
const handleThreadDelete = React.useCallback(
|
|
124
57
|
(threadId) => {
|
|
125
58
|
editor.update(() => {
|
|
@@ -139,7 +72,7 @@ function CommentPluginProvider({ children }) {
|
|
|
139
72
|
},
|
|
140
73
|
[editor, threadToNodes]
|
|
141
74
|
);
|
|
142
|
-
useCommentsErrorListener((error) => {
|
|
75
|
+
react.useCommentsErrorListener((error) => {
|
|
143
76
|
if (error instanceof react.CreateThreadError) {
|
|
144
77
|
handleThreadDelete(error.context.threadId);
|
|
145
78
|
}
|
|
@@ -150,8 +83,8 @@ function CommentPluginProvider({ children }) {
|
|
|
150
83
|
store.get,
|
|
151
84
|
store.get,
|
|
152
85
|
React.useCallback(
|
|
153
|
-
() =>
|
|
154
|
-
[
|
|
86
|
+
() => react.selectedThreads(room.id, store.get(), {}),
|
|
87
|
+
[room.id, store]
|
|
155
88
|
)
|
|
156
89
|
);
|
|
157
90
|
React.useEffect(() => {
|
|
@@ -172,14 +105,16 @@ function CommentPluginProvider({ children }) {
|
|
|
172
105
|
}
|
|
173
106
|
const elements = getThreadMarkElements();
|
|
174
107
|
const theme = context.getTheme();
|
|
175
|
-
|
|
176
|
-
|
|
108
|
+
const classNames = ["lb-thread-mark"];
|
|
109
|
+
if (theme && theme.liveblocks && "threadMark" in theme.liveblocks) {
|
|
110
|
+
classNames.push(theme.liveblocks.threadMark);
|
|
111
|
+
}
|
|
177
112
|
elements.forEach((element) => {
|
|
178
|
-
utils.addClassNamesToElement(element,
|
|
113
|
+
utils.addClassNamesToElement(element, ...classNames);
|
|
179
114
|
});
|
|
180
115
|
return () => {
|
|
181
116
|
elements.forEach((element) => {
|
|
182
|
-
utils.removeClassNamesFromElement(element,
|
|
117
|
+
utils.removeClassNamesFromElement(element, ...classNames);
|
|
183
118
|
});
|
|
184
119
|
};
|
|
185
120
|
}, [context, editor, threadToNodes, threads]);
|
|
@@ -213,7 +148,6 @@ function CommentPluginProvider({ children }) {
|
|
|
213
148
|
return editor.registerMutationListener(threadMarkNode.ThreadMarkNode, onMutation);
|
|
214
149
|
}, [editor]);
|
|
215
150
|
React.useEffect(() => {
|
|
216
|
-
const selectedThreads = client[core.kInternal].comments.selectedThreads;
|
|
217
151
|
function $getThreadIds(selection) {
|
|
218
152
|
if (selection === null)
|
|
219
153
|
return [];
|
|
@@ -227,7 +161,7 @@ function CommentPluginProvider({ children }) {
|
|
|
227
161
|
function $onStateRead() {
|
|
228
162
|
const selection = lexical.$getSelection();
|
|
229
163
|
const threadIds = $getThreadIds(selection).filter((id) => {
|
|
230
|
-
return selectedThreads(room.id, store.get(), {}).some(
|
|
164
|
+
return react.selectedThreads(room.id, store.get(), {}).some(
|
|
231
165
|
(thread) => thread.id === id
|
|
232
166
|
);
|
|
233
167
|
});
|
|
@@ -287,36 +221,14 @@ function CommentPluginProvider({ children }) {
|
|
|
287
221
|
}
|
|
288
222
|
);
|
|
289
223
|
}, [editor]);
|
|
290
|
-
|
|
291
|
-
(commentId, threadId) => {
|
|
292
|
-
if (commentId === void 0 && threadId === void 0) {
|
|
293
|
-
setShowActiveSelection(true);
|
|
294
|
-
} else {
|
|
295
|
-
setShowActiveSelection(false);
|
|
296
|
-
}
|
|
297
|
-
},
|
|
298
|
-
[]
|
|
299
|
-
);
|
|
300
|
-
React.useEffect(() => {
|
|
301
|
-
return editor.registerUpdateListener(({ editorState: state, tags }) => {
|
|
302
|
-
if (tags.has("collaboration"))
|
|
303
|
-
return;
|
|
304
|
-
state.read(() => setShowActiveSelection(false));
|
|
305
|
-
});
|
|
306
|
-
}, [editor]);
|
|
307
|
-
return /* @__PURE__ */ React__namespace.createElement(ShowFloatingComposerProvider, null, /* @__PURE__ */ React__namespace.createElement(ThreadCreateCallbackProvider, {
|
|
308
|
-
value: handleThreadCreate
|
|
309
|
-
}, /* @__PURE__ */ React__namespace.createElement(ThreadDeleteCallbackProvider, {
|
|
224
|
+
return /* @__PURE__ */ React__namespace.createElement(OnDeleteThreadCallback.Provider, {
|
|
310
225
|
value: handleThreadDelete
|
|
311
|
-
}, /* @__PURE__ */ React__namespace.createElement(
|
|
312
|
-
value: handleComposerFocus
|
|
313
|
-
}, /* @__PURE__ */ React__namespace.createElement(IsThreadActiveCallbackProvider, {
|
|
226
|
+
}, /* @__PURE__ */ React__namespace.createElement(IsActiveThreadContext.Provider, {
|
|
314
227
|
value: isThreadActive
|
|
315
|
-
},
|
|
228
|
+
}, children));
|
|
316
229
|
}
|
|
317
230
|
|
|
318
231
|
exports.CommentPluginProvider = CommentPluginProvider;
|
|
319
|
-
exports.
|
|
320
|
-
exports.
|
|
321
|
-
exports.useShowFloatingComposer = useShowFloatingComposer;
|
|
232
|
+
exports.IsActiveThreadContext = IsActiveThreadContext;
|
|
233
|
+
exports.OnDeleteThreadCallback = OnDeleteThreadCallback;
|
|
322
234
|
//# sourceMappingURL=comment-plugin-provider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comment-plugin-provider.js","sources":["../../src/comments/comment-plugin-provider.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n addClassNamesToElement,\n registerNestedElementResolver,\n removeClassNamesFromElement,\n} from \"@lexical/utils\";\nimport { kInternal } from \"@liveblocks/core\";\nimport {\n CreateThreadError,\n useClient,\n useRoomContextBundle,\n} from \"@liveblocks/react\";\nimport type { BaseSelection, NodeKey, NodeMutation } from \"lexical\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n $setSelection,\n} from \"lexical\";\nimport type { PropsWithChildren } from \"react\";\nimport * as React from \"react\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport { ActiveSelection } from \"../active-selection\";\nimport $getThreadMarkIds from \"./get-thread-mark-ids\";\nimport {\n $createThreadMarkNode,\n $isThreadMarkNode,\n ThreadMarkNode,\n} from \"./thread-mark-node\";\nimport $unwrapThreadMarkNode from \"./unwrap-thread-mark-node\";\nimport $wrapSelectionInThreadMarkNode from \"./wrap-selection-in-thread-mark-node\";\n\ntype ThreadToNodesMap = Map<string, Set<NodeKey>>;\n\ntype ShowFloatingComposerContextType = {\n showFloatingComposer: boolean;\n setShowFloatingComposer: (show: boolean) => void;\n} | null;\nconst ShowFloatingComposerContext =\n React.createContext<ShowFloatingComposerContextType>(null);\n\nconst ShowFloatingComposerProvider = ({ children }: PropsWithChildren) => {\n const [showFloatingComposer, setShowFloatingComposer] = useState(false);\n return (\n <ShowFloatingComposerContext.Provider\n value={{\n setShowFloatingComposer,\n showFloatingComposer,\n }}\n >\n {children}\n </ShowFloatingComposerContext.Provider>\n );\n};\n\nexport function useCreateThread() {\n const context = React.useContext(ShowFloatingComposerContext);\n if (context === null) {\n throw new Error(\n \"useCreateThread must be used within a LiveblocksPluginProvider with comments enabled\"\n );\n }\n\n return () => {\n context.setShowFloatingComposer(true);\n };\n}\n\nexport function useShowFloatingComposer() {\n const context = React.useContext(ShowFloatingComposerContext);\n if (context === null) {\n throw new Error(\n \"useShowFloatingComposer must be used within a LiveblocksPluginProvider with comments enabled\"\n );\n }\n\n return context.showFloatingComposer;\n}\n\nexport function useHideFloatingComposer() {\n const context = React.useContext(ShowFloatingComposerContext);\n if (context === null) {\n throw new Error(\n \"useHideFloatingComposer must be used within a LiveblocksPluginProvider with comments enabled\"\n );\n }\n\n return () => {\n context.setShowFloatingComposer(false);\n };\n}\n\nexport function CommentPluginProvider({ children }: PropsWithChildren) {\n const [editor, context] = useLexicalComposerContext();\n\n const [threadToNodes, setThreadToNodes] = useState<ThreadToNodesMap>(\n new Map()\n ); // A map from thread id to a set of (thread mark) node keys that are associated with the thread\n\n const [activeThreads, setActiveThreads] = useState<string[]>([]); // The threads that are currently active (or selected) in the editor\n\n const [showActiveSelection, setShowActiveSelection] = useState(false);\n\n const client = useClient();\n const {\n useRoom,\n [kInternal]: {\n useCommentsErrorListener,\n ThreadCreateCallbackProvider,\n ThreadDeleteCallbackProvider,\n ComposerFocusCallbackProvider,\n IsThreadActiveCallbackProvider,\n },\n } = useRoomContextBundle();\n\n const room = useRoom();\n\n useEffect(() => {\n if (!editor.hasNodes([ThreadMarkNode])) {\n throw new Error(\n \"CommentPluginProvider: ThreadMarkNode not registered on editor\"\n );\n }\n }, [editor]);\n\n const isThreadActive = useCallback(\n (threadId: string) => {\n return activeThreads.includes(threadId);\n },\n [activeThreads]\n );\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 handleThreadCreate = 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 /**\n * Remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads.\n * @param threadId The id of the thread to remove\n */\n const handleThreadDelete = useCallback(\n (threadId: string) => {\n editor.update(() => {\n // Retrieve node keys associated with the thread\n const keys = threadToNodes.get(threadId);\n if (keys === undefined) return;\n\n // Iterate over each thread node and disassociate the thread if from the node and unwrap the node if it is no longer associated with any threads\n for (const key of keys) {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n node.deleteID(threadId);\n\n if (node.getIDs().length === 0) {\n $unwrapThreadMarkNode(node);\n }\n }\n });\n },\n [editor, threadToNodes]\n );\n\n useCommentsErrorListener((error) => {\n // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n if (error instanceof CreateThreadError) {\n handleThreadDelete(error.context.threadId);\n }\n });\n\n const store = client[kInternal].cacheStore;\n\n const threads = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n useCallback(\n () =>\n client[kInternal].comments.selectedThreads(room.id, store.get(), {}),\n [client, room.id, store]\n )\n );\n\n /**\n * Only add styles to the thread mark elements that currently have threads associated with them.\n */\n useEffect(() => {\n function getThreadMarkElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of threads) {\n const keys = threadToNodes.get(thread.id);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const elements = getThreadMarkElements();\n\n const theme = context.getTheme();\n if (theme === null || theme === undefined) return;\n\n elements.forEach((element) => {\n addClassNamesToElement(element, theme.threadMark as string);\n });\n\n return () => {\n elements.forEach((element) => {\n removeClassNamesFromElement(element, theme.threadMark as string);\n });\n };\n }, [context, editor, threadToNodes, threads]);\n\n /**\n * Register a mutation listener that listens for mutations on 'ThreadMarkNode's and updates the map of thread to node keys accordingly.\n */\n useEffect(() => {\n function onMutation(mutations: Map<string, NodeMutation>) {\n const state = editor.getEditorState();\n setThreadToNodes((prev) => {\n const updatedMap = new Map(prev);\n state.read(() => {\n for (const [key, mutation] of mutations) {\n // If the node is destroyed, we remove its key from the map of thread to node keys\n if (mutation === \"destroyed\") {\n for (const [, nodes] of updatedMap) {\n nodes.delete(key);\n }\n }\n // Otherwise, if a new node is created or an existing node is updated, we update the map of thread to node keys to include the new/updated node\n else if (mutation === \"created\" || mutation === \"updated\") {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n\n const threadIds = node.getIDs();\n\n for (const id of threadIds) {\n const keys = updatedMap.get(id) ?? new Set();\n keys.add(key);\n updatedMap.set(id, keys);\n }\n }\n }\n });\n return updatedMap;\n });\n }\n\n return editor.registerMutationListener(ThreadMarkNode, onMutation);\n }, [editor]);\n\n /**\n * Register an update listener that listens for changes in the selection and updates the active threads accordingly.\n */\n useEffect(() => {\n const selectedThreads = client[kInternal].comments.selectedThreads;\n\n function $getThreadIds(selection: BaseSelection | null): string[] {\n if (selection === null) return [];\n\n if (!$isRangeSelection(selection)) return [];\n\n const anchor = selection.anchor.getNode();\n if (!$isTextNode(anchor)) return [];\n\n return $getThreadMarkIds(anchor, selection.anchor.offset) ?? [];\n }\n\n function $onStateRead() {\n const selection = $getSelection();\n\n const threadIds = $getThreadIds(selection).filter((id) => {\n return selectedThreads(room.id, store.get(), {}).some(\n (thread) => thread.id === id\n );\n });\n setActiveThreads(threadIds);\n }\n\n const unsubscribeCache = store.subscribe(() => {\n editor.getEditorState().read($onStateRead);\n });\n\n const unregisterUpdateListener = editor.registerUpdateListener(\n ({ editorState: state }) => {\n state.read($onStateRead);\n }\n );\n\n return () => {\n unregisterUpdateListener();\n unsubscribeCache();\n };\n }, [editor, client, room.id, store]);\n\n /**\n * When active threads change, we add a data-state attribute and set it to \"active\" for all HTML elements that are associated with the active threads.\n */\n useEffect(() => {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = threadToNodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n activeElements.forEach((element) => {\n element.setAttribute(\"data-state\", \"active\");\n });\n\n return () => {\n activeElements.forEach((element) => {\n element.removeAttribute(\"data-state\");\n });\n };\n }, [activeThreads, editor, threadToNodes]);\n\n useEffect(() => {\n return registerNestedElementResolver<ThreadMarkNode>(\n editor,\n ThreadMarkNode,\n (from: ThreadMarkNode) => {\n return $createThreadMarkNode(from.getIDs());\n },\n (from: ThreadMarkNode, to: ThreadMarkNode) => {\n const ids = from.getIDs();\n ids.forEach((id) => {\n to.addID(id);\n });\n }\n );\n }, [editor]);\n\n const handleComposerFocus = useCallback(\n (commentId: string | undefined, threadId: string | undefined) => {\n if (commentId === undefined && threadId === undefined) {\n setShowActiveSelection(true);\n } else {\n setShowActiveSelection(false);\n }\n },\n []\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(() => setShowActiveSelection(false));\n });\n }, [editor]);\n\n return (\n <ShowFloatingComposerProvider>\n <ThreadCreateCallbackProvider value={handleThreadCreate}>\n <ThreadDeleteCallbackProvider value={handleThreadDelete}>\n <ComposerFocusCallbackProvider value={handleComposerFocus}>\n <IsThreadActiveCallbackProvider value={isThreadActive}>\n {showActiveSelection && <ActiveSelection />}\n {children}\n </IsThreadActiveCallbackProvider>\n </ComposerFocusCallbackProvider>\n </ThreadDeleteCallbackProvider>\n </ThreadCreateCallbackProvider>\n </ShowFloatingComposerProvider>\n );\n}\n"],"names":["React","useState","useLexicalComposerContext","useClient","kInternal","useRoomContextBundle","useEffect","ThreadMarkNode","useCallback","$getSelection","$isRangeSelection","$wrapSelectionInThreadMarkNode","$setSelection","$getNodeByKey","$isThreadMarkNode","$unwrapThreadMarkNode","CreateThreadError","useSyncExternalStoreWithSelector","addClassNamesToElement","removeClassNamesFromElement","$isTextNode","$getThreadMarkIds","activeElements","registerNestedElementResolver","$createThreadMarkNode","ActiveSelection"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"comment-plugin-provider.js","sources":["../../src/comments/comment-plugin-provider.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n addClassNamesToElement,\n registerNestedElementResolver,\n removeClassNamesFromElement,\n} from \"@lexical/utils\";\nimport { kInternal } from \"@liveblocks/core\";\nimport {\n CreateThreadError,\n selectedThreads,\n useClient,\n useCommentsErrorListener,\n useRoom,\n} from \"@liveblocks/react\";\nimport type { BaseSelection, NodeKey, NodeMutation } from \"lexical\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n} from \"lexical\";\nimport type { PropsWithChildren } from \"react\";\nimport * as React from \"react\";\nimport { createContext, useCallback, useEffect, useState } from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport $getThreadMarkIds from \"./get-thread-mark-ids\";\nimport {\n $createThreadMarkNode,\n $isThreadMarkNode,\n ThreadMarkNode,\n} from \"./thread-mark-node\";\nimport $unwrapThreadMarkNode from \"./unwrap-thread-mark-node\";\n\nexport const OnDeleteThreadCallback = createContext<\n ((threadId: string) => void) | null\n>(null);\n\nexport const IsActiveThreadContext = createContext<\n (threadId: string) => boolean\n>((_: string) => false);\n\ntype ThreadToNodesMap = Map<string, Set<NodeKey>>;\n\nexport function CommentPluginProvider({ children }: PropsWithChildren) {\n const [editor, context] = useLexicalComposerContext();\n\n const [threadToNodes, setThreadToNodes] = useState<ThreadToNodesMap>(\n new Map()\n ); // A map from thread id to a set of (thread mark) node keys that are associated with the thread\n\n const [activeThreads, setActiveThreads] = useState<string[]>([]); // The threads that are currently active (or selected) in the editor\n\n const client = useClient();\n\n const room = useRoom();\n\n useEffect(() => {\n if (!editor.hasNodes([ThreadMarkNode])) {\n throw new Error(\n \"CommentPluginProvider: ThreadMarkNode not registered on editor\"\n );\n }\n }, [editor]);\n\n const isThreadActive = useCallback(\n (threadId: string) => {\n return activeThreads.includes(threadId);\n },\n [activeThreads]\n );\n\n /**\n * Remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads.\n * @param threadId The id of the thread to remove\n */\n const handleThreadDelete = useCallback(\n (threadId: string) => {\n editor.update(() => {\n // Retrieve node keys associated with the thread\n const keys = threadToNodes.get(threadId);\n if (keys === undefined) return;\n\n // Iterate over each thread node and disassociate the thread if from the node and unwrap the node if it is no longer associated with any threads\n for (const key of keys) {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n node.deleteID(threadId);\n\n if (node.getIDs().length === 0) {\n $unwrapThreadMarkNode(node);\n }\n }\n });\n },\n [editor, threadToNodes]\n );\n\n useCommentsErrorListener((error) => {\n // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n if (error instanceof CreateThreadError) {\n handleThreadDelete(error.context.threadId);\n }\n });\n\n const store = client[kInternal].cacheStore;\n\n const threads = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n useCallback(\n () => selectedThreads(room.id, store.get(), {}),\n [room.id, store]\n )\n );\n\n /**\n * Only add styles to the thread mark elements that currently have threads associated with them.\n */\n useEffect(() => {\n function getThreadMarkElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of threads) {\n const keys = threadToNodes.get(thread.id);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const elements = getThreadMarkElements();\n\n const theme = context.getTheme();\n\n const classNames = [\"lb-thread-mark\"];\n if (theme && theme.liveblocks && \"threadMark\" in theme.liveblocks) {\n classNames.push((theme.liveblocks as { threadMark: string }).threadMark);\n }\n\n elements.forEach((element) => {\n addClassNamesToElement(element, ...classNames);\n });\n\n return () => {\n elements.forEach((element) => {\n removeClassNamesFromElement(element, ...classNames);\n });\n };\n }, [context, editor, threadToNodes, threads]);\n\n /**\n * Register a mutation listener that listens for mutations on 'ThreadMarkNode's and updates the map of thread to node keys accordingly.\n */\n useEffect(() => {\n function onMutation(mutations: Map<string, NodeMutation>) {\n const state = editor.getEditorState();\n setThreadToNodes((prev) => {\n const updatedMap = new Map(prev);\n state.read(() => {\n for (const [key, mutation] of mutations) {\n // If the node is destroyed, we remove its key from the map of thread to node keys\n if (mutation === \"destroyed\") {\n for (const [, nodes] of updatedMap) {\n nodes.delete(key);\n }\n }\n // Otherwise, if a new node is created or an existing node is updated, we update the map of thread to node keys to include the new/updated node\n else if (mutation === \"created\" || mutation === \"updated\") {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n\n const threadIds = node.getIDs();\n\n for (const id of threadIds) {\n const keys = updatedMap.get(id) ?? new Set();\n keys.add(key);\n updatedMap.set(id, keys);\n }\n }\n }\n });\n return updatedMap;\n });\n }\n\n return editor.registerMutationListener(ThreadMarkNode, onMutation);\n }, [editor]);\n\n /**\n * Register an update listener that listens for changes in the selection and updates the active threads accordingly.\n */\n useEffect(() => {\n function $getThreadIds(selection: BaseSelection | null): string[] {\n if (selection === null) return [];\n\n if (!$isRangeSelection(selection)) return [];\n\n const anchor = selection.anchor.getNode();\n if (!$isTextNode(anchor)) return [];\n\n return $getThreadMarkIds(anchor, selection.anchor.offset) ?? [];\n }\n\n function $onStateRead() {\n const selection = $getSelection();\n\n const threadIds = $getThreadIds(selection).filter((id) => {\n return selectedThreads(room.id, store.get(), {}).some(\n (thread) => thread.id === id\n );\n });\n setActiveThreads(threadIds);\n }\n\n const unsubscribeCache = store.subscribe(() => {\n editor.getEditorState().read($onStateRead);\n });\n\n const unregisterUpdateListener = editor.registerUpdateListener(\n ({ editorState: state }) => {\n state.read($onStateRead);\n }\n );\n\n return () => {\n unregisterUpdateListener();\n unsubscribeCache();\n };\n }, [editor, client, room.id, store]);\n\n /**\n * When active threads change, we add a data-state attribute and set it to \"active\" for all HTML elements that are associated with the active threads.\n */\n useEffect(() => {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = threadToNodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n activeElements.forEach((element) => {\n element.setAttribute(\"data-state\", \"active\");\n });\n\n return () => {\n activeElements.forEach((element) => {\n element.removeAttribute(\"data-state\");\n });\n };\n }, [activeThreads, editor, threadToNodes]);\n\n useEffect(() => {\n return registerNestedElementResolver<ThreadMarkNode>(\n editor,\n ThreadMarkNode,\n (from: ThreadMarkNode) => {\n return $createThreadMarkNode(from.getIDs());\n },\n (from: ThreadMarkNode, to: ThreadMarkNode) => {\n const ids = from.getIDs();\n ids.forEach((id) => {\n to.addID(id);\n });\n }\n );\n }, [editor]);\n\n return (\n <OnDeleteThreadCallback.Provider value={handleThreadDelete}>\n <IsActiveThreadContext.Provider value={isThreadActive}>\n {children}\n </IsActiveThreadContext.Provider>\n </OnDeleteThreadCallback.Provider>\n );\n}\n"],"names":["createContext","useLexicalComposerContext","useState","useClient","useRoom","useEffect","ThreadMarkNode","useCallback","$getNodeByKey","$isThreadMarkNode","$unwrapThreadMarkNode","useCommentsErrorListener","CreateThreadError","kInternal","useSyncExternalStoreWithSelector","selectedThreads","addClassNamesToElement","removeClassNamesFromElement","$isRangeSelection","$isTextNode","$getThreadMarkIds","$getSelection","activeElements","registerNestedElementResolver","$createThreadMarkNode","React"],"mappings":"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"}
|
|
@@ -1,76 +1,24 @@
|
|
|
1
1
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
2
2
|
import { addClassNamesToElement, removeClassNamesFromElement, registerNestedElementResolver } from '@lexical/utils';
|
|
3
3
|
import { kInternal } from '@liveblocks/core';
|
|
4
|
-
import { useClient,
|
|
5
|
-
import { $
|
|
4
|
+
import { useClient, useRoom, useCommentsErrorListener, CreateThreadError, selectedThreads } from '@liveblocks/react';
|
|
5
|
+
import { $getNodeByKey, $isRangeSelection, $isTextNode, $getSelection } from 'lexical';
|
|
6
6
|
import * as React from 'react';
|
|
7
|
-
import { useState, useEffect, useCallback } from 'react';
|
|
7
|
+
import { createContext, useState, useEffect, useCallback } from 'react';
|
|
8
8
|
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js';
|
|
9
|
-
import { ActiveSelection } from '../active-selection.mjs';
|
|
10
9
|
import $getThreadMarkIds from './get-thread-mark-ids.mjs';
|
|
11
10
|
import { ThreadMarkNode, $isThreadMarkNode, $createThreadMarkNode } from './thread-mark-node.mjs';
|
|
12
11
|
import $unwrapThreadMarkNode from './unwrap-thread-mark-node.mjs';
|
|
13
|
-
import $wrapSelectionInThreadMarkNode from './wrap-selection-in-thread-mark-node.mjs';
|
|
14
12
|
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const [showFloatingComposer, setShowFloatingComposer] = useState(false);
|
|
18
|
-
return /* @__PURE__ */ React.createElement(ShowFloatingComposerContext.Provider, {
|
|
19
|
-
value: {
|
|
20
|
-
setShowFloatingComposer,
|
|
21
|
-
showFloatingComposer
|
|
22
|
-
}
|
|
23
|
-
}, children);
|
|
24
|
-
};
|
|
25
|
-
function useCreateThread() {
|
|
26
|
-
const context = React.useContext(ShowFloatingComposerContext);
|
|
27
|
-
if (context === null) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
"useCreateThread must be used within a LiveblocksPluginProvider with comments enabled"
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
return () => {
|
|
33
|
-
context.setShowFloatingComposer(true);
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
function useShowFloatingComposer() {
|
|
37
|
-
const context = React.useContext(ShowFloatingComposerContext);
|
|
38
|
-
if (context === null) {
|
|
39
|
-
throw new Error(
|
|
40
|
-
"useShowFloatingComposer must be used within a LiveblocksPluginProvider with comments enabled"
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
return context.showFloatingComposer;
|
|
44
|
-
}
|
|
45
|
-
function useHideFloatingComposer() {
|
|
46
|
-
const context = React.useContext(ShowFloatingComposerContext);
|
|
47
|
-
if (context === null) {
|
|
48
|
-
throw new Error(
|
|
49
|
-
"useHideFloatingComposer must be used within a LiveblocksPluginProvider with comments enabled"
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
return () => {
|
|
53
|
-
context.setShowFloatingComposer(false);
|
|
54
|
-
};
|
|
55
|
-
}
|
|
13
|
+
const OnDeleteThreadCallback = createContext(null);
|
|
14
|
+
const IsActiveThreadContext = createContext((_) => false);
|
|
56
15
|
function CommentPluginProvider({ children }) {
|
|
57
16
|
const [editor, context] = useLexicalComposerContext();
|
|
58
17
|
const [threadToNodes, setThreadToNodes] = useState(
|
|
59
18
|
/* @__PURE__ */ new Map()
|
|
60
19
|
);
|
|
61
20
|
const [activeThreads, setActiveThreads] = useState([]);
|
|
62
|
-
const [showActiveSelection, setShowActiveSelection] = useState(false);
|
|
63
21
|
const client = useClient();
|
|
64
|
-
const {
|
|
65
|
-
useRoom,
|
|
66
|
-
[kInternal]: {
|
|
67
|
-
useCommentsErrorListener,
|
|
68
|
-
ThreadCreateCallbackProvider,
|
|
69
|
-
ThreadDeleteCallbackProvider,
|
|
70
|
-
ComposerFocusCallbackProvider,
|
|
71
|
-
IsThreadActiveCallbackProvider
|
|
72
|
-
}
|
|
73
|
-
} = useRoomContextBundle();
|
|
74
22
|
const room = useRoom();
|
|
75
23
|
useEffect(() => {
|
|
76
24
|
if (!editor.hasNodes([ThreadMarkNode])) {
|
|
@@ -85,21 +33,6 @@ function CommentPluginProvider({ children }) {
|
|
|
85
33
|
},
|
|
86
34
|
[activeThreads]
|
|
87
35
|
);
|
|
88
|
-
const handleThreadCreate = useCallback(
|
|
89
|
-
(threadId) => {
|
|
90
|
-
editor.update(() => {
|
|
91
|
-
const selection = $getSelection();
|
|
92
|
-
if (!$isRangeSelection(selection))
|
|
93
|
-
return;
|
|
94
|
-
if (selection.isCollapsed())
|
|
95
|
-
return;
|
|
96
|
-
const isBackward = selection.isBackward();
|
|
97
|
-
$wrapSelectionInThreadMarkNode(selection, isBackward, threadId);
|
|
98
|
-
$setSelection(null);
|
|
99
|
-
});
|
|
100
|
-
},
|
|
101
|
-
[editor]
|
|
102
|
-
);
|
|
103
36
|
const handleThreadDelete = useCallback(
|
|
104
37
|
(threadId) => {
|
|
105
38
|
editor.update(() => {
|
|
@@ -130,8 +63,8 @@ function CommentPluginProvider({ children }) {
|
|
|
130
63
|
store.get,
|
|
131
64
|
store.get,
|
|
132
65
|
useCallback(
|
|
133
|
-
() =>
|
|
134
|
-
[
|
|
66
|
+
() => selectedThreads(room.id, store.get(), {}),
|
|
67
|
+
[room.id, store]
|
|
135
68
|
)
|
|
136
69
|
);
|
|
137
70
|
useEffect(() => {
|
|
@@ -152,14 +85,16 @@ function CommentPluginProvider({ children }) {
|
|
|
152
85
|
}
|
|
153
86
|
const elements = getThreadMarkElements();
|
|
154
87
|
const theme = context.getTheme();
|
|
155
|
-
|
|
156
|
-
|
|
88
|
+
const classNames = ["lb-thread-mark"];
|
|
89
|
+
if (theme && theme.liveblocks && "threadMark" in theme.liveblocks) {
|
|
90
|
+
classNames.push(theme.liveblocks.threadMark);
|
|
91
|
+
}
|
|
157
92
|
elements.forEach((element) => {
|
|
158
|
-
addClassNamesToElement(element,
|
|
93
|
+
addClassNamesToElement(element, ...classNames);
|
|
159
94
|
});
|
|
160
95
|
return () => {
|
|
161
96
|
elements.forEach((element) => {
|
|
162
|
-
removeClassNamesFromElement(element,
|
|
97
|
+
removeClassNamesFromElement(element, ...classNames);
|
|
163
98
|
});
|
|
164
99
|
};
|
|
165
100
|
}, [context, editor, threadToNodes, threads]);
|
|
@@ -193,7 +128,6 @@ function CommentPluginProvider({ children }) {
|
|
|
193
128
|
return editor.registerMutationListener(ThreadMarkNode, onMutation);
|
|
194
129
|
}, [editor]);
|
|
195
130
|
useEffect(() => {
|
|
196
|
-
const selectedThreads = client[kInternal].comments.selectedThreads;
|
|
197
131
|
function $getThreadIds(selection) {
|
|
198
132
|
if (selection === null)
|
|
199
133
|
return [];
|
|
@@ -267,33 +201,12 @@ function CommentPluginProvider({ children }) {
|
|
|
267
201
|
}
|
|
268
202
|
);
|
|
269
203
|
}, [editor]);
|
|
270
|
-
|
|
271
|
-
(commentId, threadId) => {
|
|
272
|
-
if (commentId === void 0 && threadId === void 0) {
|
|
273
|
-
setShowActiveSelection(true);
|
|
274
|
-
} else {
|
|
275
|
-
setShowActiveSelection(false);
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
[]
|
|
279
|
-
);
|
|
280
|
-
useEffect(() => {
|
|
281
|
-
return editor.registerUpdateListener(({ editorState: state, tags }) => {
|
|
282
|
-
if (tags.has("collaboration"))
|
|
283
|
-
return;
|
|
284
|
-
state.read(() => setShowActiveSelection(false));
|
|
285
|
-
});
|
|
286
|
-
}, [editor]);
|
|
287
|
-
return /* @__PURE__ */ React.createElement(ShowFloatingComposerProvider, null, /* @__PURE__ */ React.createElement(ThreadCreateCallbackProvider, {
|
|
288
|
-
value: handleThreadCreate
|
|
289
|
-
}, /* @__PURE__ */ React.createElement(ThreadDeleteCallbackProvider, {
|
|
204
|
+
return /* @__PURE__ */ React.createElement(OnDeleteThreadCallback.Provider, {
|
|
290
205
|
value: handleThreadDelete
|
|
291
|
-
}, /* @__PURE__ */ React.createElement(
|
|
292
|
-
value: handleComposerFocus
|
|
293
|
-
}, /* @__PURE__ */ React.createElement(IsThreadActiveCallbackProvider, {
|
|
206
|
+
}, /* @__PURE__ */ React.createElement(IsActiveThreadContext.Provider, {
|
|
294
207
|
value: isThreadActive
|
|
295
|
-
},
|
|
208
|
+
}, children));
|
|
296
209
|
}
|
|
297
210
|
|
|
298
|
-
export { CommentPluginProvider,
|
|
211
|
+
export { CommentPluginProvider, IsActiveThreadContext, OnDeleteThreadCallback };
|
|
299
212
|
//# sourceMappingURL=comment-plugin-provider.mjs.map
|