"use client"; import { ChevronRightIcon, Code2Icon, FileCodeIcon, Heading1Icon, Heading2Icon, Heading3Icon, InfoIcon, ListIcon, ListOrderedIcon, MinusIcon, PilcrowIcon, QuoteIcon, RadicalIcon, SquareIcon, TableIcon, } from "lucide-react"; import { KEYS } from "platejs"; import type { PlateElementProps } from "platejs/react"; import { PlateElement, useEditorRef } from "platejs/react"; import type * as React from "react"; import { insertBlock, insertInlineElement } from "@/components/editor/transforms"; import { InlineCombobox, InlineComboboxContent, InlineComboboxEmpty, InlineComboboxGroup, InlineComboboxGroupLabel, InlineComboboxInput, InlineComboboxItem, } from "@/components/ui/inline-combobox"; interface SlashCommandItem { icon: React.ReactNode; keywords: string[]; label: string; value: string; onSelect: (editor: any) => void; } const slashCommandGroups: { heading: string; items: SlashCommandItem[] }[] = [ { heading: "Basic Blocks", items: [ { icon: , keywords: ["paragraph", "text", "plain"], label: "Text", value: "text", onSelect: (editor) => insertBlock(editor, KEYS.p), }, { icon: , keywords: ["title", "h1", "heading"], label: "Heading 1", value: "heading1", onSelect: (editor) => insertBlock(editor, "h1"), }, { icon: , keywords: ["subtitle", "h2", "heading"], label: "Heading 2", value: "heading2", onSelect: (editor) => insertBlock(editor, "h2"), }, { icon: , keywords: ["subtitle", "h3", "heading"], label: "Heading 3", value: "heading3", onSelect: (editor) => insertBlock(editor, "h3"), }, { icon: , keywords: ["citation", "blockquote"], label: "Quote", value: "quote", onSelect: (editor) => insertBlock(editor, KEYS.blockquote), }, { icon: , keywords: ["divider", "separator", "line"], label: "Divider", value: "divider", onSelect: (editor) => insertBlock(editor, KEYS.hr), }, ], }, { heading: "Lists", items: [ { icon: , keywords: ["unordered", "ul", "bullet"], label: "Bulleted list", value: "bulleted-list", onSelect: (editor) => insertBlock(editor, KEYS.ul), }, { icon: , keywords: ["ordered", "ol", "numbered"], label: "Numbered list", value: "numbered-list", onSelect: (editor) => insertBlock(editor, KEYS.ol), }, { icon: , keywords: ["checklist", "task", "checkbox", "todo"], label: "To-do list", value: "todo-list", onSelect: (editor) => insertBlock(editor, KEYS.listTodo), }, ], }, { heading: "Advanced", items: [ { icon: , keywords: ["table", "grid"], label: "Table", value: "table", onSelect: (editor) => insertBlock(editor, KEYS.table), }, { icon: , keywords: ["code", "codeblock", "snippet"], label: "Code block", value: "code-block", onSelect: (editor) => insertBlock(editor, KEYS.codeBlock), }, { icon: , keywords: ["callout", "note", "info", "warning", "tip"], label: "Callout", value: "callout", onSelect: (editor) => insertBlock(editor, KEYS.callout), }, { icon: , keywords: ["toggle", "collapsible", "expand"], label: "Toggle", value: "toggle", onSelect: (editor) => insertBlock(editor, KEYS.toggle), }, { icon: , keywords: ["equation", "math", "formula", "latex"], label: "Equation", value: "equation", onSelect: (editor) => insertInlineElement(editor, KEYS.equation), }, ], }, { heading: "Inline", items: [ { icon: , keywords: ["link", "url", "href"], label: "Link", value: "link", onSelect: (editor) => insertInlineElement(editor, KEYS.link), }, ], }, ]; export function SlashInputElement({ children, ...props }: PlateElementProps) { const editor = useEditorRef(); return ( No results found. {slashCommandGroups.map(({ heading, items }) => ( {heading} {items.map(({ icon, keywords, label, value, onSelect }) => ( { onSelect(editor); editor.tf.focus(); }} > {icon} {label} ))} ))} {children} ); }