diff --git a/packages/react/src/components/FormattingToolbar/FormattingToolbarController.tsx b/packages/react/src/components/FormattingToolbar/FormattingToolbarController.tsx index 839903c172..ae9852d206 100644 --- a/packages/react/src/components/FormattingToolbar/FormattingToolbarController.tsx +++ b/packages/react/src/components/FormattingToolbar/FormattingToolbarController.tsx @@ -5,12 +5,13 @@ import { StyleSchema, } from "@blocknote/core"; import { flip, offset } from "@floating-ui/react"; -import { FC, useState } from "react"; +import { FC, useMemo, useRef, useState } from "react"; import { useBlockNoteEditor } from "../../hooks/useBlockNoteEditor"; import { useEditorContentOrSelectionChange } from "../../hooks/useEditorContentOrSelectionChange"; import { useUIElementPositioning } from "../../hooks/useUIElementPositioning"; import { useUIPluginState } from "../../hooks/useUIPluginState"; +import { mergeRefs } from "../../util/mergeRefs"; import { FormattingToolbarProps } from "./FormattingToolbarProps"; import { FormattingToolbar } from "./mantine/FormattingToolbar"; @@ -32,6 +33,8 @@ const textAlignmentToPlacement = ( export const FormattingToolbarController = (props: { formattingToolbar?: FC; }) => { + const divRef = useRef(null); + const editor = useBlockNoteEditor< BlockSchema, InlineContentSchema, @@ -79,14 +82,28 @@ export const FormattingToolbarController = (props: { } ); + const combinedRef = useMemo(() => mergeRefs([divRef, ref]), [divRef, ref]); + if (!isMounted || !state) { return null; } + if (!state.show && divRef.current) { + // The component is fading out. Use the previous state to render the toolbar with innerHTML, + // because otherwise the toolbar will quickly flickr (i.e.: show a different state) while fading out, + // which looks weird + return ( +
+ ); + } + const Component = props.formattingToolbar || FormattingToolbar; return ( -
+
);