import { useBlockNoteEditor } from '@blocknote/react'; import { styled } from '@linaria/react'; import { autoUpdate, flip, offset, useFloating } from '@floating-ui/react'; import { motion } from 'framer-motion'; import { createPortal } from 'react-dom'; import { SLASH_MENU_DROPDOWN_CLICK_OUTSIDE_ID } from '@/ui/input/constants/SlashMenuDropdownClickOutsideId'; import { SLASH_MENU_LIST_ID } from '@/ui/input/constants/SlashMenuListId'; import { CustomSlashMenuListItem } from '@/blocknote-editor/components/CustomSlashMenuListItem'; import { CustomSlashMenuSelectedIndexSyncEffect } from '@/blocknote-editor/components/CustomSlashMenuSelectedIndexSyncEffect'; import type { CustomSlashMenuProps, SuggestionItem, } from '@/blocknote-editor/types/types'; import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContainer'; import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList'; export type { SuggestionItem }; const StyledContainer = styled.div` height: 1px; width: 1px; `; export const CustomSlashMenu = ({ items, selectedIndex, }: CustomSlashMenuProps) => { const editor = useBlockNoteEditor(); const currentBlock = editor?.getTextCursorPosition()?.block; const blockType = currentBlock?.type; const headingLevel = blockType === 'heading' ? Number(currentBlock?.props?.level) : null; const getOffsetValue = (placement: string) => { if (!placement.startsWith('top')) return 0; switch (headingLevel) { case 1: return 65; case 2: return 50; case 3: return 45; default: return 40; } }; const { refs, floatingStyles } = useFloating({ placement: 'bottom-start', whileElementsMounted: autoUpdate, middleware: [flip(), offset(({ placement }) => getOffsetValue(placement))], }); return ( <> {createPortal( item.title)} > {items.map((item) => ( ))} , document.body, )} ); };