@liveblocks/react-tiptap 2.16.0-toolbars2 → 2.16.0-toolbars4
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/index.d.mts +195 -5
- package/dist/index.d.ts +195 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/toolbar/FloatingToolbar.js +8 -13
- package/dist/toolbar/FloatingToolbar.js.map +1 -1
- package/dist/toolbar/FloatingToolbar.mjs +8 -13
- package/dist/toolbar/FloatingToolbar.mjs.map +1 -1
- package/dist/toolbar/Toolbar.js +70 -28
- package/dist/toolbar/Toolbar.js.map +1 -1
- package/dist/toolbar/Toolbar.mjs +72 -30
- package/dist/toolbar/Toolbar.mjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.mjs +1 -1
- package/package.json +6 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingToolbar.js","sources":["../../src/toolbar/FloatingToolbar.tsx"],"sourcesContent":["import {\n autoUpdate,\n type DetectOverflowOptions,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n type UseFloatingOptions,\n} from \"@floating-ui/react-dom\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n TooltipProvider,\n useInitial,\n useRefs,\n} from \"@liveblocks/react-ui/_private\";\nimport { type Editor, isTextSelection, useEditorState } from \"@tiptap/react\";\nimport type {\n ComponentProps,\n FocusEvent as ReactFocusEvent,\n PointerEvent as ReactPointerEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport { EditorProvider } from \"../context\";\nimport type { FloatingPosition } from \"../types\";\nimport { FloatingToolbarContext, FloatingToolbarExternal } from \"./shared\";\nimport {\n applyToolbarSlot,\n Toolbar,\n type ToolbarSlot,\n type ToolbarSlotProps,\n} from \"./Toolbar\";\n\nexport interface FloatingToolbarProps\n extends Omit<ComponentProps<\"div\">, \"children\"> {\n editor: Editor | null;\n position?: FloatingPosition;\n offset?: number;\n children?: ToolbarSlot;\n before?: ToolbarSlot;\n after?: ToolbarSlot;\n}\n\nexport const FLOATING_TOOLBAR_COLLISION_PADDING = 10;\nconst FLOATING_TOOLBAR_OPEN_DELAY = 50;\n\nfunction DefaultFloatingToolbarContent({ editor }: ToolbarSlotProps) {\n const supportsThread = \"addPendingComment\" in editor.commands;\n\n return (\n <>\n <Toolbar.BlockSelector />\n <Toolbar.SectionInline />\n {supportsThread ? (\n <>\n <Toolbar.Separator />\n <Toolbar.SectionCollaboration />\n </>\n ) : null}\n </>\n );\n}\n\nexport const FloatingToolbar = Object.assign(\n forwardRef<HTMLDivElement, FloatingToolbarProps>(\n (\n {\n children = DefaultFloatingToolbarContent,\n before,\n after,\n position = \"top\",\n offset: sideOffset = 6,\n editor,\n onPointerDown,\n onFocus,\n onBlur,\n className,\n ...props\n },\n forwardedRef\n ) => {\n const toolbarRef = useRef<HTMLDivElement>(null);\n const externalIds = useInitial<Set<string>>(() => new Set());\n const [isPointerDown, setPointerDown] = useState(false);\n const [isFocused, setFocused] = useState(false);\n const [isManuallyClosed, setManuallyClosed] = useState(false);\n const isEditable =\n useEditorState({\n editor,\n equalityFn: Object.is,\n selector: (ctx) => ctx.editor?.isEditable ?? false,\n }) ?? false;\n const hasSelectionRange =\n useEditorState({\n editor,\n equalityFn: Object.is,\n selector: (ctx) => {\n const editor = ctx.editor;\n\n if (!editor) {\n return false;\n }\n\n const { doc, selection } = editor.state;\n const { empty, ranges } = selection;\n const from = Math.min(...ranges.map((range) => range.$from.pos));\n const to = Math.max(...ranges.map((range) => range.$to.pos));\n\n if (empty) {\n return false;\n }\n\n return (\n isTextSelection(selection) && doc.textBetween(from, to).length > 0\n );\n },\n }) ?? false;\n\n const isOpen =\n isFocused && !isPointerDown && hasSelectionRange && !isManuallyClosed;\n const [delayedIsOpen, setDelayedIsOpen] = useState(isOpen);\n const delayedIsOpenTimeoutRef = useRef<number>();\n\n // Reset the manually closed state when there's another change\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n setManuallyClosed(false);\n\n const handleSelectionChange = () => {\n setManuallyClosed(false);\n };\n\n editor.on(\"selectionUpdate\", handleSelectionChange);\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionChange);\n };\n }, [isFocused, hasSelectionRange, editor]);\n\n // Don't close when the focus moves from the editor to the toolbar\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const handleFocus = () => {\n setFocused(true);\n };\n\n const handleBlur = (event: FocusEvent) => {\n if (\n event.relatedTarget &&\n toolbarRef.current?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n if (event.relatedTarget === editor.view.dom) {\n return;\n }\n\n for (const externalId of externalIds) {\n if (\n document\n .getElementById(externalId)\n ?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n }\n\n setFocused(false);\n };\n\n editor.view.dom.addEventListener(\"focus\", handleFocus);\n editor.view.dom.addEventListener(\"blur\", handleBlur);\n\n return () => {\n editor.view.dom.removeEventListener(\"focus\", handleFocus);\n editor.view.dom.removeEventListener(\"blur\", handleBlur);\n };\n }, [editor, externalIds]);\n\n const handleFocus = useCallback(\n (event: ReactFocusEvent<HTMLDivElement>) => {\n onFocus?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(true);\n }\n },\n [onFocus]\n );\n\n // Close the toolbar when the it loses focus to something else than the editor\n const handleBlur = useCallback(\n (event: ReactFocusEvent<HTMLDivElement>) => {\n onBlur?.(event);\n\n if (!event.isDefaultPrevented()) {\n if (\n event.relatedTarget &&\n toolbarRef.current?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n if (event.relatedTarget === editor?.view.dom) {\n return;\n }\n\n for (const externalId of externalIds) {\n if (\n document\n .getElementById(externalId)\n ?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n }\n\n setFocused(false);\n }\n },\n [onBlur, editor, externalIds]\n );\n\n // Delay the opening of the toolbar to avoid flickering issues\n useEffect(() => {\n if (isOpen) {\n delayedIsOpenTimeoutRef.current = window.setTimeout(() => {\n setDelayedIsOpen(true);\n }, FLOATING_TOOLBAR_OPEN_DELAY);\n } else {\n setDelayedIsOpen(false);\n }\n\n return () => {\n window.clearTimeout(delayedIsOpenTimeoutRef.current);\n };\n }, [isOpen]);\n\n const floatingOptions: UseFloatingOptions = useMemo(() => {\n const detectOverflowOptions: DetectOverflowOptions = {\n padding: FLOATING_TOOLBAR_COLLISION_PADDING,\n };\n\n return {\n strategy: \"fixed\",\n placement: position,\n middleware: [\n inline(detectOverflowOptions),\n flip({ ...detectOverflowOptions, crossAxis: false }),\n hide(detectOverflowOptions),\n shift({\n ...detectOverflowOptions,\n limiter: limitShift(),\n }),\n offset(sideOffset),\n size(detectOverflowOptions),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n };\n }, [position, sideOffset]);\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n isPositioned,\n } = useFloating({\n ...floatingOptions,\n open: delayedIsOpen,\n });\n const mergedRefs = useRefs(forwardedRef, toolbarRef, setFloating);\n\n const handlePointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n onPointerDown?.(event);\n\n event.stopPropagation();\n\n // Prevent the toolbar from closing when clicking on the toolbar itself\n if (event.target === toolbarRef.current) {\n event.preventDefault();\n }\n },\n [onPointerDown]\n );\n\n useEffect(() => {\n if (!editor || !isEditable) {\n return;\n }\n\n const handlePointerDown = () => {\n setPointerDown(true);\n };\n const handlePointerUp = () => {\n setPointerDown(false);\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n document.addEventListener(\"pointercancel\", handlePointerUp);\n document.addEventListener(\"pointerup\", handlePointerUp);\n\n return () => {\n document.removeEventListener(\"pointerdown\", handlePointerDown);\n document.removeEventListener(\"pointercancel\", handlePointerUp);\n document.removeEventListener(\"pointerup\", handlePointerUp);\n };\n }, [editor, isEditable]);\n\n useLayoutEffect(() => {\n if (!editor || !delayedIsOpen) {\n return;\n }\n\n const updateSelectionReference = () => {\n const domSelection = window.getSelection();\n\n if (\n editor.state.selection.empty ||\n !domSelection ||\n !domSelection.rangeCount\n ) {\n setReference(null);\n } else {\n const domRange = domSelection.getRangeAt(0);\n\n setReference(domRange);\n }\n };\n\n editor.on(\"transaction\", updateSelectionReference);\n updateSelectionReference();\n\n return () => {\n editor.off(\"transaction\", updateSelectionReference);\n };\n }, [editor, delayedIsOpen, setReference]);\n\n useEffect(() => {\n if (!editor || !delayedIsOpen) {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.target !== editor.view.dom && event.defaultPrevented) {\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n\n editor.commands.focus();\n setManuallyClosed(true);\n }\n };\n\n editor.view.dom.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n editor.view.dom.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [editor, delayedIsOpen]);\n\n const close = useCallback(() => {\n setManuallyClosed(true);\n }, [setManuallyClosed]);\n\n const registerExternal = useCallback(\n (id: string) => {\n externalIds.add(id);\n\n return () => {\n externalIds.delete(id);\n };\n },\n [externalIds]\n );\n\n if (!editor || !delayedIsOpen) {\n return null;\n }\n\n const slotProps: ToolbarSlotProps = { editor };\n\n return createPortal(\n <TooltipProvider>\n <EditorProvider editor={editor}>\n <FloatingToolbarContext.Provider\n value={{ close, registerExternal }}\n >\n <div\n role=\"toolbar\"\n aria-label=\"Floating toolbar\"\n aria-orientation=\"horizontal\"\n className={classNames(\n \"lb-root lb-portal lb-elevation lb-tiptap-floating-toolbar lb-tiptap-toolbar\",\n className\n )}\n ref={mergedRefs}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: isPositioned\n ? `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`\n : \"translate3d(0, -200%, 0)\",\n minWidth: \"max-content\",\n }}\n onPointerDown={handlePointerDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n {...props}\n >\n {applyToolbarSlot(before, slotProps)}\n {applyToolbarSlot(children, slotProps)}\n {applyToolbarSlot(after, slotProps)}\n </div>\n </FloatingToolbarContext.Provider>\n </EditorProvider>\n </TooltipProvider>,\n document.body\n );\n }\n ),\n {\n External: FloatingToolbarExternal,\n }\n);\n"],"names":["jsxs","Fragment","jsx","Toolbar","forwardRef","useRef","useInitial","useState","useEditorState","editor","isTextSelection","useEffect","handleFocus","handleBlur","useCallback","useMemo","inline","flip","hide","shift","limitShift","offset","size","autoUpdate","useFloating","useRefs","handlePointerDown","useLayoutEffect","createPortal","TooltipProvider","EditorProvider","FloatingToolbarContext","classNames","applyToolbarSlot","FloatingToolbarExternal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FloatingToolbar.js","sources":["../../src/toolbar/FloatingToolbar.tsx"],"sourcesContent":["import {\n autoUpdate,\n type DetectOverflowOptions,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n type UseFloatingOptions,\n} from \"@floating-ui/react-dom\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n TooltipProvider,\n useInitial,\n useRefs,\n} from \"@liveblocks/react-ui/_private\";\nimport { type Editor, isTextSelection, useEditorState } from \"@tiptap/react\";\nimport type {\n ComponentProps,\n FocusEvent as ReactFocusEvent,\n PointerEvent as ReactPointerEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport { EditorProvider } from \"../context\";\nimport type { FloatingPosition } from \"../types\";\nimport { FloatingToolbarContext, FloatingToolbarExternal } from \"./shared\";\nimport {\n applyToolbarSlot,\n Toolbar,\n type ToolbarSlot,\n type ToolbarSlotProps,\n} from \"./Toolbar\";\n\nexport interface FloatingToolbarProps\n extends Omit<ComponentProps<\"div\">, \"children\"> {\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n\n /**\n * The vertical position of the floating toolbar.\n */\n position?: FloatingPosition;\n\n /**\n * The vertical offset of the floating toolbar from the selection.\n */\n offset?: number;\n\n /**\n * The content of the floating toolbar, overriding the default content.\n * Use the `before` and `after` props if you want to keep and extend the default content.\n */\n children?: ToolbarSlot;\n\n /**\n * The content to display at the start of the floating toolbar.\n */\n before?: ToolbarSlot;\n\n /**\n * The content to display at the end of the floating toolbar.\n */\n after?: ToolbarSlot;\n}\n\nexport const FLOATING_TOOLBAR_COLLISION_PADDING = 10;\nconst FLOATING_TOOLBAR_OPEN_DELAY = 50;\n\nfunction DefaultFloatingToolbarContent({ editor }: ToolbarSlotProps) {\n const supportsThread = \"addPendingComment\" in editor.commands;\n\n return (\n <>\n <Toolbar.BlockSelector />\n <Toolbar.SectionInline />\n {supportsThread ? (\n <>\n <Toolbar.Separator />\n <Toolbar.SectionCollaboration />\n </>\n ) : null}\n </>\n );\n}\n\n/**\n * A floating toolbar attached to the selection and containing actions and values related to the editor.\n *\n * @example\n * <FloatingToolbar editor={editor} />\n *\n * @example\n * <FloatingToolbar editor={editor}>\n * <Toolbar.BlockSelector />\n * <Toolbar.Separator />\n * <Toolbar.SectionInline />\n * <Toolbar.Separator />\n * <Toolbar.Button name=\"Custom action\" onClick={() => { ... }} icon={<Icon.QuestionMark />} />\n * </FloatingToolbar>\n */\nexport const FloatingToolbar = Object.assign(\n forwardRef<HTMLDivElement, FloatingToolbarProps>(\n (\n {\n children = DefaultFloatingToolbarContent,\n before,\n after,\n position = \"top\",\n offset: sideOffset = 6,\n editor,\n onPointerDown,\n onFocus,\n onBlur,\n className,\n ...props\n },\n forwardedRef\n ) => {\n const toolbarRef = useRef<HTMLDivElement>(null);\n const externalIds = useInitial<Set<string>>(() => new Set());\n const [isPointerDown, setPointerDown] = useState(false);\n const [isFocused, setFocused] = useState(false);\n const [isManuallyClosed, setManuallyClosed] = useState(false);\n const hasSelectionRange =\n useEditorState({\n editor,\n equalityFn: Object.is,\n selector: (ctx) => {\n const editor = ctx.editor;\n\n if (!editor) {\n return false;\n }\n\n const { doc, selection } = editor.state;\n const { empty, ranges } = selection;\n const from = Math.min(...ranges.map((range) => range.$from.pos));\n const to = Math.max(...ranges.map((range) => range.$to.pos));\n\n if (empty) {\n return false;\n }\n\n return (\n isTextSelection(selection) && doc.textBetween(from, to).length > 0\n );\n },\n }) ?? false;\n\n const isOpen =\n isFocused && !isPointerDown && hasSelectionRange && !isManuallyClosed;\n const [delayedIsOpen, setDelayedIsOpen] = useState(isOpen);\n const delayedIsOpenTimeoutRef = useRef<number>();\n\n // Reset the manually closed state when there's another change\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n setManuallyClosed(false);\n\n const handleSelectionChange = () => {\n setManuallyClosed(false);\n };\n\n editor.on(\"selectionUpdate\", handleSelectionChange);\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionChange);\n };\n }, [isFocused, hasSelectionRange, editor]);\n\n // Don't close when the focus moves from the editor to the toolbar\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const handleFocus = () => {\n setFocused(true);\n };\n\n const handleBlur = (event: FocusEvent) => {\n if (\n event.relatedTarget &&\n toolbarRef.current?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n if (event.relatedTarget === editor.view.dom) {\n return;\n }\n\n for (const externalId of externalIds) {\n if (\n document\n .getElementById(externalId)\n ?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n }\n\n setFocused(false);\n };\n\n editor.view.dom.addEventListener(\"focus\", handleFocus);\n editor.view.dom.addEventListener(\"blur\", handleBlur);\n\n return () => {\n editor.view.dom.removeEventListener(\"focus\", handleFocus);\n editor.view.dom.removeEventListener(\"blur\", handleBlur);\n };\n }, [editor, externalIds]);\n\n const handleFocus = useCallback(\n (event: ReactFocusEvent<HTMLDivElement>) => {\n onFocus?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(true);\n }\n },\n [onFocus]\n );\n\n // Close the toolbar when the it loses focus to something else than the editor\n const handleBlur = useCallback(\n (event: ReactFocusEvent<HTMLDivElement>) => {\n onBlur?.(event);\n\n if (!event.isDefaultPrevented()) {\n if (\n event.relatedTarget &&\n toolbarRef.current?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n if (event.relatedTarget === editor?.view.dom) {\n return;\n }\n\n for (const externalId of externalIds) {\n if (\n document\n .getElementById(externalId)\n ?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n }\n\n setFocused(false);\n }\n },\n [onBlur, editor, externalIds]\n );\n\n // Delay the opening of the toolbar to avoid flickering issues\n useEffect(() => {\n if (isOpen) {\n delayedIsOpenTimeoutRef.current = window.setTimeout(() => {\n setDelayedIsOpen(true);\n }, FLOATING_TOOLBAR_OPEN_DELAY);\n } else {\n setDelayedIsOpen(false);\n }\n\n return () => {\n window.clearTimeout(delayedIsOpenTimeoutRef.current);\n };\n }, [isOpen]);\n\n const floatingOptions: UseFloatingOptions = useMemo(() => {\n const detectOverflowOptions: DetectOverflowOptions = {\n padding: FLOATING_TOOLBAR_COLLISION_PADDING,\n };\n\n return {\n strategy: \"fixed\",\n placement: position,\n middleware: [\n inline(detectOverflowOptions),\n flip({ ...detectOverflowOptions, crossAxis: false }),\n hide(detectOverflowOptions),\n shift({\n ...detectOverflowOptions,\n limiter: limitShift(),\n }),\n offset(sideOffset),\n size(detectOverflowOptions),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n };\n }, [position, sideOffset]);\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n isPositioned,\n } = useFloating({\n ...floatingOptions,\n open: delayedIsOpen,\n });\n const mergedRefs = useRefs(forwardedRef, toolbarRef, setFloating);\n\n const handlePointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n onPointerDown?.(event);\n\n event.stopPropagation();\n\n // Prevent the toolbar from closing when clicking on the toolbar itself\n if (event.target === toolbarRef.current) {\n event.preventDefault();\n }\n },\n [onPointerDown]\n );\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const handlePointerDown = () => {\n setPointerDown(true);\n };\n const handlePointerUp = () => {\n setPointerDown(false);\n };\n\n editor.view.dom.addEventListener(\"pointerdown\", handlePointerDown);\n editor.view.dom.addEventListener(\"pointercancel\", handlePointerUp);\n editor.view.dom.addEventListener(\"pointerup\", handlePointerUp);\n\n return () => {\n editor.view.dom.removeEventListener(\"pointerdown\", handlePointerDown);\n editor.view.dom.removeEventListener(\"pointercancel\", handlePointerUp);\n editor.view.dom.removeEventListener(\"pointerup\", handlePointerUp);\n };\n }, [editor]);\n\n useLayoutEffect(() => {\n if (!editor || !delayedIsOpen) {\n return;\n }\n\n const updateSelectionReference = () => {\n const domSelection = window.getSelection();\n\n if (\n editor.state.selection.empty ||\n !domSelection ||\n !domSelection.rangeCount\n ) {\n setReference(null);\n } else {\n const domRange = domSelection.getRangeAt(0);\n\n setReference(domRange);\n }\n };\n\n editor.on(\"transaction\", updateSelectionReference);\n updateSelectionReference();\n\n return () => {\n editor.off(\"transaction\", updateSelectionReference);\n };\n }, [editor, delayedIsOpen, setReference]);\n\n useEffect(() => {\n if (!editor || !delayedIsOpen) {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.target !== editor.view.dom && event.defaultPrevented) {\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n\n editor.commands.focus();\n setManuallyClosed(true);\n }\n };\n\n editor.view.dom.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n editor.view.dom.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [editor, delayedIsOpen]);\n\n const close = useCallback(() => {\n setManuallyClosed(true);\n }, [setManuallyClosed]);\n\n const registerExternal = useCallback(\n (id: string) => {\n externalIds.add(id);\n\n return () => {\n externalIds.delete(id);\n };\n },\n [externalIds]\n );\n\n if (!editor || !delayedIsOpen) {\n return null;\n }\n\n const slotProps: ToolbarSlotProps = { editor };\n\n return createPortal(\n <TooltipProvider>\n <EditorProvider editor={editor}>\n <FloatingToolbarContext.Provider\n value={{ close, registerExternal }}\n >\n <div\n role=\"toolbar\"\n aria-label=\"Floating toolbar\"\n aria-orientation=\"horizontal\"\n className={classNames(\n \"lb-root lb-portal lb-elevation lb-tiptap-floating-toolbar lb-tiptap-toolbar\",\n className\n )}\n ref={mergedRefs}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: isPositioned\n ? `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`\n : \"translate3d(0, -200%, 0)\",\n minWidth: \"max-content\",\n }}\n onPointerDown={handlePointerDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n {...props}\n >\n {applyToolbarSlot(before, slotProps)}\n {applyToolbarSlot(children, slotProps)}\n {applyToolbarSlot(after, slotProps)}\n </div>\n </FloatingToolbarContext.Provider>\n </EditorProvider>\n </TooltipProvider>,\n document.body\n );\n }\n ),\n {\n /**\n * A component that can be wrapped around elements which are rendered outside of the floating\n * toolbar (e.g. portals) to prevent the toolbar from closing when clicking/focusing within them.\n *\n * @example\n * <FloatingToolbar editor={editor}>\n * <Popover.Root>\n * <Popover.Trigger asChild>\n * <Toolbar.Button>Open popover</Toolbar.Button>\n * </Popover.Trigger>\n * <Popover.Portal>\n * <FloatingToolbar.External>\n * <Popover.Content>\n * This popover is rendered outside of the floating toolbar, but the toolbar will not close when clicking/focusing within it.\n * </Popover.Content>\n * </FloatingToolbar.External>\n * </Popover.Portal>\n * </Popover.Root>\n * </FloatingToolbar>\n */\n External: FloatingToolbarExternal,\n }\n);\n"],"names":["jsxs","Fragment","jsx","Toolbar","forwardRef","useRef","useInitial","useState","useEditorState","editor","isTextSelection","useEffect","handleFocus","handleBlur","useCallback","useMemo","inline","flip","hide","shift","limitShift","offset","size","autoUpdate","useFloating","useRefs","handlePointerDown","useLayoutEffect","createPortal","TooltipProvider","EditorProvider","FloatingToolbarContext","classNames","applyToolbarSlot","FloatingToolbarExternal"],"mappings":"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"}
|
|
@@ -47,11 +47,6 @@ const FloatingToolbar = Object.assign(
|
|
|
47
47
|
const [isPointerDown, setPointerDown] = useState(false);
|
|
48
48
|
const [isFocused, setFocused] = useState(false);
|
|
49
49
|
const [isManuallyClosed, setManuallyClosed] = useState(false);
|
|
50
|
-
const isEditable = useEditorState({
|
|
51
|
-
editor,
|
|
52
|
-
equalityFn: Object.is,
|
|
53
|
-
selector: (ctx) => ctx.editor?.isEditable ?? false
|
|
54
|
-
}) ?? false;
|
|
55
50
|
const hasSelectionRange = useEditorState({
|
|
56
51
|
editor,
|
|
57
52
|
equalityFn: Object.is,
|
|
@@ -202,7 +197,7 @@ const FloatingToolbar = Object.assign(
|
|
|
202
197
|
[onPointerDown]
|
|
203
198
|
);
|
|
204
199
|
useEffect(() => {
|
|
205
|
-
if (!editor
|
|
200
|
+
if (!editor) {
|
|
206
201
|
return;
|
|
207
202
|
}
|
|
208
203
|
const handlePointerDown2 = () => {
|
|
@@ -211,15 +206,15 @@ const FloatingToolbar = Object.assign(
|
|
|
211
206
|
const handlePointerUp = () => {
|
|
212
207
|
setPointerDown(false);
|
|
213
208
|
};
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
209
|
+
editor.view.dom.addEventListener("pointerdown", handlePointerDown2);
|
|
210
|
+
editor.view.dom.addEventListener("pointercancel", handlePointerUp);
|
|
211
|
+
editor.view.dom.addEventListener("pointerup", handlePointerUp);
|
|
217
212
|
return () => {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
213
|
+
editor.view.dom.removeEventListener("pointerdown", handlePointerDown2);
|
|
214
|
+
editor.view.dom.removeEventListener("pointercancel", handlePointerUp);
|
|
215
|
+
editor.view.dom.removeEventListener("pointerup", handlePointerUp);
|
|
221
216
|
};
|
|
222
|
-
}, [editor
|
|
217
|
+
}, [editor]);
|
|
223
218
|
useLayoutEffect(() => {
|
|
224
219
|
if (!editor || !delayedIsOpen) {
|
|
225
220
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingToolbar.mjs","sources":["../../src/toolbar/FloatingToolbar.tsx"],"sourcesContent":["import {\n autoUpdate,\n type DetectOverflowOptions,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n type UseFloatingOptions,\n} from \"@floating-ui/react-dom\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n TooltipProvider,\n useInitial,\n useRefs,\n} from \"@liveblocks/react-ui/_private\";\nimport { type Editor, isTextSelection, useEditorState } from \"@tiptap/react\";\nimport type {\n ComponentProps,\n FocusEvent as ReactFocusEvent,\n PointerEvent as ReactPointerEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport { EditorProvider } from \"../context\";\nimport type { FloatingPosition } from \"../types\";\nimport { FloatingToolbarContext, FloatingToolbarExternal } from \"./shared\";\nimport {\n applyToolbarSlot,\n Toolbar,\n type ToolbarSlot,\n type ToolbarSlotProps,\n} from \"./Toolbar\";\n\nexport interface FloatingToolbarProps\n extends Omit<ComponentProps<\"div\">, \"children\"> {\n editor: Editor | null;\n position?: FloatingPosition;\n offset?: number;\n children?: ToolbarSlot;\n before?: ToolbarSlot;\n after?: ToolbarSlot;\n}\n\nexport const FLOATING_TOOLBAR_COLLISION_PADDING = 10;\nconst FLOATING_TOOLBAR_OPEN_DELAY = 50;\n\nfunction DefaultFloatingToolbarContent({ editor }: ToolbarSlotProps) {\n const supportsThread = \"addPendingComment\" in editor.commands;\n\n return (\n <>\n <Toolbar.BlockSelector />\n <Toolbar.SectionInline />\n {supportsThread ? (\n <>\n <Toolbar.Separator />\n <Toolbar.SectionCollaboration />\n </>\n ) : null}\n </>\n );\n}\n\nexport const FloatingToolbar = Object.assign(\n forwardRef<HTMLDivElement, FloatingToolbarProps>(\n (\n {\n children = DefaultFloatingToolbarContent,\n before,\n after,\n position = \"top\",\n offset: sideOffset = 6,\n editor,\n onPointerDown,\n onFocus,\n onBlur,\n className,\n ...props\n },\n forwardedRef\n ) => {\n const toolbarRef = useRef<HTMLDivElement>(null);\n const externalIds = useInitial<Set<string>>(() => new Set());\n const [isPointerDown, setPointerDown] = useState(false);\n const [isFocused, setFocused] = useState(false);\n const [isManuallyClosed, setManuallyClosed] = useState(false);\n const isEditable =\n useEditorState({\n editor,\n equalityFn: Object.is,\n selector: (ctx) => ctx.editor?.isEditable ?? false,\n }) ?? false;\n const hasSelectionRange =\n useEditorState({\n editor,\n equalityFn: Object.is,\n selector: (ctx) => {\n const editor = ctx.editor;\n\n if (!editor) {\n return false;\n }\n\n const { doc, selection } = editor.state;\n const { empty, ranges } = selection;\n const from = Math.min(...ranges.map((range) => range.$from.pos));\n const to = Math.max(...ranges.map((range) => range.$to.pos));\n\n if (empty) {\n return false;\n }\n\n return (\n isTextSelection(selection) && doc.textBetween(from, to).length > 0\n );\n },\n }) ?? false;\n\n const isOpen =\n isFocused && !isPointerDown && hasSelectionRange && !isManuallyClosed;\n const [delayedIsOpen, setDelayedIsOpen] = useState(isOpen);\n const delayedIsOpenTimeoutRef = useRef<number>();\n\n // Reset the manually closed state when there's another change\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n setManuallyClosed(false);\n\n const handleSelectionChange = () => {\n setManuallyClosed(false);\n };\n\n editor.on(\"selectionUpdate\", handleSelectionChange);\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionChange);\n };\n }, [isFocused, hasSelectionRange, editor]);\n\n // Don't close when the focus moves from the editor to the toolbar\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const handleFocus = () => {\n setFocused(true);\n };\n\n const handleBlur = (event: FocusEvent) => {\n if (\n event.relatedTarget &&\n toolbarRef.current?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n if (event.relatedTarget === editor.view.dom) {\n return;\n }\n\n for (const externalId of externalIds) {\n if (\n document\n .getElementById(externalId)\n ?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n }\n\n setFocused(false);\n };\n\n editor.view.dom.addEventListener(\"focus\", handleFocus);\n editor.view.dom.addEventListener(\"blur\", handleBlur);\n\n return () => {\n editor.view.dom.removeEventListener(\"focus\", handleFocus);\n editor.view.dom.removeEventListener(\"blur\", handleBlur);\n };\n }, [editor, externalIds]);\n\n const handleFocus = useCallback(\n (event: ReactFocusEvent<HTMLDivElement>) => {\n onFocus?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(true);\n }\n },\n [onFocus]\n );\n\n // Close the toolbar when the it loses focus to something else than the editor\n const handleBlur = useCallback(\n (event: ReactFocusEvent<HTMLDivElement>) => {\n onBlur?.(event);\n\n if (!event.isDefaultPrevented()) {\n if (\n event.relatedTarget &&\n toolbarRef.current?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n if (event.relatedTarget === editor?.view.dom) {\n return;\n }\n\n for (const externalId of externalIds) {\n if (\n document\n .getElementById(externalId)\n ?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n }\n\n setFocused(false);\n }\n },\n [onBlur, editor, externalIds]\n );\n\n // Delay the opening of the toolbar to avoid flickering issues\n useEffect(() => {\n if (isOpen) {\n delayedIsOpenTimeoutRef.current = window.setTimeout(() => {\n setDelayedIsOpen(true);\n }, FLOATING_TOOLBAR_OPEN_DELAY);\n } else {\n setDelayedIsOpen(false);\n }\n\n return () => {\n window.clearTimeout(delayedIsOpenTimeoutRef.current);\n };\n }, [isOpen]);\n\n const floatingOptions: UseFloatingOptions = useMemo(() => {\n const detectOverflowOptions: DetectOverflowOptions = {\n padding: FLOATING_TOOLBAR_COLLISION_PADDING,\n };\n\n return {\n strategy: \"fixed\",\n placement: position,\n middleware: [\n inline(detectOverflowOptions),\n flip({ ...detectOverflowOptions, crossAxis: false }),\n hide(detectOverflowOptions),\n shift({\n ...detectOverflowOptions,\n limiter: limitShift(),\n }),\n offset(sideOffset),\n size(detectOverflowOptions),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n };\n }, [position, sideOffset]);\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n isPositioned,\n } = useFloating({\n ...floatingOptions,\n open: delayedIsOpen,\n });\n const mergedRefs = useRefs(forwardedRef, toolbarRef, setFloating);\n\n const handlePointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n onPointerDown?.(event);\n\n event.stopPropagation();\n\n // Prevent the toolbar from closing when clicking on the toolbar itself\n if (event.target === toolbarRef.current) {\n event.preventDefault();\n }\n },\n [onPointerDown]\n );\n\n useEffect(() => {\n if (!editor || !isEditable) {\n return;\n }\n\n const handlePointerDown = () => {\n setPointerDown(true);\n };\n const handlePointerUp = () => {\n setPointerDown(false);\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n document.addEventListener(\"pointercancel\", handlePointerUp);\n document.addEventListener(\"pointerup\", handlePointerUp);\n\n return () => {\n document.removeEventListener(\"pointerdown\", handlePointerDown);\n document.removeEventListener(\"pointercancel\", handlePointerUp);\n document.removeEventListener(\"pointerup\", handlePointerUp);\n };\n }, [editor, isEditable]);\n\n useLayoutEffect(() => {\n if (!editor || !delayedIsOpen) {\n return;\n }\n\n const updateSelectionReference = () => {\n const domSelection = window.getSelection();\n\n if (\n editor.state.selection.empty ||\n !domSelection ||\n !domSelection.rangeCount\n ) {\n setReference(null);\n } else {\n const domRange = domSelection.getRangeAt(0);\n\n setReference(domRange);\n }\n };\n\n editor.on(\"transaction\", updateSelectionReference);\n updateSelectionReference();\n\n return () => {\n editor.off(\"transaction\", updateSelectionReference);\n };\n }, [editor, delayedIsOpen, setReference]);\n\n useEffect(() => {\n if (!editor || !delayedIsOpen) {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.target !== editor.view.dom && event.defaultPrevented) {\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n\n editor.commands.focus();\n setManuallyClosed(true);\n }\n };\n\n editor.view.dom.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n editor.view.dom.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [editor, delayedIsOpen]);\n\n const close = useCallback(() => {\n setManuallyClosed(true);\n }, [setManuallyClosed]);\n\n const registerExternal = useCallback(\n (id: string) => {\n externalIds.add(id);\n\n return () => {\n externalIds.delete(id);\n };\n },\n [externalIds]\n );\n\n if (!editor || !delayedIsOpen) {\n return null;\n }\n\n const slotProps: ToolbarSlotProps = { editor };\n\n return createPortal(\n <TooltipProvider>\n <EditorProvider editor={editor}>\n <FloatingToolbarContext.Provider\n value={{ close, registerExternal }}\n >\n <div\n role=\"toolbar\"\n aria-label=\"Floating toolbar\"\n aria-orientation=\"horizontal\"\n className={classNames(\n \"lb-root lb-portal lb-elevation lb-tiptap-floating-toolbar lb-tiptap-toolbar\",\n className\n )}\n ref={mergedRefs}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: isPositioned\n ? `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`\n : \"translate3d(0, -200%, 0)\",\n minWidth: \"max-content\",\n }}\n onPointerDown={handlePointerDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n {...props}\n >\n {applyToolbarSlot(before, slotProps)}\n {applyToolbarSlot(children, slotProps)}\n {applyToolbarSlot(after, slotProps)}\n </div>\n </FloatingToolbarContext.Provider>\n </EditorProvider>\n </TooltipProvider>,\n document.body\n );\n }\n ),\n {\n External: FloatingToolbarExternal,\n }\n);\n"],"names":["editor","handleFocus","handleBlur","handlePointerDown"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FloatingToolbar.mjs","sources":["../../src/toolbar/FloatingToolbar.tsx"],"sourcesContent":["import {\n autoUpdate,\n type DetectOverflowOptions,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n type UseFloatingOptions,\n} from \"@floating-ui/react-dom\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n TooltipProvider,\n useInitial,\n useRefs,\n} from \"@liveblocks/react-ui/_private\";\nimport { type Editor, isTextSelection, useEditorState } from \"@tiptap/react\";\nimport type {\n ComponentProps,\n FocusEvent as ReactFocusEvent,\n PointerEvent as ReactPointerEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport { EditorProvider } from \"../context\";\nimport type { FloatingPosition } from \"../types\";\nimport { FloatingToolbarContext, FloatingToolbarExternal } from \"./shared\";\nimport {\n applyToolbarSlot,\n Toolbar,\n type ToolbarSlot,\n type ToolbarSlotProps,\n} from \"./Toolbar\";\n\nexport interface FloatingToolbarProps\n extends Omit<ComponentProps<\"div\">, \"children\"> {\n /**\n * The Tiptap editor.\n */\n editor: Editor | null;\n\n /**\n * The vertical position of the floating toolbar.\n */\n position?: FloatingPosition;\n\n /**\n * The vertical offset of the floating toolbar from the selection.\n */\n offset?: number;\n\n /**\n * The content of the floating toolbar, overriding the default content.\n * Use the `before` and `after` props if you want to keep and extend the default content.\n */\n children?: ToolbarSlot;\n\n /**\n * The content to display at the start of the floating toolbar.\n */\n before?: ToolbarSlot;\n\n /**\n * The content to display at the end of the floating toolbar.\n */\n after?: ToolbarSlot;\n}\n\nexport const FLOATING_TOOLBAR_COLLISION_PADDING = 10;\nconst FLOATING_TOOLBAR_OPEN_DELAY = 50;\n\nfunction DefaultFloatingToolbarContent({ editor }: ToolbarSlotProps) {\n const supportsThread = \"addPendingComment\" in editor.commands;\n\n return (\n <>\n <Toolbar.BlockSelector />\n <Toolbar.SectionInline />\n {supportsThread ? (\n <>\n <Toolbar.Separator />\n <Toolbar.SectionCollaboration />\n </>\n ) : null}\n </>\n );\n}\n\n/**\n * A floating toolbar attached to the selection and containing actions and values related to the editor.\n *\n * @example\n * <FloatingToolbar editor={editor} />\n *\n * @example\n * <FloatingToolbar editor={editor}>\n * <Toolbar.BlockSelector />\n * <Toolbar.Separator />\n * <Toolbar.SectionInline />\n * <Toolbar.Separator />\n * <Toolbar.Button name=\"Custom action\" onClick={() => { ... }} icon={<Icon.QuestionMark />} />\n * </FloatingToolbar>\n */\nexport const FloatingToolbar = Object.assign(\n forwardRef<HTMLDivElement, FloatingToolbarProps>(\n (\n {\n children = DefaultFloatingToolbarContent,\n before,\n after,\n position = \"top\",\n offset: sideOffset = 6,\n editor,\n onPointerDown,\n onFocus,\n onBlur,\n className,\n ...props\n },\n forwardedRef\n ) => {\n const toolbarRef = useRef<HTMLDivElement>(null);\n const externalIds = useInitial<Set<string>>(() => new Set());\n const [isPointerDown, setPointerDown] = useState(false);\n const [isFocused, setFocused] = useState(false);\n const [isManuallyClosed, setManuallyClosed] = useState(false);\n const hasSelectionRange =\n useEditorState({\n editor,\n equalityFn: Object.is,\n selector: (ctx) => {\n const editor = ctx.editor;\n\n if (!editor) {\n return false;\n }\n\n const { doc, selection } = editor.state;\n const { empty, ranges } = selection;\n const from = Math.min(...ranges.map((range) => range.$from.pos));\n const to = Math.max(...ranges.map((range) => range.$to.pos));\n\n if (empty) {\n return false;\n }\n\n return (\n isTextSelection(selection) && doc.textBetween(from, to).length > 0\n );\n },\n }) ?? false;\n\n const isOpen =\n isFocused && !isPointerDown && hasSelectionRange && !isManuallyClosed;\n const [delayedIsOpen, setDelayedIsOpen] = useState(isOpen);\n const delayedIsOpenTimeoutRef = useRef<number>();\n\n // Reset the manually closed state when there's another change\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n setManuallyClosed(false);\n\n const handleSelectionChange = () => {\n setManuallyClosed(false);\n };\n\n editor.on(\"selectionUpdate\", handleSelectionChange);\n\n return () => {\n editor.off(\"selectionUpdate\", handleSelectionChange);\n };\n }, [isFocused, hasSelectionRange, editor]);\n\n // Don't close when the focus moves from the editor to the toolbar\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const handleFocus = () => {\n setFocused(true);\n };\n\n const handleBlur = (event: FocusEvent) => {\n if (\n event.relatedTarget &&\n toolbarRef.current?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n if (event.relatedTarget === editor.view.dom) {\n return;\n }\n\n for (const externalId of externalIds) {\n if (\n document\n .getElementById(externalId)\n ?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n }\n\n setFocused(false);\n };\n\n editor.view.dom.addEventListener(\"focus\", handleFocus);\n editor.view.dom.addEventListener(\"blur\", handleBlur);\n\n return () => {\n editor.view.dom.removeEventListener(\"focus\", handleFocus);\n editor.view.dom.removeEventListener(\"blur\", handleBlur);\n };\n }, [editor, externalIds]);\n\n const handleFocus = useCallback(\n (event: ReactFocusEvent<HTMLDivElement>) => {\n onFocus?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(true);\n }\n },\n [onFocus]\n );\n\n // Close the toolbar when the it loses focus to something else than the editor\n const handleBlur = useCallback(\n (event: ReactFocusEvent<HTMLDivElement>) => {\n onBlur?.(event);\n\n if (!event.isDefaultPrevented()) {\n if (\n event.relatedTarget &&\n toolbarRef.current?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n if (event.relatedTarget === editor?.view.dom) {\n return;\n }\n\n for (const externalId of externalIds) {\n if (\n document\n .getElementById(externalId)\n ?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n }\n\n setFocused(false);\n }\n },\n [onBlur, editor, externalIds]\n );\n\n // Delay the opening of the toolbar to avoid flickering issues\n useEffect(() => {\n if (isOpen) {\n delayedIsOpenTimeoutRef.current = window.setTimeout(() => {\n setDelayedIsOpen(true);\n }, FLOATING_TOOLBAR_OPEN_DELAY);\n } else {\n setDelayedIsOpen(false);\n }\n\n return () => {\n window.clearTimeout(delayedIsOpenTimeoutRef.current);\n };\n }, [isOpen]);\n\n const floatingOptions: UseFloatingOptions = useMemo(() => {\n const detectOverflowOptions: DetectOverflowOptions = {\n padding: FLOATING_TOOLBAR_COLLISION_PADDING,\n };\n\n return {\n strategy: \"fixed\",\n placement: position,\n middleware: [\n inline(detectOverflowOptions),\n flip({ ...detectOverflowOptions, crossAxis: false }),\n hide(detectOverflowOptions),\n shift({\n ...detectOverflowOptions,\n limiter: limitShift(),\n }),\n offset(sideOffset),\n size(detectOverflowOptions),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n };\n }, [position, sideOffset]);\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n isPositioned,\n } = useFloating({\n ...floatingOptions,\n open: delayedIsOpen,\n });\n const mergedRefs = useRefs(forwardedRef, toolbarRef, setFloating);\n\n const handlePointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n onPointerDown?.(event);\n\n event.stopPropagation();\n\n // Prevent the toolbar from closing when clicking on the toolbar itself\n if (event.target === toolbarRef.current) {\n event.preventDefault();\n }\n },\n [onPointerDown]\n );\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const handlePointerDown = () => {\n setPointerDown(true);\n };\n const handlePointerUp = () => {\n setPointerDown(false);\n };\n\n editor.view.dom.addEventListener(\"pointerdown\", handlePointerDown);\n editor.view.dom.addEventListener(\"pointercancel\", handlePointerUp);\n editor.view.dom.addEventListener(\"pointerup\", handlePointerUp);\n\n return () => {\n editor.view.dom.removeEventListener(\"pointerdown\", handlePointerDown);\n editor.view.dom.removeEventListener(\"pointercancel\", handlePointerUp);\n editor.view.dom.removeEventListener(\"pointerup\", handlePointerUp);\n };\n }, [editor]);\n\n useLayoutEffect(() => {\n if (!editor || !delayedIsOpen) {\n return;\n }\n\n const updateSelectionReference = () => {\n const domSelection = window.getSelection();\n\n if (\n editor.state.selection.empty ||\n !domSelection ||\n !domSelection.rangeCount\n ) {\n setReference(null);\n } else {\n const domRange = domSelection.getRangeAt(0);\n\n setReference(domRange);\n }\n };\n\n editor.on(\"transaction\", updateSelectionReference);\n updateSelectionReference();\n\n return () => {\n editor.off(\"transaction\", updateSelectionReference);\n };\n }, [editor, delayedIsOpen, setReference]);\n\n useEffect(() => {\n if (!editor || !delayedIsOpen) {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.target !== editor.view.dom && event.defaultPrevented) {\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n\n editor.commands.focus();\n setManuallyClosed(true);\n }\n };\n\n editor.view.dom.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n editor.view.dom.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [editor, delayedIsOpen]);\n\n const close = useCallback(() => {\n setManuallyClosed(true);\n }, [setManuallyClosed]);\n\n const registerExternal = useCallback(\n (id: string) => {\n externalIds.add(id);\n\n return () => {\n externalIds.delete(id);\n };\n },\n [externalIds]\n );\n\n if (!editor || !delayedIsOpen) {\n return null;\n }\n\n const slotProps: ToolbarSlotProps = { editor };\n\n return createPortal(\n <TooltipProvider>\n <EditorProvider editor={editor}>\n <FloatingToolbarContext.Provider\n value={{ close, registerExternal }}\n >\n <div\n role=\"toolbar\"\n aria-label=\"Floating toolbar\"\n aria-orientation=\"horizontal\"\n className={classNames(\n \"lb-root lb-portal lb-elevation lb-tiptap-floating-toolbar lb-tiptap-toolbar\",\n className\n )}\n ref={mergedRefs}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: isPositioned\n ? `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`\n : \"translate3d(0, -200%, 0)\",\n minWidth: \"max-content\",\n }}\n onPointerDown={handlePointerDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n {...props}\n >\n {applyToolbarSlot(before, slotProps)}\n {applyToolbarSlot(children, slotProps)}\n {applyToolbarSlot(after, slotProps)}\n </div>\n </FloatingToolbarContext.Provider>\n </EditorProvider>\n </TooltipProvider>,\n document.body\n );\n }\n ),\n {\n /**\n * A component that can be wrapped around elements which are rendered outside of the floating\n * toolbar (e.g. portals) to prevent the toolbar from closing when clicking/focusing within them.\n *\n * @example\n * <FloatingToolbar editor={editor}>\n * <Popover.Root>\n * <Popover.Trigger asChild>\n * <Toolbar.Button>Open popover</Toolbar.Button>\n * </Popover.Trigger>\n * <Popover.Portal>\n * <FloatingToolbar.External>\n * <Popover.Content>\n * This popover is rendered outside of the floating toolbar, but the toolbar will not close when clicking/focusing within it.\n * </Popover.Content>\n * </FloatingToolbar.External>\n * </Popover.Portal>\n * </Popover.Root>\n * </FloatingToolbar>\n */\n External: FloatingToolbarExternal,\n }\n);\n"],"names":["editor","handleFocus","handleBlur","handlePointerDown"],"mappings":"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"}
|
package/dist/toolbar/Toolbar.js
CHANGED
|
@@ -41,7 +41,20 @@ function applyToolbarSlot(slot, props) {
|
|
|
41
41
|
return slot;
|
|
42
42
|
}
|
|
43
43
|
const ToolbarButton = react.forwardRef(
|
|
44
|
-
({ icon, children, name, shortcut, ...props }, forwardedRef) => {
|
|
44
|
+
({ icon, children, name, shortcut, onKeyDown, ...props }, forwardedRef) => {
|
|
45
|
+
const floatingToolbarContext = react.useContext(shared.FloatingToolbarContext);
|
|
46
|
+
const closeFloatingToolbar = floatingToolbarContext?.close;
|
|
47
|
+
const handleKeyDown = react.useCallback(
|
|
48
|
+
(event) => {
|
|
49
|
+
onKeyDown?.(event);
|
|
50
|
+
if (!event.isDefaultPrevented() && closeFloatingToolbar && event.key === "Escape") {
|
|
51
|
+
closeFloatingToolbar();
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
event.stopPropagation();
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
[onKeyDown, closeFloatingToolbar]
|
|
57
|
+
);
|
|
45
58
|
return /* @__PURE__ */ jsxRuntime.jsx(_private.ShortcutTooltip, {
|
|
46
59
|
content: name,
|
|
47
60
|
shortcut,
|
|
@@ -51,6 +64,7 @@ const ToolbarButton = react.forwardRef(
|
|
|
51
64
|
ref: forwardedRef,
|
|
52
65
|
icon,
|
|
53
66
|
...props,
|
|
67
|
+
onKeyDown: handleKeyDown,
|
|
54
68
|
children
|
|
55
69
|
})
|
|
56
70
|
});
|
|
@@ -70,55 +84,76 @@ const ToolbarToggle = react.forwardRef(
|
|
|
70
84
|
);
|
|
71
85
|
function createDefaultBlockSelectorItems(editor) {
|
|
72
86
|
const items = [
|
|
87
|
+
{
|
|
88
|
+
name: "Text",
|
|
89
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(_private.TextIcon, {}),
|
|
90
|
+
isActive: "default",
|
|
91
|
+
setActive: (editor2) => editor2.chain().focus().clearNodes().run()
|
|
92
|
+
},
|
|
73
93
|
"toggleHeading" in editor.commands ? {
|
|
74
94
|
name: "Heading 1",
|
|
95
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(_private.H1Icon, {}),
|
|
75
96
|
isActive: (editor2) => editor2.isActive("heading", { level: 1 }),
|
|
76
97
|
setActive: (editor2) => editor2.chain().focus().clearNodes().toggleHeading({ level: 1 }).run()
|
|
77
98
|
} : null,
|
|
78
99
|
"toggleHeading" in editor.commands ? {
|
|
79
100
|
name: "Heading 2",
|
|
101
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(_private.H2Icon, {}),
|
|
80
102
|
isActive: (editor2) => editor2.isActive("heading", { level: 2 }),
|
|
81
103
|
setActive: (editor2) => editor2.chain().focus().clearNodes().toggleHeading({ level: 2 }).run()
|
|
82
104
|
} : null,
|
|
83
105
|
"toggleHeading" in editor.commands ? {
|
|
84
106
|
name: "Heading 3",
|
|
107
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(_private.H3Icon, {}),
|
|
85
108
|
isActive: (editor2) => editor2.isActive("heading", { level: 3 }),
|
|
86
109
|
setActive: (editor2) => editor2.chain().focus().clearNodes().toggleHeading({ level: 3 }).run()
|
|
87
110
|
} : null,
|
|
88
111
|
"toggleBulletList" in editor.commands ? {
|
|
89
112
|
name: "Bullet list",
|
|
113
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(_private.ListUnorderedIcon, {}),
|
|
90
114
|
isActive: (editor2) => editor2.isActive("bulletList"),
|
|
91
115
|
setActive: (editor2) => editor2.chain().focus().clearNodes().toggleBulletList().run()
|
|
92
116
|
} : null,
|
|
93
117
|
"toggleOrderedList" in editor.commands ? {
|
|
94
118
|
name: "Numbered list",
|
|
119
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(_private.ListOrderedIcon, {}),
|
|
95
120
|
isActive: (editor2) => editor2.isActive("orderedList"),
|
|
96
121
|
setActive: (editor2) => editor2.chain().focus().clearNodes().toggleOrderedList().run()
|
|
97
122
|
} : null,
|
|
98
123
|
"toggleBlockquote" in editor.commands ? {
|
|
99
124
|
name: "Blockquote",
|
|
125
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(_private.BlockquoteIcon, {}),
|
|
100
126
|
isActive: (editor2) => editor2.isActive("blockquote"),
|
|
101
127
|
setActive: (editor2) => editor2.chain().focus().clearNodes().toggleBlockquote().run()
|
|
102
128
|
} : null
|
|
103
129
|
];
|
|
104
130
|
return items.filter(Boolean);
|
|
105
131
|
}
|
|
106
|
-
const
|
|
107
|
-
name: "Text",
|
|
108
|
-
isActive: () => false,
|
|
109
|
-
setActive: (editor) => editor.chain().focus().clearNodes().run()
|
|
110
|
-
};
|
|
111
|
-
const ToolbarBlockSelector = react.forwardRef(({ items, ...props }, forwardedRef) => {
|
|
132
|
+
const ToolbarBlockSelector = react.forwardRef(({ items, onKeyDown, ...props }, forwardedRef) => {
|
|
112
133
|
const floatingToolbarContext = react.useContext(shared.FloatingToolbarContext);
|
|
134
|
+
const closeFloatingToolbar = floatingToolbarContext?.close;
|
|
113
135
|
const editor = context.useCurrentEditor(
|
|
114
136
|
"BlockSelector",
|
|
115
137
|
"Toolbar or FloatingToolbar"
|
|
116
138
|
);
|
|
117
139
|
const resolvedItems = react.useMemo(() => {
|
|
118
|
-
|
|
119
|
-
|
|
140
|
+
if (Array.isArray(items)) {
|
|
141
|
+
return items;
|
|
142
|
+
}
|
|
143
|
+
const defaultItems = createDefaultBlockSelectorItems(editor);
|
|
144
|
+
return items ? items(defaultItems) : defaultItems;
|
|
120
145
|
}, [editor, items]);
|
|
121
|
-
|
|
146
|
+
let defaultItem;
|
|
147
|
+
let activeItem = editor.isInitialized ? resolvedItems.find((item) => {
|
|
148
|
+
if (item.isActive === "default") {
|
|
149
|
+
defaultItem = item;
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
return item.isActive(editor);
|
|
153
|
+
}) : void 0;
|
|
154
|
+
if (!activeItem) {
|
|
155
|
+
activeItem = defaultItem;
|
|
156
|
+
}
|
|
122
157
|
const handleItemChange = (name) => {
|
|
123
158
|
const item = resolvedItems.find((item2) => item2.name === name);
|
|
124
159
|
if (item) {
|
|
@@ -126,8 +161,19 @@ const ToolbarBlockSelector = react.forwardRef(({ items, ...props }, forwardedRef
|
|
|
126
161
|
floatingToolbarContext?.close();
|
|
127
162
|
}
|
|
128
163
|
};
|
|
164
|
+
const handleKeyDown = react.useCallback(
|
|
165
|
+
(event) => {
|
|
166
|
+
onKeyDown?.(event);
|
|
167
|
+
if (!event.isDefaultPrevented() && closeFloatingToolbar && event.key === "Escape") {
|
|
168
|
+
closeFloatingToolbar();
|
|
169
|
+
event.preventDefault();
|
|
170
|
+
event.stopPropagation();
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
[onKeyDown, closeFloatingToolbar]
|
|
174
|
+
);
|
|
129
175
|
return /* @__PURE__ */ jsxRuntime.jsxs(SelectPrimitive__namespace.Root, {
|
|
130
|
-
value: activeItem
|
|
176
|
+
value: activeItem?.name,
|
|
131
177
|
onValueChange: handleItemChange,
|
|
132
178
|
children: [
|
|
133
179
|
/* @__PURE__ */ jsxRuntime.jsx(_private.ShortcutTooltip, {
|
|
@@ -136,18 +182,11 @@ const ToolbarBlockSelector = react.forwardRef(({ items, ...props }, forwardedRef
|
|
|
136
182
|
asChild: true,
|
|
137
183
|
...props,
|
|
138
184
|
ref: forwardedRef,
|
|
139
|
-
|
|
140
|
-
|
|
185
|
+
onKeyDown: handleKeyDown,
|
|
186
|
+
disabled: resolvedItems.length === 0,
|
|
187
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(_private.SelectButton, {
|
|
141
188
|
variant: "toolbar",
|
|
142
|
-
children:
|
|
143
|
-
/* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Value, {
|
|
144
|
-
children: activeItem.name
|
|
145
|
-
}),
|
|
146
|
-
/* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Icon, {
|
|
147
|
-
className: "lb-dropdown-chevron",
|
|
148
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(_private.ChevronDownIcon, {})
|
|
149
|
-
})
|
|
150
|
-
]
|
|
189
|
+
children: activeItem?.name ?? "Turn into\u2026"
|
|
151
190
|
})
|
|
152
191
|
})
|
|
153
192
|
}),
|
|
@@ -161,14 +200,17 @@ const ToolbarBlockSelector = react.forwardRef(({ items, ...props }, forwardedRef
|
|
|
161
200
|
children: resolvedItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(SelectPrimitive__namespace.Item, {
|
|
162
201
|
value: item.name,
|
|
163
202
|
className: "lb-dropdown-item",
|
|
203
|
+
"data-name": item.name,
|
|
164
204
|
children: [
|
|
205
|
+
item.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", {
|
|
206
|
+
className: "lb-dropdown-item-icon lb-icon-container",
|
|
207
|
+
children: item.icon
|
|
208
|
+
}) : null,
|
|
165
209
|
/* @__PURE__ */ jsxRuntime.jsx("span", {
|
|
166
210
|
className: "lb-dropdown-item-label",
|
|
167
|
-
children:
|
|
168
|
-
children: item.name
|
|
169
|
-
})
|
|
211
|
+
children: item.label ?? item.name
|
|
170
212
|
}),
|
|
171
|
-
item.name === activeItem
|
|
213
|
+
item.name === activeItem?.name ? /* @__PURE__ */ jsxRuntime.jsx("span", {
|
|
172
214
|
className: "lb-dropdown-item-accessory lb-icon-container",
|
|
173
215
|
children: /* @__PURE__ */ jsxRuntime.jsx(_private.CheckIcon, {})
|
|
174
216
|
}) : null
|
|
@@ -339,11 +381,11 @@ const Toolbar = Object.assign(
|
|
|
339
381
|
{
|
|
340
382
|
Button: ToolbarButton,
|
|
341
383
|
Toggle: ToolbarToggle,
|
|
384
|
+
BlockSelector: ToolbarBlockSelector,
|
|
342
385
|
Separator: ToolbarSeparator,
|
|
343
386
|
SectionHistory: ToolbarSectionHistory,
|
|
344
387
|
SectionInline: ToolbarSectionInline,
|
|
345
|
-
SectionCollaboration: ToolbarSectionCollaboration
|
|
346
|
-
BlockSelector: ToolbarBlockSelector
|
|
388
|
+
SectionCollaboration: ToolbarSectionCollaboration
|
|
347
389
|
}
|
|
348
390
|
);
|
|
349
391
|
|