@liveblocks/react-lexical 2.0.0-alpha2 → 2.0.0-alpha3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,44 +3,49 @@
3
3
  var react = require('@liveblocks/react');
4
4
  var reactUi = require('@liveblocks/react-ui');
5
5
  var React = require('react');
6
+ var classnames = require('../classnames.js');
6
7
  var commentPluginProvider = require('./comment-plugin-provider.js');
7
8
 
8
- const DefaultThread = ({ thread, isActive }) => {
9
+ const ThreadWrapper = ({ Thread, isActive, ...props }) => {
9
10
  const onDeleteThread = React.useContext(commentPluginProvider.OnDeleteThreadCallback);
10
11
  if (onDeleteThread === null) {
11
12
  throw new Error("OnDeleteThreadCallback not provided");
12
13
  }
13
14
  const handleThreadDelete = React.useCallback(
14
- (thread2) => {
15
- onDeleteThread(thread2.id);
15
+ (thread) => {
16
+ onDeleteThread(thread.id);
16
17
  },
17
18
  [onDeleteThread]
18
19
  );
19
- return /* @__PURE__ */ React.createElement(reactUi.Thread, {
20
- thread,
20
+ return /* @__PURE__ */ React.createElement(Thread, {
21
+ onThreadDelete: handleThreadDelete,
21
22
  "data-state": isActive ? "active" : null,
22
- onThreadDelete: handleThreadDelete
23
+ ...props
23
24
  });
24
25
  };
25
- const ThreadPanel = ({ renderThread }) => {
26
- const { threads } = react.useThreads();
27
- const isThreadActive = React.useContext(commentPluginProvider.IsActiveThreadContext);
28
- const ThreadComponent = renderThread ?? DefaultThread;
29
- if (!threads || threads.length === 0) {
26
+ const ThreadPanel = React.forwardRef(
27
+ ({ components, overrides, className, ...props }, forwardedRef) => {
28
+ const $ = reactUi.useOverrides(overrides);
29
+ const { threads } = react.useThreads();
30
+ const isThreadActive = React.useContext(commentPluginProvider.IsActiveThreadContext);
31
+ const Thread = components?.Thread ?? reactUi.Thread;
30
32
  return /* @__PURE__ */ React.createElement("div", {
31
- className: "lb-root lb-lexical-threads-empty"
32
- }, "No threads yet");
33
+ className: classnames.classNames(className, "lb-root lb-lexical-thread-panel"),
34
+ ref: forwardedRef,
35
+ ...props
36
+ }, threads && threads.length > 0 ? threads.map((thread) => {
37
+ return /* @__PURE__ */ React.createElement(ThreadWrapper, {
38
+ Thread,
39
+ isActive: isThreadActive(thread.id),
40
+ key: thread.id,
41
+ thread,
42
+ className: "lb-lexical-thread-panel-thread"
43
+ });
44
+ }) : /* @__PURE__ */ React.createElement("div", {
45
+ className: "lb-lexical-thread-panel-empty"
46
+ }, $.THREAD_PANEL_EMPTY));
33
47
  }
34
- return /* @__PURE__ */ React.createElement("div", {
35
- className: "lb-lexical-threads lb-root"
36
- }, threads.map((thread) => {
37
- return /* @__PURE__ */ React.createElement(ThreadComponent, {
38
- isActive: isThreadActive(thread.id),
39
- key: thread.id,
40
- thread
41
- });
42
- }));
43
- };
48
+ );
44
49
 
45
50
  exports.ThreadPanel = ThreadPanel;
46
51
  //# sourceMappingURL=ThreadPanel.js.map
@@ -1 +1 @@
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
+ {"version":3,"file":"ThreadPanel.js","sources":["../../src/comments/ThreadPanel.tsx"],"sourcesContent":["import type { BaseMetadata, ThreadData } from \"@liveblocks/core\";\nimport { useThreads } from \"@liveblocks/react\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n ThreadOverrides,\n ThreadPanelOverrides,\n ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport { Thread as DefaultThread, useOverrides } from \"@liveblocks/react-ui\";\nimport type { ComponentProps, ComponentType } from \"react\";\nimport React, { forwardRef, useCallback, useContext } from \"react\";\n\nimport { classNames } from \"../classnames\";\nimport {\n IsActiveThreadContext,\n OnDeleteThreadCallback,\n} from \"./comment-plugin-provider\";\n\ntype ThreadPanelComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface ThreadPanelProps extends ComponentProps<\"div\"> {\n /**\n * Override the component's components.\n */\n components?: Partial<ThreadPanelComponents>;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<\n GlobalOverrides &\n ThreadPanelOverrides &\n ThreadOverrides &\n CommentOverrides &\n ComposerOverrides\n >;\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n Thread: ComponentType<ThreadProps>;\n isActive: boolean;\n}\n\nconst ThreadWrapper = ({ Thread, isActive, ...props }: ThreadWrapperProps) => {\n const onDeleteThread = useContext(OnDeleteThreadCallback);\n\n if (onDeleteThread === null) {\n throw new Error(\"OnDeleteThreadCallback not provided\");\n }\n\n const handleThreadDelete = useCallback(\n (thread: ThreadData<BaseMetadata>) => {\n onDeleteThread(thread.id);\n },\n [onDeleteThread]\n );\n\n return (\n <Thread\n onThreadDelete={handleThreadDelete}\n data-state={isActive ? \"active\" : null}\n {...props}\n />\n );\n};\n\nexport const ThreadPanel = forwardRef<HTMLDivElement, ThreadPanelProps>(\n ({ components, overrides, className, ...props }, forwardedRef) => {\n const $ = useOverrides(overrides);\n const { threads } = useThreads();\n const isThreadActive = useContext(IsActiveThreadContext);\n const Thread = components?.Thread ?? DefaultThread;\n\n return (\n <div\n className={classNames(className, \"lb-root lb-lexical-thread-panel\")}\n ref={forwardedRef}\n {...props}\n >\n {threads && threads.length > 0 ? (\n threads.map((thread) => {\n return (\n <ThreadWrapper\n Thread={Thread}\n isActive={isThreadActive(thread.id)}\n key={thread.id}\n thread={thread}\n className=\"lb-lexical-thread-panel-thread\"\n />\n );\n })\n ) : (\n <div className=\"lb-lexical-thread-panel-empty\">\n {$.THREAD_PANEL_EMPTY}\n </div>\n )}\n </div>\n );\n }\n);\n"],"names":["useContext","OnDeleteThreadCallback","useCallback","forwardRef","useOverrides","useThreads","IsActiveThreadContext","DefaultThread","classNames"],"mappings":";;;;;;;;AA+CA,MAAM,gBAAgB,CAAC,EAAE,MAAQ,EAAA,QAAA,EAAA,GAAa,OAAgC,KAAA;AAC5E,EAAM,MAAA,cAAA,GAAiBA,iBAAWC,4CAAsB,CAAA,CAAA;AAExD,EAAA,IAAI,mBAAmB,IAAM,EAAA;AAC3B,IAAM,MAAA,IAAI,MAAM,qCAAqC,CAAA,CAAA;AAAA,GACvD;AAEA,EAAA,MAAM,kBAAqB,GAAAC,iBAAA;AAAA,IACzB,CAAC,MAAqC,KAAA;AACpC,MAAA,cAAA,CAAe,OAAO,EAAE,CAAA,CAAA;AAAA,KAC1B;AAAA,IACA,CAAC,cAAc,CAAA;AAAA,GACjB,CAAA;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IACC,cAAgB,EAAA,kBAAA;AAAA,IAChB,YAAA,EAAY,WAAW,QAAW,GAAA,IAAA;AAAA,IACjC,GAAG,KAAA;AAAA,GACN,CAAA,CAAA;AAEJ,CAAA,CAAA;AAEO,MAAM,WAAc,GAAAC,gBAAA;AAAA,EACzB,CAAC,EAAE,UAAA,EAAY,WAAW,SAAc,EAAA,GAAA,KAAA,IAAS,YAAiB,KAAA;AAChE,IAAM,MAAA,CAAA,GAAIC,qBAAa,SAAS,CAAA,CAAA;AAChC,IAAM,MAAA,EAAE,OAAQ,EAAA,GAAIC,gBAAW,EAAA,CAAA;AAC/B,IAAM,MAAA,cAAA,GAAiBL,iBAAWM,2CAAqB,CAAA,CAAA;AACvD,IAAM,MAAA,MAAA,GAAS,YAAY,MAAU,IAAAC,cAAA,CAAA;AAErC,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,MACC,SAAA,EAAWC,qBAAW,CAAA,SAAA,EAAW,iCAAiC,CAAA;AAAA,MAClE,GAAK,EAAA,YAAA;AAAA,MACJ,GAAG,KAAA;AAAA,KAAA,EAEH,WAAW,OAAQ,CAAA,MAAA,GAAS,IAC3B,OAAQ,CAAA,GAAA,CAAI,CAAC,MAAW,KAAA;AACtB,MAAA,uBACG,KAAA,CAAA,aAAA,CAAA,aAAA,EAAA;AAAA,QACC,MAAA;AAAA,QACA,QAAA,EAAU,cAAe,CAAA,MAAA,CAAO,EAAE,CAAA;AAAA,QAClC,KAAK,MAAO,CAAA,EAAA;AAAA,QACZ,MAAA;AAAA,QACA,SAAU,EAAA,gCAAA;AAAA,OACZ,CAAA,CAAA;AAAA,KAEH,oBAEA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,MAAI,SAAU,EAAA,+BAAA;AAAA,KACZ,EAAA,CAAA,CAAE,kBACL,CAEJ,CAAA,CAAA;AAAA,GAEJ;AACF;;;;"}
@@ -1,44 +1,49 @@
1
1
  import { useThreads } from '@liveblocks/react';
2
- import { Thread } from '@liveblocks/react-ui';
3
- import React__default, { useContext, useCallback } from 'react';
2
+ import { useOverrides, Thread } from '@liveblocks/react-ui';
3
+ import React__default, { useContext, useCallback, forwardRef } from 'react';
4
+ import { classNames } from '../classnames.mjs';
4
5
  import { OnDeleteThreadCallback, IsActiveThreadContext } from './comment-plugin-provider.mjs';
5
6
 
6
- const DefaultThread = ({ thread, isActive }) => {
7
+ const ThreadWrapper = ({ Thread, isActive, ...props }) => {
7
8
  const onDeleteThread = useContext(OnDeleteThreadCallback);
8
9
  if (onDeleteThread === null) {
9
10
  throw new Error("OnDeleteThreadCallback not provided");
10
11
  }
11
12
  const handleThreadDelete = useCallback(
12
- (thread2) => {
13
- onDeleteThread(thread2.id);
13
+ (thread) => {
14
+ onDeleteThread(thread.id);
14
15
  },
15
16
  [onDeleteThread]
16
17
  );
17
18
  return /* @__PURE__ */ React__default.createElement(Thread, {
18
- thread,
19
+ onThreadDelete: handleThreadDelete,
19
20
  "data-state": isActive ? "active" : null,
20
- onThreadDelete: handleThreadDelete
21
+ ...props
21
22
  });
22
23
  };
23
- const ThreadPanel = ({ renderThread }) => {
24
- const { threads } = useThreads();
25
- const isThreadActive = useContext(IsActiveThreadContext);
26
- const ThreadComponent = renderThread ?? DefaultThread;
27
- if (!threads || threads.length === 0) {
24
+ const ThreadPanel = forwardRef(
25
+ ({ components, overrides, className, ...props }, forwardedRef) => {
26
+ const $ = useOverrides(overrides);
27
+ const { threads } = useThreads();
28
+ const isThreadActive = useContext(IsActiveThreadContext);
29
+ const Thread$1 = components?.Thread ?? Thread;
28
30
  return /* @__PURE__ */ React__default.createElement("div", {
29
- className: "lb-root lb-lexical-threads-empty"
30
- }, "No threads yet");
31
+ className: classNames(className, "lb-root lb-lexical-thread-panel"),
32
+ ref: forwardedRef,
33
+ ...props
34
+ }, threads && threads.length > 0 ? threads.map((thread) => {
35
+ return /* @__PURE__ */ React__default.createElement(ThreadWrapper, {
36
+ Thread: Thread$1,
37
+ isActive: isThreadActive(thread.id),
38
+ key: thread.id,
39
+ thread,
40
+ className: "lb-lexical-thread-panel-thread"
41
+ });
42
+ }) : /* @__PURE__ */ React__default.createElement("div", {
43
+ className: "lb-lexical-thread-panel-empty"
44
+ }, $.THREAD_PANEL_EMPTY));
31
45
  }
32
- return /* @__PURE__ */ React__default.createElement("div", {
33
- className: "lb-lexical-threads lb-root"
34
- }, threads.map((thread) => {
35
- return /* @__PURE__ */ React__default.createElement(ThreadComponent, {
36
- isActive: isThreadActive(thread.id),
37
- key: thread.id,
38
- thread
39
- });
40
- }));
41
- };
46
+ );
42
47
 
43
48
  export { ThreadPanel };
44
49
  //# sourceMappingURL=ThreadPanel.mjs.map
@@ -1 +1 @@
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;;;;"}
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 type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n ThreadOverrides,\n ThreadPanelOverrides,\n ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport { Thread as DefaultThread, useOverrides } from \"@liveblocks/react-ui\";\nimport type { ComponentProps, ComponentType } from \"react\";\nimport React, { forwardRef, useCallback, useContext } from \"react\";\n\nimport { classNames } from \"../classnames\";\nimport {\n IsActiveThreadContext,\n OnDeleteThreadCallback,\n} from \"./comment-plugin-provider\";\n\ntype ThreadPanelComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface ThreadPanelProps extends ComponentProps<\"div\"> {\n /**\n * Override the component's components.\n */\n components?: Partial<ThreadPanelComponents>;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<\n GlobalOverrides &\n ThreadPanelOverrides &\n ThreadOverrides &\n CommentOverrides &\n ComposerOverrides\n >;\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n Thread: ComponentType<ThreadProps>;\n isActive: boolean;\n}\n\nconst ThreadWrapper = ({ Thread, isActive, ...props }: ThreadWrapperProps) => {\n const onDeleteThread = useContext(OnDeleteThreadCallback);\n\n if (onDeleteThread === null) {\n throw new Error(\"OnDeleteThreadCallback not provided\");\n }\n\n const handleThreadDelete = useCallback(\n (thread: ThreadData<BaseMetadata>) => {\n onDeleteThread(thread.id);\n },\n [onDeleteThread]\n );\n\n return (\n <Thread\n onThreadDelete={handleThreadDelete}\n data-state={isActive ? \"active\" : null}\n {...props}\n />\n );\n};\n\nexport const ThreadPanel = forwardRef<HTMLDivElement, ThreadPanelProps>(\n ({ components, overrides, className, ...props }, forwardedRef) => {\n const $ = useOverrides(overrides);\n const { threads } = useThreads();\n const isThreadActive = useContext(IsActiveThreadContext);\n const Thread = components?.Thread ?? DefaultThread;\n\n return (\n <div\n className={classNames(className, \"lb-root lb-lexical-thread-panel\")}\n ref={forwardedRef}\n {...props}\n >\n {threads && threads.length > 0 ? (\n threads.map((thread) => {\n return (\n <ThreadWrapper\n Thread={Thread}\n isActive={isThreadActive(thread.id)}\n key={thread.id}\n thread={thread}\n className=\"lb-lexical-thread-panel-thread\"\n />\n );\n })\n ) : (\n <div className=\"lb-lexical-thread-panel-empty\">\n {$.THREAD_PANEL_EMPTY}\n </div>\n )}\n </div>\n );\n }\n);\n"],"names":["React","Thread","DefaultThread"],"mappings":";;;;;;AA+CA,MAAM,gBAAgB,CAAC,EAAE,MAAQ,EAAA,QAAA,EAAA,GAAa,OAAgC,KAAA;AAC5E,EAAM,MAAA,cAAA,GAAiB,WAAW,sBAAsB,CAAA,CAAA;AAExD,EAAA,IAAI,mBAAmB,IAAM,EAAA;AAC3B,IAAM,MAAA,IAAI,MAAM,qCAAqC,CAAA,CAAA;AAAA,GACvD;AAEA,EAAA,MAAM,kBAAqB,GAAA,WAAA;AAAA,IACzB,CAAC,MAAqC,KAAA;AACpC,MAAA,cAAA,CAAe,OAAO,EAAE,CAAA,CAAA;AAAA,KAC1B;AAAA,IACA,CAAC,cAAc,CAAA;AAAA,GACjB,CAAA;AAEA,EAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IACC,cAAgB,EAAA,kBAAA;AAAA,IAChB,YAAA,EAAY,WAAW,QAAW,GAAA,IAAA;AAAA,IACjC,GAAG,KAAA;AAAA,GACN,CAAA,CAAA;AAEJ,CAAA,CAAA;AAEO,MAAM,WAAc,GAAA,UAAA;AAAA,EACzB,CAAC,EAAE,UAAA,EAAY,WAAW,SAAc,EAAA,GAAA,KAAA,IAAS,YAAiB,KAAA;AAChE,IAAM,MAAA,CAAA,GAAI,aAAa,SAAS,CAAA,CAAA;AAChC,IAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,UAAW,EAAA,CAAA;AAC/B,IAAM,MAAA,cAAA,GAAiB,WAAW,qBAAqB,CAAA,CAAA;AACvD,IAAM,MAAAC,QAAA,GAAS,YAAY,MAAU,IAAAC,MAAA,CAAA;AAErC,IAAA,uBACGF,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,MACC,SAAA,EAAW,UAAW,CAAA,SAAA,EAAW,iCAAiC,CAAA;AAAA,MAClE,GAAK,EAAA,YAAA;AAAA,MACJ,GAAG,KAAA;AAAA,KAAA,EAEH,WAAW,OAAQ,CAAA,MAAA,GAAS,IAC3B,OAAQ,CAAA,GAAA,CAAI,CAAC,MAAW,KAAA;AACtB,MAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,aAAA,EAAA;AAAA,gBACCC,QAAA;AAAA,QACA,QAAA,EAAU,cAAe,CAAA,MAAA,CAAO,EAAE,CAAA;AAAA,QAClC,KAAK,MAAO,CAAA,EAAA;AAAA,QACZ,MAAA;AAAA,QACA,SAAU,EAAA,gCAAA;AAAA,OACZ,CAAA,CAAA;AAAA,KAEH,oBAEAD,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,MAAI,SAAU,EAAA,+BAAA;AAAA,KACZ,EAAA,CAAA,CAAE,kBACL,CAEJ,CAAA,CAAA;AAAA,GAEJ;AACF;;;;"}
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- import { BaseMetadata, ThreadData } from '@liveblocks/core';
2
- import { ComposerProps } from '@liveblocks/react-ui';
1
+ import { BaseMetadata } from '@liveblocks/core';
2
+ import { ComposerProps, GlobalOverrides, ThreadPanelOverrides, ThreadOverrides, CommentOverrides, ComposerOverrides, ThreadProps } from '@liveblocks/react-ui';
3
3
  import * as lexical from 'lexical';
4
- import { LexicalCommand, ElementNode, NodeKey, RangeSelection, LexicalNode, BaseSelection, Spread, SerializedElementNode, DecoratorNode, DOMConversionMap, DOMExportOutput, SerializedLexicalNode } from 'lexical';
5
- import React, { ComponentType, ReactNode, JSX as JSX$1 } from 'react';
4
+ import { LexicalCommand, NodeKey } from 'lexical';
5
+ import React, { ComponentProps, ComponentType, ReactNode } from 'react';
6
6
  import { InitialConfigType } from '@lexical/react/LexicalComposer';
7
7
 
8
8
  declare const OPEN_FLOATING_COMPOSER_COMMAND: LexicalCommand<void>;
@@ -12,62 +12,20 @@ declare type ThreadMetadata = {
12
12
  declare type FloatingComposerProps<M extends BaseMetadata = ThreadMetadata> = Omit<ComposerProps<M>, "threadId" | "commentId">;
13
13
  declare const FloatingComposer: React.ForwardRefExoticComponent<FloatingComposerProps<ThreadMetadata> & React.RefAttributes<HTMLFormElement>>;
14
14
 
15
- /**
16
- * MIT License
17
- * Copyright (c) Meta Platforms, Inc. and affiliates.
18
-
19
- * Permission is hereby granted, free of charge, to any person obtaining a copy
20
- * of this software and associated documentation files (the "Software"), to deal
21
- * in the Software without restriction, including without limitation the rights
22
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23
- * copies of the Software, and to permit persons to whom the Software is
24
- * furnished to do so, subject to the following conditions:
25
- *
26
- * The above copyright notice and this permission notice shall be included in all
27
- * copies or substantial portions of the Software.
28
- *
29
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35
- * SOFTWARE.
36
- */
37
-
38
- declare type SerializedThreadMarkNode = Spread<{
39
- ids: Array<string>;
40
- }, SerializedElementNode>;
41
- declare class ThreadMarkNode extends ElementNode {
42
- static getType(): string;
43
- static clone(node: ThreadMarkNode): ThreadMarkNode;
44
- static importDOM(): null;
45
- static importJSON(serializedNode: SerializedThreadMarkNode): ThreadMarkNode;
46
- exportJSON(): SerializedThreadMarkNode;
47
- constructor(ids: Array<string>, key?: NodeKey);
48
- createDOM(): HTMLElement;
49
- updateDOM(): boolean;
50
- hasID(id: string): boolean;
51
- getIDs(): Array<string>;
52
- addID(id: string): void;
53
- deleteID(id: string): void;
54
- insertNewAfter(_: RangeSelection, restoreSelection?: boolean): null | ElementNode;
55
- canInsertTextBefore(): false;
56
- canInsertTextAfter(): false;
57
- canBeEmpty(): false;
58
- isInline(): true;
59
- extractWithChild(_: LexicalNode, selection: BaseSelection, destination: "clone" | "html"): boolean;
60
- excludeFromCopy(destination: "clone" | "html"): boolean;
61
- }
62
-
63
- declare type ThreadProps = {
64
- thread: ThreadData<BaseMetadata>;
65
- isActive: boolean;
15
+ declare type ThreadPanelComponents = {
16
+ Thread: ComponentType<ThreadProps>;
66
17
  };
67
- declare type ThreadPanelProps = {
68
- renderThread?: ComponentType<ThreadProps>;
69
- };
70
- declare const ThreadPanel: ({ renderThread }: ThreadPanelProps) => React.JSX.Element;
18
+ interface ThreadPanelProps extends ComponentProps<"div"> {
19
+ /**
20
+ * Override the component's components.
21
+ */
22
+ components?: Partial<ThreadPanelComponents>;
23
+ /**
24
+ * Override the component's strings.
25
+ */
26
+ overrides?: Partial<GlobalOverrides & ThreadPanelOverrides & ThreadOverrides & CommentOverrides & ComposerOverrides>;
27
+ }
28
+ declare const ThreadPanel: React.ForwardRefExoticComponent<Omit<ThreadPanelProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
71
29
 
72
30
  declare function liveblocksConfig(editorConfig: Omit<InitialConfigType, "editorState">): {
73
31
  nodes: (lexical.KlassConstructor<typeof lexical.LexicalNode> | lexical.LexicalNodeReplacement)[];
@@ -90,24 +48,4 @@ declare function Mention({ nodeKey, children, }: {
90
48
  children: ReactNode;
91
49
  }): React.JSX.Element;
92
50
 
93
- declare type SerializedMentionNode = Spread<{
94
- userId: string;
95
- }, SerializedLexicalNode>;
96
- declare class MentionNode extends DecoratorNode<JSX$1.Element> {
97
- __id: string;
98
- __userId: string;
99
- constructor(id: string, userId: string, key?: NodeKey);
100
- static getType(): string;
101
- static clone(node: MentionNode): MentionNode;
102
- createDOM(): HTMLElement;
103
- updateDOM(): boolean;
104
- static importDom(): DOMConversionMap<HTMLElement> | null;
105
- exportDOM(): DOMExportOutput;
106
- static importJSON(serializedNode: SerializedMentionNode): MentionNode;
107
- exportJSON(): SerializedMentionNode;
108
- getUserId(): string;
109
- getId(): string;
110
- decorate(): JSX$1.Element;
111
- }
112
-
113
- export { FloatingComposer, LiveblocksPlugin, Mention, MentionNode, OPEN_FLOATING_COMPOSER_COMMAND, ThreadMarkNode, ThreadPanel, liveblocksConfig };
51
+ export { FloatingComposer, LiveblocksPlugin, Mention, OPEN_FLOATING_COMPOSER_COMMAND, ThreadPanel, ThreadPanelProps, liveblocksConfig };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { BaseMetadata, ThreadData } from '@liveblocks/core';
2
- import { ComposerProps } from '@liveblocks/react-ui';
1
+ import { BaseMetadata } from '@liveblocks/core';
2
+ import { ComposerProps, GlobalOverrides, ThreadPanelOverrides, ThreadOverrides, CommentOverrides, ComposerOverrides, ThreadProps } from '@liveblocks/react-ui';
3
3
  import * as lexical from 'lexical';
4
- import { LexicalCommand, ElementNode, NodeKey, RangeSelection, LexicalNode, BaseSelection, Spread, SerializedElementNode, DecoratorNode, DOMConversionMap, DOMExportOutput, SerializedLexicalNode } from 'lexical';
5
- import React, { ComponentType, ReactNode, JSX as JSX$1 } from 'react';
4
+ import { LexicalCommand, NodeKey } from 'lexical';
5
+ import React, { ComponentProps, ComponentType, ReactNode } from 'react';
6
6
  import { InitialConfigType } from '@lexical/react/LexicalComposer';
7
7
 
8
8
  declare const OPEN_FLOATING_COMPOSER_COMMAND: LexicalCommand<void>;
@@ -12,62 +12,20 @@ declare type ThreadMetadata = {
12
12
  declare type FloatingComposerProps<M extends BaseMetadata = ThreadMetadata> = Omit<ComposerProps<M>, "threadId" | "commentId">;
13
13
  declare const FloatingComposer: React.ForwardRefExoticComponent<FloatingComposerProps<ThreadMetadata> & React.RefAttributes<HTMLFormElement>>;
14
14
 
15
- /**
16
- * MIT License
17
- * Copyright (c) Meta Platforms, Inc. and affiliates.
18
-
19
- * Permission is hereby granted, free of charge, to any person obtaining a copy
20
- * of this software and associated documentation files (the "Software"), to deal
21
- * in the Software without restriction, including without limitation the rights
22
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23
- * copies of the Software, and to permit persons to whom the Software is
24
- * furnished to do so, subject to the following conditions:
25
- *
26
- * The above copyright notice and this permission notice shall be included in all
27
- * copies or substantial portions of the Software.
28
- *
29
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35
- * SOFTWARE.
36
- */
37
-
38
- declare type SerializedThreadMarkNode = Spread<{
39
- ids: Array<string>;
40
- }, SerializedElementNode>;
41
- declare class ThreadMarkNode extends ElementNode {
42
- static getType(): string;
43
- static clone(node: ThreadMarkNode): ThreadMarkNode;
44
- static importDOM(): null;
45
- static importJSON(serializedNode: SerializedThreadMarkNode): ThreadMarkNode;
46
- exportJSON(): SerializedThreadMarkNode;
47
- constructor(ids: Array<string>, key?: NodeKey);
48
- createDOM(): HTMLElement;
49
- updateDOM(): boolean;
50
- hasID(id: string): boolean;
51
- getIDs(): Array<string>;
52
- addID(id: string): void;
53
- deleteID(id: string): void;
54
- insertNewAfter(_: RangeSelection, restoreSelection?: boolean): null | ElementNode;
55
- canInsertTextBefore(): false;
56
- canInsertTextAfter(): false;
57
- canBeEmpty(): false;
58
- isInline(): true;
59
- extractWithChild(_: LexicalNode, selection: BaseSelection, destination: "clone" | "html"): boolean;
60
- excludeFromCopy(destination: "clone" | "html"): boolean;
61
- }
62
-
63
- declare type ThreadProps = {
64
- thread: ThreadData<BaseMetadata>;
65
- isActive: boolean;
15
+ declare type ThreadPanelComponents = {
16
+ Thread: ComponentType<ThreadProps>;
66
17
  };
67
- declare type ThreadPanelProps = {
68
- renderThread?: ComponentType<ThreadProps>;
69
- };
70
- declare const ThreadPanel: ({ renderThread }: ThreadPanelProps) => React.JSX.Element;
18
+ interface ThreadPanelProps extends ComponentProps<"div"> {
19
+ /**
20
+ * Override the component's components.
21
+ */
22
+ components?: Partial<ThreadPanelComponents>;
23
+ /**
24
+ * Override the component's strings.
25
+ */
26
+ overrides?: Partial<GlobalOverrides & ThreadPanelOverrides & ThreadOverrides & CommentOverrides & ComposerOverrides>;
27
+ }
28
+ declare const ThreadPanel: React.ForwardRefExoticComponent<Omit<ThreadPanelProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
71
29
 
72
30
  declare function liveblocksConfig(editorConfig: Omit<InitialConfigType, "editorState">): {
73
31
  nodes: (lexical.KlassConstructor<typeof lexical.LexicalNode> | lexical.LexicalNodeReplacement)[];
@@ -90,24 +48,4 @@ declare function Mention({ nodeKey, children, }: {
90
48
  children: ReactNode;
91
49
  }): React.JSX.Element;
92
50
 
93
- declare type SerializedMentionNode = Spread<{
94
- userId: string;
95
- }, SerializedLexicalNode>;
96
- declare class MentionNode extends DecoratorNode<JSX$1.Element> {
97
- __id: string;
98
- __userId: string;
99
- constructor(id: string, userId: string, key?: NodeKey);
100
- static getType(): string;
101
- static clone(node: MentionNode): MentionNode;
102
- createDOM(): HTMLElement;
103
- updateDOM(): boolean;
104
- static importDom(): DOMConversionMap<HTMLElement> | null;
105
- exportDOM(): DOMExportOutput;
106
- static importJSON(serializedNode: SerializedMentionNode): MentionNode;
107
- exportJSON(): SerializedMentionNode;
108
- getUserId(): string;
109
- getId(): string;
110
- decorate(): JSX$1.Element;
111
- }
112
-
113
- export { FloatingComposer, LiveblocksPlugin, Mention, MentionNode, OPEN_FLOATING_COMPOSER_COMMAND, ThreadMarkNode, ThreadPanel, liveblocksConfig };
51
+ export { FloatingComposer, LiveblocksPlugin, Mention, OPEN_FLOATING_COMPOSER_COMMAND, ThreadPanel, ThreadPanelProps, liveblocksConfig };
package/dist/index.js CHANGED
@@ -3,21 +3,17 @@
3
3
  var core = require('@liveblocks/core');
4
4
  var version = require('./version.js');
5
5
  var floatingComposer = require('./comments/floating-composer.js');
6
- var threadMarkNode = require('./comments/thread-mark-node.js');
7
6
  var ThreadPanel = require('./comments/ThreadPanel.js');
8
7
  var liveblocksConfig = require('./liveblocks-config.js');
9
8
  var liveblocksPluginProvider = require('./liveblocks-plugin-provider.js');
10
9
  var mentionComponent = require('./mentions/mention-component.js');
11
- var mentionNode = require('./mentions/mention-node.js');
12
10
 
13
11
  core.detectDupes(version.PKG_NAME, version.PKG_VERSION, version.PKG_FORMAT);
14
12
 
15
13
  exports.FloatingComposer = floatingComposer.FloatingComposer;
16
14
  exports.OPEN_FLOATING_COMPOSER_COMMAND = floatingComposer.OPEN_FLOATING_COMPOSER_COMMAND;
17
- exports.ThreadMarkNode = threadMarkNode.ThreadMarkNode;
18
15
  exports.ThreadPanel = ThreadPanel.ThreadPanel;
19
16
  exports.liveblocksConfig = liveblocksConfig.liveblocksConfig;
20
17
  exports.LiveblocksPlugin = liveblocksPluginProvider.LiveblocksPlugin;
21
18
  exports.Mention = mentionComponent.Mention;
22
- exports.MentionNode = mentionNode.MentionNode;
23
19
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport {\n FloatingComposer,\n OPEN_FLOATING_COMPOSER_COMMAND,\n} from \"./comments/floating-composer\";\nexport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nexport { ThreadPanel } from \"./comments/ThreadPanel\";\nexport { liveblocksConfig } from \"./liveblocks-config\";\nexport { LiveblocksPlugin } from \"./liveblocks-plugin-provider\";\nexport { Mention } from \"./mentions/mention-component\";\nexport { MentionNode } from \"./mentions/mention-node\";\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;;;;;;AAIAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport {\n FloatingComposer,\n OPEN_FLOATING_COMPOSER_COMMAND,\n} from \"./comments/floating-composer\";\nexport type { ThreadPanelProps } from \"./comments/ThreadPanel\";\nexport { ThreadPanel } from \"./comments/ThreadPanel\";\nexport { liveblocksConfig } from \"./liveblocks-config\";\nexport { LiveblocksPlugin } from \"./liveblocks-plugin-provider\";\nexport { Mention } from \"./mentions/mention-component\";\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;;;;AAIAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;;;;;"}
package/dist/index.mjs CHANGED
@@ -1,12 +1,10 @@
1
1
  import { detectDupes } from '@liveblocks/core';
2
2
  import { PKG_NAME, PKG_VERSION, PKG_FORMAT } from './version.mjs';
3
3
  export { FloatingComposer, OPEN_FLOATING_COMPOSER_COMMAND } from './comments/floating-composer.mjs';
4
- export { ThreadMarkNode } from './comments/thread-mark-node.mjs';
5
4
  export { ThreadPanel } from './comments/ThreadPanel.mjs';
6
5
  export { liveblocksConfig } from './liveblocks-config.mjs';
7
6
  export { LiveblocksPlugin } from './liveblocks-plugin-provider.mjs';
8
7
  export { Mention } from './mentions/mention-component.mjs';
9
- export { MentionNode } from './mentions/mention-node.mjs';
10
8
 
11
9
  detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
12
10
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport {\n FloatingComposer,\n OPEN_FLOATING_COMPOSER_COMMAND,\n} from \"./comments/floating-composer\";\nexport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nexport { ThreadPanel } from \"./comments/ThreadPanel\";\nexport { liveblocksConfig } from \"./liveblocks-config\";\nexport { LiveblocksPlugin } from \"./liveblocks-plugin-provider\";\nexport { Mention } from \"./mentions/mention-component\";\nexport { MentionNode } from \"./mentions/mention-node\";\n"],"names":[],"mappings":";;;;;;;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport {\n FloatingComposer,\n OPEN_FLOATING_COMPOSER_COMMAND,\n} from \"./comments/floating-composer\";\nexport type { ThreadPanelProps } from \"./comments/ThreadPanel\";\nexport { ThreadPanel } from \"./comments/ThreadPanel\";\nexport { liveblocksConfig } from \"./liveblocks-config\";\nexport { LiveblocksPlugin } from \"./liveblocks-plugin-provider\";\nexport { Mention } from \"./mentions/mention-component\";\n"],"names":[],"mappings":";;;;;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var LexicalCollaborationContext = require('@lexical/react/LexicalCollaborationContext');
3
4
  var LexicalCollaborationPlugin = require('@lexical/react/LexicalCollaborationPlugin');
4
5
  var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
5
6
  var core = require('@liveblocks/core');
@@ -10,6 +11,7 @@ var yjs = require('yjs');
10
11
  var commentPluginProvider = require('./comments/comment-plugin-provider.js');
11
12
  var mentionPlugin = require('./mentions/mention-plugin.js');
12
13
 
14
+ const providersMap = /* @__PURE__ */ new Map();
13
15
  const LiveblocksPlugin = ({
14
16
  children
15
17
  }) => {
@@ -17,16 +19,8 @@ const LiveblocksPlugin = ({
17
19
  const hasResolveMentionSuggestions = client[core.kInternal].resolveMentionSuggestions !== void 0;
18
20
  const [editor] = LexicalComposerContext.useLexicalComposerContext();
19
21
  const room = react.useRoom();
20
- const [provider, setProvider] = React.useState();
21
- const doc = React.useMemo(() => new yjs.Doc(), []);
22
- React.useEffect(() => {
23
- const _provider = new yjs$1.LiveblocksYjsProvider(room, doc);
24
- setProvider(_provider);
25
- return () => {
26
- _provider.destroy();
27
- setProvider(void 0);
28
- };
29
- }, [room, doc]);
22
+ const collabContext = React.useContext(LexicalCollaborationContext.CollaborationContext);
23
+ const previousRoomIdRef = React.useRef(null);
30
24
  React.useEffect(() => {
31
25
  if (process.env.NODE_ENV !== "production") {
32
26
  if (!editor.getEditorState().isEmpty()) {
@@ -40,18 +34,37 @@ const LiveblocksPlugin = ({
40
34
  room[core.kInternal].reportTextEditor("lexical", "root");
41
35
  }, [room]);
42
36
  const info = react.useSelf((me) => me.info);
43
- const username = info?.name;
37
+ const username = info?.name || "";
44
38
  const cursorcolor = info?.color;
45
39
  const providerFactory = React.useCallback(
46
40
  (id, yjsDocMap) => {
47
- yjsDocMap.set(id, doc);
48
- return provider;
41
+ if (previousRoomIdRef.current !== null && previousRoomIdRef.current !== id) {
42
+ const previousProvider = providersMap.get(id);
43
+ if (previousProvider !== void 0) {
44
+ previousProvider.destroy();
45
+ }
46
+ }
47
+ let doc = yjsDocMap.get(id);
48
+ if (doc === void 0) {
49
+ doc = new yjs.Doc();
50
+ const provider = new yjs$1.LiveblocksYjsProvider(room, doc);
51
+ yjsDocMap.set(id, doc);
52
+ providersMap.set(id, provider);
53
+ }
54
+ return core.nn(
55
+ providersMap.get(id),
56
+ "Internal error. Should never happen"
57
+ );
49
58
  },
50
- [provider, doc]
59
+ [room]
51
60
  );
52
- return /* @__PURE__ */ React.createElement(React.Fragment, null, provider && /* @__PURE__ */ React.createElement(LexicalCollaborationPlugin.CollaborationPlugin, {
61
+ React.useEffect(() => {
62
+ collabContext.name = username || "";
63
+ }, [collabContext, username]);
64
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(LexicalCollaborationPlugin.CollaborationPlugin, {
65
+ key: room.id,
66
+ id: room.id,
53
67
  providerFactory,
54
- id: "liveblocks-document",
55
68
  username,
56
69
  cursorColor: cursorcolor,
57
70
  shouldBootstrap: true
@@ -1 +1 @@
1
- {"version":3,"file":"liveblocks-plugin-provider.js","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport type {\n BaseMetadata,\n BaseUserMeta,\n Json,\n JsonObject,\n LsonObject,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient, useRoom, useSelf } from \"@liveblocks/react\";\nimport { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\n\nexport type LiveblocksPluginProps = {\n children?: React.ReactNode;\n};\n\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const client = useClient();\n const hasResolveMentionSuggestions =\n client[kInternal].resolveMentionSuggestions !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n\n const [provider, setProvider] = useState<\n | LiveblocksYjsProvider<\n JsonObject,\n LsonObject,\n BaseUserMeta,\n Json,\n BaseMetadata\n >\n | undefined\n >();\n\n const doc = useMemo(() => new Doc(), []);\n\n useEffect(() => {\n const _provider = new LiveblocksYjsProvider(room, doc);\n setProvider(_provider);\n return () => {\n _provider.destroy();\n setProvider(undefined);\n };\n }, [room, doc]);\n\n // Warn users if initialConfig.editorState, set on the composer, is not null\n useEffect(() => {\n // only in dev mode\n if (process.env.NODE_ENV !== \"production\") {\n // A user should not even be set an emptyState, but when passing null, getEditorState still has initial empty state\n if (!editor.getEditorState().isEmpty()) {\n console.warn(\n \"Warning: LiveblocksPlugin: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // we know editor is already defined as we're inside LexicalComposer, and we only want this running the first time\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n // Report that this is lexical and root is the rootKey\n room[kInternal].reportTextEditor(\"lexical\", \"root\");\n }, [room]);\n\n // Get user info or allow override from props\n const info = useSelf((me) => me.info);\n const username = info?.name;\n const cursorcolor = info?.color as string | undefined;\n\n // Create the provider factory\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>) => {\n yjsDocMap.set(id, doc);\n return provider as Provider;\n },\n [provider, doc]\n );\n\n return (\n <>\n {provider && (\n <CollaborationPlugin\n providerFactory={providerFactory}\n id={\"liveblocks-document\"}\n username={username}\n cursorColor={cursorcolor}\n shouldBootstrap={true}\n />\n )}\n\n {hasResolveMentionSuggestions && <MentionPlugin />}\n\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n"],"names":["useClient","kInternal","useLexicalComposerContext","useRoom","useState","useMemo","Doc","useEffect","LiveblocksYjsProvider","useSelf","useCallback","CollaborationPlugin","MentionPlugin","CommentPluginProvider"],"mappings":";;;;;;;;;;;;AAuBO,MAAM,mBAAmB,CAAC;AAAA,EAC/B,QAAA;AACF,CAA0C,KAAA;AACxC,EAAA,MAAM,SAASA,eAAU,EAAA,CAAA;AACzB,EAAM,MAAA,4BAAA,GACJ,MAAO,CAAAC,cAAA,CAAA,CAAW,yBAA8B,KAAA,KAAA,CAAA,CAAA;AAClD,EAAM,MAAA,CAAC,MAAM,CAAA,GAAIC,gDAA0B,EAAA,CAAA;AAC3C,EAAA,MAAM,OAAOC,aAAQ,EAAA,CAAA;AAErB,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIC,cAS9B,EAAA,CAAA;AAEF,EAAA,MAAM,MAAMC,aAAQ,CAAA,MAAM,IAAIC,OAAI,EAAA,EAAG,EAAE,CAAA,CAAA;AAEvC,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,MAAM,SAAY,GAAA,IAAIC,2BAAsB,CAAA,IAAA,EAAM,GAAG,CAAA,CAAA;AACrD,IAAA,WAAA,CAAY,SAAS,CAAA,CAAA;AACrB,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,CAAU,OAAQ,EAAA,CAAA;AAClB,MAAA,WAAA,CAAY,KAAS,CAAA,CAAA,CAAA;AAAA,KACvB,CAAA;AAAA,GACC,EAAA,CAAC,IAAM,EAAA,GAAG,CAAC,CAAA,CAAA;AAGd,EAAAD,eAAA,CAAU,MAAM;AAEd,IAAI,IAAA,OAAA,CAAQ,GAAI,CAAA,QAAA,KAAa,YAAc,EAAA;AAEzC,MAAA,IAAI,CAAC,MAAA,CAAO,cAAe,EAAA,CAAE,SAAW,EAAA;AACtC,QAAQ,OAAA,CAAA,IAAA;AAAA,UACN,qFAAA;AAAA,SACF,CAAA;AAAA,OACF;AAAA,KACF;AAAA,GAIF,EAAG,EAAE,CAAA,CAAA;AAEL,EAAAA,eAAA,CAAU,MAAM;AAEd,IAAK,IAAA,CAAAN,cAAA,CAAA,CAAW,gBAAiB,CAAA,SAAA,EAAW,MAAM,CAAA,CAAA;AAAA,GACpD,EAAG,CAAC,IAAI,CAAC,CAAA,CAAA;AAGT,EAAA,MAAM,IAAO,GAAAQ,aAAA,CAAQ,CAAC,EAAA,KAAO,GAAG,IAAI,CAAA,CAAA;AACpC,EAAA,MAAM,WAAW,IAAM,EAAA,IAAA,CAAA;AACvB,EAAA,MAAM,cAAc,IAAM,EAAA,KAAA,CAAA;AAG1B,EAAA,MAAM,eAAkB,GAAAC,iBAAA;AAAA,IACtB,CAAC,IAAY,SAAgC,KAAA;AAC3C,MAAU,SAAA,CAAA,GAAA,CAAI,IAAI,GAAG,CAAA,CAAA;AACrB,MAAO,OAAA,QAAA,CAAA;AAAA,KACT;AAAA,IACA,CAAC,UAAU,GAAG,CAAA;AAAA,GAChB,CAAA;AAEA,EACE,uBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EACG,4BACE,KAAA,CAAA,aAAA,CAAAC,8CAAA,EAAA;AAAA,IACC,eAAA;AAAA,IACA,EAAI,EAAA,qBAAA;AAAA,IACJ,QAAA;AAAA,IACA,WAAa,EAAA,WAAA;AAAA,IACb,eAAiB,EAAA,IAAA;AAAA,GACnB,CAAA,EAGD,gDAAiC,KAAA,CAAA,aAAA,CAAAC,2BAAA,EAAA,IAAc,mBAE/C,KAAA,CAAA,aAAA,CAAAC,2CAAA,EAAA,IAAA,EAAuB,QAAS,CACnC,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"liveblocks-plugin-provider.js","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { CollaborationContext } from \"@lexical/react/LexicalCollaborationContext\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { kInternal, nn } from \"@liveblocks/core\";\nimport { useClient, useRoom, useSelf } from \"@liveblocks/react\";\nimport { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport React, { useCallback, useContext, useEffect, useRef } from \"react\";\nimport { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\n\n// TODO: Replace by ref once I understand why useRef is not stable (?!)\nconst providersMap = new Map<\n string,\n LiveblocksYjsProvider<never, never, never, never, never>\n>();\n\nexport type LiveblocksPluginProps = {\n children?: React.ReactNode;\n};\n\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const client = useClient();\n const hasResolveMentionSuggestions =\n client[kInternal].resolveMentionSuggestions !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n const collabContext = useContext(CollaborationContext);\n const previousRoomIdRef = useRef<string | null>(null);\n\n // Warn users if initialConfig.editorState, set on the composer, is not null\n useEffect(() => {\n // only in dev mode\n if (process.env.NODE_ENV !== \"production\") {\n // A user should not even be set an emptyState, but when passing null, getEditorState still has initial empty state\n if (!editor.getEditorState().isEmpty()) {\n console.warn(\n \"Warning: LiveblocksPlugin: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // we know editor is already defined as we're inside LexicalComposer, and we only want this running the first time\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n // Report that this is lexical and root is the rootKey\n room[kInternal].reportTextEditor(\"lexical\", \"root\");\n }, [room]);\n\n // Get user info or allow override from props\n const info = useSelf((me) => me.info);\n const username = info?.name || \"\"; // use empty string to prevent random name\n const cursorcolor = info?.color as string | undefined;\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n // Destroy previously used provider to avoid memory leaks\n // TODO: Find a way to destroy the last used provider on unmount (while working with StrictMode)\n if (\n previousRoomIdRef.current !== null &&\n previousRoomIdRef.current !== id\n ) {\n const previousProvider = providersMap.get(id);\n if (previousProvider !== undefined) {\n previousProvider.destroy();\n }\n }\n\n let doc = yjsDocMap.get(id);\n\n if (doc === undefined) {\n doc = new Doc();\n const provider = new LiveblocksYjsProvider(room, doc);\n yjsDocMap.set(id, doc);\n providersMap.set(id, provider);\n }\n\n return nn(\n providersMap.get(id),\n \"Internal error. Should never happen\"\n ) as Provider;\n },\n [room]\n );\n\n useEffect(() => {\n collabContext.name = username || \"\";\n }, [collabContext, username]);\n\n return (\n <>\n <CollaborationPlugin\n // Setting the key allows us to reset the internal Y.doc used by useYjsCollaboration\n // without implementing `reload` event\n key={room.id}\n id={room.id}\n providerFactory={providerFactory}\n username={username}\n cursorColor={cursorcolor}\n shouldBootstrap={true}\n />\n\n {hasResolveMentionSuggestions && <MentionPlugin />}\n\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n"],"names":["useClient","kInternal","useLexicalComposerContext","useRoom","useContext","CollaborationContext","useRef","useEffect","useSelf","useCallback","Doc","LiveblocksYjsProvider","nn","CollaborationPlugin","MentionPlugin","CommentPluginProvider"],"mappings":"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"}
@@ -1,13 +1,15 @@
1
+ import { CollaborationContext } from '@lexical/react/LexicalCollaborationContext';
1
2
  import { CollaborationPlugin } from '@lexical/react/LexicalCollaborationPlugin';
2
3
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
3
- import { kInternal } from '@liveblocks/core';
4
+ import { kInternal, nn } from '@liveblocks/core';
4
5
  import { useClient, useRoom, useSelf } from '@liveblocks/react';
5
6
  import { LiveblocksYjsProvider } from '@liveblocks/yjs';
6
- import React__default, { useState, useMemo, useEffect, useCallback } from 'react';
7
+ import React__default, { useContext, useRef, useEffect, useCallback } from 'react';
7
8
  import { Doc } from 'yjs';
8
9
  import { CommentPluginProvider } from './comments/comment-plugin-provider.mjs';
9
10
  import { MentionPlugin } from './mentions/mention-plugin.mjs';
10
11
 
12
+ const providersMap = /* @__PURE__ */ new Map();
11
13
  const LiveblocksPlugin = ({
12
14
  children
13
15
  }) => {
@@ -15,16 +17,8 @@ const LiveblocksPlugin = ({
15
17
  const hasResolveMentionSuggestions = client[kInternal].resolveMentionSuggestions !== void 0;
16
18
  const [editor] = useLexicalComposerContext();
17
19
  const room = useRoom();
18
- const [provider, setProvider] = useState();
19
- const doc = useMemo(() => new Doc(), []);
20
- useEffect(() => {
21
- const _provider = new LiveblocksYjsProvider(room, doc);
22
- setProvider(_provider);
23
- return () => {
24
- _provider.destroy();
25
- setProvider(void 0);
26
- };
27
- }, [room, doc]);
20
+ const collabContext = useContext(CollaborationContext);
21
+ const previousRoomIdRef = useRef(null);
28
22
  useEffect(() => {
29
23
  if (process.env.NODE_ENV !== "production") {
30
24
  if (!editor.getEditorState().isEmpty()) {
@@ -38,18 +32,37 @@ const LiveblocksPlugin = ({
38
32
  room[kInternal].reportTextEditor("lexical", "root");
39
33
  }, [room]);
40
34
  const info = useSelf((me) => me.info);
41
- const username = info?.name;
35
+ const username = info?.name || "";
42
36
  const cursorcolor = info?.color;
43
37
  const providerFactory = useCallback(
44
38
  (id, yjsDocMap) => {
45
- yjsDocMap.set(id, doc);
46
- return provider;
39
+ if (previousRoomIdRef.current !== null && previousRoomIdRef.current !== id) {
40
+ const previousProvider = providersMap.get(id);
41
+ if (previousProvider !== void 0) {
42
+ previousProvider.destroy();
43
+ }
44
+ }
45
+ let doc = yjsDocMap.get(id);
46
+ if (doc === void 0) {
47
+ doc = new Doc();
48
+ const provider = new LiveblocksYjsProvider(room, doc);
49
+ yjsDocMap.set(id, doc);
50
+ providersMap.set(id, provider);
51
+ }
52
+ return nn(
53
+ providersMap.get(id),
54
+ "Internal error. Should never happen"
55
+ );
47
56
  },
48
- [provider, doc]
57
+ [room]
49
58
  );
50
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, provider && /* @__PURE__ */ React__default.createElement(CollaborationPlugin, {
59
+ useEffect(() => {
60
+ collabContext.name = username || "";
61
+ }, [collabContext, username]);
62
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(CollaborationPlugin, {
63
+ key: room.id,
64
+ id: room.id,
51
65
  providerFactory,
52
- id: "liveblocks-document",
53
66
  username,
54
67
  cursorColor: cursorcolor,
55
68
  shouldBootstrap: true
@@ -1 +1 @@
1
- {"version":3,"file":"liveblocks-plugin-provider.mjs","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport type {\n BaseMetadata,\n BaseUserMeta,\n Json,\n JsonObject,\n LsonObject,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient, useRoom, useSelf } from \"@liveblocks/react\";\nimport { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\n\nexport type LiveblocksPluginProps = {\n children?: React.ReactNode;\n};\n\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const client = useClient();\n const hasResolveMentionSuggestions =\n client[kInternal].resolveMentionSuggestions !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n\n const [provider, setProvider] = useState<\n | LiveblocksYjsProvider<\n JsonObject,\n LsonObject,\n BaseUserMeta,\n Json,\n BaseMetadata\n >\n | undefined\n >();\n\n const doc = useMemo(() => new Doc(), []);\n\n useEffect(() => {\n const _provider = new LiveblocksYjsProvider(room, doc);\n setProvider(_provider);\n return () => {\n _provider.destroy();\n setProvider(undefined);\n };\n }, [room, doc]);\n\n // Warn users if initialConfig.editorState, set on the composer, is not null\n useEffect(() => {\n // only in dev mode\n if (process.env.NODE_ENV !== \"production\") {\n // A user should not even be set an emptyState, but when passing null, getEditorState still has initial empty state\n if (!editor.getEditorState().isEmpty()) {\n console.warn(\n \"Warning: LiveblocksPlugin: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // we know editor is already defined as we're inside LexicalComposer, and we only want this running the first time\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n // Report that this is lexical and root is the rootKey\n room[kInternal].reportTextEditor(\"lexical\", \"root\");\n }, [room]);\n\n // Get user info or allow override from props\n const info = useSelf((me) => me.info);\n const username = info?.name;\n const cursorcolor = info?.color as string | undefined;\n\n // Create the provider factory\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>) => {\n yjsDocMap.set(id, doc);\n return provider as Provider;\n },\n [provider, doc]\n );\n\n return (\n <>\n {provider && (\n <CollaborationPlugin\n providerFactory={providerFactory}\n id={\"liveblocks-document\"}\n username={username}\n cursorColor={cursorcolor}\n shouldBootstrap={true}\n />\n )}\n\n {hasResolveMentionSuggestions && <MentionPlugin />}\n\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n"],"names":["React"],"mappings":";;;;;;;;;;AAuBO,MAAM,mBAAmB,CAAC;AAAA,EAC/B,QAAA;AACF,CAA0C,KAAA;AACxC,EAAA,MAAM,SAAS,SAAU,EAAA,CAAA;AACzB,EAAM,MAAA,4BAAA,GACJ,MAAO,CAAA,SAAA,CAAA,CAAW,yBAA8B,KAAA,KAAA,CAAA,CAAA;AAClD,EAAM,MAAA,CAAC,MAAM,CAAA,GAAI,yBAA0B,EAAA,CAAA;AAC3C,EAAA,MAAM,OAAO,OAAQ,EAAA,CAAA;AAErB,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,QAS9B,EAAA,CAAA;AAEF,EAAA,MAAM,MAAM,OAAQ,CAAA,MAAM,IAAI,GAAI,EAAA,EAAG,EAAE,CAAA,CAAA;AAEvC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,SAAY,GAAA,IAAI,qBAAsB,CAAA,IAAA,EAAM,GAAG,CAAA,CAAA;AACrD,IAAA,WAAA,CAAY,SAAS,CAAA,CAAA;AACrB,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,CAAU,OAAQ,EAAA,CAAA;AAClB,MAAA,WAAA,CAAY,KAAS,CAAA,CAAA,CAAA;AAAA,KACvB,CAAA;AAAA,GACC,EAAA,CAAC,IAAM,EAAA,GAAG,CAAC,CAAA,CAAA;AAGd,EAAA,SAAA,CAAU,MAAM;AAEd,IAAI,IAAA,OAAA,CAAQ,GAAI,CAAA,QAAA,KAAa,YAAc,EAAA;AAEzC,MAAA,IAAI,CAAC,MAAA,CAAO,cAAe,EAAA,CAAE,SAAW,EAAA;AACtC,QAAQ,OAAA,CAAA,IAAA;AAAA,UACN,qFAAA;AAAA,SACF,CAAA;AAAA,OACF;AAAA,KACF;AAAA,GAIF,EAAG,EAAE,CAAA,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AAEd,IAAK,IAAA,CAAA,SAAA,CAAA,CAAW,gBAAiB,CAAA,SAAA,EAAW,MAAM,CAAA,CAAA;AAAA,GACpD,EAAG,CAAC,IAAI,CAAC,CAAA,CAAA;AAGT,EAAA,MAAM,IAAO,GAAA,OAAA,CAAQ,CAAC,EAAA,KAAO,GAAG,IAAI,CAAA,CAAA;AACpC,EAAA,MAAM,WAAW,IAAM,EAAA,IAAA,CAAA;AACvB,EAAA,MAAM,cAAc,IAAM,EAAA,KAAA,CAAA;AAG1B,EAAA,MAAM,eAAkB,GAAA,WAAA;AAAA,IACtB,CAAC,IAAY,SAAgC,KAAA;AAC3C,MAAU,SAAA,CAAA,GAAA,CAAI,IAAI,GAAG,CAAA,CAAA;AACrB,MAAO,OAAA,QAAA,CAAA;AAAA,KACT;AAAA,IACA,CAAC,UAAU,GAAG,CAAA;AAAA,GAChB,CAAA;AAEA,EACE,uBAAAA,cAAA,CAAA,aAAA,CAAAA,cAAA,CAAA,QAAA,EAAA,IAAA,EACG,4BACEA,cAAA,CAAA,aAAA,CAAA,mBAAA,EAAA;AAAA,IACC,eAAA;AAAA,IACA,EAAI,EAAA,qBAAA;AAAA,IACJ,QAAA;AAAA,IACA,WAAa,EAAA,WAAA;AAAA,IACb,eAAiB,EAAA,IAAA;AAAA,GACnB,CAAA,EAGD,gDAAiCA,cAAA,CAAA,aAAA,CAAA,aAAA,EAAA,IAAc,mBAE/CA,cAAA,CAAA,aAAA,CAAA,qBAAA,EAAA,IAAA,EAAuB,QAAS,CACnC,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"liveblocks-plugin-provider.mjs","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { CollaborationContext } from \"@lexical/react/LexicalCollaborationContext\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { kInternal, nn } from \"@liveblocks/core\";\nimport { useClient, useRoom, useSelf } from \"@liveblocks/react\";\nimport { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport React, { useCallback, useContext, useEffect, useRef } from \"react\";\nimport { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\n\n// TODO: Replace by ref once I understand why useRef is not stable (?!)\nconst providersMap = new Map<\n string,\n LiveblocksYjsProvider<never, never, never, never, never>\n>();\n\nexport type LiveblocksPluginProps = {\n children?: React.ReactNode;\n};\n\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const client = useClient();\n const hasResolveMentionSuggestions =\n client[kInternal].resolveMentionSuggestions !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n const collabContext = useContext(CollaborationContext);\n const previousRoomIdRef = useRef<string | null>(null);\n\n // Warn users if initialConfig.editorState, set on the composer, is not null\n useEffect(() => {\n // only in dev mode\n if (process.env.NODE_ENV !== \"production\") {\n // A user should not even be set an emptyState, but when passing null, getEditorState still has initial empty state\n if (!editor.getEditorState().isEmpty()) {\n console.warn(\n \"Warning: LiveblocksPlugin: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // we know editor is already defined as we're inside LexicalComposer, and we only want this running the first time\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n // Report that this is lexical and root is the rootKey\n room[kInternal].reportTextEditor(\"lexical\", \"root\");\n }, [room]);\n\n // Get user info or allow override from props\n const info = useSelf((me) => me.info);\n const username = info?.name || \"\"; // use empty string to prevent random name\n const cursorcolor = info?.color as string | undefined;\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n // Destroy previously used provider to avoid memory leaks\n // TODO: Find a way to destroy the last used provider on unmount (while working with StrictMode)\n if (\n previousRoomIdRef.current !== null &&\n previousRoomIdRef.current !== id\n ) {\n const previousProvider = providersMap.get(id);\n if (previousProvider !== undefined) {\n previousProvider.destroy();\n }\n }\n\n let doc = yjsDocMap.get(id);\n\n if (doc === undefined) {\n doc = new Doc();\n const provider = new LiveblocksYjsProvider(room, doc);\n yjsDocMap.set(id, doc);\n providersMap.set(id, provider);\n }\n\n return nn(\n providersMap.get(id),\n \"Internal error. Should never happen\"\n ) as Provider;\n },\n [room]\n );\n\n useEffect(() => {\n collabContext.name = username || \"\";\n }, [collabContext, username]);\n\n return (\n <>\n <CollaborationPlugin\n // Setting the key allows us to reset the internal Y.doc used by useYjsCollaboration\n // without implementing `reload` event\n key={room.id}\n id={room.id}\n providerFactory={providerFactory}\n username={username}\n cursorColor={cursorcolor}\n shouldBootstrap={true}\n />\n\n {hasResolveMentionSuggestions && <MentionPlugin />}\n\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n"],"names":["React"],"mappings":"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"}
package/dist/version.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const PKG_NAME = "@liveblocks/react-lexical";
4
- const PKG_VERSION = typeof "2.0.0-alpha2" === "string" && "2.0.0-alpha2";
4
+ const PKG_VERSION = typeof "2.0.0-alpha3" === "string" && "2.0.0-alpha3";
5
5
  const PKG_FORMAT = typeof "cjs" === "string" && "cjs";
6
6
 
7
7
  exports.PKG_FORMAT = PKG_FORMAT;
package/dist/version.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  const PKG_NAME = "@liveblocks/react-lexical";
2
- const PKG_VERSION = typeof "2.0.0-alpha2" === "string" && "2.0.0-alpha2";
2
+ const PKG_VERSION = typeof "2.0.0-alpha3" === "string" && "2.0.0-alpha3";
3
3
  const PKG_FORMAT = typeof "esm" === "string" && "esm";
4
4
 
5
5
  export { PKG_FORMAT, PKG_NAME, PKG_VERSION };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liveblocks/react-lexical",
3
- "version": "2.0.0-alpha2",
3
+ "version": "2.0.0-alpha3",
4
4
  "description": "A lexical react plugin to enable collaboration, comments, live cursors, and more.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "commonjs",
@@ -42,11 +42,11 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@floating-ui/react-dom": "^2.1.0",
45
- "@liveblocks/client": "2.0.0-alpha2",
46
- "@liveblocks/core": "2.0.0-alpha2",
47
- "@liveblocks/react": "2.0.0-alpha2",
48
- "@liveblocks/react-ui": "2.0.0-alpha2",
49
- "@liveblocks/yjs": "2.0.0-alpha2",
45
+ "@liveblocks/client": "2.0.0-alpha3",
46
+ "@liveblocks/core": "2.0.0-alpha3",
47
+ "@liveblocks/react": "2.0.0-alpha3",
48
+ "@liveblocks/react-ui": "2.0.0-alpha3",
49
+ "@liveblocks/yjs": "2.0.0-alpha3",
50
50
  "nanoid": "^3",
51
51
  "use-sync-external-store": "^1.2.2",
52
52
  "yjs": "^13.6.14"
@@ -1,17 +1,28 @@
1
1
  @import "./utils";
2
2
  @import "./constants";
3
3
 
4
- .lb-lexical-threads-empty {
4
+ .lb-lexical-thread-panel {
5
+ display: flex;
6
+ flex-direction: column;
7
+ }
8
+
9
+ .lb-lexical-thread-panel-empty {
10
+ position: absolute;
11
+ inset: 0;
5
12
  display: flex;
6
13
  justify-content: center;
7
14
  align-items: center;
8
- block-size: max-content;
9
- color: rgb(55 53 47 / 50%);
15
+ padding: var(--lb-spacing);
16
+ color: var(--lb-foreground-tertiary);
17
+ font-size: 0.875em;
18
+ text-align: center;
19
+ text-wrap: balance;
10
20
  }
11
21
 
12
- .lb-lexical-threads {
13
- display: flex;
14
- flex-direction: column;
22
+ .lb-lexical-thread-panel-thread {
23
+ &:where(:not(:last-of-type)) {
24
+ border-block-end: 1px solid var(--lb-foreground-subtle);
25
+ }
15
26
  }
16
27
 
17
28
  /*************************************
package/styles.css CHANGED
@@ -1 +1 @@
1
- .lb-lexical-threads-empty{color:#37352f80;justify-content:center;align-items:center;block-size:max-content;display:flex}.lb-lexical-threads{flex-direction:column;display:flex}.lb-lexical-suggestions-list{margin:0;padding:0;list-style:none}.lb-lexical-mention-suggestions{--lb-lexical-mention-suggestion-avatar-size:1.25rem}.lb-lexical-mention-suggestion{padding:calc(.375*var(--lb-spacing))calc(.625*var(--lb-spacing))}.lb-lexical-mention-suggestion-avatar{inline-size:var(--lb-lexical-mention-suggestion-avatar-size);margin-inline-start:calc(-.125*var(--lb-spacing));margin-inline-end:calc(.5*var(--lb-spacing));margin-block:calc(.125*var(--lb-spacing));background:var(--lb-foreground-subtle);color:var(--lb-foreground-moderate)}.lb-lexical-suggestions{animation-duration:var(--lb-transition-duration);animation-timing-function:var(--lb-transition-easing);will-change:transform,opacity;padding:4px}.lb-lexical-suggestions-list-item{padding:calc(.25*var(--lb-spacing))calc(.5*var(--lb-spacing));border-radius:calc(var(--lb-radius) - .75*4px);color:var(--lb-foreground-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;outline:none;align-items:center;scroll-margin-block:4px;font-size:.875rem;transition-property:background,color,opacity;display:flex}.lb-lexical-suggestions-list-item:where([data-highlighted],[data-selected]){background:var(--lb-foreground-subtle);transition-duration:calc(var(--lb-transition-duration)/2)}.lb-lexical-suggestions-list-item:where(:disabled,[data-disabled]){opacity:.5;cursor:not-allowed}.lb-lexical-suggestions:where([data-side=top]){animation-name:lb-animation-slide-up}.lb-lexical-suggestions:where([data-side=bottom]){animation-name:lb-animation-slide-down}.lb-lexical-suggestions:where([data-state=closed]){animation-name:lb-animation-disappear}.lb-lexical-mention{border-radius:calc(.675*var(--lb-radius));background:var(--lb-accent-subtle);color:var(--lb-accent);-webkit-box-decoration-break:clone;box-decoration-break:clone;padding:.1em .3em;font-weight:500}.lb-lexical-mention::selection{background:0 0}.lb-lexical-mention ::selection{background:0 0}.lb-lexical-mention:where([data-selected]){background:var(--lb-accent);color:var(--lb-accent-foreground)}.lb-lexical-active-selection{background-color:var(--lb-selection)}.lb-thread-mark{color:var(--lb-foreground);text-decoration-line:underline;-webkit-text-decoration-color:var(--lb-foreground-moderate);text-decoration-color:var(--lb-foreground-moderate);text-underline-offset:2px;outline:none;font-weight:500;transition-property:color,text-decoration-color}.lb-thread-mark:where([data-state=active]){color:var(--lb-accent);-webkit-text-decoration-color:var(--lb-accent-moderate);text-decoration-color:var(--lb-accent-moderate)}@media (prefers-reduced-motion){.lb-lexical-suggestions:where(:not([data-state=closed])){animation-name:lb-animation-appear}}
1
+ .lb-lexical-thread-panel{flex-direction:column;display:flex}.lb-lexical-thread-panel-empty{padding:var(--lb-spacing);color:var(--lb-foreground-tertiary);text-align:center;text-wrap:balance;justify-content:center;align-items:center;font-size:.875em;display:flex;position:absolute;inset:0}.lb-lexical-thread-panel-thread:where(:not(:last-of-type)){border-block-end:1px solid var(--lb-foreground-subtle)}.lb-lexical-suggestions-list{margin:0;padding:0;list-style:none}.lb-lexical-mention-suggestions{--lb-lexical-mention-suggestion-avatar-size:1.25rem}.lb-lexical-mention-suggestion{padding:calc(.375*var(--lb-spacing))calc(.625*var(--lb-spacing))}.lb-lexical-mention-suggestion-avatar{inline-size:var(--lb-lexical-mention-suggestion-avatar-size);margin-inline-start:calc(-.125*var(--lb-spacing));margin-inline-end:calc(.5*var(--lb-spacing));margin-block:calc(.125*var(--lb-spacing));background:var(--lb-foreground-subtle);color:var(--lb-foreground-moderate)}.lb-lexical-suggestions{animation-duration:var(--lb-transition-duration);animation-timing-function:var(--lb-transition-easing);will-change:transform,opacity;padding:4px}.lb-lexical-suggestions-list-item{padding:calc(.25*var(--lb-spacing))calc(.5*var(--lb-spacing));border-radius:calc(var(--lb-radius) - .75*4px);color:var(--lb-foreground-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;outline:none;align-items:center;scroll-margin-block:4px;font-size:.875rem;transition-property:background,color,opacity;display:flex}.lb-lexical-suggestions-list-item:where([data-highlighted],[data-selected]){background:var(--lb-foreground-subtle);transition-duration:calc(var(--lb-transition-duration)/2)}.lb-lexical-suggestions-list-item:where(:disabled,[data-disabled]){opacity:.5;cursor:not-allowed}.lb-lexical-suggestions:where([data-side=top]){animation-name:lb-animation-slide-up}.lb-lexical-suggestions:where([data-side=bottom]){animation-name:lb-animation-slide-down}.lb-lexical-suggestions:where([data-state=closed]){animation-name:lb-animation-disappear}.lb-lexical-mention{border-radius:calc(.675*var(--lb-radius));background:var(--lb-accent-subtle);color:var(--lb-accent);-webkit-box-decoration-break:clone;box-decoration-break:clone;padding:.1em .3em;font-weight:500}.lb-lexical-mention::selection{background:0 0}.lb-lexical-mention ::selection{background:0 0}.lb-lexical-mention:where([data-selected]){background:var(--lb-accent);color:var(--lb-accent-foreground)}.lb-lexical-active-selection{background-color:var(--lb-selection)}.lb-thread-mark{color:var(--lb-foreground);text-decoration-line:underline;-webkit-text-decoration-color:var(--lb-foreground-moderate);text-decoration-color:var(--lb-foreground-moderate);text-underline-offset:2px;outline:none;font-weight:500;transition-property:color,text-decoration-color}.lb-thread-mark:where([data-state=active]){color:var(--lb-accent);-webkit-text-decoration-color:var(--lb-accent-moderate);text-decoration-color:var(--lb-accent-moderate)}@media (prefers-reduced-motion){.lb-lexical-suggestions:where(:not([data-state=closed])){animation-name:lb-animation-appear}}
package/styles.css.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["src/styles/src/styles/index.css","src/styles/src/styles/utils.css"],"names":[],"mappings":"AAGA,0BAAA,eAAA,CAAA,sBAAA,CAAA,kBAAA,CAAA,sBAAA,CAAA,YAAA,CAQA,oBAAA,qBAAA,CAAA,YAAA,CASA,6BAAA,QAAA,CAAA,SAAA,CAAA,eAAA,CAUA,gCAAA,mDAAA,CAIA,+BAAA,gEAAA,CAIA,sCAAA,4DAAA,CAAA,iDAAA,CAAA,4CAAA,CAAA,yCAAA,CAAA,sCAAA,CAAA,mCAAA,CAaA,wBAAA,gDAAA,CAAA,qDAAA,CAAA,6BAAA,CAAA,WAAA,CAOA,kCAAA,6DAAA,CAAA,8CAAA,CAAA,oCAAA,CAAA,cAAA,CAAA,wBAAA,CAAA,gBAAA,CAAA,YAAA,CAAA,kBAAA,CAAA,uBAAA,CAAA,iBAAA,CAAA,4CAAA,CAAA,YAAA,CAeE,4EAAA,sCAAA,CAAA,yDAAA,CAKA,mEAAA,UAAA,CAAA,kBAAA,CAWA,+CAAA,oCAAA,CAIA,kDAAA,sCAAA,CAIA,mDAAA,qCAAA,CAeF,oBAAA,yCAAA,CAAA,kCAAA,CAAA,sBAAA,CAAA,kCAAA,CAAA,0BAAA,CAAA,iBAAA,CAAA,eAAA,CC/GE,+BAAA,cAAA,CAAA,gCAAA,cAAA,CDyHA,2CAAA,2BAAA,CAAA,iCAAA,CAUF,6BAAA,oCAAA,CAQA,gBAAA,0BAAA,CAAA,8BAAA,CAAA,2DAAA,CAAA,mDAAA,CAAA,yBAAA,CAAA,YAAA,CAAA,eAAA,CAAA,+CAAA,CASE,2CAAA,sBAAA,CAAA,uDAAA,CAAA,+CAAA,CA/CF,gCACE,yDAAA,kCAAA,CAAA","file":"styles.css","sourcesContent":["@import \"./utils\";\n@import \"./constants\";\n\n.lb-lexical-threads-empty {\n display: flex;\n justify-content: center;\n align-items: center;\n block-size: max-content;\n color: rgb(55 53 47 / 50%);\n}\n\n.lb-lexical-threads {\n display: flex;\n flex-direction: column;\n}\n\n/*************************************\n * Suggestions *\n *************************************/\n\n.lb-lexical-suggestions-list {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n/*************************************\n * Mention suggestions *\n *************************************/\n\n.lb-lexical-mention-suggestions {\n --lb-lexical-mention-suggestion-avatar-size: 1.25rem;\n}\n\n.lb-lexical-mention-suggestion {\n padding: calc(0.375 * var(--lb-spacing)) calc(0.625 * var(--lb-spacing));\n}\n\n.lb-lexical-mention-suggestion-avatar {\n inline-size: var(--lb-lexical-mention-suggestion-avatar-size);\n margin-inline-start: calc(-0.125 * var(--lb-spacing));\n margin-inline-end: calc(0.5 * var(--lb-spacing));\n margin-block: calc(0.125 * var(--lb-spacing));\n background: var(--lb-foreground-subtle);\n color: var(--lb-foreground-moderate);\n}\n\n/*************************************\n * Elevation lists *\n *************************************/\n\n.lb-lexical-suggestions {\n padding: $lb-elevation-list-padding;\n animation-duration: var(--lb-transition-duration);\n animation-timing-function: var(--lb-transition-easing);\n will-change: transform, opacity;\n}\n\n.lb-lexical-suggestions-list-item {\n display: flex;\n align-items: center;\n padding: calc(0.25 * var(--lb-spacing)) calc(0.5 * var(--lb-spacing));\n border-radius: calc(var(--lb-radius) - 0.75 * $lb-elevation-list-padding);\n color: var(--lb-foreground-secondary);\n outline: none;\n font-size: 0.875rem;\n cursor: pointer;\n user-select: none;\n transition-property: background, color, opacity;\n scroll-margin-block: $lb-elevation-list-padding;\n}\n\n:is(.lb-lexical-suggestions-list-item) {\n &:where([data-highlighted], [data-selected]) {\n background: var(--lb-foreground-subtle);\n transition-duration: calc(var(--lb-transition-duration) / 2);\n }\n\n &:where(:disabled, [data-disabled]) {\n opacity: 0.5;\n cursor: not-allowed;\n }\n}\n\n/*************************************\n * Floating animations *\n *************************************/\n\n:is(.lb-lexical-suggestions) {\n &:where([data-side=\"top\"]) {\n animation-name: lb-animation-slide-up;\n }\n\n &:where([data-side=\"bottom\"]) {\n animation-name: lb-animation-slide-down;\n }\n\n &:where([data-state=\"closed\"]) {\n animation-name: lb-animation-disappear;\n }\n}\n\n@media (prefers-reduced-motion) {\n .lb-lexical-suggestions:where(:not([data-state=\"closed\"])) {\n animation-name: lb-animation-appear;\n }\n}\n\n/*************************************\n * Mention *\n *************************************/\n\n.lb-lexical-mention {\n padding: 0.1em 0.3em;\n border-radius: calc(0.675 * var(--lb-radius));\n background: var(--lb-accent-subtle);\n color: var(--lb-accent);\n box-decoration-break: clone;\n font-weight: 500;\n\n @include invisible-selection;\n\n &:where([data-selected]) {\n background: var(--lb-accent);\n color: var(--lb-accent-foreground);\n }\n}\n\n/*************************************\n * Active selection *\n *************************************/\n\n.lb-lexical-active-selection {\n background-color: var(--lb-selection);\n}\n\n/*************************************\n * Thread Mark *\n *************************************/\n\n.lb-thread-mark {\n color: var(--lb-foreground);\n outline: none;\n font-weight: 500;\n transition-property: color, text-decoration-color;\n text-decoration-line: underline;\n text-decoration-color: var(--lb-foreground-moderate);\n text-underline-offset: 2px;\n\n &:where([data-state=\"active\"]) {\n color: var(--lb-accent);\n text-decoration-color: var(--lb-accent-moderate);\n }\n}\n","@mixin invisible-selection {\n &::selection,\n *::selection {\n background: transparent;\n }\n}\n"]}
1
+ {"version":3,"sources":["src/styles/src/styles/index.css","src/styles/src/styles/utils.css"],"names":[],"mappings":"AAGA,yBAAA,qBAAA,CAAA,YAAA,CAKA,+BAAA,yBAAA,CAAA,mCAAA,CAAA,iBAAA,CAAA,iBAAA,CAAA,sBAAA,CAAA,kBAAA,CAAA,gBAAA,CAAA,YAAA,CAAA,iBAAA,CAAA,OAAA,CAcE,2DAAA,sDAAA,CASF,6BAAA,QAAA,CAAA,SAAA,CAAA,eAAA,CAUA,gCAAA,mDAAA,CAIA,+BAAA,gEAAA,CAIA,sCAAA,4DAAA,CAAA,iDAAA,CAAA,4CAAA,CAAA,yCAAA,CAAA,sCAAA,CAAA,mCAAA,CAaA,wBAAA,gDAAA,CAAA,qDAAA,CAAA,6BAAA,CAAA,WAAA,CAOA,kCAAA,6DAAA,CAAA,8CAAA,CAAA,oCAAA,CAAA,cAAA,CAAA,wBAAA,CAAA,gBAAA,CAAA,YAAA,CAAA,kBAAA,CAAA,uBAAA,CAAA,iBAAA,CAAA,4CAAA,CAAA,YAAA,CAeE,4EAAA,sCAAA,CAAA,yDAAA,CAKA,mEAAA,UAAA,CAAA,kBAAA,CAWA,+CAAA,oCAAA,CAIA,kDAAA,sCAAA,CAIA,mDAAA,qCAAA,CAeF,oBAAA,yCAAA,CAAA,kCAAA,CAAA,sBAAA,CAAA,kCAAA,CAAA,0BAAA,CAAA,iBAAA,CAAA,eAAA,CC1HE,+BAAA,cAAA,CAAA,gCAAA,cAAA,CDoIA,2CAAA,2BAAA,CAAA,iCAAA,CAUF,6BAAA,oCAAA,CAQA,gBAAA,0BAAA,CAAA,8BAAA,CAAA,2DAAA,CAAA,mDAAA,CAAA,yBAAA,CAAA,YAAA,CAAA,eAAA,CAAA,+CAAA,CASE,2CAAA,sBAAA,CAAA,uDAAA,CAAA,+CAAA,CA/CF,gCACE,yDAAA,kCAAA,CAAA","file":"styles.css","sourcesContent":["@import \"./utils\";\n@import \"./constants\";\n\n.lb-lexical-thread-panel {\n display: flex;\n flex-direction: column;\n}\n\n.lb-lexical-thread-panel-empty {\n position: absolute;\n inset: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n padding: var(--lb-spacing);\n color: var(--lb-foreground-tertiary);\n font-size: 0.875em;\n text-align: center;\n text-wrap: balance;\n}\n\n.lb-lexical-thread-panel-thread {\n &:where(:not(:last-of-type)) {\n border-block-end: 1px solid var(--lb-foreground-subtle);\n }\n}\n\n/*************************************\n * Suggestions *\n *************************************/\n\n.lb-lexical-suggestions-list {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n/*************************************\n * Mention suggestions *\n *************************************/\n\n.lb-lexical-mention-suggestions {\n --lb-lexical-mention-suggestion-avatar-size: 1.25rem;\n}\n\n.lb-lexical-mention-suggestion {\n padding: calc(0.375 * var(--lb-spacing)) calc(0.625 * var(--lb-spacing));\n}\n\n.lb-lexical-mention-suggestion-avatar {\n inline-size: var(--lb-lexical-mention-suggestion-avatar-size);\n margin-inline-start: calc(-0.125 * var(--lb-spacing));\n margin-inline-end: calc(0.5 * var(--lb-spacing));\n margin-block: calc(0.125 * var(--lb-spacing));\n background: var(--lb-foreground-subtle);\n color: var(--lb-foreground-moderate);\n}\n\n/*************************************\n * Elevation lists *\n *************************************/\n\n.lb-lexical-suggestions {\n padding: $lb-elevation-list-padding;\n animation-duration: var(--lb-transition-duration);\n animation-timing-function: var(--lb-transition-easing);\n will-change: transform, opacity;\n}\n\n.lb-lexical-suggestions-list-item {\n display: flex;\n align-items: center;\n padding: calc(0.25 * var(--lb-spacing)) calc(0.5 * var(--lb-spacing));\n border-radius: calc(var(--lb-radius) - 0.75 * $lb-elevation-list-padding);\n color: var(--lb-foreground-secondary);\n outline: none;\n font-size: 0.875rem;\n cursor: pointer;\n user-select: none;\n transition-property: background, color, opacity;\n scroll-margin-block: $lb-elevation-list-padding;\n}\n\n:is(.lb-lexical-suggestions-list-item) {\n &:where([data-highlighted], [data-selected]) {\n background: var(--lb-foreground-subtle);\n transition-duration: calc(var(--lb-transition-duration) / 2);\n }\n\n &:where(:disabled, [data-disabled]) {\n opacity: 0.5;\n cursor: not-allowed;\n }\n}\n\n/*************************************\n * Floating animations *\n *************************************/\n\n:is(.lb-lexical-suggestions) {\n &:where([data-side=\"top\"]) {\n animation-name: lb-animation-slide-up;\n }\n\n &:where([data-side=\"bottom\"]) {\n animation-name: lb-animation-slide-down;\n }\n\n &:where([data-state=\"closed\"]) {\n animation-name: lb-animation-disappear;\n }\n}\n\n@media (prefers-reduced-motion) {\n .lb-lexical-suggestions:where(:not([data-state=\"closed\"])) {\n animation-name: lb-animation-appear;\n }\n}\n\n/*************************************\n * Mention *\n *************************************/\n\n.lb-lexical-mention {\n padding: 0.1em 0.3em;\n border-radius: calc(0.675 * var(--lb-radius));\n background: var(--lb-accent-subtle);\n color: var(--lb-accent);\n box-decoration-break: clone;\n font-weight: 500;\n\n @include invisible-selection;\n\n &:where([data-selected]) {\n background: var(--lb-accent);\n color: var(--lb-accent-foreground);\n }\n}\n\n/*************************************\n * Active selection *\n *************************************/\n\n.lb-lexical-active-selection {\n background-color: var(--lb-selection);\n}\n\n/*************************************\n * Thread Mark *\n *************************************/\n\n.lb-thread-mark {\n color: var(--lb-foreground);\n outline: none;\n font-weight: 500;\n transition-property: color, text-decoration-color;\n text-decoration-line: underline;\n text-decoration-color: var(--lb-foreground-moderate);\n text-underline-offset: 2px;\n\n &:where([data-state=\"active\"]) {\n color: var(--lb-accent);\n text-decoration-color: var(--lb-accent-moderate);\n }\n}\n","@mixin invisible-selection {\n &::selection,\n *::selection {\n background: transparent;\n }\n}\n"]}