@liveblocks/react-lexical 3.6.0 → 3.7.0-preview1

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.
@@ -1,11 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  var threadMarkNode = require('./comments/thread-mark-node.cjs');
4
+ var groupMentionNode = require('./mentions/group-mention-node.cjs');
4
5
  var mentionNode = require('./mentions/mention-node.cjs');
5
6
 
6
7
  function liveblocksConfig(editorConfig) {
7
8
  const nodes = [...editorConfig.nodes ?? []];
8
- nodes.push(threadMarkNode.ThreadMarkNode, mentionNode.MentionNode);
9
+ nodes.push(threadMarkNode.ThreadMarkNode, mentionNode.MentionNode, groupMentionNode.GroupMentionNode);
9
10
  return {
10
11
  ...editorConfig,
11
12
  nodes,
@@ -1 +1 @@
1
- {"version":3,"file":"liveblocks-config.cjs","sources":["../src/liveblocks-config.ts"],"sourcesContent":["import type { InitialConfigType } from \"@lexical/react/LexicalComposer\";\n\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\n\n/**\n * Function that takes a Lexical editor config and modifies it to add the necessary\n * `nodes` and `theme` to make `LiveblocksPlugin` works correctly.\n *\n * @example\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport function liveblocksConfig(\n editorConfig: Omit<InitialConfigType, \"editorState\">\n) {\n const nodes = [...(editorConfig.nodes ?? [])];\n\n nodes.push(ThreadMarkNode, MentionNode);\n\n return {\n ...editorConfig,\n nodes,\n editorState: null, // explicitly null because CollabProvider requires it\n };\n}\n"],"names":["ThreadMarkNode","MentionNode"],"mappings":";;;;;AAoCO,SAAS,iBACd,YACA,EAAA;AACA,EAAA,MAAM,QAAQ,CAAC,GAAI,YAAa,CAAA,KAAA,IAAS,EAAG,CAAA,CAAA;AAE5C,EAAM,KAAA,CAAA,IAAA,CAAKA,+BAAgBC,uBAAW,CAAA,CAAA;AAEtC,EAAO,OAAA;AAAA,IACL,GAAG,YAAA;AAAA,IACH,KAAA;AAAA,IACA,WAAa,EAAA,IAAA;AAAA,GACf,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"liveblocks-config.cjs","sources":["../src/liveblocks-config.ts"],"sourcesContent":["import type { InitialConfigType } from \"@lexical/react/LexicalComposer\";\n\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { GroupMentionNode } from \"./mentions/group-mention-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\n\n/**\n * Function that takes a Lexical editor config and modifies it to add the necessary\n * `nodes` and `theme` to make `LiveblocksPlugin` works correctly.\n *\n * @example\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport function liveblocksConfig(\n editorConfig: Omit<InitialConfigType, \"editorState\">\n) {\n const nodes = [...(editorConfig.nodes ?? [])];\n\n nodes.push(ThreadMarkNode, MentionNode, GroupMentionNode);\n\n return {\n ...editorConfig,\n nodes,\n editorState: null, // explicitly null because CollabProvider requires it\n };\n}\n"],"names":["ThreadMarkNode","MentionNode","GroupMentionNode"],"mappings":";;;;;;AAqCO,SAAS,iBACd,YACA,EAAA;AACA,EAAA,MAAM,QAAQ,CAAC,GAAI,YAAa,CAAA,KAAA,IAAS,EAAG,CAAA,CAAA;AAE5C,EAAM,KAAA,CAAA,IAAA,CAAKA,6BAAgB,EAAAC,uBAAA,EAAaC,iCAAgB,CAAA,CAAA;AAExD,EAAO,OAAA;AAAA,IACL,GAAG,YAAA;AAAA,IACH,KAAA;AAAA,IACA,WAAa,EAAA,IAAA;AAAA,GACf,CAAA;AACF;;;;"}
@@ -1,9 +1,10 @@
1
1
  import { ThreadMarkNode } from './comments/thread-mark-node.js';
2
+ import { GroupMentionNode } from './mentions/group-mention-node.js';
2
3
  import { MentionNode } from './mentions/mention-node.js';
3
4
 
4
5
  function liveblocksConfig(editorConfig) {
5
6
  const nodes = [...editorConfig.nodes ?? []];
6
- nodes.push(ThreadMarkNode, MentionNode);
7
+ nodes.push(ThreadMarkNode, MentionNode, GroupMentionNode);
7
8
  return {
8
9
  ...editorConfig,
9
10
  nodes,
@@ -1 +1 @@
1
- {"version":3,"file":"liveblocks-config.js","sources":["../src/liveblocks-config.ts"],"sourcesContent":["import type { InitialConfigType } from \"@lexical/react/LexicalComposer\";\n\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\n\n/**\n * Function that takes a Lexical editor config and modifies it to add the necessary\n * `nodes` and `theme` to make `LiveblocksPlugin` works correctly.\n *\n * @example\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport function liveblocksConfig(\n editorConfig: Omit<InitialConfigType, \"editorState\">\n) {\n const nodes = [...(editorConfig.nodes ?? [])];\n\n nodes.push(ThreadMarkNode, MentionNode);\n\n return {\n ...editorConfig,\n nodes,\n editorState: null, // explicitly null because CollabProvider requires it\n };\n}\n"],"names":[],"mappings":";;;AAoCO,SAAS,iBACd,YACA,EAAA;AACA,EAAA,MAAM,QAAQ,CAAC,GAAI,YAAa,CAAA,KAAA,IAAS,EAAG,CAAA,CAAA;AAE5C,EAAM,KAAA,CAAA,IAAA,CAAK,gBAAgB,WAAW,CAAA,CAAA;AAEtC,EAAO,OAAA;AAAA,IACL,GAAG,YAAA;AAAA,IACH,KAAA;AAAA,IACA,WAAa,EAAA,IAAA;AAAA,GACf,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"liveblocks-config.js","sources":["../src/liveblocks-config.ts"],"sourcesContent":["import type { InitialConfigType } from \"@lexical/react/LexicalComposer\";\n\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { GroupMentionNode } from \"./mentions/group-mention-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\n\n/**\n * Function that takes a Lexical editor config and modifies it to add the necessary\n * `nodes` and `theme` to make `LiveblocksPlugin` works correctly.\n *\n * @example\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport function liveblocksConfig(\n editorConfig: Omit<InitialConfigType, \"editorState\">\n) {\n const nodes = [...(editorConfig.nodes ?? [])];\n\n nodes.push(ThreadMarkNode, MentionNode, GroupMentionNode);\n\n return {\n ...editorConfig,\n nodes,\n editorState: null, // explicitly null because CollabProvider requires it\n };\n}\n"],"names":[],"mappings":";;;;AAqCO,SAAS,iBACd,YACA,EAAA;AACA,EAAA,MAAM,QAAQ,CAAC,GAAI,YAAa,CAAA,KAAA,IAAS,EAAG,CAAA,CAAA;AAE5C,EAAM,KAAA,CAAA,IAAA,CAAK,cAAgB,EAAA,WAAA,EAAa,gBAAgB,CAAA,CAAA;AAExD,EAAO,OAAA;AAAA,IACL,GAAG,YAAA;AAAA,IACH,KAAA;AAAA,IACA,WAAa,EAAA,IAAA;AAAA,GACf,CAAA;AACF;;;;"}
@@ -11,6 +11,7 @@ var yjs = require('@liveblocks/yjs');
11
11
  var react = require('react');
12
12
  var commentPluginProvider = require('./comments/comment-plugin-provider.cjs');
13
13
  var threadMarkNode = require('./comments/thread-mark-node.cjs');
14
+ var groupMentionNode = require('./mentions/group-mention-node.cjs');
14
15
  var mentionNode = require('./mentions/mention-node.cjs');
15
16
  var mentionPlugin = require('./mentions/mention-plugin.cjs');
16
17
  var useRootElement = require('./use-root-element.cjs');
@@ -41,7 +42,7 @@ const LiveblocksPlugin = ({
41
42
  const isResolveMentionSuggestionsDefined = _private.useResolveMentionSuggestions() !== void 0;
42
43
  const [editor] = LexicalComposerContext.useLexicalComposerContext();
43
44
  const room = react$1.useRoom();
44
- if (!editor.hasNodes([threadMarkNode.ThreadMarkNode, mentionNode.MentionNode])) {
45
+ if (!editor.hasNodes([threadMarkNode.ThreadMarkNode, mentionNode.MentionNode, groupMentionNode.GroupMentionNode])) {
45
46
  throw new Error(
46
47
  "LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig"
47
48
  );
@@ -1 +1 @@
1
- {"version":3,"file":"liveblocks-plugin-provider.cjs","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { autoUpdate, useFloating } from \"@floating-ui/react-dom\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { TextEditorType } from \"@liveblocks/core\";\nimport { useRoom, useSelf } from \"@liveblocks/react\";\nimport {\n useLayoutEffect,\n useReportTextEditor,\n useResolveMentionSuggestions,\n useYjsProvider,\n} from \"@liveblocks/react/_private\";\nimport { getYjsProviderForRoom } from \"@liveblocks/yjs\";\nimport type { MutableRefObject, ReactNode } from \"react\";\nimport { useCallback, useEffect, useState, useSyncExternalStore } from \"react\";\nimport type { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\nimport { useRootElement } from \"./use-root-element\";\n\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => {};\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport type LiveblocksPluginProps = {\n children?: ReactNode;\n};\n\n/**\n * Liveblocks plugin for Lexical that adds collaboration to your editor.\n *\n * `LiveblocksPlugin` should always be nested inside `LexicalComposer`.\n *\n * @example\n *\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const isResolveMentionSuggestionsDefined =\n useResolveMentionSuggestions() !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n\n if (!editor.hasNodes([ThreadMarkNode, MentionNode])) {\n throw new Error(\n \"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig\"\n );\n }\n\n const [containerRef, setContainerRef] = useState<\n MutableRefObject<HTMLDivElement | null> | undefined\n >(undefined);\n\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\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 useReportTextEditor(TextEditorType.Lexical, \"root\");\n\n // Get user info or allow override from props\n const self = useSelf();\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n const provider = getYjsProviderForRoom(room);\n yjsDocMap.set(id, provider.getYDoc());\n\n return provider as Provider;\n },\n [room]\n );\n\n const root = useRootElement();\n\n useLayoutEffect(() => {\n if (root === null) return;\n setReference({\n getBoundingClientRect: () => root.getBoundingClientRect(),\n });\n }, [setReference, root]);\n\n const handleFloatingRef = useCallback(\n (node: HTMLDivElement) => {\n setFloating(node);\n setContainerRef({ current: node });\n },\n [setFloating, setContainerRef]\n );\n\n return (\n <>\n <div\n ref={handleFloatingRef}\n className=\"lb-root lb-lexical-cursors\"\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n />\n\n {self && (\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={self.info?.name ?? \"\"} // use empty string to prevent random name\n cursorColor={self.info?.color as string | undefined}\n cursorsContainerRef={containerRef}\n shouldBootstrap={true}\n />\n )}\n\n {isResolveMentionSuggestionsDefined && <MentionPlugin />}\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n"],"names":["useYjsProvider","useCallback","useSyncExternalStore","useResolveMentionSuggestions","useLexicalComposerContext","useRoom","ThreadMarkNode","MentionNode","useState","useFloating","autoUpdate","useEffect","useReportTextEditor","TextEditorType","useSelf","getYjsProviderForRoom","useRootElement","useLayoutEffect","jsxs","Fragment","jsx","CollaborationPlugin","MentionPlugin","CommentPluginProvider"],"mappings":"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"}
1
+ {"version":3,"file":"liveblocks-plugin-provider.cjs","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { autoUpdate, useFloating } from \"@floating-ui/react-dom\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { TextEditorType } from \"@liveblocks/core\";\nimport { useRoom, useSelf } from \"@liveblocks/react\";\nimport {\n useLayoutEffect,\n useReportTextEditor,\n useResolveMentionSuggestions,\n useYjsProvider,\n} from \"@liveblocks/react/_private\";\nimport { getYjsProviderForRoom } from \"@liveblocks/yjs\";\nimport type { MutableRefObject, ReactNode } from \"react\";\nimport { useCallback, useEffect, useState, useSyncExternalStore } from \"react\";\nimport type { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { GroupMentionNode } from \"./mentions/group-mention-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\nimport { useRootElement } from \"./use-root-element\";\n\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => {};\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport type LiveblocksPluginProps = {\n children?: ReactNode;\n};\n\n/**\n * Liveblocks plugin for Lexical that adds collaboration to your editor.\n *\n * `LiveblocksPlugin` should always be nested inside `LexicalComposer`.\n *\n * @example\n *\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const isResolveMentionSuggestionsDefined =\n useResolveMentionSuggestions() !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n\n if (!editor.hasNodes([ThreadMarkNode, MentionNode, GroupMentionNode])) {\n throw new Error(\n \"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig\"\n );\n }\n\n const [containerRef, setContainerRef] = useState<\n MutableRefObject<HTMLDivElement | null> | undefined\n >(undefined);\n\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\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 useReportTextEditor(TextEditorType.Lexical, \"root\");\n\n // Get user info or allow override from props\n const self = useSelf();\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n const provider = getYjsProviderForRoom(room);\n yjsDocMap.set(id, provider.getYDoc());\n\n return provider as Provider;\n },\n [room]\n );\n\n const root = useRootElement();\n\n useLayoutEffect(() => {\n if (root === null) return;\n setReference({\n getBoundingClientRect: () => root.getBoundingClientRect(),\n });\n }, [setReference, root]);\n\n const handleFloatingRef = useCallback(\n (node: HTMLDivElement) => {\n setFloating(node);\n setContainerRef({ current: node });\n },\n [setFloating, setContainerRef]\n );\n\n return (\n <>\n <div\n ref={handleFloatingRef}\n className=\"lb-root lb-lexical-cursors\"\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n />\n\n {self && (\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={self.info?.name ?? \"\"} // use empty string to prevent random name\n cursorColor={self.info?.color as string | undefined}\n cursorsContainerRef={containerRef}\n shouldBootstrap={true}\n />\n )}\n\n {isResolveMentionSuggestionsDefined && <MentionPlugin />}\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n"],"names":["useYjsProvider","useCallback","useSyncExternalStore","useResolveMentionSuggestions","useLexicalComposerContext","useRoom","ThreadMarkNode","MentionNode","GroupMentionNode","useState","useFloating","autoUpdate","useEffect","useReportTextEditor","TextEditorType","useSelf","getYjsProviderForRoom","useRootElement","useLayoutEffect","jsxs","Fragment","jsx","CollaborationPlugin","MentionPlugin","CommentPluginProvider"],"mappings":"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"}
@@ -9,6 +9,7 @@ import { getYjsProviderForRoom } from '@liveblocks/yjs';
9
9
  import { useCallback, useSyncExternalStore, useState, useEffect } from 'react';
10
10
  import { CommentPluginProvider } from './comments/comment-plugin-provider.js';
11
11
  import { ThreadMarkNode } from './comments/thread-mark-node.js';
12
+ import { GroupMentionNode } from './mentions/group-mention-node.js';
12
13
  import { MentionNode } from './mentions/mention-node.js';
13
14
  import { MentionPlugin } from './mentions/mention-plugin.js';
14
15
  import { useRootElement } from './use-root-element.js';
@@ -39,7 +40,7 @@ const LiveblocksPlugin = ({
39
40
  const isResolveMentionSuggestionsDefined = useResolveMentionSuggestions() !== void 0;
40
41
  const [editor] = useLexicalComposerContext();
41
42
  const room = useRoom();
42
- if (!editor.hasNodes([ThreadMarkNode, MentionNode])) {
43
+ if (!editor.hasNodes([ThreadMarkNode, MentionNode, GroupMentionNode])) {
43
44
  throw new Error(
44
45
  "LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig"
45
46
  );
@@ -1 +1 @@
1
- {"version":3,"file":"liveblocks-plugin-provider.js","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { autoUpdate, useFloating } from \"@floating-ui/react-dom\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { TextEditorType } from \"@liveblocks/core\";\nimport { useRoom, useSelf } from \"@liveblocks/react\";\nimport {\n useLayoutEffect,\n useReportTextEditor,\n useResolveMentionSuggestions,\n useYjsProvider,\n} from \"@liveblocks/react/_private\";\nimport { getYjsProviderForRoom } from \"@liveblocks/yjs\";\nimport type { MutableRefObject, ReactNode } from \"react\";\nimport { useCallback, useEffect, useState, useSyncExternalStore } from \"react\";\nimport type { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\nimport { useRootElement } from \"./use-root-element\";\n\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => {};\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport type LiveblocksPluginProps = {\n children?: ReactNode;\n};\n\n/**\n * Liveblocks plugin for Lexical that adds collaboration to your editor.\n *\n * `LiveblocksPlugin` should always be nested inside `LexicalComposer`.\n *\n * @example\n *\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const isResolveMentionSuggestionsDefined =\n useResolveMentionSuggestions() !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n\n if (!editor.hasNodes([ThreadMarkNode, MentionNode])) {\n throw new Error(\n \"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig\"\n );\n }\n\n const [containerRef, setContainerRef] = useState<\n MutableRefObject<HTMLDivElement | null> | undefined\n >(undefined);\n\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\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 useReportTextEditor(TextEditorType.Lexical, \"root\");\n\n // Get user info or allow override from props\n const self = useSelf();\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n const provider = getYjsProviderForRoom(room);\n yjsDocMap.set(id, provider.getYDoc());\n\n return provider as Provider;\n },\n [room]\n );\n\n const root = useRootElement();\n\n useLayoutEffect(() => {\n if (root === null) return;\n setReference({\n getBoundingClientRect: () => root.getBoundingClientRect(),\n });\n }, [setReference, root]);\n\n const handleFloatingRef = useCallback(\n (node: HTMLDivElement) => {\n setFloating(node);\n setContainerRef({ current: node });\n },\n [setFloating, setContainerRef]\n );\n\n return (\n <>\n <div\n ref={handleFloatingRef}\n className=\"lb-root lb-lexical-cursors\"\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n />\n\n {self && (\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={self.info?.name ?? \"\"} // use empty string to prevent random name\n cursorColor={self.info?.color as string | undefined}\n cursorsContainerRef={containerRef}\n shouldBootstrap={true}\n />\n )}\n\n {isResolveMentionSuggestionsDefined && <MentionPlugin />}\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"liveblocks-plugin-provider.js","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { autoUpdate, useFloating } from \"@floating-ui/react-dom\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { TextEditorType } from \"@liveblocks/core\";\nimport { useRoom, useSelf } from \"@liveblocks/react\";\nimport {\n useLayoutEffect,\n useReportTextEditor,\n useResolveMentionSuggestions,\n useYjsProvider,\n} from \"@liveblocks/react/_private\";\nimport { getYjsProviderForRoom } from \"@liveblocks/yjs\";\nimport type { MutableRefObject, ReactNode } from \"react\";\nimport { useCallback, useEffect, useState, useSyncExternalStore } from \"react\";\nimport type { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { GroupMentionNode } from \"./mentions/group-mention-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\nimport { useRootElement } from \"./use-root-element\";\n\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => {};\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport type LiveblocksPluginProps = {\n children?: ReactNode;\n};\n\n/**\n * Liveblocks plugin for Lexical that adds collaboration to your editor.\n *\n * `LiveblocksPlugin` should always be nested inside `LexicalComposer`.\n *\n * @example\n *\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const isResolveMentionSuggestionsDefined =\n useResolveMentionSuggestions() !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n\n if (!editor.hasNodes([ThreadMarkNode, MentionNode, GroupMentionNode])) {\n throw new Error(\n \"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig\"\n );\n }\n\n const [containerRef, setContainerRef] = useState<\n MutableRefObject<HTMLDivElement | null> | undefined\n >(undefined);\n\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\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 useReportTextEditor(TextEditorType.Lexical, \"root\");\n\n // Get user info or allow override from props\n const self = useSelf();\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n const provider = getYjsProviderForRoom(room);\n yjsDocMap.set(id, provider.getYDoc());\n\n return provider as Provider;\n },\n [room]\n );\n\n const root = useRootElement();\n\n useLayoutEffect(() => {\n if (root === null) return;\n setReference({\n getBoundingClientRect: () => root.getBoundingClientRect(),\n });\n }, [setReference, root]);\n\n const handleFloatingRef = useCallback(\n (node: HTMLDivElement) => {\n setFloating(node);\n setContainerRef({ current: node });\n },\n [setFloating, setContainerRef]\n );\n\n return (\n <>\n <div\n ref={handleFloatingRef}\n className=\"lb-root lb-lexical-cursors\"\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n />\n\n {self && (\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={self.info?.name ?? \"\"} // use empty string to prevent random name\n cursorColor={self.info?.color as string | undefined}\n cursorsContainerRef={containerRef}\n shouldBootstrap={true}\n />\n )}\n\n {isResolveMentionSuggestionsDefined && <MentionPlugin />}\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var core = require('@liveblocks/core');
5
+ var _private = require('@liveblocks/react-ui/_private');
6
+ var lexical = require('lexical');
7
+ var mentionComponent = require('./mention-component.cjs');
8
+
9
+ function GroupMention({
10
+ mention,
11
+ nodeKey
12
+ }) {
13
+ return /* @__PURE__ */ jsxRuntime.jsxs(mentionComponent.Mention, {
14
+ nodeKey,
15
+ children: [
16
+ core.MENTION_CHARACTER,
17
+ /* @__PURE__ */ jsxRuntime.jsx(_private.Group, {
18
+ groupId: mention.id
19
+ })
20
+ ]
21
+ });
22
+ }
23
+ class GroupMentionNode extends lexical.DecoratorNode {
24
+ __id;
25
+ __groupId;
26
+ __userIds;
27
+ constructor(id, groupId, userIds, key) {
28
+ super(key);
29
+ this.__id = id;
30
+ this.__groupId = groupId;
31
+ this.__userIds = userIds;
32
+ }
33
+ static getType() {
34
+ return "lb-group-mention";
35
+ }
36
+ static clone(node) {
37
+ return new GroupMentionNode(
38
+ node.__id,
39
+ node.__groupId,
40
+ node.__userIds,
41
+ node.__key
42
+ );
43
+ }
44
+ createDOM() {
45
+ const element = document.createElement("span");
46
+ element.style.display = "inline-block";
47
+ element.style.userSelect = "none";
48
+ return element;
49
+ }
50
+ updateDOM() {
51
+ return false;
52
+ }
53
+ static importDom() {
54
+ return {
55
+ span: () => ({
56
+ conversion: (element) => {
57
+ const groupId = element.getAttribute("data-lexical-lb-group-mention");
58
+ if (!groupId) {
59
+ return null;
60
+ }
61
+ const userIdsAttribute = element.getAttribute(
62
+ "data-lexical-lb-user-ids"
63
+ );
64
+ let userIds;
65
+ if (userIdsAttribute) {
66
+ try {
67
+ const parsedUserIds = JSON.parse(userIdsAttribute);
68
+ if (Array.isArray(parsedUserIds)) {
69
+ userIds = parsedUserIds;
70
+ }
71
+ } catch {
72
+ }
73
+ }
74
+ const node = $createGroupMentionNode(groupId, userIds);
75
+ return { node };
76
+ },
77
+ priority: 1
78
+ })
79
+ };
80
+ }
81
+ exportDOM() {
82
+ const element = document.createElement("span");
83
+ element.setAttribute("data-lexical-lb-group-mention", this.getGroupId());
84
+ element.setAttribute(
85
+ "data-lexical-lb-group-mention-users",
86
+ JSON.stringify(this.getUserIds())
87
+ );
88
+ element.textContent = this.getTextContent();
89
+ return { element };
90
+ }
91
+ static importJSON(serializedNode) {
92
+ const node = $createGroupMentionNode(
93
+ serializedNode.groupId,
94
+ serializedNode.userIds
95
+ );
96
+ return node;
97
+ }
98
+ exportJSON() {
99
+ return {
100
+ groupId: this.__groupId,
101
+ userIds: this.__userIds,
102
+ type: "lb-group-mention",
103
+ version: 1
104
+ };
105
+ }
106
+ getGroupId() {
107
+ const self = this.getLatest();
108
+ return self.__groupId;
109
+ }
110
+ getId() {
111
+ const self = this.getLatest();
112
+ return self.__id;
113
+ }
114
+ getUserIds() {
115
+ const self = this.getLatest();
116
+ return self.__userIds;
117
+ }
118
+ decorate() {
119
+ const mention = {
120
+ id: this.getGroupId(),
121
+ kind: "group",
122
+ userIds: this.getUserIds()
123
+ };
124
+ return /* @__PURE__ */ jsxRuntime.jsx(GroupMention, {
125
+ mention,
126
+ nodeKey: this.getKey()
127
+ });
128
+ }
129
+ }
130
+ function $isGroupMentionNode(node) {
131
+ return node instanceof GroupMentionNode;
132
+ }
133
+ function $createGroupMentionNode(groupId, userIds) {
134
+ const node = new GroupMentionNode(
135
+ core.createInboxNotificationId(),
136
+ groupId,
137
+ userIds
138
+ );
139
+ return lexical.$applyNodeReplacement(node);
140
+ }
141
+
142
+ exports.$createGroupMentionNode = $createGroupMentionNode;
143
+ exports.$isGroupMentionNode = $isGroupMentionNode;
144
+ exports.GroupMentionNode = GroupMentionNode;
145
+ //# sourceMappingURL=group-mention-node.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-mention-node.cjs","sources":["../../src/mentions/group-mention-node.tsx"],"sourcesContent":["import {\n createInboxNotificationId,\n type GroupMentionData,\n MENTION_CHARACTER,\n} from \"@liveblocks/core\";\nimport { Group } from \"@liveblocks/react-ui/_private\";\nimport type {\n DOMConversionMap,\n DOMExportOutput,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\nimport type { JSX } from \"react\";\n\nimport { Mention } from \"./mention-component\";\n\nexport type SerializedGroupMentionNode = Spread<\n {\n groupId: string;\n userIds?: string[];\n },\n SerializedLexicalNode\n>;\n\nfunction GroupMention({\n mention,\n nodeKey,\n}: {\n mention: GroupMentionData;\n nodeKey: string;\n}) {\n return (\n <Mention nodeKey={nodeKey}>\n {MENTION_CHARACTER}\n <Group groupId={mention.id} />\n </Mention>\n );\n}\n\nexport class GroupMentionNode extends DecoratorNode<JSX.Element> {\n __id: string;\n __groupId: string;\n __userIds: string[] | undefined;\n\n constructor(\n id: string,\n groupId: string,\n userIds: string[] | undefined,\n key?: NodeKey\n ) {\n super(key);\n this.__id = id;\n this.__groupId = groupId;\n this.__userIds = userIds;\n }\n\n static getType(): string {\n return \"lb-group-mention\";\n }\n\n static clone(node: GroupMentionNode): GroupMentionNode {\n return new GroupMentionNode(\n node.__id,\n node.__groupId,\n node.__userIds,\n node.__key\n );\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n element.style.display = \"inline-block\";\n element.style.userSelect = \"none\";\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n static importDom(): DOMConversionMap<HTMLElement> | null {\n return {\n span: () => ({\n conversion: (element) => {\n const groupId = element.getAttribute(\"data-lexical-lb-group-mention\");\n\n if (!groupId) {\n return null;\n }\n\n const userIdsAttribute = element.getAttribute(\n \"data-lexical-lb-user-ids\"\n );\n let userIds: string[] | undefined;\n\n if (userIdsAttribute) {\n try {\n const parsedUserIds = JSON.parse(userIdsAttribute) as string[];\n\n if (Array.isArray(parsedUserIds)) {\n userIds = parsedUserIds;\n }\n } catch {\n // Invalid userIds attribute\n }\n }\n\n const node = $createGroupMentionNode(groupId, userIds);\n return { node };\n },\n priority: 1,\n }),\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"span\");\n element.setAttribute(\"data-lexical-lb-group-mention\", this.getGroupId());\n element.setAttribute(\n \"data-lexical-lb-group-mention-users\",\n JSON.stringify(this.getUserIds())\n );\n element.textContent = this.getTextContent();\n return { element };\n }\n\n static importJSON(\n serializedNode: SerializedGroupMentionNode\n ): GroupMentionNode {\n const node = $createGroupMentionNode(\n serializedNode.groupId,\n serializedNode.userIds\n );\n return node;\n }\n\n exportJSON(): SerializedGroupMentionNode {\n return {\n groupId: this.__groupId,\n userIds: this.__userIds,\n type: \"lb-group-mention\",\n version: 1,\n };\n }\n\n getGroupId(): string {\n const self = this.getLatest();\n return self.__groupId;\n }\n\n getId(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n getUserIds(): string[] | undefined {\n const self = this.getLatest();\n return self.__userIds;\n }\n\n decorate(): JSX.Element {\n const mention: GroupMentionData = {\n id: this.getGroupId(),\n kind: \"group\",\n userIds: this.getUserIds(),\n };\n\n return <GroupMention mention={mention} nodeKey={this.getKey()} />;\n }\n}\n\nexport function $isGroupMentionNode(\n node: LexicalNode | null | undefined\n): node is GroupMentionNode {\n return node instanceof GroupMentionNode;\n}\n\nexport function $createGroupMentionNode(\n groupId: string,\n userIds: string[] | undefined\n): GroupMentionNode {\n const node = new GroupMentionNode(\n createInboxNotificationId(),\n groupId,\n userIds\n );\n return $applyNodeReplacement(node);\n}\n"],"names":["jsxs","Mention","MENTION_CHARACTER","jsx","Group","DecoratorNode","createInboxNotificationId","$applyNodeReplacement"],"mappings":"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"}
@@ -0,0 +1,141 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { MENTION_CHARACTER, createInboxNotificationId } from '@liveblocks/core';
3
+ import { Group } from '@liveblocks/react-ui/_private';
4
+ import { DecoratorNode, $applyNodeReplacement } from 'lexical';
5
+ import { Mention } from './mention-component.js';
6
+
7
+ function GroupMention({
8
+ mention,
9
+ nodeKey
10
+ }) {
11
+ return /* @__PURE__ */ jsxs(Mention, {
12
+ nodeKey,
13
+ children: [
14
+ MENTION_CHARACTER,
15
+ /* @__PURE__ */ jsx(Group, {
16
+ groupId: mention.id
17
+ })
18
+ ]
19
+ });
20
+ }
21
+ class GroupMentionNode extends DecoratorNode {
22
+ __id;
23
+ __groupId;
24
+ __userIds;
25
+ constructor(id, groupId, userIds, key) {
26
+ super(key);
27
+ this.__id = id;
28
+ this.__groupId = groupId;
29
+ this.__userIds = userIds;
30
+ }
31
+ static getType() {
32
+ return "lb-group-mention";
33
+ }
34
+ static clone(node) {
35
+ return new GroupMentionNode(
36
+ node.__id,
37
+ node.__groupId,
38
+ node.__userIds,
39
+ node.__key
40
+ );
41
+ }
42
+ createDOM() {
43
+ const element = document.createElement("span");
44
+ element.style.display = "inline-block";
45
+ element.style.userSelect = "none";
46
+ return element;
47
+ }
48
+ updateDOM() {
49
+ return false;
50
+ }
51
+ static importDom() {
52
+ return {
53
+ span: () => ({
54
+ conversion: (element) => {
55
+ const groupId = element.getAttribute("data-lexical-lb-group-mention");
56
+ if (!groupId) {
57
+ return null;
58
+ }
59
+ const userIdsAttribute = element.getAttribute(
60
+ "data-lexical-lb-user-ids"
61
+ );
62
+ let userIds;
63
+ if (userIdsAttribute) {
64
+ try {
65
+ const parsedUserIds = JSON.parse(userIdsAttribute);
66
+ if (Array.isArray(parsedUserIds)) {
67
+ userIds = parsedUserIds;
68
+ }
69
+ } catch {
70
+ }
71
+ }
72
+ const node = $createGroupMentionNode(groupId, userIds);
73
+ return { node };
74
+ },
75
+ priority: 1
76
+ })
77
+ };
78
+ }
79
+ exportDOM() {
80
+ const element = document.createElement("span");
81
+ element.setAttribute("data-lexical-lb-group-mention", this.getGroupId());
82
+ element.setAttribute(
83
+ "data-lexical-lb-group-mention-users",
84
+ JSON.stringify(this.getUserIds())
85
+ );
86
+ element.textContent = this.getTextContent();
87
+ return { element };
88
+ }
89
+ static importJSON(serializedNode) {
90
+ const node = $createGroupMentionNode(
91
+ serializedNode.groupId,
92
+ serializedNode.userIds
93
+ );
94
+ return node;
95
+ }
96
+ exportJSON() {
97
+ return {
98
+ groupId: this.__groupId,
99
+ userIds: this.__userIds,
100
+ type: "lb-group-mention",
101
+ version: 1
102
+ };
103
+ }
104
+ getGroupId() {
105
+ const self = this.getLatest();
106
+ return self.__groupId;
107
+ }
108
+ getId() {
109
+ const self = this.getLatest();
110
+ return self.__id;
111
+ }
112
+ getUserIds() {
113
+ const self = this.getLatest();
114
+ return self.__userIds;
115
+ }
116
+ decorate() {
117
+ const mention = {
118
+ id: this.getGroupId(),
119
+ kind: "group",
120
+ userIds: this.getUserIds()
121
+ };
122
+ return /* @__PURE__ */ jsx(GroupMention, {
123
+ mention,
124
+ nodeKey: this.getKey()
125
+ });
126
+ }
127
+ }
128
+ function $isGroupMentionNode(node) {
129
+ return node instanceof GroupMentionNode;
130
+ }
131
+ function $createGroupMentionNode(groupId, userIds) {
132
+ const node = new GroupMentionNode(
133
+ createInboxNotificationId(),
134
+ groupId,
135
+ userIds
136
+ );
137
+ return $applyNodeReplacement(node);
138
+ }
139
+
140
+ export { $createGroupMentionNode, $isGroupMentionNode, GroupMentionNode };
141
+ //# sourceMappingURL=group-mention-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-mention-node.js","sources":["../../src/mentions/group-mention-node.tsx"],"sourcesContent":["import {\n createInboxNotificationId,\n type GroupMentionData,\n MENTION_CHARACTER,\n} from \"@liveblocks/core\";\nimport { Group } from \"@liveblocks/react-ui/_private\";\nimport type {\n DOMConversionMap,\n DOMExportOutput,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\nimport type { JSX } from \"react\";\n\nimport { Mention } from \"./mention-component\";\n\nexport type SerializedGroupMentionNode = Spread<\n {\n groupId: string;\n userIds?: string[];\n },\n SerializedLexicalNode\n>;\n\nfunction GroupMention({\n mention,\n nodeKey,\n}: {\n mention: GroupMentionData;\n nodeKey: string;\n}) {\n return (\n <Mention nodeKey={nodeKey}>\n {MENTION_CHARACTER}\n <Group groupId={mention.id} />\n </Mention>\n );\n}\n\nexport class GroupMentionNode extends DecoratorNode<JSX.Element> {\n __id: string;\n __groupId: string;\n __userIds: string[] | undefined;\n\n constructor(\n id: string,\n groupId: string,\n userIds: string[] | undefined,\n key?: NodeKey\n ) {\n super(key);\n this.__id = id;\n this.__groupId = groupId;\n this.__userIds = userIds;\n }\n\n static getType(): string {\n return \"lb-group-mention\";\n }\n\n static clone(node: GroupMentionNode): GroupMentionNode {\n return new GroupMentionNode(\n node.__id,\n node.__groupId,\n node.__userIds,\n node.__key\n );\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n element.style.display = \"inline-block\";\n element.style.userSelect = \"none\";\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n static importDom(): DOMConversionMap<HTMLElement> | null {\n return {\n span: () => ({\n conversion: (element) => {\n const groupId = element.getAttribute(\"data-lexical-lb-group-mention\");\n\n if (!groupId) {\n return null;\n }\n\n const userIdsAttribute = element.getAttribute(\n \"data-lexical-lb-user-ids\"\n );\n let userIds: string[] | undefined;\n\n if (userIdsAttribute) {\n try {\n const parsedUserIds = JSON.parse(userIdsAttribute) as string[];\n\n if (Array.isArray(parsedUserIds)) {\n userIds = parsedUserIds;\n }\n } catch {\n // Invalid userIds attribute\n }\n }\n\n const node = $createGroupMentionNode(groupId, userIds);\n return { node };\n },\n priority: 1,\n }),\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"span\");\n element.setAttribute(\"data-lexical-lb-group-mention\", this.getGroupId());\n element.setAttribute(\n \"data-lexical-lb-group-mention-users\",\n JSON.stringify(this.getUserIds())\n );\n element.textContent = this.getTextContent();\n return { element };\n }\n\n static importJSON(\n serializedNode: SerializedGroupMentionNode\n ): GroupMentionNode {\n const node = $createGroupMentionNode(\n serializedNode.groupId,\n serializedNode.userIds\n );\n return node;\n }\n\n exportJSON(): SerializedGroupMentionNode {\n return {\n groupId: this.__groupId,\n userIds: this.__userIds,\n type: \"lb-group-mention\",\n version: 1,\n };\n }\n\n getGroupId(): string {\n const self = this.getLatest();\n return self.__groupId;\n }\n\n getId(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n getUserIds(): string[] | undefined {\n const self = this.getLatest();\n return self.__userIds;\n }\n\n decorate(): JSX.Element {\n const mention: GroupMentionData = {\n id: this.getGroupId(),\n kind: \"group\",\n userIds: this.getUserIds(),\n };\n\n return <GroupMention mention={mention} nodeKey={this.getKey()} />;\n }\n}\n\nexport function $isGroupMentionNode(\n node: LexicalNode | null | undefined\n): node is GroupMentionNode {\n return node instanceof GroupMentionNode;\n}\n\nexport function $createGroupMentionNode(\n groupId: string,\n userIds: string[] | undefined\n): GroupMentionNode {\n const node = new GroupMentionNode(\n createInboxNotificationId(),\n groupId,\n userIds\n );\n return $applyNodeReplacement(node);\n}\n"],"names":[],"mappings":"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"}
@@ -2,31 +2,36 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
5
+ var _private = require('@liveblocks/react-ui/_private');
5
6
  var lexical = require('lexical');
6
7
  var react = require('react');
7
8
 
8
- function Mention({
9
- nodeKey,
10
- children
11
- }) {
12
- const [editor] = LexicalComposerContext.useLexicalComposerContext();
13
- const isSelected = useIsNodeSelected(nodeKey);
14
- function handleClick(event) {
15
- editor.update(() => {
16
- event.stopPropagation();
17
- event.preventDefault();
18
- const selection = lexical.$createNodeSelection();
19
- selection.add(nodeKey);
20
- lexical.$setSelection(selection);
9
+ const Mention = react.forwardRef(
10
+ ({ nodeKey, children, className, ...props }, forwardedRef) => {
11
+ const [editor] = LexicalComposerContext.useLexicalComposerContext();
12
+ const isSelected = useIsNodeSelected(nodeKey);
13
+ const handleClick = react.useCallback(
14
+ (event) => {
15
+ editor.update(() => {
16
+ event.stopPropagation();
17
+ event.preventDefault();
18
+ const selection = lexical.$createNodeSelection();
19
+ selection.add(nodeKey);
20
+ lexical.$setSelection(selection);
21
+ });
22
+ },
23
+ [editor, nodeKey]
24
+ );
25
+ return /* @__PURE__ */ jsxRuntime.jsx("span", {
26
+ onClick: handleClick,
27
+ "data-selected": isSelected ? "" : void 0,
28
+ className: _private.cn("lb-root lb-mention lb-lexical-mention", className),
29
+ ref: forwardedRef,
30
+ ...props,
31
+ children
21
32
  });
22
33
  }
23
- return /* @__PURE__ */ jsxRuntime.jsx("span", {
24
- onClick: handleClick,
25
- "data-selected": isSelected ? "" : void 0,
26
- className: "lb-root lb-mention lb-lexical-mention",
27
- children
28
- });
29
- }
34
+ );
30
35
  function $isNodeSelected(key) {
31
36
  const node = lexical.$getNodeByKey(key);
32
37
  if (node === null)
@@ -1 +1 @@
1
- {"version":3,"file":"mention-component.cjs","sources":["../../src/mentions/mention-component.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { NodeKey } from \"lexical\";\nimport { $createNodeSelection, $getNodeByKey, $setSelection } from \"lexical\";\nimport type { MouseEvent, ReactNode } from \"react\";\nimport { useCallback, useSyncExternalStore } from \"react\";\n\nexport function Mention({\n nodeKey,\n children,\n}: {\n nodeKey: NodeKey;\n children: ReactNode;\n}) {\n const [editor] = useLexicalComposerContext();\n const isSelected = useIsNodeSelected(nodeKey);\n\n function handleClick(event: MouseEvent) {\n editor.update(() => {\n event.stopPropagation();\n event.preventDefault();\n\n const selection = $createNodeSelection();\n selection.add(nodeKey);\n $setSelection(selection);\n });\n }\n\n return (\n <span\n onClick={handleClick}\n data-selected={isSelected ? \"\" : undefined}\n className=\"lb-root lb-mention lb-lexical-mention\"\n >\n {children}\n </span>\n );\n}\n\nfunction $isNodeSelected(key: NodeKey): boolean {\n const node = $getNodeByKey(key);\n if (node === null) return false;\n return node.isSelected();\n}\n\nfunction useIsNodeSelected(key: NodeKey) {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerUpdateListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getEditorState().read(() => $isNodeSelected(key));\n }, [editor, key]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n"],"names":["useLexicalComposerContext","$createNodeSelection","$setSelection","jsx","$getNodeByKey","useCallback","useSyncExternalStore"],"mappings":";;;;;;;AAMO,SAAS,OAAQ,CAAA;AAAA,EACtB,OAAA;AAAA,EACA,QAAA;AACF,CAGG,EAAA;AACD,EAAM,MAAA,CAAC,MAAM,CAAA,GAAIA,gDAA0B,EAAA,CAAA;AAC3C,EAAM,MAAA,UAAA,GAAa,kBAAkB,OAAO,CAAA,CAAA;AAE5C,EAAA,SAAS,YAAY,KAAmB,EAAA;AACtC,IAAA,MAAA,CAAO,OAAO,MAAM;AAClB,MAAA,KAAA,CAAM,eAAgB,EAAA,CAAA;AACtB,MAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AAErB,MAAA,MAAM,YAAYC,4BAAqB,EAAA,CAAA;AACvC,MAAA,SAAA,CAAU,IAAI,OAAO,CAAA,CAAA;AACrB,MAAAC,qBAAA,CAAc,SAAS,CAAA,CAAA;AAAA,KACxB,CAAA,CAAA;AAAA,GACH;AAEA,EAAA,uBACGC,cAAA,CAAA,MAAA,EAAA;AAAA,IACC,OAAS,EAAA,WAAA;AAAA,IACT,eAAA,EAAe,aAAa,EAAK,GAAA,KAAA,CAAA;AAAA,IACjC,SAAU,EAAA,uCAAA;AAAA,IAET,QAAA;AAAA,GACH,CAAA,CAAA;AAEJ,CAAA;AAEA,SAAS,gBAAgB,GAAuB,EAAA;AAC9C,EAAM,MAAA,IAAA,GAAOC,sBAAc,GAAG,CAAA,CAAA;AAC9B,EAAA,IAAI,IAAS,KAAA,IAAA;AAAM,IAAO,OAAA,KAAA,CAAA;AAC1B,EAAA,OAAO,KAAK,UAAW,EAAA,CAAA;AACzB,CAAA;AAEA,SAAS,kBAAkB,GAAc,EAAA;AACvC,EAAM,MAAA,CAAC,MAAM,CAAA,GAAIJ,gDAA0B,EAAA,CAAA;AAE3C,EAAA,MAAM,SAAY,GAAAK,iBAAA;AAAA,IAChB,CAAC,aAA8B,KAAA;AAC7B,MAAO,OAAA,MAAA,CAAO,uBAAuB,aAAa,CAAA,CAAA;AAAA,KACpD;AAAA,IACA,CAAC,MAAM,CAAA;AAAA,GACT,CAAA;AAEA,EAAM,MAAA,WAAA,GAAcA,kBAAY,MAAM;AACpC,IAAA,OAAO,OAAO,cAAe,EAAA,CAAE,KAAK,MAAM,eAAA,CAAgB,GAAG,CAAC,CAAA,CAAA;AAAA,GAC7D,EAAA,CAAC,MAAQ,EAAA,GAAG,CAAC,CAAA,CAAA;AAEhB,EAAO,OAAAC,0BAAA,CAAqB,SAAW,EAAA,WAAA,EAAa,WAAW,CAAA,CAAA;AACjE;;;;"}
1
+ {"version":3,"file":"mention-component.cjs","sources":["../../src/mentions/mention-component.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { cn } from \"@liveblocks/react-ui/_private\";\nimport type { NodeKey } from \"lexical\";\nimport { $createNodeSelection, $getNodeByKey, $setSelection } from \"lexical\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type MouseEvent,\n} from \"react\";\nimport { useCallback, useSyncExternalStore } from \"react\";\n\ninterface MentionProps extends ComponentPropsWithoutRef<\"span\"> {\n nodeKey: NodeKey;\n}\n\nexport const Mention = forwardRef<HTMLSpanElement, MentionProps>(\n ({ nodeKey, children, className, ...props }, forwardedRef) => {\n const [editor] = useLexicalComposerContext();\n const isSelected = useIsNodeSelected(nodeKey);\n\n const handleClick = useCallback(\n (event: MouseEvent) => {\n editor.update(() => {\n event.stopPropagation();\n event.preventDefault();\n\n const selection = $createNodeSelection();\n selection.add(nodeKey);\n $setSelection(selection);\n });\n },\n [editor, nodeKey]\n );\n\n return (\n <span\n onClick={handleClick}\n data-selected={isSelected ? \"\" : undefined}\n className={cn(\"lb-root lb-mention lb-lexical-mention\", className)}\n ref={forwardedRef}\n {...props}\n >\n {children}\n </span>\n );\n }\n);\n\nfunction $isNodeSelected(key: NodeKey): boolean {\n const node = $getNodeByKey(key);\n if (node === null) return false;\n return node.isSelected();\n}\n\nfunction useIsNodeSelected(key: NodeKey) {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerUpdateListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getEditorState().read(() => $isNodeSelected(key));\n }, [editor, key]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n"],"names":["forwardRef","useLexicalComposerContext","useCallback","$createNodeSelection","$setSelection","jsx","cn","$getNodeByKey","useSyncExternalStore"],"mappings":";;;;;;;;AAeO,MAAM,OAAU,GAAAA,gBAAA;AAAA,EACrB,CAAC,EAAE,OAAA,EAAS,UAAU,SAAc,EAAA,GAAA,KAAA,IAAS,YAAiB,KAAA;AAC5D,IAAM,MAAA,CAAC,MAAM,CAAA,GAAIC,gDAA0B,EAAA,CAAA;AAC3C,IAAM,MAAA,UAAA,GAAa,kBAAkB,OAAO,CAAA,CAAA;AAE5C,IAAA,MAAM,WAAc,GAAAC,iBAAA;AAAA,MAClB,CAAC,KAAsB,KAAA;AACrB,QAAA,MAAA,CAAO,OAAO,MAAM;AAClB,UAAA,KAAA,CAAM,eAAgB,EAAA,CAAA;AACtB,UAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AAErB,UAAA,MAAM,YAAYC,4BAAqB,EAAA,CAAA;AACvC,UAAA,SAAA,CAAU,IAAI,OAAO,CAAA,CAAA;AACrB,UAAAC,qBAAA,CAAc,SAAS,CAAA,CAAA;AAAA,SACxB,CAAA,CAAA;AAAA,OACH;AAAA,MACA,CAAC,QAAQ,OAAO,CAAA;AAAA,KAClB,CAAA;AAEA,IAAA,uBACGC,cAAA,CAAA,MAAA,EAAA;AAAA,MACC,OAAS,EAAA,WAAA;AAAA,MACT,eAAA,EAAe,aAAa,EAAK,GAAA,KAAA,CAAA;AAAA,MACjC,SAAA,EAAWC,WAAG,CAAA,uCAAA,EAAyC,SAAS,CAAA;AAAA,MAChE,GAAK,EAAA,YAAA;AAAA,MACJ,GAAG,KAAA;AAAA,MAEH,QAAA;AAAA,KACH,CAAA,CAAA;AAAA,GAEJ;AACF,EAAA;AAEA,SAAS,gBAAgB,GAAuB,EAAA;AAC9C,EAAM,MAAA,IAAA,GAAOC,sBAAc,GAAG,CAAA,CAAA;AAC9B,EAAA,IAAI,IAAS,KAAA,IAAA;AAAM,IAAO,OAAA,KAAA,CAAA;AAC1B,EAAA,OAAO,KAAK,UAAW,EAAA,CAAA;AACzB,CAAA;AAEA,SAAS,kBAAkB,GAAc,EAAA;AACvC,EAAM,MAAA,CAAC,MAAM,CAAA,GAAIN,gDAA0B,EAAA,CAAA;AAE3C,EAAA,MAAM,SAAY,GAAAC,iBAAA;AAAA,IAChB,CAAC,aAA8B,KAAA;AAC7B,MAAO,OAAA,MAAA,CAAO,uBAAuB,aAAa,CAAA,CAAA;AAAA,KACpD;AAAA,IACA,CAAC,MAAM,CAAA;AAAA,GACT,CAAA;AAEA,EAAM,MAAA,WAAA,GAAcA,kBAAY,MAAM;AACpC,IAAA,OAAO,OAAO,cAAe,EAAA,CAAE,KAAK,MAAM,eAAA,CAAgB,GAAG,CAAC,CAAA,CAAA;AAAA,GAC7D,EAAA,CAAC,MAAQ,EAAA,GAAG,CAAC,CAAA,CAAA;AAEhB,EAAO,OAAAM,0BAAA,CAAqB,SAAW,EAAA,WAAA,EAAa,WAAW,CAAA,CAAA;AACjE;;;;"}