@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 @@
|
|
|
1
|
+
{"version":3,"file":"comment-plugin-provider.js","sources":["../../src/comments/comment-plugin-provider.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n addClassNamesToElement,\n registerNestedElementResolver,\n removeClassNamesFromElement,\n} from \"@lexical/utils\";\nimport { kInternal } from \"@liveblocks/core\";\nimport {\n CreateThreadError,\n useClient,\n useRoomContextBundle,\n} from \"@liveblocks/react\";\nimport type { BaseSelection, NodeKey, NodeMutation } from \"lexical\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n $setSelection,\n} from \"lexical\";\nimport type { PropsWithChildren } from \"react\";\nimport * as React from \"react\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport { ActiveSelection } from \"../active-selection\";\nimport $getThreadMarkIds from \"./get-thread-mark-ids\";\nimport {\n $createThreadMarkNode,\n $isThreadMarkNode,\n ThreadMarkNode,\n} from \"./thread-mark-node\";\nimport $unwrapThreadMarkNode from \"./unwrap-thread-mark-node\";\nimport $wrapSelectionInThreadMarkNode from \"./wrap-selection-in-thread-mark-node\";\n\ntype ThreadToNodesMap = Map<string, Set<NodeKey>>;\n\ntype ShowFloatingComposerContextType = {\n showFloatingComposer: boolean;\n setShowFloatingComposer: (show: boolean) => void;\n} | null;\nconst ShowFloatingComposerContext =\n React.createContext<ShowFloatingComposerContextType>(null);\n\nconst ShowFloatingComposerProvider = ({ children }: PropsWithChildren) => {\n const [showFloatingComposer, setShowFloatingComposer] = useState(false);\n return (\n <ShowFloatingComposerContext.Provider\n value={{\n setShowFloatingComposer,\n showFloatingComposer,\n }}\n >\n {children}\n </ShowFloatingComposerContext.Provider>\n );\n};\n\nexport function useCreateThread() {\n const context = React.useContext(ShowFloatingComposerContext);\n if (context === null) {\n throw new Error(\n \"useCreateThread must be used within a LiveblocksPluginProvider with comments enabled\"\n );\n }\n\n return () => {\n context.setShowFloatingComposer(true);\n };\n}\n\nexport function useShowFloatingComposer() {\n const context = React.useContext(ShowFloatingComposerContext);\n if (context === null) {\n throw new Error(\n \"useShowFloatingComposer must be used within a LiveblocksPluginProvider with comments enabled\"\n );\n }\n\n return context.showFloatingComposer;\n}\n\nexport function useHideFloatingComposer() {\n const context = React.useContext(ShowFloatingComposerContext);\n if (context === null) {\n throw new Error(\n \"useHideFloatingComposer must be used within a LiveblocksPluginProvider with comments enabled\"\n );\n }\n\n return () => {\n context.setShowFloatingComposer(false);\n };\n}\n\nexport function CommentPluginProvider({ children }: PropsWithChildren) {\n const [editor, context] = useLexicalComposerContext();\n\n const [threadToNodes, setThreadToNodes] = useState<ThreadToNodesMap>(\n new Map()\n ); // A map from thread id to a set of (thread mark) node keys that are associated with the thread\n\n const [activeThreads, setActiveThreads] = useState<string[]>([]); // The threads that are currently active (or selected) in the editor\n\n const [showActiveSelection, setShowActiveSelection] = useState(false);\n\n const client = useClient();\n const {\n useRoom,\n [kInternal]: {\n useCommentsErrorListener,\n ThreadCreateCallbackProvider,\n ThreadDeleteCallbackProvider,\n ComposerFocusCallbackProvider,\n IsThreadActiveCallbackProvider,\n },\n } = useRoomContextBundle();\n\n const room = useRoom();\n\n useEffect(() => {\n if (!editor.hasNodes([ThreadMarkNode])) {\n throw new Error(\n \"CommentPluginProvider: ThreadMarkNode not registered on editor\"\n );\n }\n }, [editor]);\n\n const isThreadActive = useCallback(\n (threadId: string) => {\n return activeThreads.includes(threadId);\n },\n [activeThreads]\n );\n\n /**\n * Create a new ThreadMarkNode and wrap the selected content in it.\n * @param threadId The id of the thread to associate with the selected content\n */\n const handleThreadCreate = useCallback(\n (threadId: string) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n // If the selection is collapsed, we do not create a new thread node in the editor.\n if (selection.isCollapsed()) return;\n\n const isBackward = selection.isBackward();\n // Wrap content in a ThreadMarkNode\n $wrapSelectionInThreadMarkNode(selection, isBackward, threadId);\n\n // Clear the selection after wrapping\n $setSelection(null);\n });\n },\n [editor]\n );\n\n /**\n * Remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads.\n * @param threadId The id of the thread to remove\n */\n const handleThreadDelete = useCallback(\n (threadId: string) => {\n editor.update(() => {\n // Retrieve node keys associated with the thread\n const keys = threadToNodes.get(threadId);\n if (keys === undefined) return;\n\n // Iterate over each thread node and disassociate the thread if from the node and unwrap the node if it is no longer associated with any threads\n for (const key of keys) {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n node.deleteID(threadId);\n\n if (node.getIDs().length === 0) {\n $unwrapThreadMarkNode(node);\n }\n }\n });\n },\n [editor, threadToNodes]\n );\n\n useCommentsErrorListener((error) => {\n // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n if (error instanceof CreateThreadError) {\n handleThreadDelete(error.context.threadId);\n }\n });\n\n const store = client[kInternal].cacheStore;\n\n const threads = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n useCallback(\n () =>\n client[kInternal].comments.selectedThreads(room.id, store.get(), {}),\n [client, room.id, store]\n )\n );\n\n /**\n * Only add styles to the thread mark elements that currently have threads associated with them.\n */\n useEffect(() => {\n function getThreadMarkElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of threads) {\n const keys = threadToNodes.get(thread.id);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const elements = getThreadMarkElements();\n\n const theme = context.getTheme();\n if (theme === null || theme === undefined) return;\n\n elements.forEach((element) => {\n addClassNamesToElement(element, theme.threadMark as string);\n });\n\n return () => {\n elements.forEach((element) => {\n removeClassNamesFromElement(element, theme.threadMark as string);\n });\n };\n }, [context, editor, threadToNodes, threads]);\n\n /**\n * Register a mutation listener that listens for mutations on 'ThreadMarkNode's and updates the map of thread to node keys accordingly.\n */\n useEffect(() => {\n function onMutation(mutations: Map<string, NodeMutation>) {\n const state = editor.getEditorState();\n setThreadToNodes((prev) => {\n const updatedMap = new Map(prev);\n state.read(() => {\n for (const [key, mutation] of mutations) {\n // If the node is destroyed, we remove its key from the map of thread to node keys\n if (mutation === \"destroyed\") {\n for (const [, nodes] of updatedMap) {\n nodes.delete(key);\n }\n }\n // Otherwise, if a new node is created or an existing node is updated, we update the map of thread to node keys to include the new/updated node\n else if (mutation === \"created\" || mutation === \"updated\") {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n\n const threadIds = node.getIDs();\n\n for (const id of threadIds) {\n const keys = updatedMap.get(id) ?? new Set();\n keys.add(key);\n updatedMap.set(id, keys);\n }\n }\n }\n });\n return updatedMap;\n });\n }\n\n return editor.registerMutationListener(ThreadMarkNode, onMutation);\n }, [editor]);\n\n /**\n * Register an update listener that listens for changes in the selection and updates the active threads accordingly.\n */\n useEffect(() => {\n const selectedThreads = client[kInternal].comments.selectedThreads;\n\n function $getThreadIds(selection: BaseSelection | null): string[] {\n if (selection === null) return [];\n\n if (!$isRangeSelection(selection)) return [];\n\n const anchor = selection.anchor.getNode();\n if (!$isTextNode(anchor)) return [];\n\n return $getThreadMarkIds(anchor, selection.anchor.offset) ?? [];\n }\n\n function $onStateRead() {\n const selection = $getSelection();\n\n const threadIds = $getThreadIds(selection).filter((id) => {\n return selectedThreads(room.id, store.get(), {}).some(\n (thread) => thread.id === id\n );\n });\n setActiveThreads(threadIds);\n }\n\n const unsubscribeCache = store.subscribe(() => {\n editor.getEditorState().read($onStateRead);\n });\n\n const unregisterUpdateListener = editor.registerUpdateListener(\n ({ editorState: state }) => {\n state.read($onStateRead);\n }\n );\n\n return () => {\n unregisterUpdateListener();\n unsubscribeCache();\n };\n }, [editor, client, room.id, store]);\n\n /**\n * When active threads change, we add a data-state attribute and set it to \"active\" for all HTML elements that are associated with the active threads.\n */\n useEffect(() => {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = threadToNodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n activeElements.forEach((element) => {\n element.setAttribute(\"data-state\", \"active\");\n });\n\n return () => {\n activeElements.forEach((element) => {\n element.removeAttribute(\"data-state\");\n });\n };\n }, [activeThreads, editor, threadToNodes]);\n\n useEffect(() => {\n return registerNestedElementResolver<ThreadMarkNode>(\n editor,\n ThreadMarkNode,\n (from: ThreadMarkNode) => {\n return $createThreadMarkNode(from.getIDs());\n },\n (from: ThreadMarkNode, to: ThreadMarkNode) => {\n const ids = from.getIDs();\n ids.forEach((id) => {\n to.addID(id);\n });\n }\n );\n }, [editor]);\n\n const handleComposerFocus = useCallback(\n (commentId: string | undefined, threadId: string | undefined) => {\n if (commentId === undefined && threadId === undefined) {\n setShowActiveSelection(true);\n } else {\n setShowActiveSelection(false);\n }\n },\n []\n );\n\n useEffect(() => {\n return editor.registerUpdateListener(({ editorState: state, tags }) => {\n // Ignore selection updates related to collaboration\n if (tags.has(\"collaboration\")) return;\n state.read(() => setShowActiveSelection(false));\n });\n }, [editor]);\n\n return (\n <ShowFloatingComposerProvider>\n <ThreadCreateCallbackProvider value={handleThreadCreate}>\n <ThreadDeleteCallbackProvider value={handleThreadDelete}>\n <ComposerFocusCallbackProvider value={handleComposerFocus}>\n <IsThreadActiveCallbackProvider value={isThreadActive}>\n {showActiveSelection && <ActiveSelection />}\n {children}\n </IsThreadActiveCallbackProvider>\n </ComposerFocusCallbackProvider>\n </ThreadDeleteCallbackProvider>\n </ThreadCreateCallbackProvider>\n </ShowFloatingComposerProvider>\n );\n}\n"],"names":["React","useState","useLexicalComposerContext","useClient","kInternal","useRoomContextBundle","useEffect","ThreadMarkNode","useCallback","$getSelection","$isRangeSelection","$wrapSelectionInThreadMarkNode","$setSelection","$getNodeByKey","$isThreadMarkNode","$unwrapThreadMarkNode","CreateThreadError","useSyncExternalStoreWithSelector","addClassNamesToElement","removeClassNamesFromElement","$isTextNode","$getThreadMarkIds","activeElements","registerNestedElementResolver","$createThreadMarkNode","ActiveSelection"],"mappings":"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"}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
2
|
+
import { addClassNamesToElement, removeClassNamesFromElement, registerNestedElementResolver } from '@lexical/utils';
|
|
3
|
+
import { kInternal } from '@liveblocks/core';
|
|
4
|
+
import { useClient, useRoomContextBundle, CreateThreadError } from '@liveblocks/react';
|
|
5
|
+
import { $getSelection, $isRangeSelection, $setSelection, $getNodeByKey, $isTextNode } from 'lexical';
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
8
|
+
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js';
|
|
9
|
+
import { ActiveSelection } from '../active-selection.mjs';
|
|
10
|
+
import $getThreadMarkIds from './get-thread-mark-ids.mjs';
|
|
11
|
+
import { ThreadMarkNode, $isThreadMarkNode, $createThreadMarkNode } from './thread-mark-node.mjs';
|
|
12
|
+
import $unwrapThreadMarkNode from './unwrap-thread-mark-node.mjs';
|
|
13
|
+
import $wrapSelectionInThreadMarkNode from './wrap-selection-in-thread-mark-node.mjs';
|
|
14
|
+
|
|
15
|
+
const ShowFloatingComposerContext = React.createContext(null);
|
|
16
|
+
const ShowFloatingComposerProvider = ({ children }) => {
|
|
17
|
+
const [showFloatingComposer, setShowFloatingComposer] = useState(false);
|
|
18
|
+
return /* @__PURE__ */ React.createElement(ShowFloatingComposerContext.Provider, {
|
|
19
|
+
value: {
|
|
20
|
+
setShowFloatingComposer,
|
|
21
|
+
showFloatingComposer
|
|
22
|
+
}
|
|
23
|
+
}, children);
|
|
24
|
+
};
|
|
25
|
+
function useCreateThread() {
|
|
26
|
+
const context = React.useContext(ShowFloatingComposerContext);
|
|
27
|
+
if (context === null) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
"useCreateThread must be used within a LiveblocksPluginProvider with comments enabled"
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
return () => {
|
|
33
|
+
context.setShowFloatingComposer(true);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function useShowFloatingComposer() {
|
|
37
|
+
const context = React.useContext(ShowFloatingComposerContext);
|
|
38
|
+
if (context === null) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
"useShowFloatingComposer must be used within a LiveblocksPluginProvider with comments enabled"
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return context.showFloatingComposer;
|
|
44
|
+
}
|
|
45
|
+
function useHideFloatingComposer() {
|
|
46
|
+
const context = React.useContext(ShowFloatingComposerContext);
|
|
47
|
+
if (context === null) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
"useHideFloatingComposer must be used within a LiveblocksPluginProvider with comments enabled"
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return () => {
|
|
53
|
+
context.setShowFloatingComposer(false);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function CommentPluginProvider({ children }) {
|
|
57
|
+
const [editor, context] = useLexicalComposerContext();
|
|
58
|
+
const [threadToNodes, setThreadToNodes] = useState(
|
|
59
|
+
/* @__PURE__ */ new Map()
|
|
60
|
+
);
|
|
61
|
+
const [activeThreads, setActiveThreads] = useState([]);
|
|
62
|
+
const [showActiveSelection, setShowActiveSelection] = useState(false);
|
|
63
|
+
const client = useClient();
|
|
64
|
+
const {
|
|
65
|
+
useRoom,
|
|
66
|
+
[kInternal]: {
|
|
67
|
+
useCommentsErrorListener,
|
|
68
|
+
ThreadCreateCallbackProvider,
|
|
69
|
+
ThreadDeleteCallbackProvider,
|
|
70
|
+
ComposerFocusCallbackProvider,
|
|
71
|
+
IsThreadActiveCallbackProvider
|
|
72
|
+
}
|
|
73
|
+
} = useRoomContextBundle();
|
|
74
|
+
const room = useRoom();
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (!editor.hasNodes([ThreadMarkNode])) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
"CommentPluginProvider: ThreadMarkNode not registered on editor"
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
}, [editor]);
|
|
82
|
+
const isThreadActive = useCallback(
|
|
83
|
+
(threadId) => {
|
|
84
|
+
return activeThreads.includes(threadId);
|
|
85
|
+
},
|
|
86
|
+
[activeThreads]
|
|
87
|
+
);
|
|
88
|
+
const handleThreadCreate = useCallback(
|
|
89
|
+
(threadId) => {
|
|
90
|
+
editor.update(() => {
|
|
91
|
+
const selection = $getSelection();
|
|
92
|
+
if (!$isRangeSelection(selection))
|
|
93
|
+
return;
|
|
94
|
+
if (selection.isCollapsed())
|
|
95
|
+
return;
|
|
96
|
+
const isBackward = selection.isBackward();
|
|
97
|
+
$wrapSelectionInThreadMarkNode(selection, isBackward, threadId);
|
|
98
|
+
$setSelection(null);
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
[editor]
|
|
102
|
+
);
|
|
103
|
+
const handleThreadDelete = useCallback(
|
|
104
|
+
(threadId) => {
|
|
105
|
+
editor.update(() => {
|
|
106
|
+
const keys = threadToNodes.get(threadId);
|
|
107
|
+
if (keys === void 0)
|
|
108
|
+
return;
|
|
109
|
+
for (const key of keys) {
|
|
110
|
+
const node = $getNodeByKey(key);
|
|
111
|
+
if (!$isThreadMarkNode(node))
|
|
112
|
+
continue;
|
|
113
|
+
node.deleteID(threadId);
|
|
114
|
+
if (node.getIDs().length === 0) {
|
|
115
|
+
$unwrapThreadMarkNode(node);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
},
|
|
120
|
+
[editor, threadToNodes]
|
|
121
|
+
);
|
|
122
|
+
useCommentsErrorListener((error) => {
|
|
123
|
+
if (error instanceof CreateThreadError) {
|
|
124
|
+
handleThreadDelete(error.context.threadId);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
const store = client[kInternal].cacheStore;
|
|
128
|
+
const threads = useSyncExternalStoreWithSelector(
|
|
129
|
+
store.subscribe,
|
|
130
|
+
store.get,
|
|
131
|
+
store.get,
|
|
132
|
+
useCallback(
|
|
133
|
+
() => client[kInternal].comments.selectedThreads(room.id, store.get(), {}),
|
|
134
|
+
[client, room.id, store]
|
|
135
|
+
)
|
|
136
|
+
);
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
function getThreadMarkElements() {
|
|
139
|
+
const activeElements = /* @__PURE__ */ new Set();
|
|
140
|
+
for (const thread of threads) {
|
|
141
|
+
const keys = threadToNodes.get(thread.id);
|
|
142
|
+
if (keys === void 0)
|
|
143
|
+
continue;
|
|
144
|
+
for (const key of keys) {
|
|
145
|
+
const element = editor.getElementByKey(key);
|
|
146
|
+
if (element === null)
|
|
147
|
+
continue;
|
|
148
|
+
activeElements.add(element);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return activeElements;
|
|
152
|
+
}
|
|
153
|
+
const elements = getThreadMarkElements();
|
|
154
|
+
const theme = context.getTheme();
|
|
155
|
+
if (theme === null || theme === void 0)
|
|
156
|
+
return;
|
|
157
|
+
elements.forEach((element) => {
|
|
158
|
+
addClassNamesToElement(element, theme.threadMark);
|
|
159
|
+
});
|
|
160
|
+
return () => {
|
|
161
|
+
elements.forEach((element) => {
|
|
162
|
+
removeClassNamesFromElement(element, theme.threadMark);
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
}, [context, editor, threadToNodes, threads]);
|
|
166
|
+
useEffect(() => {
|
|
167
|
+
function onMutation(mutations) {
|
|
168
|
+
const state = editor.getEditorState();
|
|
169
|
+
setThreadToNodes((prev) => {
|
|
170
|
+
const updatedMap = new Map(prev);
|
|
171
|
+
state.read(() => {
|
|
172
|
+
for (const [key, mutation] of mutations) {
|
|
173
|
+
if (mutation === "destroyed") {
|
|
174
|
+
for (const [, nodes] of updatedMap) {
|
|
175
|
+
nodes.delete(key);
|
|
176
|
+
}
|
|
177
|
+
} else if (mutation === "created" || mutation === "updated") {
|
|
178
|
+
const node = $getNodeByKey(key);
|
|
179
|
+
if (!$isThreadMarkNode(node))
|
|
180
|
+
continue;
|
|
181
|
+
const threadIds = node.getIDs();
|
|
182
|
+
for (const id of threadIds) {
|
|
183
|
+
const keys = updatedMap.get(id) ?? /* @__PURE__ */ new Set();
|
|
184
|
+
keys.add(key);
|
|
185
|
+
updatedMap.set(id, keys);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
return updatedMap;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return editor.registerMutationListener(ThreadMarkNode, onMutation);
|
|
194
|
+
}, [editor]);
|
|
195
|
+
useEffect(() => {
|
|
196
|
+
const selectedThreads = client[kInternal].comments.selectedThreads;
|
|
197
|
+
function $getThreadIds(selection) {
|
|
198
|
+
if (selection === null)
|
|
199
|
+
return [];
|
|
200
|
+
if (!$isRangeSelection(selection))
|
|
201
|
+
return [];
|
|
202
|
+
const anchor = selection.anchor.getNode();
|
|
203
|
+
if (!$isTextNode(anchor))
|
|
204
|
+
return [];
|
|
205
|
+
return $getThreadMarkIds(anchor, selection.anchor.offset) ?? [];
|
|
206
|
+
}
|
|
207
|
+
function $onStateRead() {
|
|
208
|
+
const selection = $getSelection();
|
|
209
|
+
const threadIds = $getThreadIds(selection).filter((id) => {
|
|
210
|
+
return selectedThreads(room.id, store.get(), {}).some(
|
|
211
|
+
(thread) => thread.id === id
|
|
212
|
+
);
|
|
213
|
+
});
|
|
214
|
+
setActiveThreads(threadIds);
|
|
215
|
+
}
|
|
216
|
+
const unsubscribeCache = store.subscribe(() => {
|
|
217
|
+
editor.getEditorState().read($onStateRead);
|
|
218
|
+
});
|
|
219
|
+
const unregisterUpdateListener = editor.registerUpdateListener(
|
|
220
|
+
({ editorState: state }) => {
|
|
221
|
+
state.read($onStateRead);
|
|
222
|
+
}
|
|
223
|
+
);
|
|
224
|
+
return () => {
|
|
225
|
+
unregisterUpdateListener();
|
|
226
|
+
unsubscribeCache();
|
|
227
|
+
};
|
|
228
|
+
}, [editor, client, room.id, store]);
|
|
229
|
+
useEffect(() => {
|
|
230
|
+
function getActiveElements() {
|
|
231
|
+
const activeElements2 = /* @__PURE__ */ new Set();
|
|
232
|
+
for (const thread of activeThreads) {
|
|
233
|
+
const keys = threadToNodes.get(thread);
|
|
234
|
+
if (keys === void 0)
|
|
235
|
+
continue;
|
|
236
|
+
for (const key of keys) {
|
|
237
|
+
const element = editor.getElementByKey(key);
|
|
238
|
+
if (element === null)
|
|
239
|
+
continue;
|
|
240
|
+
activeElements2.add(element);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return activeElements2;
|
|
244
|
+
}
|
|
245
|
+
const activeElements = getActiveElements();
|
|
246
|
+
activeElements.forEach((element) => {
|
|
247
|
+
element.setAttribute("data-state", "active");
|
|
248
|
+
});
|
|
249
|
+
return () => {
|
|
250
|
+
activeElements.forEach((element) => {
|
|
251
|
+
element.removeAttribute("data-state");
|
|
252
|
+
});
|
|
253
|
+
};
|
|
254
|
+
}, [activeThreads, editor, threadToNodes]);
|
|
255
|
+
useEffect(() => {
|
|
256
|
+
return registerNestedElementResolver(
|
|
257
|
+
editor,
|
|
258
|
+
ThreadMarkNode,
|
|
259
|
+
(from) => {
|
|
260
|
+
return $createThreadMarkNode(from.getIDs());
|
|
261
|
+
},
|
|
262
|
+
(from, to) => {
|
|
263
|
+
const ids = from.getIDs();
|
|
264
|
+
ids.forEach((id) => {
|
|
265
|
+
to.addID(id);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
);
|
|
269
|
+
}, [editor]);
|
|
270
|
+
const handleComposerFocus = useCallback(
|
|
271
|
+
(commentId, threadId) => {
|
|
272
|
+
if (commentId === void 0 && threadId === void 0) {
|
|
273
|
+
setShowActiveSelection(true);
|
|
274
|
+
} else {
|
|
275
|
+
setShowActiveSelection(false);
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
[]
|
|
279
|
+
);
|
|
280
|
+
useEffect(() => {
|
|
281
|
+
return editor.registerUpdateListener(({ editorState: state, tags }) => {
|
|
282
|
+
if (tags.has("collaboration"))
|
|
283
|
+
return;
|
|
284
|
+
state.read(() => setShowActiveSelection(false));
|
|
285
|
+
});
|
|
286
|
+
}, [editor]);
|
|
287
|
+
return /* @__PURE__ */ React.createElement(ShowFloatingComposerProvider, null, /* @__PURE__ */ React.createElement(ThreadCreateCallbackProvider, {
|
|
288
|
+
value: handleThreadCreate
|
|
289
|
+
}, /* @__PURE__ */ React.createElement(ThreadDeleteCallbackProvider, {
|
|
290
|
+
value: handleThreadDelete
|
|
291
|
+
}, /* @__PURE__ */ React.createElement(ComposerFocusCallbackProvider, {
|
|
292
|
+
value: handleComposerFocus
|
|
293
|
+
}, /* @__PURE__ */ React.createElement(IsThreadActiveCallbackProvider, {
|
|
294
|
+
value: isThreadActive
|
|
295
|
+
}, showActiveSelection && /* @__PURE__ */ React.createElement(ActiveSelection, null), children)))));
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export { CommentPluginProvider, useCreateThread, useHideFloatingComposer, useShowFloatingComposer };
|
|
299
|
+
//# sourceMappingURL=comment-plugin-provider.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-plugin-provider.mjs","sources":["../../src/comments/comment-plugin-provider.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n addClassNamesToElement,\n registerNestedElementResolver,\n removeClassNamesFromElement,\n} from \"@lexical/utils\";\nimport { kInternal } from \"@liveblocks/core\";\nimport {\n CreateThreadError,\n useClient,\n useRoomContextBundle,\n} from \"@liveblocks/react\";\nimport type { BaseSelection, NodeKey, NodeMutation } from \"lexical\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n $setSelection,\n} from \"lexical\";\nimport type { PropsWithChildren } from \"react\";\nimport * as React from \"react\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport { ActiveSelection } from \"../active-selection\";\nimport $getThreadMarkIds from \"./get-thread-mark-ids\";\nimport {\n $createThreadMarkNode,\n $isThreadMarkNode,\n ThreadMarkNode,\n} from \"./thread-mark-node\";\nimport $unwrapThreadMarkNode from \"./unwrap-thread-mark-node\";\nimport $wrapSelectionInThreadMarkNode from \"./wrap-selection-in-thread-mark-node\";\n\ntype ThreadToNodesMap = Map<string, Set<NodeKey>>;\n\ntype ShowFloatingComposerContextType = {\n showFloatingComposer: boolean;\n setShowFloatingComposer: (show: boolean) => void;\n} | null;\nconst ShowFloatingComposerContext =\n React.createContext<ShowFloatingComposerContextType>(null);\n\nconst ShowFloatingComposerProvider = ({ children }: PropsWithChildren) => {\n const [showFloatingComposer, setShowFloatingComposer] = useState(false);\n return (\n <ShowFloatingComposerContext.Provider\n value={{\n setShowFloatingComposer,\n showFloatingComposer,\n }}\n >\n {children}\n </ShowFloatingComposerContext.Provider>\n );\n};\n\nexport function useCreateThread() {\n const context = React.useContext(ShowFloatingComposerContext);\n if (context === null) {\n throw new Error(\n \"useCreateThread must be used within a LiveblocksPluginProvider with comments enabled\"\n );\n }\n\n return () => {\n context.setShowFloatingComposer(true);\n };\n}\n\nexport function useShowFloatingComposer() {\n const context = React.useContext(ShowFloatingComposerContext);\n if (context === null) {\n throw new Error(\n \"useShowFloatingComposer must be used within a LiveblocksPluginProvider with comments enabled\"\n );\n }\n\n return context.showFloatingComposer;\n}\n\nexport function useHideFloatingComposer() {\n const context = React.useContext(ShowFloatingComposerContext);\n if (context === null) {\n throw new Error(\n \"useHideFloatingComposer must be used within a LiveblocksPluginProvider with comments enabled\"\n );\n }\n\n return () => {\n context.setShowFloatingComposer(false);\n };\n}\n\nexport function CommentPluginProvider({ children }: PropsWithChildren) {\n const [editor, context] = useLexicalComposerContext();\n\n const [threadToNodes, setThreadToNodes] = useState<ThreadToNodesMap>(\n new Map()\n ); // A map from thread id to a set of (thread mark) node keys that are associated with the thread\n\n const [activeThreads, setActiveThreads] = useState<string[]>([]); // The threads that are currently active (or selected) in the editor\n\n const [showActiveSelection, setShowActiveSelection] = useState(false);\n\n const client = useClient();\n const {\n useRoom,\n [kInternal]: {\n useCommentsErrorListener,\n ThreadCreateCallbackProvider,\n ThreadDeleteCallbackProvider,\n ComposerFocusCallbackProvider,\n IsThreadActiveCallbackProvider,\n },\n } = useRoomContextBundle();\n\n const room = useRoom();\n\n useEffect(() => {\n if (!editor.hasNodes([ThreadMarkNode])) {\n throw new Error(\n \"CommentPluginProvider: ThreadMarkNode not registered on editor\"\n );\n }\n }, [editor]);\n\n const isThreadActive = useCallback(\n (threadId: string) => {\n return activeThreads.includes(threadId);\n },\n [activeThreads]\n );\n\n /**\n * Create a new ThreadMarkNode and wrap the selected content in it.\n * @param threadId The id of the thread to associate with the selected content\n */\n const handleThreadCreate = useCallback(\n (threadId: string) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n // If the selection is collapsed, we do not create a new thread node in the editor.\n if (selection.isCollapsed()) return;\n\n const isBackward = selection.isBackward();\n // Wrap content in a ThreadMarkNode\n $wrapSelectionInThreadMarkNode(selection, isBackward, threadId);\n\n // Clear the selection after wrapping\n $setSelection(null);\n });\n },\n [editor]\n );\n\n /**\n * Remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads.\n * @param threadId The id of the thread to remove\n */\n const handleThreadDelete = useCallback(\n (threadId: string) => {\n editor.update(() => {\n // Retrieve node keys associated with the thread\n const keys = threadToNodes.get(threadId);\n if (keys === undefined) return;\n\n // Iterate over each thread node and disassociate the thread if from the node and unwrap the node if it is no longer associated with any threads\n for (const key of keys) {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n node.deleteID(threadId);\n\n if (node.getIDs().length === 0) {\n $unwrapThreadMarkNode(node);\n }\n }\n });\n },\n [editor, threadToNodes]\n );\n\n useCommentsErrorListener((error) => {\n // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n if (error instanceof CreateThreadError) {\n handleThreadDelete(error.context.threadId);\n }\n });\n\n const store = client[kInternal].cacheStore;\n\n const threads = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n useCallback(\n () =>\n client[kInternal].comments.selectedThreads(room.id, store.get(), {}),\n [client, room.id, store]\n )\n );\n\n /**\n * Only add styles to the thread mark elements that currently have threads associated with them.\n */\n useEffect(() => {\n function getThreadMarkElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of threads) {\n const keys = threadToNodes.get(thread.id);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const elements = getThreadMarkElements();\n\n const theme = context.getTheme();\n if (theme === null || theme === undefined) return;\n\n elements.forEach((element) => {\n addClassNamesToElement(element, theme.threadMark as string);\n });\n\n return () => {\n elements.forEach((element) => {\n removeClassNamesFromElement(element, theme.threadMark as string);\n });\n };\n }, [context, editor, threadToNodes, threads]);\n\n /**\n * Register a mutation listener that listens for mutations on 'ThreadMarkNode's and updates the map of thread to node keys accordingly.\n */\n useEffect(() => {\n function onMutation(mutations: Map<string, NodeMutation>) {\n const state = editor.getEditorState();\n setThreadToNodes((prev) => {\n const updatedMap = new Map(prev);\n state.read(() => {\n for (const [key, mutation] of mutations) {\n // If the node is destroyed, we remove its key from the map of thread to node keys\n if (mutation === \"destroyed\") {\n for (const [, nodes] of updatedMap) {\n nodes.delete(key);\n }\n }\n // Otherwise, if a new node is created or an existing node is updated, we update the map of thread to node keys to include the new/updated node\n else if (mutation === \"created\" || mutation === \"updated\") {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n\n const threadIds = node.getIDs();\n\n for (const id of threadIds) {\n const keys = updatedMap.get(id) ?? new Set();\n keys.add(key);\n updatedMap.set(id, keys);\n }\n }\n }\n });\n return updatedMap;\n });\n }\n\n return editor.registerMutationListener(ThreadMarkNode, onMutation);\n }, [editor]);\n\n /**\n * Register an update listener that listens for changes in the selection and updates the active threads accordingly.\n */\n useEffect(() => {\n const selectedThreads = client[kInternal].comments.selectedThreads;\n\n function $getThreadIds(selection: BaseSelection | null): string[] {\n if (selection === null) return [];\n\n if (!$isRangeSelection(selection)) return [];\n\n const anchor = selection.anchor.getNode();\n if (!$isTextNode(anchor)) return [];\n\n return $getThreadMarkIds(anchor, selection.anchor.offset) ?? [];\n }\n\n function $onStateRead() {\n const selection = $getSelection();\n\n const threadIds = $getThreadIds(selection).filter((id) => {\n return selectedThreads(room.id, store.get(), {}).some(\n (thread) => thread.id === id\n );\n });\n setActiveThreads(threadIds);\n }\n\n const unsubscribeCache = store.subscribe(() => {\n editor.getEditorState().read($onStateRead);\n });\n\n const unregisterUpdateListener = editor.registerUpdateListener(\n ({ editorState: state }) => {\n state.read($onStateRead);\n }\n );\n\n return () => {\n unregisterUpdateListener();\n unsubscribeCache();\n };\n }, [editor, client, room.id, store]);\n\n /**\n * When active threads change, we add a data-state attribute and set it to \"active\" for all HTML elements that are associated with the active threads.\n */\n useEffect(() => {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = threadToNodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n activeElements.forEach((element) => {\n element.setAttribute(\"data-state\", \"active\");\n });\n\n return () => {\n activeElements.forEach((element) => {\n element.removeAttribute(\"data-state\");\n });\n };\n }, [activeThreads, editor, threadToNodes]);\n\n useEffect(() => {\n return registerNestedElementResolver<ThreadMarkNode>(\n editor,\n ThreadMarkNode,\n (from: ThreadMarkNode) => {\n return $createThreadMarkNode(from.getIDs());\n },\n (from: ThreadMarkNode, to: ThreadMarkNode) => {\n const ids = from.getIDs();\n ids.forEach((id) => {\n to.addID(id);\n });\n }\n );\n }, [editor]);\n\n const handleComposerFocus = useCallback(\n (commentId: string | undefined, threadId: string | undefined) => {\n if (commentId === undefined && threadId === undefined) {\n setShowActiveSelection(true);\n } else {\n setShowActiveSelection(false);\n }\n },\n []\n );\n\n useEffect(() => {\n return editor.registerUpdateListener(({ editorState: state, tags }) => {\n // Ignore selection updates related to collaboration\n if (tags.has(\"collaboration\")) return;\n state.read(() => setShowActiveSelection(false));\n });\n }, [editor]);\n\n return (\n <ShowFloatingComposerProvider>\n <ThreadCreateCallbackProvider value={handleThreadCreate}>\n <ThreadDeleteCallbackProvider value={handleThreadDelete}>\n <ComposerFocusCallbackProvider value={handleComposerFocus}>\n <IsThreadActiveCallbackProvider value={isThreadActive}>\n {showActiveSelection && <ActiveSelection />}\n {children}\n </IsThreadActiveCallbackProvider>\n </ComposerFocusCallbackProvider>\n </ThreadDeleteCallbackProvider>\n </ThreadCreateCallbackProvider>\n </ShowFloatingComposerProvider>\n );\n}\n"],"names":["activeElements"],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var reactComments = require('@liveblocks/react-comments');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var floatingSelectionContainer = require('../floating-selection-container.js');
|
|
6
|
+
var commentPluginProvider = require('./comment-plugin-provider.js');
|
|
7
|
+
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
8
|
+
|
|
9
|
+
const FloatingComposer = React.forwardRef(function FloatingComposer2(props, forwardedRef) {
|
|
10
|
+
const shouldShowFloatingComposer = commentPluginProvider.useShowFloatingComposer();
|
|
11
|
+
const hideFloatingComposer = commentPluginProvider.useHideFloatingComposer();
|
|
12
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
13
|
+
if (!shouldShowFloatingComposer)
|
|
14
|
+
return null;
|
|
15
|
+
function handleKeyDown(event) {
|
|
16
|
+
if (event.key === "Escape") {
|
|
17
|
+
hideFloatingComposer();
|
|
18
|
+
editor.focus();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return /* @__PURE__ */ React.createElement(floatingSelectionContainer.FloatingSelectionContainer, {
|
|
22
|
+
sideOffset: 5,
|
|
23
|
+
alignOffset: 0,
|
|
24
|
+
collisionPadding: 5
|
|
25
|
+
}, /* @__PURE__ */ React.createElement(reactComments.Composer, {
|
|
26
|
+
autoFocus: true,
|
|
27
|
+
onKeyDown: handleKeyDown,
|
|
28
|
+
...props,
|
|
29
|
+
ref: forwardedRef
|
|
30
|
+
}));
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
exports.FloatingComposer = FloatingComposer;
|
|
34
|
+
//# sourceMappingURL=floating-composer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"floating-composer.js","sources":["../../src/comments/floating-composer.tsx"],"sourcesContent":["import { Composer, ComposerProps } from \"@liveblocks/react-comments\";\nimport React, { ComponentRef, forwardRef, KeyboardEvent } from \"react\";\nimport { FloatingSelectionContainer } from \"../floating-selection-container\";\nimport type { BaseMetadata } from \"@liveblocks/core\";\nimport {\n useHideFloatingComposer,\n useShowFloatingComposer,\n} from \"./comment-plugin-provider\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\n\ntype ComposerElement = ComponentRef<typeof Composer>;\n\ntype ThreadMetadata = {\n resolved?: boolean;\n};\n\ntype FloatingComposerProps<M extends BaseMetadata = ThreadMetadata> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n>;\n\nexport const FloatingComposer = forwardRef<\n ComposerElement,\n FloatingComposerProps\n>(function FloatingComposer(props, forwardedRef) {\n const shouldShowFloatingComposer = useShowFloatingComposer();\n const hideFloatingComposer = useHideFloatingComposer();\n const [editor] = useLexicalComposerContext();\n\n if (!shouldShowFloatingComposer) return null;\n\n function handleKeyDown(event: KeyboardEvent<HTMLFormElement>) {\n if (event.key === \"Escape\") {\n hideFloatingComposer();\n editor.focus();\n }\n }\n\n return (\n <FloatingSelectionContainer\n sideOffset={5}\n alignOffset={0}\n collisionPadding={5}\n >\n <Composer\n autoFocus\n onKeyDown={handleKeyDown}\n {...props}\n ref={forwardedRef}\n />\n </FloatingSelectionContainer>\n );\n});\n"],"names":["forwardRef","FloatingComposer","useShowFloatingComposer","useHideFloatingComposer","useLexicalComposerContext","FloatingSelectionContainer","Composer"],"mappings":";;;;;;;;AAqBO,MAAM,gBAAmB,GAAAA,gBAAA,CAG9B,SAASC,iBAAAA,CAAiB,OAAO,YAAc,EAAA;AAC/C,EAAA,MAAM,6BAA6BC,6CAAwB,EAAA,CAAA;AAC3D,EAAA,MAAM,uBAAuBC,6CAAwB,EAAA,CAAA;AACrD,EAAM,MAAA,CAAC,MAAM,CAAA,GAAIC,gDAA0B,EAAA,CAAA;AAE3C,EAAA,IAAI,CAAC,0BAAA;AAA4B,IAAO,OAAA,IAAA,CAAA;AAExC,EAAA,SAAS,cAAc,KAAuC,EAAA;AAC5D,IAAI,IAAA,KAAA,CAAM,QAAQ,QAAU,EAAA;AAC1B,MAAqB,oBAAA,EAAA,CAAA;AACrB,MAAA,MAAA,CAAO,KAAM,EAAA,CAAA;AAAA,KACf;AAAA,GACF;AAEA,EAAA,uBACG,KAAA,CAAA,aAAA,CAAAC,qDAAA,EAAA;AAAA,IACC,UAAY,EAAA,CAAA;AAAA,IACZ,WAAa,EAAA,CAAA;AAAA,IACb,gBAAkB,EAAA,CAAA;AAAA,GAAA,kBAEjB,KAAA,CAAA,aAAA,CAAAC,sBAAA,EAAA;AAAA,IACC,SAAS,EAAA,IAAA;AAAA,IACT,SAAW,EAAA,aAAA;AAAA,IACV,GAAG,KAAA;AAAA,IACJ,GAAK,EAAA,YAAA;AAAA,GACP,CACF,CAAA,CAAA;AAEJ,CAAC;;;;"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Composer } from '@liveblocks/react-comments';
|
|
2
|
+
import React__default, { forwardRef } from 'react';
|
|
3
|
+
import { FloatingSelectionContainer } from '../floating-selection-container.mjs';
|
|
4
|
+
import { useShowFloatingComposer, useHideFloatingComposer } from './comment-plugin-provider.mjs';
|
|
5
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
6
|
+
|
|
7
|
+
const FloatingComposer = forwardRef(function FloatingComposer2(props, forwardedRef) {
|
|
8
|
+
const shouldShowFloatingComposer = useShowFloatingComposer();
|
|
9
|
+
const hideFloatingComposer = useHideFloatingComposer();
|
|
10
|
+
const [editor] = useLexicalComposerContext();
|
|
11
|
+
if (!shouldShowFloatingComposer)
|
|
12
|
+
return null;
|
|
13
|
+
function handleKeyDown(event) {
|
|
14
|
+
if (event.key === "Escape") {
|
|
15
|
+
hideFloatingComposer();
|
|
16
|
+
editor.focus();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return /* @__PURE__ */ React__default.createElement(FloatingSelectionContainer, {
|
|
20
|
+
sideOffset: 5,
|
|
21
|
+
alignOffset: 0,
|
|
22
|
+
collisionPadding: 5
|
|
23
|
+
}, /* @__PURE__ */ React__default.createElement(Composer, {
|
|
24
|
+
autoFocus: true,
|
|
25
|
+
onKeyDown: handleKeyDown,
|
|
26
|
+
...props,
|
|
27
|
+
ref: forwardedRef
|
|
28
|
+
}));
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export { FloatingComposer };
|
|
32
|
+
//# sourceMappingURL=floating-composer.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"floating-composer.mjs","sources":["../../src/comments/floating-composer.tsx"],"sourcesContent":["import { Composer, ComposerProps } from \"@liveblocks/react-comments\";\nimport React, { ComponentRef, forwardRef, KeyboardEvent } from \"react\";\nimport { FloatingSelectionContainer } from \"../floating-selection-container\";\nimport type { BaseMetadata } from \"@liveblocks/core\";\nimport {\n useHideFloatingComposer,\n useShowFloatingComposer,\n} from \"./comment-plugin-provider\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\n\ntype ComposerElement = ComponentRef<typeof Composer>;\n\ntype ThreadMetadata = {\n resolved?: boolean;\n};\n\ntype FloatingComposerProps<M extends BaseMetadata = ThreadMetadata> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n>;\n\nexport const FloatingComposer = forwardRef<\n ComposerElement,\n FloatingComposerProps\n>(function FloatingComposer(props, forwardedRef) {\n const shouldShowFloatingComposer = useShowFloatingComposer();\n const hideFloatingComposer = useHideFloatingComposer();\n const [editor] = useLexicalComposerContext();\n\n if (!shouldShowFloatingComposer) return null;\n\n function handleKeyDown(event: KeyboardEvent<HTMLFormElement>) {\n if (event.key === \"Escape\") {\n hideFloatingComposer();\n editor.focus();\n }\n }\n\n return (\n <FloatingSelectionContainer\n sideOffset={5}\n alignOffset={0}\n collisionPadding={5}\n >\n <Composer\n autoFocus\n onKeyDown={handleKeyDown}\n {...props}\n ref={forwardedRef}\n />\n </FloatingSelectionContainer>\n );\n});\n"],"names":["FloatingComposer","React"],"mappings":";;;;;;AAqBO,MAAM,gBAAmB,GAAA,UAAA,CAG9B,SAASA,iBAAAA,CAAiB,OAAO,YAAc,EAAA;AAC/C,EAAA,MAAM,6BAA6B,uBAAwB,EAAA,CAAA;AAC3D,EAAA,MAAM,uBAAuB,uBAAwB,EAAA,CAAA;AACrD,EAAM,MAAA,CAAC,MAAM,CAAA,GAAI,yBAA0B,EAAA,CAAA;AAE3C,EAAA,IAAI,CAAC,0BAAA;AAA4B,IAAO,OAAA,IAAA,CAAA;AAExC,EAAA,SAAS,cAAc,KAAuC,EAAA;AAC5D,IAAI,IAAA,KAAA,CAAM,QAAQ,QAAU,EAAA;AAC1B,MAAqB,oBAAA,EAAA,CAAA;AACrB,MAAA,MAAA,CAAO,KAAM,EAAA,CAAA;AAAA,KACf;AAAA,GACF;AAEA,EAAA,uBACGC,cAAA,CAAA,aAAA,CAAA,0BAAA,EAAA;AAAA,IACC,UAAY,EAAA,CAAA;AAAA,IACZ,WAAa,EAAA,CAAA;AAAA,IACb,gBAAkB,EAAA,CAAA;AAAA,GAAA,kBAEjBA,cAAA,CAAA,aAAA,CAAA,QAAA,EAAA;AAAA,IACC,SAAS,EAAA,IAAA;AAAA,IACT,SAAW,EAAA,aAAA;AAAA,IACV,GAAG,KAAA;AAAA,IACJ,GAAK,EAAA,YAAA;AAAA,GACP,CACF,CAAA,CAAA;AAEJ,CAAC;;;;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lexical = require('lexical');
|
|
4
|
+
var threadMarkNode = require('./thread-mark-node.js');
|
|
5
|
+
|
|
6
|
+
function $getThreadMarkIds(node, offset) {
|
|
7
|
+
let currentNode = node;
|
|
8
|
+
while (currentNode !== null) {
|
|
9
|
+
if (threadMarkNode.$isThreadMarkNode(currentNode)) {
|
|
10
|
+
return currentNode.getIDs();
|
|
11
|
+
} else if (lexical.$isTextNode(currentNode) && offset === currentNode.getTextContentSize()) {
|
|
12
|
+
const nextSibling = currentNode.getNextSibling();
|
|
13
|
+
if (threadMarkNode.$isThreadMarkNode(nextSibling)) {
|
|
14
|
+
return nextSibling.getIDs();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
currentNode = currentNode.getParent();
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = $getThreadMarkIds;
|
|
23
|
+
//# sourceMappingURL=get-thread-mark-ids.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-thread-mark-ids.js","sources":["../../src/comments/get-thread-mark-ids.ts"],"sourcesContent":["import type { LexicalNode, TextNode } from \"lexical\";\nimport { $isTextNode } from \"lexical\";\n\nimport { $isThreadMarkNode } from \"./thread-mark-node\";\n\nexport default function $getThreadMarkIds(\n node: TextNode,\n offset: number\n): null | Array<string> {\n let currentNode: LexicalNode | null = node;\n while (currentNode !== null) {\n if ($isThreadMarkNode(currentNode)) {\n return currentNode.getIDs();\n } else if (\n $isTextNode(currentNode) &&\n offset === currentNode.getTextContentSize()\n ) {\n const nextSibling = currentNode.getNextSibling();\n if ($isThreadMarkNode(nextSibling)) {\n return nextSibling.getIDs();\n }\n }\n currentNode = currentNode.getParent();\n }\n return null;\n}\n"],"names":["$isThreadMarkNode","$isTextNode"],"mappings":";;;;;AAKwB,SAAA,iBAAA,CACtB,MACA,MACsB,EAAA;AACtB,EAAA,IAAI,WAAkC,GAAA,IAAA,CAAA;AACtC,EAAA,OAAO,gBAAgB,IAAM,EAAA;AAC3B,IAAI,IAAAA,gCAAA,CAAkB,WAAW,CAAG,EAAA;AAClC,MAAA,OAAO,YAAY,MAAO,EAAA,CAAA;AAAA,eAE1BC,mBAAY,CAAA,WAAW,KACvB,MAAW,KAAA,WAAA,CAAY,oBACvB,EAAA;AACA,MAAM,MAAA,WAAA,GAAc,YAAY,cAAe,EAAA,CAAA;AAC/C,MAAI,IAAAD,gCAAA,CAAkB,WAAW,CAAG,EAAA;AAClC,QAAA,OAAO,YAAY,MAAO,EAAA,CAAA;AAAA,OAC5B;AAAA,KACF;AACA,IAAA,WAAA,GAAc,YAAY,SAAU,EAAA,CAAA;AAAA,GACtC;AACA,EAAO,OAAA,IAAA,CAAA;AACT;;;;"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { $isTextNode } from 'lexical';
|
|
2
|
+
import { $isThreadMarkNode } from './thread-mark-node.mjs';
|
|
3
|
+
|
|
4
|
+
function $getThreadMarkIds(node, offset) {
|
|
5
|
+
let currentNode = node;
|
|
6
|
+
while (currentNode !== null) {
|
|
7
|
+
if ($isThreadMarkNode(currentNode)) {
|
|
8
|
+
return currentNode.getIDs();
|
|
9
|
+
} else if ($isTextNode(currentNode) && offset === currentNode.getTextContentSize()) {
|
|
10
|
+
const nextSibling = currentNode.getNextSibling();
|
|
11
|
+
if ($isThreadMarkNode(nextSibling)) {
|
|
12
|
+
return nextSibling.getIDs();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
currentNode = currentNode.getParent();
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { $getThreadMarkIds as default };
|
|
21
|
+
//# sourceMappingURL=get-thread-mark-ids.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-thread-mark-ids.mjs","sources":["../../src/comments/get-thread-mark-ids.ts"],"sourcesContent":["import type { LexicalNode, TextNode } from \"lexical\";\nimport { $isTextNode } from \"lexical\";\n\nimport { $isThreadMarkNode } from \"./thread-mark-node\";\n\nexport default function $getThreadMarkIds(\n node: TextNode,\n offset: number\n): null | Array<string> {\n let currentNode: LexicalNode | null = node;\n while (currentNode !== null) {\n if ($isThreadMarkNode(currentNode)) {\n return currentNode.getIDs();\n } else if (\n $isTextNode(currentNode) &&\n offset === currentNode.getTextContentSize()\n ) {\n const nextSibling = currentNode.getNextSibling();\n if ($isThreadMarkNode(nextSibling)) {\n return nextSibling.getIDs();\n }\n }\n currentNode = currentNode.getParent();\n }\n return null;\n}\n"],"names":[],"mappings":";;;AAKwB,SAAA,iBAAA,CACtB,MACA,MACsB,EAAA;AACtB,EAAA,IAAI,WAAkC,GAAA,IAAA,CAAA;AACtC,EAAA,OAAO,gBAAgB,IAAM,EAAA;AAC3B,IAAI,IAAA,iBAAA,CAAkB,WAAW,CAAG,EAAA;AAClC,MAAA,OAAO,YAAY,MAAO,EAAA,CAAA;AAAA,eAE1B,WAAY,CAAA,WAAW,KACvB,MAAW,KAAA,WAAA,CAAY,oBACvB,EAAA;AACA,MAAM,MAAA,WAAA,GAAc,YAAY,cAAe,EAAA,CAAA;AAC/C,MAAI,IAAA,iBAAA,CAAkB,WAAW,CAAG,EAAA;AAClC,QAAA,OAAO,YAAY,MAAO,EAAA,CAAA;AAAA,OAC5B;AAAA,KACF;AACA,IAAA,WAAA,GAAc,YAAY,SAAU,EAAA,CAAA;AAAA,GACtC;AACA,EAAO,OAAA,IAAA,CAAA;AACT;;;;"}
|