'use client'; import { useCallback, useState } from 'react'; import { AIChatPlugin } from '@udecode/plate-ai/react'; import { BlockquotePlugin } from '@udecode/plate-block-quote/react'; import { unsetNodes } from '@udecode/plate-common'; import { ParagraphPlugin, focusEditor, useEditorPlugin, } from '@udecode/plate-common/react'; import { HEADING_KEYS } from '@udecode/plate-heading'; import { IndentListPlugin } from '@udecode/plate-indent-list/react'; import { BLOCK_CONTEXT_MENU_ID, BlockMenuPlugin, BlockSelectionPlugin, } from '@udecode/plate-selection/react'; import { useIsTouchDevice } from '~/lib/hooks/use-is-touch-device'; import { ContextMenu, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, } from './context-menu'; type Value = 'askAI' | null; export function BlockContextMenu({ children }: { children: React.ReactNode }) { const { api, editor } = useEditorPlugin(BlockMenuPlugin); const [value, setValue] = useState(null); const isTouch = useIsTouchDevice(); const handleTurnInto = useCallback( (type: string) => { editor .getApi(BlockSelectionPlugin) .blockSelection.getNodes() .forEach(([node, path]) => { if (node[IndentListPlugin.key]) { unsetNodes(editor, [IndentListPlugin.key, 'indent'], { at: path }); } editor.tf.toggle.block({ type }, { at: path }); }); }, [editor] ); const handleAlign = useCallback( (align: 'center' | 'left' | 'right') => { editor .getTransforms(BlockSelectionPlugin) .blockSelection.setNodes({ align }); }, [editor] ); if (isTouch) { return children; } return ( { if (!open) { // prevent unselect the block selection setTimeout(() => { api.blockMenu.hide(); }, 0); } }} modal={false} > { const dataset = (event.target as HTMLElement).dataset; const disabled = dataset?.slateEditor === 'true'; if (disabled) return event.preventDefault(); api.blockMenu.show(BLOCK_CONTEXT_MENU_ID, { x: event.clientX, y: event.clientY, }); }} >
{children}
{ e.preventDefault(); editor.getApi(BlockSelectionPlugin).blockSelection.focus(); if (value === 'askAI') { editor.getApi(AIChatPlugin).aiChat.show(); } setValue(null); }} > { setValue('askAI'); }} > Ask AI { editor .getTransforms(BlockSelectionPlugin) .blockSelection.removeNodes(); focusEditor(editor); }} > Delete { editor .getTransforms(BlockSelectionPlugin) .blockSelection.duplicate( editor.getApi(BlockSelectionPlugin).blockSelection.getNodes() ); }} > Duplicate {/* ⌘ + D */} Turn into handleTurnInto(ParagraphPlugin.key)} > Paragraph handleTurnInto(HEADING_KEYS.h1)}> Heading 1 handleTurnInto(HEADING_KEYS.h2)}> Heading 2 handleTurnInto(HEADING_KEYS.h3)}> Heading 3 handleTurnInto(BlockquotePlugin.key)} > Blockquote editor .getTransforms(BlockSelectionPlugin) .blockSelection.setIndent(1) } > Indent editor .getTransforms(BlockSelectionPlugin) .blockSelection.setIndent(-1) } > Outdent Align handleAlign('left')}> Left handleAlign('center')}> Center handleAlign('right')}> Right
); }