Files
twenty/packages/twenty-front/src/modules/blocknote-editor/components/BlockEditorDropdownFocusEffect.tsx
T
Abdullah. 4ed09a3feb Upgrade blocknote dependencies from 0.31.1 to 0.47.0. (#18207)
This PR pgrades all BlockNote packages (@blocknote/core,
@blocknote/react, @blocknote/mantine, @blocknote/server-util,
@blocknote/xl-docx-exporter, @blocknote/xl-pdf-exporter) to 0.47.0 and
adapts the codebase to the new API.

### Changes
- Dependency upgrades: Bumped all BlockNote packages to 0.47.0, added
required Mantine v8 peer dependencies, removed unnecessary prosemirror
resolutions
- Formatting toolbar: Replaced the manual reimplementation of
FormattingToolbarController (which handled visibility, positioning,
portal rendering, text-alignment-based placement, and a
dangerouslySetInnerHTML transition trick) with BlockNote's built-in
FormattingToolbarController. The toolbar buttons themselves are
unchanged.
- Side menu: Replaced manual drag handle menu positioning and rendering
(DashboardBlockDragHandleMenu, DashboardBlockColorPicker, and their
floating configs) with BlockNote's built-in SideMenuController,
DragHandleButton, and DragHandleMenu components. Deleted 4 files that
became dead code.
- Extension API migration: Replaced deprecated editor.suggestionMenus
and editor.formattingToolbar APIs with the new extension system
(SuggestionMenu, useExtensionState, editor.getExtension())
- Slash menu fixes: Filtered out BlockNote's new default "File" item
(added in 0.47) to avoid duplicates with our custom one; added icon
mappings for new block types (Toggle List, Divider, Toggle Headings,
Headings 4-6)
- Server-side: Switched @blocknote/server-util to dynamic import() to
handle ESM-only transitive dependencies in CJS context
2026-02-27 09:16:49 +01:00

58 lines
2.0 KiB
TypeScript

import { SuggestionMenu } from '@blocknote/core/extensions';
import { useExtensionState } from '@blocknote/react';
import { useStore } from 'jotai';
import { useCallback, useState } from 'react';
import { isSlashMenuOpenComponentState } from '@/blocknote-editor/states/isSlashMenuOpenComponentState';
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
import { useSetActiveDropdownFocusIdAndMemorizePrevious } from '@/ui/layout/dropdown/hooks/useSetFocusedDropdownIdAndMemorizePrevious';
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
export const BlockEditorDropdownFocusEffect = () => {
const [prevShowing, setPrevShowing] = useState<boolean | null>(null);
const isSlashMenuOpenState = useAtomComponentStateCallbackState(
isSlashMenuOpenComponentState,
);
const { setActiveDropdownFocusIdAndMemorizePrevious } =
useSetActiveDropdownFocusIdAndMemorizePrevious();
const { goBackToPreviousDropdownFocusId } =
useGoBackToPreviousDropdownFocusId();
const store = useStore();
const suggestionState = useExtensionState(SuggestionMenu);
const isSlashMenuShowing =
suggestionState?.show === true && suggestionState?.triggerCharacter === '/';
const syncSlashMenuState = useCallback(
(showing: boolean) => {
const isAlreadyOpen = store.get(isSlashMenuOpenState);
if (showing && isAlreadyOpen !== true) {
setActiveDropdownFocusIdAndMemorizePrevious('custom-slash-menu');
store.set(isSlashMenuOpenState, true);
} else if (!showing && isAlreadyOpen === true) {
goBackToPreviousDropdownFocusId();
store.set(isSlashMenuOpenState, false);
}
},
[
isSlashMenuOpenState,
setActiveDropdownFocusIdAndMemorizePrevious,
goBackToPreviousDropdownFocusId,
store,
],
);
if (prevShowing !== isSlashMenuShowing) {
setPrevShowing(isSlashMenuShowing);
syncSlashMenuState(isSlashMenuShowing);
}
return <></>;
};