'use client';
import React from 'react';
import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';
import { BlockquotePlugin } from '@udecode/plate-block-quote/react';
import { CodeBlockPlugin } from '@udecode/plate-code-block/react';
import {
type PlateEditor,
ParagraphPlugin,
focusEditor,
useEditorRef,
} from '@udecode/plate-common/react';
import { DatePlugin } from '@udecode/plate-date/react';
import { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';
import { HEADING_KEYS } from '@udecode/plate-heading';
import { TocPlugin } from '@udecode/plate-heading/react';
import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';
import { INDENT_LIST_KEYS, ListStyleType } from '@udecode/plate-indent-list';
import { LinkPlugin } from '@udecode/plate-link/react';
import { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';
import { TablePlugin } from '@udecode/plate-table/react';
import { TogglePlugin } from '@udecode/plate-toggle/react';
import {
CalendarIcon,
ChevronRightIcon,
Columns3Icon,
FileCodeIcon,
FilmIcon,
Heading1Icon,
Heading2Icon,
Heading3Icon,
ImageIcon,
Link2Icon,
ListIcon,
ListOrderedIcon,
MinusIcon,
PenToolIcon,
PilcrowIcon,
PlusIcon,
QuoteIcon,
SquareIcon,
TableIcon,
TableOfContentsIcon,
} from 'lucide-react';
import {
insertBlock,
insertInlineElement,
} from '~/components/editor/transforms';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuTrigger,
useOpenState,
} from './dropdown-menu';
import { ToolbarButton } from './toolbar';
type Group = {
group: string;
items: Item[];
};
interface Item {
icon: React.ReactNode;
onSelect: (editor: PlateEditor, value: string) => void;
value: string;
focusEditor?: boolean;
label?: string;
}
const groups: Group[] = [
{
group: 'Basic blocks',
items: [
{
icon: ,
label: 'Paragraph',
value: ParagraphPlugin.key,
},
{
icon: ,
label: 'Heading 1',
value: HEADING_KEYS.h1,
},
{
icon: ,
label: 'Heading 2',
value: HEADING_KEYS.h2,
},
{
icon: ,
label: 'Heading 3',
value: HEADING_KEYS.h3,
},
{
icon: ,
label: 'Table',
value: TablePlugin.key,
},
{
icon: ,
label: 'Code',
value: CodeBlockPlugin.key,
},
{
icon: ,
label: 'Quote',
value: BlockquotePlugin.key,
},
{
icon: ,
label: 'Divider',
value: HorizontalRulePlugin.key,
},
].map((item) => ({
...item,
onSelect: (editor, value) => {
insertBlock(editor, value);
},
})),
},
{
group: 'Lists',
items: [
{
icon: ,
label: 'Bulleted list',
value: ListStyleType.Disc,
},
{
icon: ,
label: 'Numbered list',
value: ListStyleType.Decimal,
},
{
icon: ,
label: 'To-do list',
value: INDENT_LIST_KEYS.todo,
},
{
icon: ,
label: 'Toggle list',
value: TogglePlugin.key,
},
].map((item) => ({
...item,
onSelect: (editor, value) => {
insertBlock(editor, value);
},
})),
},
{
group: 'Media',
items: [
{
icon: ,
label: 'Image',
value: ImagePlugin.key,
},
{
icon: ,
label: 'Embed',
value: MediaEmbedPlugin.key,
},
{
icon: ,
label: 'Excalidraw',
value: ExcalidrawPlugin.key,
},
].map((item) => ({
...item,
onSelect: (editor, value) => {
insertBlock(editor, value);
},
})),
},
{
group: 'Advanced blocks',
items: [
{
icon: ,
label: 'Table of contents',
value: TocPlugin.key,
},
{
icon: ,
label: '3 columns',
value: 'action_three_columns',
},
].map((item) => ({
...item,
onSelect: (editor, value) => {
insertBlock(editor, value);
},
})),
},
{
group: 'Inline',
items: [
{
icon: ,
label: 'Link',
value: LinkPlugin.key,
},
{
focusEditor: true,
icon: ,
label: 'Date',
value: DatePlugin.key,
},
].map((item) => ({
...item,
onSelect: (editor, value) => {
insertInlineElement(editor, value);
},
})),
},
];
export function InsertDropdownMenu(props: DropdownMenuProps) {
const editor = useEditorRef();
const openState = useOpenState();
return (
{groups.map(({ group, items: nestedItems }) => (
{nestedItems.map(({ icon, label, value, onSelect }) => (
{
onSelect(editor, value);
focusEditor(editor);
}}
>
{icon}
{label}
))}
))}
);
}