@liveblocks/react-tiptap 2.15.1 → 2.16.0-toolbars1
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/LiveblocksExtension.js +1 -1
- package/dist/LiveblocksExtension.js.map +1 -1
- package/dist/LiveblocksExtension.mjs +1 -1
- package/dist/LiveblocksExtension.mjs.map +1 -1
- package/dist/comments/AnchoredThreads.js +34 -16
- package/dist/comments/AnchoredThreads.js.map +1 -1
- package/dist/comments/AnchoredThreads.mjs +33 -15
- package/dist/comments/AnchoredThreads.mjs.map +1 -1
- package/dist/comments/CommentsExtension.js +6 -2
- package/dist/comments/CommentsExtension.js.map +1 -1
- package/dist/comments/CommentsExtension.mjs +7 -3
- package/dist/comments/CommentsExtension.mjs.map +1 -1
- package/dist/comments/FloatingComposer.js +34 -33
- package/dist/comments/FloatingComposer.js.map +1 -1
- package/dist/comments/FloatingComposer.mjs +36 -35
- package/dist/comments/FloatingComposer.mjs.map +1 -1
- package/dist/comments/FloatingThreads.js +5 -2
- package/dist/comments/FloatingThreads.js.map +1 -1
- package/dist/comments/FloatingThreads.mjs +5 -2
- package/dist/comments/FloatingThreads.mjs.map +1 -1
- package/dist/context.js +24 -0
- package/dist/context.js.map +1 -0
- package/dist/context.mjs +21 -0
- package/dist/context.mjs.map +1 -0
- package/dist/index.d.mts +65 -13
- package/dist/index.d.ts +65 -13
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -1
- package/dist/mentions/MentionsList.js +117 -107
- package/dist/mentions/MentionsList.js.map +1 -1
- package/dist/mentions/MentionsList.mjs +119 -109
- package/dist/mentions/MentionsList.mjs.map +1 -1
- package/dist/toolbar/FloatingToolbar.js +301 -0
- package/dist/toolbar/FloatingToolbar.js.map +1 -0
- package/dist/toolbar/FloatingToolbar.mjs +298 -0
- package/dist/toolbar/FloatingToolbar.mjs.map +1 -0
- package/dist/toolbar/FloatingToolbarContext.js +8 -0
- package/dist/toolbar/FloatingToolbarContext.js.map +1 -0
- package/dist/toolbar/FloatingToolbarContext.mjs +6 -0
- package/dist/toolbar/FloatingToolbarContext.mjs.map +1 -0
- package/dist/toolbar/Toolbar.js +352 -0
- package/dist/toolbar/Toolbar.js.map +1 -0
- package/dist/toolbar/Toolbar.mjs +327 -0
- package/dist/toolbar/Toolbar.mjs.map +1 -0
- package/dist/types.js +7 -3
- package/dist/types.js.map +1 -1
- package/dist/types.mjs +6 -3
- package/dist/types.mjs.map +1 -1
- package/dist/utils.js +17 -0
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +16 -1
- package/dist/utils.mjs.map +1 -1
- package/dist/version-history/HistoryVersionPreview.js +79 -79
- package/dist/version-history/HistoryVersionPreview.js.map +1 -1
- package/dist/version-history/HistoryVersionPreview.mjs +79 -79
- package/dist/version-history/HistoryVersionPreview.mjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/version.mjs +1 -1
- package/dist/version.mjs.map +1 -1
- package/package.json +11 -8
- package/src/styles/constants.css +2 -1
- package/src/styles/index.css +58 -6
- package/src/styles/utils.css +11 -0
- package/styles.css +1 -1
- package/styles.css.map +1 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useFloating, flip, offset, hide, shift, limitShift, size, autoUpdate } from '@floating-ui/react-dom';
|
|
3
|
+
import { useLayoutEffect } from '@liveblocks/react/_private';
|
|
3
4
|
import { Thread } from '@liveblocks/react-ui';
|
|
4
5
|
import { useEditorState } from '@tiptap/react';
|
|
5
|
-
import { useState, useEffect, useCallback
|
|
6
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
6
7
|
import { createPortal } from 'react-dom';
|
|
7
8
|
import { classNames } from '../classnames.mjs';
|
|
8
9
|
import { THREADS_PLUGIN_KEY } from '../types.mjs';
|
|
@@ -114,7 +115,9 @@ function FloatingThreadPortal({
|
|
|
114
115
|
}
|
|
115
116
|
});
|
|
116
117
|
const updateRef = useCallback(() => {
|
|
117
|
-
const el = editor.view.dom.querySelector(
|
|
118
|
+
const el = editor.view.dom.querySelector(
|
|
119
|
+
`[data-lb-thread-id="${thread.id}"]`
|
|
120
|
+
);
|
|
118
121
|
if (el) {
|
|
119
122
|
setReference(el);
|
|
120
123
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingThreads.mjs","sources":["../../src/comments/FloatingThreads.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport type { BaseMetadata, DM, ThreadData } from \"@liveblocks/core\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useLayoutEffect,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport { THREADS_PLUGIN_KEY } from \"../types\";\n\ntype ThreadPanelComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<M extends BaseMetadata = DM>\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<M>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<ThreadPanelComponents>;\n\n /**\n * The tiptap editor\n */\n editor: Editor | null;\n}\n\nexport function FloatingThreads({\n threads,\n components,\n editor,\n ...props\n}: FloatingThreadsProps) {\n const Thread = components?.Thread ?? DefaultThread;\n\n const { pluginState } = useEditorState({\n editor,\n selector: (ctx) => {\n if (!ctx?.editor?.state) return { pluginState: undefined };\n const state = THREADS_PLUGIN_KEY.getState(ctx.editor.state);\n return {\n pluginState: state,\n };\n },\n equalityFn: (prev, next) => {\n if (!prev || !next) return false;\n return prev.pluginState?.selectedThreadPos === next.pluginState?.selectedThreadPos &&\n prev.pluginState?.selectedThreadId === next.pluginState?.selectedThreadId;\n },\n }) ?? { pluginState: undefined };\n\n const [activeThread, setActiveThread] = useState<ThreadData | null>(null);\n\n useEffect(() => {\n if (!editor || !pluginState) {\n setActiveThread(null);\n return;\n }\n const { selectedThreadId, selectedThreadPos } = pluginState;\n if (selectedThreadId === null || selectedThreadPos === null) {\n setActiveThread(null);\n return;\n }\n const active = (threads ?? []).find((thread) =>\n selectedThreadId === thread.id\n );\n setActiveThread(active ?? null);\n }, [editor, pluginState, threads]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (!editor || activeThread === null) return false;\n editor.commands.selectThread(null);\n return true;\n }, [activeThread, editor]);\n\n if (!activeThread || !editor || activeThread.resolved) return null;\n\n return (\n <FloatingThreadPortal\n thread={activeThread}\n editor={editor}\n container={document.body}\n {...props}\n >\n {activeThread &&\n <ThreadWrapper\n key={activeThread.id}\n thread={activeThread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-tiptap-floating-threads-thread\"\n />\n }\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n thread: ThreadData;\n editor: Editor;\n container: HTMLElement;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal({\n container,\n editor,\n thread,\n children,\n className,\n style,\n ...props\n}: FloatingThreadPortalProps) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"absolute\",\n placement: \"bottom\",\n middleware: [\n flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),\n shift({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n apply({ availableWidth, availableHeight, elements }) {\n elements.floating.style.setProperty(\n \"--lb-tiptap-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-tiptap-floating-threads-available-height\",\n `${availableHeight}px`\n );\n },\n }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n const updateRef = useCallback(() => {\n const el = editor.view.dom.querySelector(`[data-lb-thread-id=\"${thread.id}\"]`);\n if (el) {\n setReference(el);\n }\n }, [setReference, editor, thread.id]);\n\n // Remote cursor updates and other edits can cause the ref to break\n useEffect(() => {\n editor.on(\"transaction\", updateRef)\n return () => {\n editor.off(\"transaction\", updateRef);\n };\n }, [editor, updateRef]);\n\n useLayoutEffect(updateRef, [updateRef]);\n\n return createPortal(\n <div\n ref={setFloating}\n {...props}\n style={{\n ...style,\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n className={classNames(\n \"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-threads\",\n className\n )}\n >\n {children}\n </div>,\n container\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n thread: ThreadData;\n Thread: ComponentType<ThreadProps>;\n onEscapeKeydown: () => void;\n}\n\nfunction ThreadWrapper({\n thread,\n Thread,\n onEscapeKeydown,\n onKeyDown,\n ...threadProps\n}: ThreadWrapperProps) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n // TODO: Add ability to preventDefault on keydown to override the default behavior, e.g. to show an alert dialog\n if (event.key === \"Escape\") {\n onEscapeKeydown();\n }\n },\n [onEscapeKeydown, onKeyDown]\n );\n\n return <Thread thread={thread} onKeyDown={handleKeyDown} {...threadProps} />;\n}\n"],"names":["Thread","DefaultThread"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FloatingThreads.mjs","sources":["../../src/comments/FloatingThreads.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport type { BaseMetadata, DM, ThreadData } from \"@liveblocks/core\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport { type Editor, useEditorState } from \"@tiptap/react\";\nimport {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport { THREADS_PLUGIN_KEY } from \"../types\";\n\ntype ThreadPanelComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<M extends BaseMetadata = DM>\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<M>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<ThreadPanelComponents>;\n\n /**\n * The tiptap editor\n */\n editor: Editor | null;\n}\n\nexport function FloatingThreads({\n threads,\n components,\n editor,\n ...props\n}: FloatingThreadsProps) {\n const Thread = components?.Thread ?? DefaultThread;\n\n const { pluginState } = useEditorState({\n editor,\n selector: (ctx) => {\n if (!ctx?.editor?.state) return { pluginState: undefined };\n const state = THREADS_PLUGIN_KEY.getState(ctx.editor.state);\n return {\n pluginState: state,\n };\n },\n equalityFn: (prev, next) => {\n if (!prev || !next) return false;\n return (\n prev.pluginState?.selectedThreadPos ===\n next.pluginState?.selectedThreadPos &&\n prev.pluginState?.selectedThreadId ===\n next.pluginState?.selectedThreadId\n );\n },\n }) ?? { pluginState: undefined };\n\n const [activeThread, setActiveThread] = useState<ThreadData | null>(null);\n\n useEffect(() => {\n if (!editor || !pluginState) {\n setActiveThread(null);\n return;\n }\n const { selectedThreadId, selectedThreadPos } = pluginState;\n if (selectedThreadId === null || selectedThreadPos === null) {\n setActiveThread(null);\n return;\n }\n const active = (threads ?? []).find(\n (thread) => selectedThreadId === thread.id\n );\n setActiveThread(active ?? null);\n }, [editor, pluginState, threads]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (!editor || activeThread === null) return false;\n editor.commands.selectThread(null);\n return true;\n }, [activeThread, editor]);\n\n if (!activeThread || !editor || activeThread.resolved) return null;\n\n return (\n <FloatingThreadPortal\n thread={activeThread}\n editor={editor}\n container={document.body}\n {...props}\n >\n {activeThread && (\n <ThreadWrapper\n key={activeThread.id}\n thread={activeThread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-tiptap-floating-threads-thread\"\n />\n )}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n thread: ThreadData;\n editor: Editor;\n container: HTMLElement;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal({\n container,\n editor,\n thread,\n children,\n className,\n style,\n ...props\n}: FloatingThreadPortalProps) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"absolute\",\n placement: \"bottom\",\n middleware: [\n flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),\n shift({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n apply({ availableWidth, availableHeight, elements }) {\n elements.floating.style.setProperty(\n \"--lb-tiptap-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-tiptap-floating-threads-available-height\",\n `${availableHeight}px`\n );\n },\n }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n const updateRef = useCallback(() => {\n const el = editor.view.dom.querySelector(\n `[data-lb-thread-id=\"${thread.id}\"]`\n );\n if (el) {\n setReference(el);\n }\n }, [setReference, editor, thread.id]);\n\n // Remote cursor updates and other edits can cause the ref to break\n useEffect(() => {\n editor.on(\"transaction\", updateRef);\n return () => {\n editor.off(\"transaction\", updateRef);\n };\n }, [editor, updateRef]);\n\n useLayoutEffect(updateRef, [updateRef]);\n\n return createPortal(\n <div\n ref={setFloating}\n {...props}\n style={{\n ...style,\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n className={classNames(\n \"lb-root lb-portal lb-elevation lb-tiptap-floating lb-tiptap-floating-threads\",\n className\n )}\n >\n {children}\n </div>,\n container\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n thread: ThreadData;\n Thread: ComponentType<ThreadProps>;\n onEscapeKeydown: () => void;\n}\n\nfunction ThreadWrapper({\n thread,\n Thread,\n onEscapeKeydown,\n onKeyDown,\n ...threadProps\n}: ThreadWrapperProps) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n // TODO: Add ability to preventDefault on keydown to override the default behavior, e.g. to show an alert dialog\n if (event.key === \"Escape\") {\n onEscapeKeydown();\n }\n },\n [onEscapeKeydown, onKeyDown]\n );\n\n return <Thread thread={thread} onKeyDown={handleKeyDown} {...threadProps} />;\n}\n"],"names":["Thread","DefaultThread"],"mappings":"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"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var core = require('@liveblocks/core');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
|
|
7
|
+
const EditorContext = react.createContext(null);
|
|
8
|
+
function EditorProvider({
|
|
9
|
+
editor,
|
|
10
|
+
children
|
|
11
|
+
}) {
|
|
12
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EditorContext.Provider, {
|
|
13
|
+
value: editor,
|
|
14
|
+
children
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function useCurrentEditor(source, parent) {
|
|
18
|
+
const currentEditor = react.useContext(EditorContext);
|
|
19
|
+
return core.nn(currentEditor, `${source} can\u2019t be used outside of ${parent}.`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
exports.EditorProvider = EditorProvider;
|
|
23
|
+
exports.useCurrentEditor = useCurrentEditor;
|
|
24
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sources":["../src/context.tsx"],"sourcesContent":["import { nn } from \"@liveblocks/core\";\nimport type { Editor } from \"@tiptap/react\";\nimport type { PropsWithChildren } from \"react\";\nimport { createContext, useContext } from \"react\";\n\nconst EditorContext = createContext<Editor | null>(null);\n\nexport function EditorProvider({\n editor,\n children,\n}: PropsWithChildren<{ editor: Editor }>) {\n return (\n <EditorContext.Provider value={editor}>{children}</EditorContext.Provider>\n );\n}\n\n/**\n * @tiptap/react already offers a `useCurrentEditor` hook but our components might\n * not live under `EditorProvider` or `EditorContent` so we create our own to reduce\n * repetition within our own nested components.\n *\n * @example\n * <Toolbar editor={editor}> // `editor` is required here\n * <ToolbarSectionInline /> // But it isn't there, because `Toolbar` uses our own `EditorProvider`\n * </Toolbar>\n */\nexport function useCurrentEditor(source: string, parent: string) {\n const currentEditor = useContext(EditorContext);\n\n return nn(currentEditor, `${source} can’t be used outside of ${parent}.`);\n}\n"],"names":["createContext","jsx","useContext","nn"],"mappings":";;;;;;AAKA,MAAM,aAAA,GAAgBA,oBAA6B,IAAI,CAAA,CAAA;AAEhD,SAAS,cAAe,CAAA;AAAA,EAC7B,MAAA;AAAA,EACA,QAAA;AACF,CAA0C,EAAA;AACxC,EACE,uBAAAC,cAAA,CAAC,cAAc,QAAd,EAAA;AAAA,IAAuB,KAAO,EAAA,MAAA;AAAA,IAAS,QAAA;AAAA,GAAS,CAAA,CAAA;AAErD,CAAA;AAYgB,SAAA,gBAAA,CAAiB,QAAgB,MAAgB,EAAA;AAC/D,EAAM,MAAA,aAAA,GAAgBC,iBAAW,aAAa,CAAA,CAAA;AAE9C,EAAA,OAAOC,OAAG,CAAA,aAAA,EAAe,CAAG,EAAA,MAAA,CAAA,+BAAA,EAAmC,MAAS,CAAA,CAAA,CAAA,CAAA,CAAA;AAC1E;;;;;"}
|
package/dist/context.mjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { nn } from '@liveblocks/core';
|
|
3
|
+
import { createContext, useContext } from 'react';
|
|
4
|
+
|
|
5
|
+
const EditorContext = createContext(null);
|
|
6
|
+
function EditorProvider({
|
|
7
|
+
editor,
|
|
8
|
+
children
|
|
9
|
+
}) {
|
|
10
|
+
return /* @__PURE__ */ jsx(EditorContext.Provider, {
|
|
11
|
+
value: editor,
|
|
12
|
+
children
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function useCurrentEditor(source, parent) {
|
|
16
|
+
const currentEditor = useContext(EditorContext);
|
|
17
|
+
return nn(currentEditor, `${source} can\u2019t be used outside of ${parent}.`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { EditorProvider, useCurrentEditor };
|
|
21
|
+
//# sourceMappingURL=context.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.mjs","sources":["../src/context.tsx"],"sourcesContent":["import { nn } from \"@liveblocks/core\";\nimport type { Editor } from \"@tiptap/react\";\nimport type { PropsWithChildren } from \"react\";\nimport { createContext, useContext } from \"react\";\n\nconst EditorContext = createContext<Editor | null>(null);\n\nexport function EditorProvider({\n editor,\n children,\n}: PropsWithChildren<{ editor: Editor }>) {\n return (\n <EditorContext.Provider value={editor}>{children}</EditorContext.Provider>\n );\n}\n\n/**\n * @tiptap/react already offers a `useCurrentEditor` hook but our components might\n * not live under `EditorProvider` or `EditorContent` so we create our own to reduce\n * repetition within our own nested components.\n *\n * @example\n * <Toolbar editor={editor}> // `editor` is required here\n * <ToolbarSectionInline /> // But it isn't there, because `Toolbar` uses our own `EditorProvider`\n * </Toolbar>\n */\nexport function useCurrentEditor(source: string, parent: string) {\n const currentEditor = useContext(EditorContext);\n\n return nn(currentEditor, `${source} can’t be used outside of ${parent}.`);\n}\n"],"names":[],"mappings":";;;;AAKA,MAAM,aAAA,GAAgB,cAA6B,IAAI,CAAA,CAAA;AAEhD,SAAS,cAAe,CAAA;AAAA,EAC7B,MAAA;AAAA,EACA,QAAA;AACF,CAA0C,EAAA;AACxC,EACE,uBAAA,GAAA,CAAC,cAAc,QAAd,EAAA;AAAA,IAAuB,KAAO,EAAA,MAAA;AAAA,IAAS,QAAA;AAAA,GAAS,CAAA,CAAA;AAErD,CAAA;AAYgB,SAAA,gBAAA,CAAiB,QAAgB,MAAgB,EAAA;AAC/D,EAAM,MAAA,aAAA,GAAgB,WAAW,aAAa,CAAA,CAAA;AAE9C,EAAA,OAAO,EAAG,CAAA,aAAA,EAAe,CAAG,EAAA,MAAA,CAAA,+BAAA,EAAmC,MAAS,CAAA,CAAA,CAAA,CAAA,CAAA;AAC1E;;;;"}
|
package/dist/index.d.mts
CHANGED
|
@@ -3,11 +3,21 @@ import { BaseMetadata, DM, ThreadData, HistoryVersion } from '@liveblocks/core';
|
|
|
3
3
|
import { ThreadProps, ComposerProps } from '@liveblocks/react-ui';
|
|
4
4
|
import { Editor } from '@tiptap/react';
|
|
5
5
|
import * as react from 'react';
|
|
6
|
-
import { ComponentPropsWithoutRef, ComponentType, HTMLAttributes } from 'react';
|
|
6
|
+
import { ComponentPropsWithoutRef, ComponentType, HTMLAttributes, ComponentProps, ReactNode } from 'react';
|
|
7
7
|
import { BaseMetadata as BaseMetadata$1 } from '@liveblocks/client';
|
|
8
8
|
import { Extension, Content } from '@tiptap/core';
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
type FloatingPosition = "top" | "bottom";
|
|
11
|
+
type CommentsCommands<ReturnType> = {
|
|
12
|
+
/**
|
|
13
|
+
* Add a comment
|
|
14
|
+
*/
|
|
15
|
+
addComment: (id: string) => ReturnType;
|
|
16
|
+
selectThread: (id: string | null) => ReturnType;
|
|
17
|
+
addPendingComment: () => ReturnType;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type AnchoredThreadsComponents = {
|
|
11
21
|
Thread: ComponentType<ThreadProps>;
|
|
12
22
|
};
|
|
13
23
|
interface AnchoredThreadsProps<M extends BaseMetadata = DM> extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
|
|
@@ -30,7 +40,7 @@ declare const FloatingComposer: react.ForwardRefExoticComponent<Omit<ComposerPro
|
|
|
30
40
|
editor: Editor | null;
|
|
31
41
|
} & react.RefAttributes<HTMLFormElement>>;
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
type ThreadPanelComponents = {
|
|
34
44
|
Thread: ComponentType<ThreadProps>;
|
|
35
45
|
};
|
|
36
46
|
interface FloatingThreadsProps<M extends BaseMetadata = DM> extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
@@ -49,7 +59,7 @@ interface FloatingThreadsProps<M extends BaseMetadata = DM> extends Omit<HTMLAtt
|
|
|
49
59
|
}
|
|
50
60
|
declare function FloatingThreads({ threads, components, editor, ...props }: FloatingThreadsProps): react_jsx_runtime.JSX.Element | null;
|
|
51
61
|
|
|
52
|
-
|
|
62
|
+
type LiveblocksExtensionOptions = {
|
|
53
63
|
field?: string;
|
|
54
64
|
comments?: boolean;
|
|
55
65
|
mentions?: boolean;
|
|
@@ -64,6 +74,55 @@ declare type LiveblocksExtensionOptions = {
|
|
|
64
74
|
declare function useIsEditorReady(): boolean;
|
|
65
75
|
declare const useLiveblocksExtension: (opts?: LiveblocksExtensionOptions) => Extension;
|
|
66
76
|
|
|
77
|
+
interface ToolbarSlotProps {
|
|
78
|
+
editor: Editor;
|
|
79
|
+
}
|
|
80
|
+
type ToolbarSlot = ReactNode | ComponentType<ToolbarSlotProps>;
|
|
81
|
+
interface ToolbarProps extends Omit<ComponentProps<"div">, "children"> {
|
|
82
|
+
editor: Editor | null;
|
|
83
|
+
children?: ToolbarSlot;
|
|
84
|
+
before?: ToolbarSlot;
|
|
85
|
+
after?: ToolbarSlot;
|
|
86
|
+
}
|
|
87
|
+
interface ToolbarButtonProps extends ComponentProps<"button"> {
|
|
88
|
+
icon?: ReactNode;
|
|
89
|
+
name: string;
|
|
90
|
+
shortcut?: string;
|
|
91
|
+
}
|
|
92
|
+
interface ToolbarToggleProps extends ToolbarButtonProps {
|
|
93
|
+
active: boolean;
|
|
94
|
+
}
|
|
95
|
+
interface ToolbarBlockSelectorItem {
|
|
96
|
+
name: string;
|
|
97
|
+
isActive: (editor: Editor) => boolean;
|
|
98
|
+
setActive: (editor: Editor) => void;
|
|
99
|
+
}
|
|
100
|
+
interface ToolbarBlockSelectorProps extends ComponentProps<"button"> {
|
|
101
|
+
items?: ToolbarBlockSelectorItem[];
|
|
102
|
+
}
|
|
103
|
+
declare function ToolbarSectionHistory(): react_jsx_runtime.JSX.Element;
|
|
104
|
+
declare function ToolbarSectionInline(): react_jsx_runtime.JSX.Element;
|
|
105
|
+
declare function ToolbarSectionCollaboration(): react_jsx_runtime.JSX.Element;
|
|
106
|
+
declare const Toolbar: react.ForwardRefExoticComponent<Omit<ToolbarProps, "ref"> & react.RefAttributes<HTMLDivElement>> & {
|
|
107
|
+
Button: react.ForwardRefExoticComponent<Omit<ToolbarButtonProps, "ref"> & react.RefAttributes<HTMLButtonElement>>;
|
|
108
|
+
Toggle: react.ForwardRefExoticComponent<Omit<ToolbarToggleProps, "ref"> & react.RefAttributes<HTMLButtonElement>>;
|
|
109
|
+
Separator: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
110
|
+
SectionHistory: typeof ToolbarSectionHistory;
|
|
111
|
+
SectionInline: typeof ToolbarSectionInline;
|
|
112
|
+
SectionCollaboration: typeof ToolbarSectionCollaboration;
|
|
113
|
+
BlockSelector: react.ForwardRefExoticComponent<Omit<ToolbarBlockSelectorProps, "ref"> & react.RefAttributes<HTMLButtonElement>>;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
interface FloatingToolbarProps extends Omit<ComponentProps<"div">, "children"> {
|
|
117
|
+
editor: Editor | null;
|
|
118
|
+
position?: FloatingPosition;
|
|
119
|
+
offset?: number;
|
|
120
|
+
children?: ToolbarSlot;
|
|
121
|
+
before?: ToolbarSlot;
|
|
122
|
+
after?: ToolbarSlot;
|
|
123
|
+
}
|
|
124
|
+
declare const FloatingToolbar: react.ForwardRefExoticComponent<Omit<FloatingToolbarProps, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
125
|
+
|
|
67
126
|
interface HistoryVersionPreviewProps extends ComponentPropsWithoutRef<"div"> {
|
|
68
127
|
version: HistoryVersion;
|
|
69
128
|
editor: Editor;
|
|
@@ -79,15 +138,8 @@ declare const HistoryVersionPreview: react.ForwardRefExoticComponent<HistoryVers
|
|
|
79
138
|
|
|
80
139
|
declare module "@tiptap/core" {
|
|
81
140
|
interface Commands<ReturnType> {
|
|
82
|
-
comments:
|
|
83
|
-
/**
|
|
84
|
-
* Add a comment
|
|
85
|
-
*/
|
|
86
|
-
addComment: (id: string) => ReturnType;
|
|
87
|
-
selectThread: (id: string | null) => ReturnType;
|
|
88
|
-
addPendingComment: () => ReturnType;
|
|
89
|
-
};
|
|
141
|
+
comments: CommentsCommands<ReturnType>;
|
|
90
142
|
}
|
|
91
143
|
}
|
|
92
144
|
|
|
93
|
-
export { AnchoredThreads, FloatingComposer, FloatingThreads, HistoryVersionPreview, useIsEditorReady, useLiveblocksExtension };
|
|
145
|
+
export { AnchoredThreads, FloatingComposer, FloatingThreads, FloatingToolbar, HistoryVersionPreview, Toolbar, useIsEditorReady, useLiveblocksExtension };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,11 +3,21 @@ import { BaseMetadata, DM, ThreadData, HistoryVersion } from '@liveblocks/core';
|
|
|
3
3
|
import { ThreadProps, ComposerProps } from '@liveblocks/react-ui';
|
|
4
4
|
import { Editor } from '@tiptap/react';
|
|
5
5
|
import * as react from 'react';
|
|
6
|
-
import { ComponentPropsWithoutRef, ComponentType, HTMLAttributes } from 'react';
|
|
6
|
+
import { ComponentPropsWithoutRef, ComponentType, HTMLAttributes, ComponentProps, ReactNode } from 'react';
|
|
7
7
|
import { BaseMetadata as BaseMetadata$1 } from '@liveblocks/client';
|
|
8
8
|
import { Extension, Content } from '@tiptap/core';
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
type FloatingPosition = "top" | "bottom";
|
|
11
|
+
type CommentsCommands<ReturnType> = {
|
|
12
|
+
/**
|
|
13
|
+
* Add a comment
|
|
14
|
+
*/
|
|
15
|
+
addComment: (id: string) => ReturnType;
|
|
16
|
+
selectThread: (id: string | null) => ReturnType;
|
|
17
|
+
addPendingComment: () => ReturnType;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type AnchoredThreadsComponents = {
|
|
11
21
|
Thread: ComponentType<ThreadProps>;
|
|
12
22
|
};
|
|
13
23
|
interface AnchoredThreadsProps<M extends BaseMetadata = DM> extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
|
|
@@ -30,7 +40,7 @@ declare const FloatingComposer: react.ForwardRefExoticComponent<Omit<ComposerPro
|
|
|
30
40
|
editor: Editor | null;
|
|
31
41
|
} & react.RefAttributes<HTMLFormElement>>;
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
type ThreadPanelComponents = {
|
|
34
44
|
Thread: ComponentType<ThreadProps>;
|
|
35
45
|
};
|
|
36
46
|
interface FloatingThreadsProps<M extends BaseMetadata = DM> extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
@@ -49,7 +59,7 @@ interface FloatingThreadsProps<M extends BaseMetadata = DM> extends Omit<HTMLAtt
|
|
|
49
59
|
}
|
|
50
60
|
declare function FloatingThreads({ threads, components, editor, ...props }: FloatingThreadsProps): react_jsx_runtime.JSX.Element | null;
|
|
51
61
|
|
|
52
|
-
|
|
62
|
+
type LiveblocksExtensionOptions = {
|
|
53
63
|
field?: string;
|
|
54
64
|
comments?: boolean;
|
|
55
65
|
mentions?: boolean;
|
|
@@ -64,6 +74,55 @@ declare type LiveblocksExtensionOptions = {
|
|
|
64
74
|
declare function useIsEditorReady(): boolean;
|
|
65
75
|
declare const useLiveblocksExtension: (opts?: LiveblocksExtensionOptions) => Extension;
|
|
66
76
|
|
|
77
|
+
interface ToolbarSlotProps {
|
|
78
|
+
editor: Editor;
|
|
79
|
+
}
|
|
80
|
+
type ToolbarSlot = ReactNode | ComponentType<ToolbarSlotProps>;
|
|
81
|
+
interface ToolbarProps extends Omit<ComponentProps<"div">, "children"> {
|
|
82
|
+
editor: Editor | null;
|
|
83
|
+
children?: ToolbarSlot;
|
|
84
|
+
before?: ToolbarSlot;
|
|
85
|
+
after?: ToolbarSlot;
|
|
86
|
+
}
|
|
87
|
+
interface ToolbarButtonProps extends ComponentProps<"button"> {
|
|
88
|
+
icon?: ReactNode;
|
|
89
|
+
name: string;
|
|
90
|
+
shortcut?: string;
|
|
91
|
+
}
|
|
92
|
+
interface ToolbarToggleProps extends ToolbarButtonProps {
|
|
93
|
+
active: boolean;
|
|
94
|
+
}
|
|
95
|
+
interface ToolbarBlockSelectorItem {
|
|
96
|
+
name: string;
|
|
97
|
+
isActive: (editor: Editor) => boolean;
|
|
98
|
+
setActive: (editor: Editor) => void;
|
|
99
|
+
}
|
|
100
|
+
interface ToolbarBlockSelectorProps extends ComponentProps<"button"> {
|
|
101
|
+
items?: ToolbarBlockSelectorItem[];
|
|
102
|
+
}
|
|
103
|
+
declare function ToolbarSectionHistory(): react_jsx_runtime.JSX.Element;
|
|
104
|
+
declare function ToolbarSectionInline(): react_jsx_runtime.JSX.Element;
|
|
105
|
+
declare function ToolbarSectionCollaboration(): react_jsx_runtime.JSX.Element;
|
|
106
|
+
declare const Toolbar: react.ForwardRefExoticComponent<Omit<ToolbarProps, "ref"> & react.RefAttributes<HTMLDivElement>> & {
|
|
107
|
+
Button: react.ForwardRefExoticComponent<Omit<ToolbarButtonProps, "ref"> & react.RefAttributes<HTMLButtonElement>>;
|
|
108
|
+
Toggle: react.ForwardRefExoticComponent<Omit<ToolbarToggleProps, "ref"> & react.RefAttributes<HTMLButtonElement>>;
|
|
109
|
+
Separator: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
110
|
+
SectionHistory: typeof ToolbarSectionHistory;
|
|
111
|
+
SectionInline: typeof ToolbarSectionInline;
|
|
112
|
+
SectionCollaboration: typeof ToolbarSectionCollaboration;
|
|
113
|
+
BlockSelector: react.ForwardRefExoticComponent<Omit<ToolbarBlockSelectorProps, "ref"> & react.RefAttributes<HTMLButtonElement>>;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
interface FloatingToolbarProps extends Omit<ComponentProps<"div">, "children"> {
|
|
117
|
+
editor: Editor | null;
|
|
118
|
+
position?: FloatingPosition;
|
|
119
|
+
offset?: number;
|
|
120
|
+
children?: ToolbarSlot;
|
|
121
|
+
before?: ToolbarSlot;
|
|
122
|
+
after?: ToolbarSlot;
|
|
123
|
+
}
|
|
124
|
+
declare const FloatingToolbar: react.ForwardRefExoticComponent<Omit<FloatingToolbarProps, "ref"> & react.RefAttributes<HTMLDivElement>>;
|
|
125
|
+
|
|
67
126
|
interface HistoryVersionPreviewProps extends ComponentPropsWithoutRef<"div"> {
|
|
68
127
|
version: HistoryVersion;
|
|
69
128
|
editor: Editor;
|
|
@@ -79,15 +138,8 @@ declare const HistoryVersionPreview: react.ForwardRefExoticComponent<HistoryVers
|
|
|
79
138
|
|
|
80
139
|
declare module "@tiptap/core" {
|
|
81
140
|
interface Commands<ReturnType> {
|
|
82
|
-
comments:
|
|
83
|
-
/**
|
|
84
|
-
* Add a comment
|
|
85
|
-
*/
|
|
86
|
-
addComment: (id: string) => ReturnType;
|
|
87
|
-
selectThread: (id: string | null) => ReturnType;
|
|
88
|
-
addPendingComment: () => ReturnType;
|
|
89
|
-
};
|
|
141
|
+
comments: CommentsCommands<ReturnType>;
|
|
90
142
|
}
|
|
91
143
|
}
|
|
92
144
|
|
|
93
|
-
export { AnchoredThreads, FloatingComposer, FloatingThreads, HistoryVersionPreview, useIsEditorReady, useLiveblocksExtension };
|
|
145
|
+
export { AnchoredThreads, FloatingComposer, FloatingThreads, FloatingToolbar, HistoryVersionPreview, Toolbar, useIsEditorReady, useLiveblocksExtension };
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,8 @@ var AnchoredThreads = require('./comments/AnchoredThreads.js');
|
|
|
6
6
|
var FloatingComposer = require('./comments/FloatingComposer.js');
|
|
7
7
|
var FloatingThreads = require('./comments/FloatingThreads.js');
|
|
8
8
|
var LiveblocksExtension = require('./LiveblocksExtension.js');
|
|
9
|
+
var FloatingToolbar = require('./toolbar/FloatingToolbar.js');
|
|
10
|
+
var Toolbar = require('./toolbar/Toolbar.js');
|
|
9
11
|
var HistoryVersionPreview = require('./version-history/HistoryVersionPreview.js');
|
|
10
12
|
|
|
11
13
|
core.detectDupes(version.PKG_NAME, version.PKG_VERSION, version.PKG_FORMAT);
|
|
@@ -15,5 +17,7 @@ exports.FloatingComposer = FloatingComposer.FloatingComposer;
|
|
|
15
17
|
exports.FloatingThreads = FloatingThreads.FloatingThreads;
|
|
16
18
|
exports.useIsEditorReady = LiveblocksExtension.useIsEditorReady;
|
|
17
19
|
exports.useLiveblocksExtension = LiveblocksExtension.useLiveblocksExtension;
|
|
20
|
+
exports.FloatingToolbar = FloatingToolbar.FloatingToolbar;
|
|
21
|
+
exports.Toolbar = Toolbar.Toolbar;
|
|
18
22
|
exports.HistoryVersionPreview = HistoryVersionPreview.HistoryVersionPreview;
|
|
19
23
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport { AnchoredThreads } from \"./comments/AnchoredThreads\";\nexport { FloatingComposer } from \"./comments/FloatingComposer\";\nexport { FloatingThreads } from \"./comments/FloatingThreads\";\nexport { useLiveblocksExtension } from \"./LiveblocksExtension\";\nexport { useIsEditorReady } from \"./LiveblocksExtension\";\nexport { HistoryVersionPreview } from \"./version-history/HistoryVersionPreview\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n comments:
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport type { CommentsCommands } from \"./types\";\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport { AnchoredThreads } from \"./comments/AnchoredThreads\";\nexport { FloatingComposer } from \"./comments/FloatingComposer\";\nexport { FloatingThreads } from \"./comments/FloatingThreads\";\nexport { useLiveblocksExtension } from \"./LiveblocksExtension\";\nexport { useIsEditorReady } from \"./LiveblocksExtension\";\nexport { FloatingToolbar } from \"./toolbar/FloatingToolbar\";\nexport { Toolbar } from \"./toolbar/Toolbar\";\nexport { HistoryVersionPreview } from \"./version-history/HistoryVersionPreview\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n comments: CommentsCommands<ReturnType>;\n }\n}\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;;;;;;AAKAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;;;;;;;"}
|
package/dist/index.mjs
CHANGED
|
@@ -4,6 +4,8 @@ export { AnchoredThreads } from './comments/AnchoredThreads.mjs';
|
|
|
4
4
|
export { FloatingComposer } from './comments/FloatingComposer.mjs';
|
|
5
5
|
export { FloatingThreads } from './comments/FloatingThreads.mjs';
|
|
6
6
|
export { useIsEditorReady, useLiveblocksExtension } from './LiveblocksExtension.mjs';
|
|
7
|
+
export { FloatingToolbar } from './toolbar/FloatingToolbar.mjs';
|
|
8
|
+
export { Toolbar } from './toolbar/Toolbar.mjs';
|
|
7
9
|
export { HistoryVersionPreview } from './version-history/HistoryVersionPreview.mjs';
|
|
8
10
|
|
|
9
11
|
detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport { AnchoredThreads } from \"./comments/AnchoredThreads\";\nexport { FloatingComposer } from \"./comments/FloatingComposer\";\nexport { FloatingThreads } from \"./comments/FloatingThreads\";\nexport { useLiveblocksExtension } from \"./LiveblocksExtension\";\nexport { useIsEditorReady } from \"./LiveblocksExtension\";\nexport { HistoryVersionPreview } from \"./version-history/HistoryVersionPreview\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n comments:
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport type { CommentsCommands } from \"./types\";\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport { AnchoredThreads } from \"./comments/AnchoredThreads\";\nexport { FloatingComposer } from \"./comments/FloatingComposer\";\nexport { FloatingThreads } from \"./comments/FloatingThreads\";\nexport { useLiveblocksExtension } from \"./LiveblocksExtension\";\nexport { useIsEditorReady } from \"./LiveblocksExtension\";\nexport { FloatingToolbar } from \"./toolbar/FloatingToolbar\";\nexport { Toolbar } from \"./toolbar/Toolbar\";\nexport { HistoryVersionPreview } from \"./version-history/HistoryVersionPreview\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n comments: CommentsCommands<ReturnType>;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;AAKA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
|
|
@@ -25,118 +25,128 @@ const User = react.forwardRef(
|
|
|
25
25
|
}
|
|
26
26
|
);
|
|
27
27
|
const SUGGESTIONS_COLLISION_PADDING = 10;
|
|
28
|
-
const MentionsList = react.forwardRef(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
getBoundingClientRect: props.clientRect
|
|
57
|
-
});
|
|
58
|
-
}, [setReference, props.clientRect]);
|
|
59
|
-
const selectItem = (index) => {
|
|
60
|
-
const item = (suggestions ?? [])[index];
|
|
61
|
-
if (item) {
|
|
62
|
-
props.command({ id: item, notificationId: core.createInboxNotificationId() });
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
const upHandler = () => {
|
|
66
|
-
setSelectedIndex((selectedIndex + (suggestions?.length ?? 0) - 1) % (suggestions?.length ?? 0));
|
|
67
|
-
};
|
|
68
|
-
const downHandler = () => {
|
|
69
|
-
setSelectedIndex((selectedIndex + 1) % (suggestions?.length ?? 0));
|
|
70
|
-
};
|
|
71
|
-
const enterHandler = () => {
|
|
72
|
-
selectItem(selectedIndex);
|
|
73
|
-
};
|
|
74
|
-
react.useEffect(() => setSelectedIndex(0), [suggestions]);
|
|
75
|
-
react.useImperativeHandle(ref, () => ({
|
|
76
|
-
onKeyDown: ({ event }) => {
|
|
77
|
-
if (event.key === "ArrowUp") {
|
|
78
|
-
upHandler();
|
|
79
|
-
return true;
|
|
28
|
+
const MentionsList = react.forwardRef(
|
|
29
|
+
(props, ref) => {
|
|
30
|
+
const [selectedIndex, setSelectedIndex] = react.useState(0);
|
|
31
|
+
const room = react$1.useRoom();
|
|
32
|
+
const suggestions = _private.useMentionSuggestions(room.id, props.query);
|
|
33
|
+
const { onMouseEnter, onClick } = props;
|
|
34
|
+
const {
|
|
35
|
+
refs: { setReference, setFloating },
|
|
36
|
+
strategy,
|
|
37
|
+
x,
|
|
38
|
+
y
|
|
39
|
+
} = reactDom.useFloating({
|
|
40
|
+
strategy: "fixed",
|
|
41
|
+
placement: "top-start",
|
|
42
|
+
middleware: [
|
|
43
|
+
reactDom.flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),
|
|
44
|
+
reactDom.offset(10),
|
|
45
|
+
reactDom.hide({ padding: SUGGESTIONS_COLLISION_PADDING }),
|
|
46
|
+
reactDom.shift({
|
|
47
|
+
padding: SUGGESTIONS_COLLISION_PADDING,
|
|
48
|
+
limiter: reactDom.limitShift()
|
|
49
|
+
}),
|
|
50
|
+
reactDom.size({ padding: SUGGESTIONS_COLLISION_PADDING })
|
|
51
|
+
],
|
|
52
|
+
whileElementsMounted: (...args) => {
|
|
53
|
+
return reactDom.autoUpdate(...args, {
|
|
54
|
+
animationFrame: true
|
|
55
|
+
});
|
|
80
56
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
57
|
+
});
|
|
58
|
+
_private.useLayoutEffect(() => {
|
|
59
|
+
setReference({
|
|
60
|
+
getBoundingClientRect: props.clientRect
|
|
61
|
+
});
|
|
62
|
+
}, [setReference, props.clientRect]);
|
|
63
|
+
const selectItem = (index) => {
|
|
64
|
+
const item = (suggestions ?? [])[index];
|
|
65
|
+
if (item) {
|
|
66
|
+
props.command({
|
|
67
|
+
id: item,
|
|
68
|
+
notificationId: core.createInboxNotificationId()
|
|
69
|
+
});
|
|
84
70
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
71
|
+
};
|
|
72
|
+
const upHandler = () => {
|
|
73
|
+
setSelectedIndex(
|
|
74
|
+
(selectedIndex + (suggestions?.length ?? 0) - 1) % (suggestions?.length ?? 0)
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
const downHandler = () => {
|
|
78
|
+
setSelectedIndex((selectedIndex + 1) % (suggestions?.length ?? 0));
|
|
79
|
+
};
|
|
80
|
+
const enterHandler = () => {
|
|
81
|
+
selectItem(selectedIndex);
|
|
82
|
+
};
|
|
83
|
+
react.useEffect(() => setSelectedIndex(0), [suggestions]);
|
|
84
|
+
react.useImperativeHandle(ref, () => ({
|
|
85
|
+
onKeyDown: ({ event }) => {
|
|
86
|
+
if (event.key === "ArrowUp") {
|
|
87
|
+
upHandler();
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
if (event.key === "ArrowDown") {
|
|
91
|
+
downHandler();
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
if (event.key === "Enter") {
|
|
95
|
+
enterHandler();
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
88
99
|
}
|
|
89
|
-
|
|
100
|
+
}));
|
|
101
|
+
const handleClick = (index) => (event) => {
|
|
102
|
+
onClick?.(event);
|
|
103
|
+
if (event.isDefaultPrevented())
|
|
104
|
+
return;
|
|
105
|
+
selectItem(index);
|
|
106
|
+
};
|
|
107
|
+
const handleMouseEnter = (index) => (event) => {
|
|
108
|
+
onMouseEnter?.(event);
|
|
109
|
+
if (event.isDefaultPrevented())
|
|
110
|
+
return;
|
|
111
|
+
setSelectedIndex(index);
|
|
112
|
+
};
|
|
113
|
+
if (suggestions === void 0 || suggestions.length === 0) {
|
|
114
|
+
return null;
|
|
90
115
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
116
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
117
|
+
className: "lb-root lb-portal lb-elevation lb-tiptap-suggestions lb-tiptap-mention-suggestions",
|
|
118
|
+
ref: setFloating,
|
|
119
|
+
style: {
|
|
120
|
+
position: strategy,
|
|
121
|
+
top: 0,
|
|
122
|
+
left: 0,
|
|
123
|
+
transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
|
|
124
|
+
minWidth: "max-content",
|
|
125
|
+
display: props.hide ? "none" : "block"
|
|
126
|
+
},
|
|
127
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
128
|
+
className: "lb-tiptap-suggestions-list lb-tiptap-mention-suggestions-list",
|
|
129
|
+
children: suggestions.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
130
|
+
className: "lb-tiptap-suggestions-list-item lb-tiptap-mention-suggestion",
|
|
131
|
+
role: "option",
|
|
132
|
+
"data-highlighted": index === selectedIndex || void 0,
|
|
133
|
+
onMouseEnter: handleMouseEnter(index),
|
|
134
|
+
onClick: handleClick(index),
|
|
135
|
+
children: [
|
|
136
|
+
/* @__PURE__ */ jsxRuntime.jsx(Avatar.Avatar, {
|
|
137
|
+
userId: item,
|
|
138
|
+
className: "lb-tiptap-mention-suggestion-avatar"
|
|
139
|
+
}),
|
|
140
|
+
/* @__PURE__ */ jsxRuntime.jsx(User, {
|
|
141
|
+
userId: item,
|
|
142
|
+
className: "lb-tiptap-mention-suggestion-user"
|
|
143
|
+
})
|
|
144
|
+
]
|
|
145
|
+
}, index))
|
|
146
|
+
})
|
|
147
|
+
});
|
|
106
148
|
}
|
|
107
|
-
|
|
108
|
-
className: "lb-root lb-portal lb-elevation lb-tiptap-suggestions lb-tiptap-mention-suggestions",
|
|
109
|
-
ref: setFloating,
|
|
110
|
-
style: {
|
|
111
|
-
position: strategy,
|
|
112
|
-
top: 0,
|
|
113
|
-
left: 0,
|
|
114
|
-
transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
|
|
115
|
-
minWidth: "max-content",
|
|
116
|
-
display: props.hide ? "none" : "block"
|
|
117
|
-
},
|
|
118
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
119
|
-
className: "lb-tiptap-suggestions-list lb-tiptap-mention-suggestions-list",
|
|
120
|
-
children: suggestions.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
121
|
-
className: "lb-tiptap-suggestions-list-item lb-tiptap-mention-suggestion",
|
|
122
|
-
role: "option",
|
|
123
|
-
"data-highlighted": index === selectedIndex || void 0,
|
|
124
|
-
onMouseEnter: handleMouseEnter(index),
|
|
125
|
-
onClick: handleClick(index),
|
|
126
|
-
children: [
|
|
127
|
-
/* @__PURE__ */ jsxRuntime.jsx(Avatar.Avatar, {
|
|
128
|
-
userId: item,
|
|
129
|
-
className: "lb-tiptap-mention-suggestion-avatar"
|
|
130
|
-
}),
|
|
131
|
-
/* @__PURE__ */ jsxRuntime.jsx(User, {
|
|
132
|
-
userId: item,
|
|
133
|
-
className: "lb-tiptap-mention-suggestion-user"
|
|
134
|
-
})
|
|
135
|
-
]
|
|
136
|
-
}, index))
|
|
137
|
-
})
|
|
138
|
-
});
|
|
139
|
-
});
|
|
149
|
+
);
|
|
140
150
|
|
|
141
151
|
exports.MentionsList = MentionsList;
|
|
142
152
|
exports.SUGGESTIONS_COLLISION_PADDING = SUGGESTIONS_COLLISION_PADDING;
|