@liveblocks/react-lexical 1.12.0-lexical3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/active-selection.js +143 -0
- package/dist/active-selection.js.map +1 -0
- package/dist/active-selection.mjs +123 -0
- package/dist/active-selection.mjs.map +1 -0
- package/dist/comments/ThreadPanel.js +26 -0
- package/dist/comments/ThreadPanel.js.map +1 -0
- package/dist/comments/ThreadPanel.mjs +24 -0
- package/dist/comments/ThreadPanel.mjs.map +1 -0
- package/dist/comments/comment-plugin-provider.js +322 -0
- package/dist/comments/comment-plugin-provider.js.map +1 -0
- package/dist/comments/comment-plugin-provider.mjs +299 -0
- package/dist/comments/comment-plugin-provider.mjs.map +1 -0
- package/dist/comments/floating-composer.js +34 -0
- package/dist/comments/floating-composer.js.map +1 -0
- package/dist/comments/floating-composer.mjs +32 -0
- package/dist/comments/floating-composer.mjs.map +1 -0
- package/dist/comments/get-thread-mark-ids.js +23 -0
- package/dist/comments/get-thread-mark-ids.js.map +1 -0
- package/dist/comments/get-thread-mark-ids.mjs +21 -0
- package/dist/comments/get-thread-mark-ids.mjs.map +1 -0
- package/dist/comments/thread-mark-node.js +138 -0
- package/dist/comments/thread-mark-node.js.map +1 -0
- package/dist/comments/thread-mark-node.mjs +134 -0
- package/dist/comments/thread-mark-node.mjs.map +1 -0
- package/dist/comments/unwrap-thread-mark-node.js +19 -0
- package/dist/comments/unwrap-thread-mark-node.js.map +1 -0
- package/dist/comments/unwrap-thread-mark-node.mjs +17 -0
- package/dist/comments/unwrap-thread-mark-node.mjs.map +1 -0
- package/dist/comments/wrap-selection-in-thread-mark-node.js +63 -0
- package/dist/comments/wrap-selection-in-thread-mark-node.js.map +1 -0
- package/dist/comments/wrap-selection-in-thread-mark-node.mjs +61 -0
- package/dist/comments/wrap-selection-in-thread-mark-node.mjs.map +1 -0
- package/dist/floating-selection-container.js +157 -0
- package/dist/floating-selection-container.js.map +1 -0
- package/dist/floating-selection-container.mjs +155 -0
- package/dist/floating-selection-container.mjs.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +11 -0
- package/dist/index.mjs.map +1 -0
- package/dist/liveblocks-config.js +89 -0
- package/dist/liveblocks-config.js.map +1 -0
- package/dist/liveblocks-config.mjs +67 -0
- package/dist/liveblocks-config.mjs.map +1 -0
- package/dist/liveblocks-plugin-provider.js +79 -0
- package/dist/liveblocks-plugin-provider.js.map +1 -0
- package/dist/liveblocks-plugin-provider.mjs +76 -0
- package/dist/liveblocks-plugin-provider.mjs.map +1 -0
- package/dist/mentions/avatar.js +49 -0
- package/dist/mentions/avatar.js.map +1 -0
- package/dist/mentions/avatar.mjs +47 -0
- package/dist/mentions/avatar.mjs.map +1 -0
- package/dist/mentions/mention-component.js +63 -0
- package/dist/mentions/mention-component.js.map +1 -0
- package/dist/mentions/mention-component.mjs +60 -0
- package/dist/mentions/mention-component.mjs.map +1 -0
- package/dist/mentions/mention-node.js +105 -0
- package/dist/mentions/mention-node.js.map +1 -0
- package/dist/mentions/mention-node.mjs +84 -0
- package/dist/mentions/mention-node.mjs.map +1 -0
- package/dist/mentions/mention-plugin.js +291 -0
- package/dist/mentions/mention-plugin.js.map +1 -0
- package/dist/mentions/mention-plugin.mjs +284 -0
- package/dist/mentions/mention-plugin.mjs.map +1 -0
- package/dist/mentions/suggestions.js +161 -0
- package/dist/mentions/suggestions.js.map +1 -0
- package/dist/mentions/suggestions.mjs +158 -0
- package/dist/mentions/suggestions.mjs.map +1 -0
- package/dist/mentions/user.js +21 -0
- package/dist/mentions/user.js.map +1 -0
- package/dist/mentions/user.mjs +19 -0
- package/dist/mentions/user.mjs.map +1 -0
- package/dist/version.js +10 -0
- package/dist/version.js.map +1 -0
- package/dist/version.mjs +6 -0
- package/dist/version.mjs.map +1 -0
- package/package.json +102 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var LexicalCollaborationPlugin = require('@lexical/react/LexicalCollaborationPlugin');
|
|
4
|
+
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
5
|
+
var core = require('@liveblocks/core');
|
|
6
|
+
var react = require('@liveblocks/react');
|
|
7
|
+
var LiveblocksProvider = require('@liveblocks/yjs');
|
|
8
|
+
var React = require('react');
|
|
9
|
+
var yjs = require('yjs');
|
|
10
|
+
var commentPluginProvider = require('./comments/comment-plugin-provider.js');
|
|
11
|
+
var liveblocksConfig = require('./liveblocks-config.js');
|
|
12
|
+
var mentionPlugin = require('./mentions/mention-plugin.js');
|
|
13
|
+
|
|
14
|
+
const LiveblocksLexicalConfigContext = React.createContext(null);
|
|
15
|
+
const LiveblocksPluginProvider = ({
|
|
16
|
+
children
|
|
17
|
+
}) => {
|
|
18
|
+
const client = react.useClient();
|
|
19
|
+
const hasResolveMentionSuggestions = client[core.kInternal].resolveMentionSuggestions !== void 0;
|
|
20
|
+
const { useSelf, useRoom } = react.useRoomContextBundle();
|
|
21
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
22
|
+
const room = useRoom();
|
|
23
|
+
const [provider, setProvider] = React.useState();
|
|
24
|
+
const doc = React.useMemo(() => new yjs.Doc(), []);
|
|
25
|
+
React.useEffect(() => {
|
|
26
|
+
const _provider = new LiveblocksProvider(room, doc);
|
|
27
|
+
setProvider(_provider);
|
|
28
|
+
return () => {
|
|
29
|
+
_provider.destroy();
|
|
30
|
+
setProvider(void 0);
|
|
31
|
+
};
|
|
32
|
+
}, [room, doc]);
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
if (process.env.NODE_ENV !== "production") {
|
|
35
|
+
if (!editor.getEditorState().isEmpty()) {
|
|
36
|
+
console.warn(
|
|
37
|
+
"Warning: LiveblocksPluginProvider: editorState in initialConfig detected, but must be null."
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
room[core.kInternal].reportTextEditor("lexical", "root");
|
|
42
|
+
}, []);
|
|
43
|
+
const info = useSelf((me) => me.info);
|
|
44
|
+
const username = info?.name;
|
|
45
|
+
const cursorcolor = info?.color;
|
|
46
|
+
const providerFactory = React.useCallback(
|
|
47
|
+
(id, yjsDocMap) => {
|
|
48
|
+
yjsDocMap.set(id, doc);
|
|
49
|
+
return provider;
|
|
50
|
+
},
|
|
51
|
+
[provider, doc]
|
|
52
|
+
);
|
|
53
|
+
const configRef = React.useRef(null);
|
|
54
|
+
if (configRef.current === null) {
|
|
55
|
+
configRef.current = liveblocksConfig.getLiveblocksLexicalConfig();
|
|
56
|
+
}
|
|
57
|
+
return /* @__PURE__ */ React.createElement(LiveblocksLexicalConfigContext.Provider, {
|
|
58
|
+
value: configRef.current
|
|
59
|
+
}, provider && /* @__PURE__ */ React.createElement(LexicalCollaborationPlugin.CollaborationPlugin, {
|
|
60
|
+
providerFactory,
|
|
61
|
+
id: "liveblocks-document",
|
|
62
|
+
username,
|
|
63
|
+
cursorColor: cursorcolor,
|
|
64
|
+
shouldBootstrap: true
|
|
65
|
+
}), hasResolveMentionSuggestions && /* @__PURE__ */ React.createElement(mentionPlugin.default, null), configRef.current.comments && /* @__PURE__ */ React.createElement(commentPluginProvider.CommentPluginProvider, null, children));
|
|
66
|
+
};
|
|
67
|
+
function useLiveblocksLexicalConfigContext() {
|
|
68
|
+
const config = React.useContext(LiveblocksLexicalConfigContext);
|
|
69
|
+
if (config === null) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
"useLiveblocksLexicalConfigContext must be used within a LiveblocksPluginProviderProvider"
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
return config;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
exports.LiveblocksPluginProvider = LiveblocksPluginProvider;
|
|
78
|
+
exports.useLiveblocksLexicalConfigContext = useLiveblocksLexicalConfigContext;
|
|
79
|
+
//# sourceMappingURL=liveblocks-plugin-provider.js.map
|
|
@@ -0,0 +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 BaseUserMeta,\n Json,\n JsonObject,\n LsonObject,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient, useRoomContextBundle } from \"@liveblocks/react\";\nimport LiveblocksProvider from \"@liveblocks/yjs\";\nimport type { ComponentType } from \"react\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport type { MentionSuggestionsProps } from \"./liveblocks-config\";\nimport { getLiveblocksLexicalConfig } from \"./liveblocks-config\";\nimport type { createMentionNodeFactory } from \"./mentions/mention-node\";\nimport MentionPlugin from \"./mentions/mention-plugin\";\n\nexport type LiveblocksPluginProviderProps = {\n // TODO: Move these configuration options (if applicable and necessary) to the `liveblocksLexicalConfig` function to have all configuration in one place\n // /**\n // * Optionally override user information. If not, user[\"info\"] from auth will be used.\n // */\n // userInfo?: {\n // name: string;\n // color?: string;\n // };\n // /**\n // * Whether or not the user can edit the document before it has been synced\n // * default: true\n // */\n // allowEditsBeforeSync?: boolean;\n\n // /**\n // * Modify the state with this function to set the initial state.\n // * Ex. $createTextNode('initial text content');\n // *\n // * @param editor\n // * @returns void\n // */\n // initialEditorState?: (editor: LexicalEditor) => void;\n\n children?: React.ReactNode;\n};\n\nexport interface LiveblocksLexicalInternalConfig {\n comments: boolean;\n mentions: {\n factory: ReturnType<typeof createMentionNodeFactory>;\n components: {\n MentionSuggestions: ComponentType<MentionSuggestionsProps>;\n };\n };\n}\n\nconst LiveblocksLexicalConfigContext =\n createContext<LiveblocksLexicalInternalConfig | null>(null);\n\nexport const LiveblocksPluginProvider = ({\n // userInfo = undefined,\n // allowEditsBeforeSync = true,\n // initialEditorState = undefined,\n children,\n}: LiveblocksPluginProviderProps): JSX.Element => {\n const client = useClient();\n const hasResolveMentionSuggestions =\n client[kInternal].resolveMentionSuggestions !== undefined;\n const { useSelf, useRoom } = useRoomContextBundle();\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n\n const [provider, setProvider] = useState<\n LiveblocksProvider<JsonObject, LsonObject, BaseUserMeta, Json> | undefined\n >();\n\n const doc = useMemo(() => new Doc(), []);\n\n useEffect(() => {\n const _provider = new LiveblocksProvider(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: LiveblocksPluginProvider: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // Report that this is lexical and root is the rootKey\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n room[kInternal].reportTextEditor(\"lexical\", \"root\");\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 // 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 // const [synced, setSynced] = useState(false);\n\n // useEffect(() => {\n // if (!provider) {\n // return;\n // }\n // provider.on(\"sync\", setSynced);\n // return () => {\n // provider.off(\"sync\", setSynced);\n // };\n // }, [provider]);\n\n // // Disable the editor before sync\n // useEffect(() => {\n // if (!allowEditsBeforeSync) {\n // editor.setEditable(synced);\n // }\n // }, [synced, editor, allowEditsBeforeSync]);\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 const configRef = useRef<LiveblocksLexicalInternalConfig | null>(null);\n if (configRef.current === null) {\n configRef.current = getLiveblocksLexicalConfig();\n }\n\n return (\n <LiveblocksLexicalConfigContext.Provider value={configRef.current}>\n {provider && (\n <CollaborationPlugin\n providerFactory={providerFactory}\n // initialEditorState={initialEditorState}\n id={\"liveblocks-document\"}\n username={username}\n cursorColor={cursorcolor}\n shouldBootstrap={true}\n />\n )}\n\n {hasResolveMentionSuggestions && <MentionPlugin />}\n\n {configRef.current.comments && (\n <CommentPluginProvider>{children}</CommentPluginProvider>\n )}\n </LiveblocksLexicalConfigContext.Provider>\n );\n};\n\nexport function useLiveblocksLexicalConfigContext(): LiveblocksLexicalInternalConfig {\n const config = useContext(LiveblocksLexicalConfigContext);\n if (config === null) {\n throw new Error(\n \"useLiveblocksLexicalConfigContext must be used within a LiveblocksPluginProviderProvider\"\n );\n }\n return config;\n}\n"],"names":["createContext","useClient","kInternal","useRoomContextBundle","useLexicalComposerContext","useState","useMemo","Doc","useEffect","useCallback","useRef","getLiveblocksLexicalConfig","CollaborationPlugin","MentionPlugin","CommentPluginProvider","useContext"],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { CollaborationPlugin } from '@lexical/react/LexicalCollaborationPlugin';
|
|
2
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
3
|
+
import { kInternal } from '@liveblocks/core';
|
|
4
|
+
import { useClient, useRoomContextBundle } from '@liveblocks/react';
|
|
5
|
+
import LiveblocksProvider from '@liveblocks/yjs';
|
|
6
|
+
import React__default, { createContext, useState, useMemo, useEffect, useCallback, useRef, useContext } from 'react';
|
|
7
|
+
import { Doc } from 'yjs';
|
|
8
|
+
import { CommentPluginProvider } from './comments/comment-plugin-provider.mjs';
|
|
9
|
+
import { getLiveblocksLexicalConfig } from './liveblocks-config.mjs';
|
|
10
|
+
import MentionPlugin from './mentions/mention-plugin.mjs';
|
|
11
|
+
|
|
12
|
+
const LiveblocksLexicalConfigContext = createContext(null);
|
|
13
|
+
const LiveblocksPluginProvider = ({
|
|
14
|
+
children
|
|
15
|
+
}) => {
|
|
16
|
+
const client = useClient();
|
|
17
|
+
const hasResolveMentionSuggestions = client[kInternal].resolveMentionSuggestions !== void 0;
|
|
18
|
+
const { useSelf, useRoom } = useRoomContextBundle();
|
|
19
|
+
const [editor] = useLexicalComposerContext();
|
|
20
|
+
const room = useRoom();
|
|
21
|
+
const [provider, setProvider] = useState();
|
|
22
|
+
const doc = useMemo(() => new Doc(), []);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const _provider = new LiveblocksProvider(room, doc);
|
|
25
|
+
setProvider(_provider);
|
|
26
|
+
return () => {
|
|
27
|
+
_provider.destroy();
|
|
28
|
+
setProvider(void 0);
|
|
29
|
+
};
|
|
30
|
+
}, [room, doc]);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (process.env.NODE_ENV !== "production") {
|
|
33
|
+
if (!editor.getEditorState().isEmpty()) {
|
|
34
|
+
console.warn(
|
|
35
|
+
"Warning: LiveblocksPluginProvider: editorState in initialConfig detected, but must be null."
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
room[kInternal].reportTextEditor("lexical", "root");
|
|
40
|
+
}, []);
|
|
41
|
+
const info = useSelf((me) => me.info);
|
|
42
|
+
const username = info?.name;
|
|
43
|
+
const cursorcolor = info?.color;
|
|
44
|
+
const providerFactory = useCallback(
|
|
45
|
+
(id, yjsDocMap) => {
|
|
46
|
+
yjsDocMap.set(id, doc);
|
|
47
|
+
return provider;
|
|
48
|
+
},
|
|
49
|
+
[provider, doc]
|
|
50
|
+
);
|
|
51
|
+
const configRef = useRef(null);
|
|
52
|
+
if (configRef.current === null) {
|
|
53
|
+
configRef.current = getLiveblocksLexicalConfig();
|
|
54
|
+
}
|
|
55
|
+
return /* @__PURE__ */ React__default.createElement(LiveblocksLexicalConfigContext.Provider, {
|
|
56
|
+
value: configRef.current
|
|
57
|
+
}, provider && /* @__PURE__ */ React__default.createElement(CollaborationPlugin, {
|
|
58
|
+
providerFactory,
|
|
59
|
+
id: "liveblocks-document",
|
|
60
|
+
username,
|
|
61
|
+
cursorColor: cursorcolor,
|
|
62
|
+
shouldBootstrap: true
|
|
63
|
+
}), hasResolveMentionSuggestions && /* @__PURE__ */ React__default.createElement(MentionPlugin, null), configRef.current.comments && /* @__PURE__ */ React__default.createElement(CommentPluginProvider, null, children));
|
|
64
|
+
};
|
|
65
|
+
function useLiveblocksLexicalConfigContext() {
|
|
66
|
+
const config = useContext(LiveblocksLexicalConfigContext);
|
|
67
|
+
if (config === null) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
"useLiveblocksLexicalConfigContext must be used within a LiveblocksPluginProviderProvider"
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
return config;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { LiveblocksPluginProvider, useLiveblocksLexicalConfigContext };
|
|
76
|
+
//# sourceMappingURL=liveblocks-plugin-provider.mjs.map
|
|
@@ -0,0 +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 BaseUserMeta,\n Json,\n JsonObject,\n LsonObject,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient, useRoomContextBundle } from \"@liveblocks/react\";\nimport LiveblocksProvider from \"@liveblocks/yjs\";\nimport type { ComponentType } from \"react\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport type { MentionSuggestionsProps } from \"./liveblocks-config\";\nimport { getLiveblocksLexicalConfig } from \"./liveblocks-config\";\nimport type { createMentionNodeFactory } from \"./mentions/mention-node\";\nimport MentionPlugin from \"./mentions/mention-plugin\";\n\nexport type LiveblocksPluginProviderProps = {\n // TODO: Move these configuration options (if applicable and necessary) to the `liveblocksLexicalConfig` function to have all configuration in one place\n // /**\n // * Optionally override user information. If not, user[\"info\"] from auth will be used.\n // */\n // userInfo?: {\n // name: string;\n // color?: string;\n // };\n // /**\n // * Whether or not the user can edit the document before it has been synced\n // * default: true\n // */\n // allowEditsBeforeSync?: boolean;\n\n // /**\n // * Modify the state with this function to set the initial state.\n // * Ex. $createTextNode('initial text content');\n // *\n // * @param editor\n // * @returns void\n // */\n // initialEditorState?: (editor: LexicalEditor) => void;\n\n children?: React.ReactNode;\n};\n\nexport interface LiveblocksLexicalInternalConfig {\n comments: boolean;\n mentions: {\n factory: ReturnType<typeof createMentionNodeFactory>;\n components: {\n MentionSuggestions: ComponentType<MentionSuggestionsProps>;\n };\n };\n}\n\nconst LiveblocksLexicalConfigContext =\n createContext<LiveblocksLexicalInternalConfig | null>(null);\n\nexport const LiveblocksPluginProvider = ({\n // userInfo = undefined,\n // allowEditsBeforeSync = true,\n // initialEditorState = undefined,\n children,\n}: LiveblocksPluginProviderProps): JSX.Element => {\n const client = useClient();\n const hasResolveMentionSuggestions =\n client[kInternal].resolveMentionSuggestions !== undefined;\n const { useSelf, useRoom } = useRoomContextBundle();\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n\n const [provider, setProvider] = useState<\n LiveblocksProvider<JsonObject, LsonObject, BaseUserMeta, Json> | undefined\n >();\n\n const doc = useMemo(() => new Doc(), []);\n\n useEffect(() => {\n const _provider = new LiveblocksProvider(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: LiveblocksPluginProvider: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // Report that this is lexical and root is the rootKey\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n room[kInternal].reportTextEditor(\"lexical\", \"root\");\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 // 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 // const [synced, setSynced] = useState(false);\n\n // useEffect(() => {\n // if (!provider) {\n // return;\n // }\n // provider.on(\"sync\", setSynced);\n // return () => {\n // provider.off(\"sync\", setSynced);\n // };\n // }, [provider]);\n\n // // Disable the editor before sync\n // useEffect(() => {\n // if (!allowEditsBeforeSync) {\n // editor.setEditable(synced);\n // }\n // }, [synced, editor, allowEditsBeforeSync]);\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 const configRef = useRef<LiveblocksLexicalInternalConfig | null>(null);\n if (configRef.current === null) {\n configRef.current = getLiveblocksLexicalConfig();\n }\n\n return (\n <LiveblocksLexicalConfigContext.Provider value={configRef.current}>\n {provider && (\n <CollaborationPlugin\n providerFactory={providerFactory}\n // initialEditorState={initialEditorState}\n id={\"liveblocks-document\"}\n username={username}\n cursorColor={cursorcolor}\n shouldBootstrap={true}\n />\n )}\n\n {hasResolveMentionSuggestions && <MentionPlugin />}\n\n {configRef.current.comments && (\n <CommentPluginProvider>{children}</CommentPluginProvider>\n )}\n </LiveblocksLexicalConfigContext.Provider>\n );\n};\n\nexport function useLiveblocksLexicalConfigContext(): LiveblocksLexicalInternalConfig {\n const config = useContext(LiveblocksLexicalConfigContext);\n if (config === null) {\n throw new Error(\n \"useLiveblocksLexicalConfigContext must be used within a LiveblocksPluginProviderProvider\"\n );\n }\n return config;\n}\n"],"names":["React"],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('@liveblocks/react');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
|
|
6
|
+
const Avatar = React.forwardRef(
|
|
7
|
+
function Avatar2(props, forwardedRef) {
|
|
8
|
+
const { userId, ...spanProps } = props;
|
|
9
|
+
const { useUser } = react.useSharedContextBundle();
|
|
10
|
+
const { user, isLoading } = useUser(userId);
|
|
11
|
+
const avatar = user ? user.avatar : void 0;
|
|
12
|
+
const name = user ? user.name : void 0;
|
|
13
|
+
function Initials() {
|
|
14
|
+
const initials = name ? getInitials(name) : void 0;
|
|
15
|
+
if (initials) {
|
|
16
|
+
return /* @__PURE__ */ React.createElement("span", {
|
|
17
|
+
"aria-hidden": true
|
|
18
|
+
}, initials);
|
|
19
|
+
}
|
|
20
|
+
if (isLoading)
|
|
21
|
+
return null;
|
|
22
|
+
if (user === void 0)
|
|
23
|
+
return null;
|
|
24
|
+
return /* @__PURE__ */ React.createElement("span", {
|
|
25
|
+
"aria-label": userId,
|
|
26
|
+
title: userId
|
|
27
|
+
}, getInitials(userId));
|
|
28
|
+
}
|
|
29
|
+
return /* @__PURE__ */ React.createElement("span", {
|
|
30
|
+
"data-loading": isLoading ? "" : void 0,
|
|
31
|
+
...spanProps,
|
|
32
|
+
ref: forwardedRef
|
|
33
|
+
}, avatar && /* @__PURE__ */ React.createElement("img", {
|
|
34
|
+
src: avatar,
|
|
35
|
+
alt: name
|
|
36
|
+
}), /* @__PURE__ */ React.createElement(Initials, null));
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
function getInitials(name) {
|
|
40
|
+
return name.trim().split(" ").reduce((initials, name2, index, array) => {
|
|
41
|
+
if (index === 0 || index === array.length - 1) {
|
|
42
|
+
initials += name2.charAt(0).toLocaleUpperCase();
|
|
43
|
+
}
|
|
44
|
+
return initials;
|
|
45
|
+
}, "");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = Avatar;
|
|
49
|
+
//# sourceMappingURL=avatar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatar.js","sources":["../../src/mentions/avatar.tsx"],"sourcesContent":["import { useSharedContextBundle } from \"@liveblocks/react\";\nimport type { HTMLAttributes } from \"react\";\nimport React, { forwardRef } from \"react\";\n\nexport interface AvatarProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n userId: string;\n}\n\nconst Avatar = forwardRef<HTMLSpanElement, AvatarProps>(\n function Avatar(props, forwardedRef) {\n const { userId, ...spanProps } = props;\n const { useUser } = useSharedContextBundle();\n\n const { user, isLoading } = useUser(userId);\n\n const avatar = user ? user.avatar : undefined;\n\n const name = user ? user.name : undefined;\n\n function Initials() {\n const initials = name ? getInitials(name) : undefined;\n if (initials) {\n return <span aria-hidden>{initials}</span>;\n }\n\n if (isLoading) return null;\n\n if (user === undefined) return null;\n\n return (\n <span aria-label={userId} title={userId}>\n {getInitials(userId)}\n </span>\n );\n }\n\n return (\n <span\n data-loading={isLoading ? \"\" : undefined}\n {...spanProps}\n ref={forwardedRef}\n >\n {avatar && <img src={avatar} alt={name} />}\n\n <Initials />\n </span>\n );\n }\n);\n\nfunction getInitials(name: string) {\n return name\n .trim()\n .split(\" \")\n .reduce((initials, name, index, array) => {\n if (index === 0 || index === array.length - 1) {\n initials += name.charAt(0).toLocaleUpperCase();\n }\n\n return initials;\n }, \"\");\n}\n\nexport default Avatar;\n"],"names":["forwardRef","Avatar","useSharedContextBundle","name"],"mappings":";;;;;AASA,MAAM,MAAS,GAAAA,gBAAA;AAAA,EACb,SAASC,OAAO,CAAA,KAAA,EAAO,YAAc,EAAA;AACnC,IAAM,MAAA,EAAE,MAAW,EAAA,GAAA,SAAA,EAAc,GAAA,KAAA,CAAA;AACjC,IAAM,MAAA,EAAE,OAAQ,EAAA,GAAIC,4BAAuB,EAAA,CAAA;AAE3C,IAAA,MAAM,EAAE,IAAA,EAAM,SAAU,EAAA,GAAI,QAAQ,MAAM,CAAA,CAAA;AAE1C,IAAM,MAAA,MAAA,GAAS,IAAO,GAAA,IAAA,CAAK,MAAS,GAAA,KAAA,CAAA,CAAA;AAEpC,IAAM,MAAA,IAAA,GAAO,IAAO,GAAA,IAAA,CAAK,IAAO,GAAA,KAAA,CAAA,CAAA;AAEhC,IAAA,SAAS,QAAW,GAAA;AAClB,MAAA,MAAM,QAAW,GAAA,IAAA,GAAO,WAAY,CAAA,IAAI,CAAI,GAAA,KAAA,CAAA,CAAA;AAC5C,MAAA,IAAI,QAAU,EAAA;AACZ,QAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,UAAK,aAAW,EAAA,IAAA;AAAA,SAAA,EAAE,QAAS,CAAA,CAAA;AAAA,OACrC;AAEA,MAAI,IAAA,SAAA;AAAW,QAAO,OAAA,IAAA,CAAA;AAEtB,MAAA,IAAI,IAAS,KAAA,KAAA,CAAA;AAAW,QAAO,OAAA,IAAA,CAAA;AAE/B,MAAA,uBACG,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,QAAK,YAAY,EAAA,MAAA;AAAA,QAAQ,KAAO,EAAA,MAAA;AAAA,OAC9B,EAAA,WAAA,CAAY,MAAM,CACrB,CAAA,CAAA;AAAA,KAEJ;AAEA,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,MACC,cAAA,EAAc,YAAY,EAAK,GAAA,KAAA,CAAA;AAAA,MAC9B,GAAG,SAAA;AAAA,MACJ,GAAK,EAAA,YAAA;AAAA,KAAA,EAEJ,0BAAW,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,MAAI,GAAK,EAAA,MAAA;AAAA,MAAQ,GAAK,EAAA,IAAA;AAAA,KAAM,CAAA,kBAEvC,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,IAAS,CACZ,CAAA,CAAA;AAAA,GAEJ;AACF,EAAA;AAEA,SAAS,YAAY,IAAc,EAAA;AACjC,EAAO,OAAA,IAAA,CACJ,IAAK,EAAA,CACL,KAAM,CAAA,GAAG,CACT,CAAA,MAAA,CAAO,CAAC,QAAA,EAAUC,KAAM,EAAA,KAAA,EAAO,KAAU,KAAA;AACxC,IAAA,IAAI,KAAU,KAAA,CAAA,IAAK,KAAU,KAAA,KAAA,CAAM,SAAS,CAAG,EAAA;AAC7C,MAAA,QAAA,IAAYA,KAAK,CAAA,MAAA,CAAO,CAAC,CAAA,CAAE,iBAAkB,EAAA,CAAA;AAAA,KAC/C;AAEA,IAAO,OAAA,QAAA,CAAA;AAAA,KACN,EAAE,CAAA,CAAA;AACT;;;;"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useSharedContextBundle } from '@liveblocks/react';
|
|
2
|
+
import React__default, { forwardRef } from 'react';
|
|
3
|
+
|
|
4
|
+
const Avatar = forwardRef(
|
|
5
|
+
function Avatar2(props, forwardedRef) {
|
|
6
|
+
const { userId, ...spanProps } = props;
|
|
7
|
+
const { useUser } = useSharedContextBundle();
|
|
8
|
+
const { user, isLoading } = useUser(userId);
|
|
9
|
+
const avatar = user ? user.avatar : void 0;
|
|
10
|
+
const name = user ? user.name : void 0;
|
|
11
|
+
function Initials() {
|
|
12
|
+
const initials = name ? getInitials(name) : void 0;
|
|
13
|
+
if (initials) {
|
|
14
|
+
return /* @__PURE__ */ React__default.createElement("span", {
|
|
15
|
+
"aria-hidden": true
|
|
16
|
+
}, initials);
|
|
17
|
+
}
|
|
18
|
+
if (isLoading)
|
|
19
|
+
return null;
|
|
20
|
+
if (user === void 0)
|
|
21
|
+
return null;
|
|
22
|
+
return /* @__PURE__ */ React__default.createElement("span", {
|
|
23
|
+
"aria-label": userId,
|
|
24
|
+
title: userId
|
|
25
|
+
}, getInitials(userId));
|
|
26
|
+
}
|
|
27
|
+
return /* @__PURE__ */ React__default.createElement("span", {
|
|
28
|
+
"data-loading": isLoading ? "" : void 0,
|
|
29
|
+
...spanProps,
|
|
30
|
+
ref: forwardedRef
|
|
31
|
+
}, avatar && /* @__PURE__ */ React__default.createElement("img", {
|
|
32
|
+
src: avatar,
|
|
33
|
+
alt: name
|
|
34
|
+
}), /* @__PURE__ */ React__default.createElement(Initials, null));
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
function getInitials(name) {
|
|
38
|
+
return name.trim().split(" ").reduce((initials, name2, index, array) => {
|
|
39
|
+
if (index === 0 || index === array.length - 1) {
|
|
40
|
+
initials += name2.charAt(0).toLocaleUpperCase();
|
|
41
|
+
}
|
|
42
|
+
return initials;
|
|
43
|
+
}, "");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { Avatar as default };
|
|
47
|
+
//# sourceMappingURL=avatar.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatar.mjs","sources":["../../src/mentions/avatar.tsx"],"sourcesContent":["import { useSharedContextBundle } from \"@liveblocks/react\";\nimport type { HTMLAttributes } from \"react\";\nimport React, { forwardRef } from \"react\";\n\nexport interface AvatarProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n userId: string;\n}\n\nconst Avatar = forwardRef<HTMLSpanElement, AvatarProps>(\n function Avatar(props, forwardedRef) {\n const { userId, ...spanProps } = props;\n const { useUser } = useSharedContextBundle();\n\n const { user, isLoading } = useUser(userId);\n\n const avatar = user ? user.avatar : undefined;\n\n const name = user ? user.name : undefined;\n\n function Initials() {\n const initials = name ? getInitials(name) : undefined;\n if (initials) {\n return <span aria-hidden>{initials}</span>;\n }\n\n if (isLoading) return null;\n\n if (user === undefined) return null;\n\n return (\n <span aria-label={userId} title={userId}>\n {getInitials(userId)}\n </span>\n );\n }\n\n return (\n <span\n data-loading={isLoading ? \"\" : undefined}\n {...spanProps}\n ref={forwardedRef}\n >\n {avatar && <img src={avatar} alt={name} />}\n\n <Initials />\n </span>\n );\n }\n);\n\nfunction getInitials(name: string) {\n return name\n .trim()\n .split(\" \")\n .reduce((initials, name, index, array) => {\n if (index === 0 || index === array.length - 1) {\n initials += name.charAt(0).toLocaleUpperCase();\n }\n\n return initials;\n }, \"\");\n}\n\nexport default Avatar;\n"],"names":["Avatar","React","name"],"mappings":";;;AASA,MAAM,MAAS,GAAA,UAAA;AAAA,EACb,SAASA,OAAO,CAAA,KAAA,EAAO,YAAc,EAAA;AACnC,IAAM,MAAA,EAAE,MAAW,EAAA,GAAA,SAAA,EAAc,GAAA,KAAA,CAAA;AACjC,IAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,sBAAuB,EAAA,CAAA;AAE3C,IAAA,MAAM,EAAE,IAAA,EAAM,SAAU,EAAA,GAAI,QAAQ,MAAM,CAAA,CAAA;AAE1C,IAAM,MAAA,MAAA,GAAS,IAAO,GAAA,IAAA,CAAK,MAAS,GAAA,KAAA,CAAA,CAAA;AAEpC,IAAM,MAAA,IAAA,GAAO,IAAO,GAAA,IAAA,CAAK,IAAO,GAAA,KAAA,CAAA,CAAA;AAEhC,IAAA,SAAS,QAAW,GAAA;AAClB,MAAA,MAAM,QAAW,GAAA,IAAA,GAAO,WAAY,CAAA,IAAI,CAAI,GAAA,KAAA,CAAA,CAAA;AAC5C,MAAA,IAAI,QAAU,EAAA;AACZ,QAAA,uBAAQC,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,UAAK,aAAW,EAAA,IAAA;AAAA,SAAA,EAAE,QAAS,CAAA,CAAA;AAAA,OACrC;AAEA,MAAI,IAAA,SAAA;AAAW,QAAO,OAAA,IAAA,CAAA;AAEtB,MAAA,IAAI,IAAS,KAAA,KAAA,CAAA;AAAW,QAAO,OAAA,IAAA,CAAA;AAE/B,MAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,QAAK,YAAY,EAAA,MAAA;AAAA,QAAQ,KAAO,EAAA,MAAA;AAAA,OAC9B,EAAA,WAAA,CAAY,MAAM,CACrB,CAAA,CAAA;AAAA,KAEJ;AAEA,IAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,MACC,cAAA,EAAc,YAAY,EAAK,GAAA,KAAA,CAAA;AAAA,MAC9B,GAAG,SAAA;AAAA,MACJ,GAAK,EAAA,YAAA;AAAA,KAAA,EAEJ,0BAAWA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,MAAI,GAAK,EAAA,MAAA;AAAA,MAAQ,GAAK,EAAA,IAAA;AAAA,KAAM,CAAA,kBAEvCA,cAAA,CAAA,aAAA,CAAA,QAAA,EAAA,IAAS,CACZ,CAAA,CAAA;AAAA,GAEJ;AACF,EAAA;AAEA,SAAS,YAAY,IAAc,EAAA;AACjC,EAAO,OAAA,IAAA,CACJ,IAAK,EAAA,CACL,KAAM,CAAA,GAAG,CACT,CAAA,MAAA,CAAO,CAAC,QAAA,EAAUC,KAAM,EAAA,KAAA,EAAO,KAAU,KAAA;AACxC,IAAA,IAAI,KAAU,KAAA,CAAA,IAAK,KAAU,KAAA,KAAA,CAAM,SAAS,CAAG,EAAA;AAC7C,MAAA,QAAA,IAAYA,KAAK,CAAA,MAAA,CAAO,CAAC,CAAA,CAAE,iBAAkB,EAAA,CAAA;AAAA,KAC/C;AAEA,IAAO,OAAA,QAAA,CAAA;AAAA,KACN,EAAE,CAAA,CAAA;AACT;;;;"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
4
|
+
var lexical = require('lexical');
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var index_js = require('use-sync-external-store/shim/index.js');
|
|
7
|
+
|
|
8
|
+
const IsSelectedContext = React.createContext(null);
|
|
9
|
+
function MentionWrapper({
|
|
10
|
+
nodeKey,
|
|
11
|
+
children
|
|
12
|
+
}) {
|
|
13
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
14
|
+
const isSelected = useIsNodeSelected(nodeKey);
|
|
15
|
+
function handleClick(event) {
|
|
16
|
+
editor.update(() => {
|
|
17
|
+
event.stopPropagation();
|
|
18
|
+
event.preventDefault();
|
|
19
|
+
const selection = lexical.$createNodeSelection();
|
|
20
|
+
selection.add(nodeKey);
|
|
21
|
+
lexical.$setSelection(selection);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return /* @__PURE__ */ React.createElement(IsSelectedContext.Provider, {
|
|
25
|
+
value: isSelected
|
|
26
|
+
}, /* @__PURE__ */ React.createElement("span", {
|
|
27
|
+
onClick: handleClick
|
|
28
|
+
}, children));
|
|
29
|
+
}
|
|
30
|
+
const Mention = React.forwardRef(function(props, forwardedRef) {
|
|
31
|
+
const isSelected = React.useContext(IsSelectedContext);
|
|
32
|
+
if (isSelected === null) {
|
|
33
|
+
throw new Error("Mention component must be wrapped in MentionWrapper");
|
|
34
|
+
}
|
|
35
|
+
return /* @__PURE__ */ React.createElement("span", {
|
|
36
|
+
"data-selected": isSelected ? "" : void 0,
|
|
37
|
+
...props,
|
|
38
|
+
ref: forwardedRef
|
|
39
|
+
}, props.children);
|
|
40
|
+
});
|
|
41
|
+
function $isNodeSelected(key) {
|
|
42
|
+
const node = lexical.$getNodeByKey(key);
|
|
43
|
+
if (node === null)
|
|
44
|
+
return false;
|
|
45
|
+
return node.isSelected();
|
|
46
|
+
}
|
|
47
|
+
function useIsNodeSelected(key) {
|
|
48
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
49
|
+
const subscribe = React.useCallback(
|
|
50
|
+
(onStoreChange) => {
|
|
51
|
+
return editor.registerUpdateListener(onStoreChange);
|
|
52
|
+
},
|
|
53
|
+
[editor]
|
|
54
|
+
);
|
|
55
|
+
const getSnapshot = React.useCallback(() => {
|
|
56
|
+
return editor.getEditorState().read(() => $isNodeSelected(key));
|
|
57
|
+
}, [editor, key]);
|
|
58
|
+
return index_js.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
exports.Mention = Mention;
|
|
62
|
+
exports.MentionWrapper = MentionWrapper;
|
|
63
|
+
//# sourceMappingURL=mention-component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mention-component.js","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 { HTMLAttributes, ReactNode } from \"react\";\nimport React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n\nconst IsSelectedContext = createContext<boolean | null>(null);\n\nexport function MentionWrapper({\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: React.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 <IsSelectedContext.Provider value={isSelected}>\n <span onClick={handleClick}>{children}</span>\n </IsSelectedContext.Provider>\n );\n}\n\nexport const Mention = forwardRef<\n HTMLSpanElement,\n HTMLAttributes<HTMLSpanElement>\n>(function (props, forwardedRef) {\n const isSelected = useContext(IsSelectedContext);\n if (isSelected === null) {\n throw new Error(\"Mention component must be wrapped in MentionWrapper\");\n }\n\n return (\n <span\n data-selected={isSelected ? \"\" : undefined}\n {...props}\n ref={forwardedRef}\n >\n {props.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":["createContext","useLexicalComposerContext","$createNodeSelection","$setSelection","forwardRef","useContext","$getNodeByKey","useCallback","useSyncExternalStore"],"mappings":";;;;;;;AAYA,MAAM,iBAAA,GAAoBA,oBAA8B,IAAI,CAAA,CAAA;AAErD,SAAS,cAAe,CAAA;AAAA,EAC7B,OAAA;AAAA,EACA,QAAA;AACF,CAGG,EAAA;AACD,EAAM,MAAA,CAAC,MAAM,CAAA,GAAIC,gDAA0B,EAAA,CAAA;AAC3C,EAAM,MAAA,UAAA,GAAa,kBAAkB,OAAO,CAAA,CAAA;AAE5C,EAAA,SAAS,YAAY,KAAyB,EAAA;AAC5C,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,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,kBAAkB,QAAlB,EAAA;AAAA,IAA2B,KAAO,EAAA,UAAA;AAAA,GAAA,kBAChC,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IAAK,OAAS,EAAA,WAAA;AAAA,GAAA,EAAc,QAAS,CACxC,CAAA,CAAA;AAEJ,CAAA;AAEO,MAAM,OAAU,GAAAC,gBAAA,CAGrB,SAAU,KAAA,EAAO,YAAc,EAAA;AAC/B,EAAM,MAAA,UAAA,GAAaC,iBAAW,iBAAiB,CAAA,CAAA;AAC/C,EAAA,IAAI,eAAe,IAAM,EAAA;AACvB,IAAM,MAAA,IAAI,MAAM,qDAAqD,CAAA,CAAA;AAAA,GACvE;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IACC,eAAA,EAAe,aAAa,EAAK,GAAA,KAAA,CAAA;AAAA,IAChC,GAAG,KAAA;AAAA,IACJ,GAAK,EAAA,YAAA;AAAA,GAAA,EAEJ,MAAM,QACT,CAAA,CAAA;AAEJ,CAAC,EAAA;AAED,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,GAAIL,gDAA0B,EAAA,CAAA;AAE3C,EAAA,MAAM,SAAY,GAAAM,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,6BAAA,CAAqB,SAAW,EAAA,WAAA,EAAa,WAAW,CAAA,CAAA;AACjE;;;;;"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
2
|
+
import { $createNodeSelection, $setSelection, $getNodeByKey } from 'lexical';
|
|
3
|
+
import React__default, { createContext, forwardRef, useContext, useCallback } from 'react';
|
|
4
|
+
import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js';
|
|
5
|
+
|
|
6
|
+
const IsSelectedContext = createContext(null);
|
|
7
|
+
function MentionWrapper({
|
|
8
|
+
nodeKey,
|
|
9
|
+
children
|
|
10
|
+
}) {
|
|
11
|
+
const [editor] = useLexicalComposerContext();
|
|
12
|
+
const isSelected = useIsNodeSelected(nodeKey);
|
|
13
|
+
function handleClick(event) {
|
|
14
|
+
editor.update(() => {
|
|
15
|
+
event.stopPropagation();
|
|
16
|
+
event.preventDefault();
|
|
17
|
+
const selection = $createNodeSelection();
|
|
18
|
+
selection.add(nodeKey);
|
|
19
|
+
$setSelection(selection);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return /* @__PURE__ */ React__default.createElement(IsSelectedContext.Provider, {
|
|
23
|
+
value: isSelected
|
|
24
|
+
}, /* @__PURE__ */ React__default.createElement("span", {
|
|
25
|
+
onClick: handleClick
|
|
26
|
+
}, children));
|
|
27
|
+
}
|
|
28
|
+
const Mention = forwardRef(function(props, forwardedRef) {
|
|
29
|
+
const isSelected = useContext(IsSelectedContext);
|
|
30
|
+
if (isSelected === null) {
|
|
31
|
+
throw new Error("Mention component must be wrapped in MentionWrapper");
|
|
32
|
+
}
|
|
33
|
+
return /* @__PURE__ */ React__default.createElement("span", {
|
|
34
|
+
"data-selected": isSelected ? "" : void 0,
|
|
35
|
+
...props,
|
|
36
|
+
ref: forwardedRef
|
|
37
|
+
}, props.children);
|
|
38
|
+
});
|
|
39
|
+
function $isNodeSelected(key) {
|
|
40
|
+
const node = $getNodeByKey(key);
|
|
41
|
+
if (node === null)
|
|
42
|
+
return false;
|
|
43
|
+
return node.isSelected();
|
|
44
|
+
}
|
|
45
|
+
function useIsNodeSelected(key) {
|
|
46
|
+
const [editor] = useLexicalComposerContext();
|
|
47
|
+
const subscribe = useCallback(
|
|
48
|
+
(onStoreChange) => {
|
|
49
|
+
return editor.registerUpdateListener(onStoreChange);
|
|
50
|
+
},
|
|
51
|
+
[editor]
|
|
52
|
+
);
|
|
53
|
+
const getSnapshot = useCallback(() => {
|
|
54
|
+
return editor.getEditorState().read(() => $isNodeSelected(key));
|
|
55
|
+
}, [editor, key]);
|
|
56
|
+
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { Mention, MentionWrapper };
|
|
60
|
+
//# sourceMappingURL=mention-component.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mention-component.mjs","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 { HTMLAttributes, ReactNode } from \"react\";\nimport React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n\nconst IsSelectedContext = createContext<boolean | null>(null);\n\nexport function MentionWrapper({\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: React.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 <IsSelectedContext.Provider value={isSelected}>\n <span onClick={handleClick}>{children}</span>\n </IsSelectedContext.Provider>\n );\n}\n\nexport const Mention = forwardRef<\n HTMLSpanElement,\n HTMLAttributes<HTMLSpanElement>\n>(function (props, forwardedRef) {\n const isSelected = useContext(IsSelectedContext);\n if (isSelected === null) {\n throw new Error(\"Mention component must be wrapped in MentionWrapper\");\n }\n\n return (\n <span\n data-selected={isSelected ? \"\" : undefined}\n {...props}\n ref={forwardedRef}\n >\n {props.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":["React"],"mappings":";;;;;AAYA,MAAM,iBAAA,GAAoB,cAA8B,IAAI,CAAA,CAAA;AAErD,SAAS,cAAe,CAAA;AAAA,EAC7B,OAAA;AAAA,EACA,QAAA;AACF,CAGG,EAAA;AACD,EAAM,MAAA,CAAC,MAAM,CAAA,GAAI,yBAA0B,EAAA,CAAA;AAC3C,EAAM,MAAA,UAAA,GAAa,kBAAkB,OAAO,CAAA,CAAA;AAE5C,EAAA,SAAS,YAAY,KAAyB,EAAA;AAC5C,IAAA,MAAA,CAAO,OAAO,MAAM;AAClB,MAAA,KAAA,CAAM,eAAgB,EAAA,CAAA;AACtB,MAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AAErB,MAAA,MAAM,YAAY,oBAAqB,EAAA,CAAA;AACvC,MAAA,SAAA,CAAU,IAAI,OAAO,CAAA,CAAA;AACrB,MAAA,aAAA,CAAc,SAAS,CAAA,CAAA;AAAA,KACxB,CAAA,CAAA;AAAA,GACH;AAEA,EACE,uBAAAA,cAAA,CAAA,aAAA,CAAC,kBAAkB,QAAlB,EAAA;AAAA,IAA2B,KAAO,EAAA,UAAA;AAAA,GAAA,kBAChCA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IAAK,OAAS,EAAA,WAAA;AAAA,GAAA,EAAc,QAAS,CACxC,CAAA,CAAA;AAEJ,CAAA;AAEO,MAAM,OAAU,GAAA,UAAA,CAGrB,SAAU,KAAA,EAAO,YAAc,EAAA;AAC/B,EAAM,MAAA,UAAA,GAAa,WAAW,iBAAiB,CAAA,CAAA;AAC/C,EAAA,IAAI,eAAe,IAAM,EAAA;AACvB,IAAM,MAAA,IAAI,MAAM,qDAAqD,CAAA,CAAA;AAAA,GACvE;AAEA,EAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IACC,eAAA,EAAe,aAAa,EAAK,GAAA,KAAA,CAAA;AAAA,IAChC,GAAG,KAAA;AAAA,IACJ,GAAK,EAAA,YAAA;AAAA,GAAA,EAEJ,MAAM,QACT,CAAA,CAAA;AAEJ,CAAC,EAAA;AAED,SAAS,gBAAgB,GAAuB,EAAA;AAC9C,EAAM,MAAA,IAAA,GAAO,cAAc,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,GAAI,yBAA0B,EAAA,CAAA;AAE3C,EAAA,MAAM,SAAY,GAAA,WAAA;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,GAAc,YAAY,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,OAAA,oBAAA,CAAqB,SAAW,EAAA,WAAA,EAAa,WAAW,CAAA,CAAA;AACjE;;;;"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lexical = require('lexical');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var mentionComponent = require('./mention-component.js');
|
|
6
|
+
|
|
7
|
+
function _interopNamespaceDefault(e) {
|
|
8
|
+
var n = Object.create(null);
|
|
9
|
+
if (e) {
|
|
10
|
+
Object.keys(e).forEach(function (k) {
|
|
11
|
+
if (k !== 'default') {
|
|
12
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return e[k]; }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
25
|
+
|
|
26
|
+
function createMentionNodeFactory(Component) {
|
|
27
|
+
class MentionNode extends lexical.DecoratorNode {
|
|
28
|
+
constructor(value, key) {
|
|
29
|
+
super(key);
|
|
30
|
+
this.__id = value;
|
|
31
|
+
}
|
|
32
|
+
static getType() {
|
|
33
|
+
return "lb-mention";
|
|
34
|
+
}
|
|
35
|
+
static clone(node) {
|
|
36
|
+
return new MentionNode(node.__id);
|
|
37
|
+
}
|
|
38
|
+
createDOM() {
|
|
39
|
+
const element = document.createElement("span");
|
|
40
|
+
element.style.display = "inline-block";
|
|
41
|
+
return element;
|
|
42
|
+
}
|
|
43
|
+
updateDOM() {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
static importDom() {
|
|
47
|
+
return {
|
|
48
|
+
span: () => ({
|
|
49
|
+
conversion: (element) => {
|
|
50
|
+
const value = atob(
|
|
51
|
+
element.getAttribute("data-lexical-lb-mention")
|
|
52
|
+
);
|
|
53
|
+
const node = $createMentionNode(value);
|
|
54
|
+
return { node };
|
|
55
|
+
},
|
|
56
|
+
priority: 1
|
|
57
|
+
})
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
exportDOM() {
|
|
61
|
+
const element = document.createElement("span");
|
|
62
|
+
const value = this.getTextContent();
|
|
63
|
+
element.setAttribute("data-lexical-lb-mention", btoa(value));
|
|
64
|
+
element.textContent = this.getTextContent();
|
|
65
|
+
return { element };
|
|
66
|
+
}
|
|
67
|
+
static importJSON(serializedNode) {
|
|
68
|
+
const node = $createMentionNode(serializedNode.value);
|
|
69
|
+
return node;
|
|
70
|
+
}
|
|
71
|
+
exportJSON() {
|
|
72
|
+
return {
|
|
73
|
+
value: this.getTextContent(),
|
|
74
|
+
type: "lb-mention",
|
|
75
|
+
version: 1
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
getTextContent() {
|
|
79
|
+
const self = this.getLatest();
|
|
80
|
+
return self.__id;
|
|
81
|
+
}
|
|
82
|
+
decorate() {
|
|
83
|
+
return /* @__PURE__ */ React__namespace.createElement(mentionComponent.MentionWrapper, {
|
|
84
|
+
nodeKey: this.getKey()
|
|
85
|
+
}, /* @__PURE__ */ React__namespace.createElement(Component, {
|
|
86
|
+
userId: this.__id
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function $isMentionNode(node) {
|
|
91
|
+
return node instanceof MentionNode;
|
|
92
|
+
}
|
|
93
|
+
function $createMentionNode(id) {
|
|
94
|
+
const node = new MentionNode(id);
|
|
95
|
+
return lexical.$applyNodeReplacement(node);
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
MentionNode,
|
|
99
|
+
$isMentionNode,
|
|
100
|
+
$createMentionNode
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
exports.createMentionNodeFactory = createMentionNodeFactory;
|
|
105
|
+
//# sourceMappingURL=mention-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mention-node.js","sources":["../../src/mentions/mention-node.tsx"],"sourcesContent":["import type {\n DOMConversionMap,\n DOMExportOutput,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\nimport type { ComponentType, JSX } from \"react\";\nimport * as React from \"react\";\n\nimport type { MentionProps } from \"../liveblocks-config\";\nimport { MentionWrapper } from \"./mention-component\";\n\nexport type SerializedMentionNode = Spread<\n {\n value: string;\n },\n SerializedLexicalNode\n>;\n\nexport function createMentionNodeFactory(\n Component: ComponentType<MentionProps>\n): any {\n class MentionNode extends DecoratorNode<JSX.Element> {\n __id: string;\n\n constructor(value: string, key?: NodeKey) {\n super(key);\n this.__id = value;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id);\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n element.style.display = \"inline-block\";\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 value = atob(\n element.getAttribute(\"data-lexical-lb-mention\")!\n );\n const node = $createMentionNode(value);\n return { node };\n },\n priority: 1,\n }),\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"span\");\n const value = this.getTextContent();\n element.setAttribute(\"data-lexical-lb-mention\", btoa(value));\n element.textContent = this.getTextContent();\n return { element };\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = $createMentionNode(serializedNode.value);\n return node;\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n value: this.getTextContent(),\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getTextContent(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): JSX.Element {\n return (\n <MentionWrapper nodeKey={this.getKey()}>\n <Component userId={this.__id} />\n </MentionWrapper>\n );\n }\n }\n\n function $isMentionNode(\n node: LexicalNode | null | undefined\n ): node is MentionNode {\n return node instanceof MentionNode;\n }\n\n function $createMentionNode(id: string): MentionNode {\n const node = new MentionNode(id);\n return $applyNodeReplacement(node);\n }\n\n return {\n MentionNode,\n $isMentionNode,\n $createMentionNode,\n };\n}\n"],"names":["DecoratorNode","React","MentionWrapper","$applyNodeReplacement"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAsBO,SAAS,yBACd,SACK,EAAA;AACL,EAAA,MAAM,oBAAoBA,qBAA2B,CAAA;AAAA,IAGnD,WAAA,CAAY,OAAe,GAAe,EAAA;AACxC,MAAA,KAAA,CAAM,GAAG,CAAA,CAAA;AACT,MAAA,IAAA,CAAK,IAAO,GAAA,KAAA,CAAA;AAAA,KACd;AAAA,IAEA,OAAO,OAAkB,GAAA;AACvB,MAAO,OAAA,YAAA,CAAA;AAAA,KACT;AAAA,IAEA,OAAO,MAAM,IAAgC,EAAA;AAC3C,MAAO,OAAA,IAAI,WAAY,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AAAA,KAClC;AAAA,IAEA,SAAyB,GAAA;AACvB,MAAM,MAAA,OAAA,GAAU,QAAS,CAAA,aAAA,CAAc,MAAM,CAAA,CAAA;AAC7C,MAAA,OAAA,CAAQ,MAAM,OAAU,GAAA,cAAA,CAAA;AACxB,MAAO,OAAA,OAAA,CAAA;AAAA,KACT;AAAA,IAEA,SAAqB,GAAA;AACnB,MAAO,OAAA,KAAA,CAAA;AAAA,KACT;AAAA,IAEA,OAAO,SAAkD,GAAA;AACvD,MAAO,OAAA;AAAA,QACL,MAAM,OAAO;AAAA,UACX,UAAA,EAAY,CAAC,OAAY,KAAA;AACvB,YAAA,MAAM,KAAQ,GAAA,IAAA;AAAA,cACZ,OAAA,CAAQ,aAAa,yBAAyB,CAAA;AAAA,aAChD,CAAA;AACA,YAAM,MAAA,IAAA,GAAO,mBAAmB,KAAK,CAAA,CAAA;AACrC,YAAA,OAAO,EAAE,IAAK,EAAA,CAAA;AAAA,WAChB;AAAA,UACA,QAAU,EAAA,CAAA;AAAA,SACZ,CAAA;AAAA,OACF,CAAA;AAAA,KACF;AAAA,IAEA,SAA6B,GAAA;AAC3B,MAAM,MAAA,OAAA,GAAU,QAAS,CAAA,aAAA,CAAc,MAAM,CAAA,CAAA;AAC7C,MAAM,MAAA,KAAA,GAAQ,KAAK,cAAe,EAAA,CAAA;AAClC,MAAA,OAAA,CAAQ,YAAa,CAAA,yBAAA,EAA2B,IAAK,CAAA,KAAK,CAAC,CAAA,CAAA;AAC3D,MAAQ,OAAA,CAAA,WAAA,GAAc,KAAK,cAAe,EAAA,CAAA;AAC1C,MAAA,OAAO,EAAE,OAAQ,EAAA,CAAA;AAAA,KACnB;AAAA,IAEA,OAAO,WAAW,cAAoD,EAAA;AACpE,MAAM,MAAA,IAAA,GAAO,kBAAmB,CAAA,cAAA,CAAe,KAAK,CAAA,CAAA;AACpD,MAAO,OAAA,IAAA,CAAA;AAAA,KACT;AAAA,IAEA,UAAoC,GAAA;AAClC,MAAO,OAAA;AAAA,QACL,KAAA,EAAO,KAAK,cAAe,EAAA;AAAA,QAC3B,IAAM,EAAA,YAAA;AAAA,QACN,OAAS,EAAA,CAAA;AAAA,OACX,CAAA;AAAA,KACF;AAAA,IAEA,cAAyB,GAAA;AACvB,MAAM,MAAA,IAAA,GAAO,KAAK,SAAU,EAAA,CAAA;AAC5B,MAAA,OAAO,IAAK,CAAA,IAAA,CAAA;AAAA,KACd;AAAA,IAEA,QAAwB,GAAA;AACtB,MAAA,uBACGC,gBAAA,CAAA,aAAA,CAAAC,+BAAA,EAAA;AAAA,QAAe,OAAA,EAAS,KAAK,MAAO,EAAA;AAAA,OAAA,kBAClCD,gBAAA,CAAA,aAAA,CAAA,SAAA,EAAA;AAAA,QAAU,QAAQ,IAAK,CAAA,IAAA;AAAA,OAAM,CAChC,CAAA,CAAA;AAAA,KAEJ;AAAA,GACF;AAEA,EAAA,SAAS,eACP,IACqB,EAAA;AACrB,IAAA,OAAO,IAAgB,YAAA,WAAA,CAAA;AAAA,GACzB;AAEA,EAAA,SAAS,mBAAmB,EAAyB,EAAA;AACnD,IAAM,MAAA,IAAA,GAAO,IAAI,WAAA,CAAY,EAAE,CAAA,CAAA;AAC/B,IAAA,OAAOE,8BAAsB,IAAI,CAAA,CAAA;AAAA,GACnC;AAEA,EAAO,OAAA;AAAA,IACL,WAAA;AAAA,IACA,cAAA;AAAA,IACA,kBAAA;AAAA,GACF,CAAA;AACF;;;;"}
|