"use client"; import type { DropdownMenuProps } from "@radix-ui/react-dropdown-menu"; import { ChevronRightIcon, FileCodeIcon, Heading1Icon, Heading2Icon, Heading3Icon, InfoIcon, ListIcon, ListOrderedIcon, MinusIcon, PilcrowIcon, PlusIcon, QuoteIcon, RadicalIcon, SquareIcon, SubscriptIcon, SuperscriptIcon, TableIcon, } from "lucide-react"; import { KEYS } from "platejs"; import { type PlateEditor, useEditorRef } from "platejs/react"; import * as React from "react"; import { insertBlock, insertInlineElement } from "@/components/editor/transforms"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { ToolbarButton, ToolbarMenuGroup } from "./toolbar"; type Group = { group: string; items: Item[]; }; type Item = { icon: React.ReactNode; value: string; onSelect: (editor: PlateEditor, value: string) => void; focusEditor?: boolean; label?: string; }; const groups: Group[] = [ { group: "Basic blocks", items: [ { icon: , label: "Paragraph", value: KEYS.p, }, { icon: , label: "Heading 1", value: "h1", }, { icon: , label: "Heading 2", value: "h2", }, { icon: , label: "Heading 3", value: "h3", }, { icon: , label: "Table", value: KEYS.table, }, { icon: , label: "Code block", value: KEYS.codeBlock, }, { icon: , label: "Quote", value: KEYS.blockquote, }, { icon: , label: "Divider", value: KEYS.hr, }, ].map((item) => ({ ...item, onSelect: (editor: PlateEditor, value: string) => { insertBlock(editor, value); }, })), }, { group: "Lists", items: [ { icon: , label: "Bulleted list", value: KEYS.ul, }, { icon: , label: "Numbered list", value: KEYS.ol, }, { icon: , label: "To-do list", value: KEYS.listTodo, }, { icon: , label: "Toggle list", value: KEYS.toggle, }, ].map((item) => ({ ...item, onSelect: (editor: PlateEditor, value: string) => { insertBlock(editor, value); }, })), }, { group: "Advanced", items: [ { icon: , label: "Callout", value: KEYS.callout, }, { focusEditor: false, icon: , label: "Equation", value: KEYS.equation, }, ].map((item) => ({ ...item, onSelect: (editor: PlateEditor, value: string) => { if (item.value === KEYS.equation) { insertInlineElement(editor, value); } else { insertBlock(editor, value); } }, })), }, { group: "Marks", items: [ { icon: , label: "Superscript", value: KEYS.sup, }, { icon: , label: "Subscript", value: KEYS.sub, }, ].map((item) => ({ ...item, onSelect: (editor: PlateEditor, value: string) => { editor.tf.toggleMark(value, { remove: value === KEYS.sup ? KEYS.sub : KEYS.sup, }); }, })), }, ]; export function InsertToolbarButton(props: DropdownMenuProps) { const editor = useEditorRef(); const [open, setOpen] = React.useState(false); return ( {groups.map(({ group, items }) => ( {items.map(({ icon, label, value, onSelect, focusEditor }) => ( { onSelect(editor, value); if (focusEditor !== false) { editor.tf.focus(); } setOpen(false); }} className="group" >
{icon} {label || value}
))}
))}
); }