"use client";
import type { Editor } from "@tiptap/core";
import {
AlignCenter,
AlignLeft,
AlignRight,
Bold as BoldIcon,
Columns,
Columns3,
Heading1,
Heading2,
Heading3,
Highlighter,
Italic as ItalicIcon,
Link as LinkIcon,
List,
ListOrdered,
ListPlus,
ListX,
Quote,
Redo,
Strikethrough as StrikeIcon,
Table as TableIcon,
Type,
Underline as UnderlineIcon,
Undo,
} from "lucide-react";
import { Toggle } from "../ui/toggle";
export default function MenuBar({ editor }: { editor: Editor | null }) {
if (!editor) return null;
const opts = [
// Headings
{
icon: ,
action: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
pressed: editor.isActive("heading", { level: 1 }),
},
{
icon: ,
action: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
pressed: editor.isActive("heading", { level: 2 }),
},
{
icon: ,
action: () => editor.chain().focus().toggleHeading({ level: 3 }).run(),
pressed: editor.isActive("heading", { level: 3 }),
},
// Marks
{
icon: ,
action: () => editor.chain().focus().toggleBold().run(),
pressed: editor.isActive("bold"),
},
{
icon: ,
action: () => editor.chain().focus().toggleItalic().run(),
pressed: editor.isActive("italic"),
},
{
icon: ,
action: () => editor.chain().focus().toggleUnderline().run(),
pressed: editor.isActive("underline"),
},
{
icon: ,
action: () => editor.chain().focus().toggleStrike().run(),
pressed: editor.isActive("strike"),
},
{
icon: ,
action: () => editor.chain().focus().toggleHighlight().run(),
pressed: editor.isActive("highlight"),
},
// Link
{
icon: ,
action: () => {
if (editor.isActive("link")) {
editor.chain().focus().unsetLink().run();
return;
}
const url =
typeof window !== "undefined" ? window.prompt("Enter URL") : null;
if (url) editor.chain().focus().setLink({ href: url }).run();
},
pressed: editor.isActive("link"),
},
// Blockquote / HR
{
icon:
,
action: () => editor.chain().focus().toggleBlockquote().run(),
pressed: editor.isActive("blockquote"),
},
{
icon: ,
action: () => editor.chain().focus().setHorizontalRule().run(),
pressed: false,
},
// Align
{
icon: ,
action: () => editor.chain().focus().setTextAlign("left").run(),
pressed: editor.isActive({ textAlign: "left" }),
},
{
icon: ,
action: () => editor.chain().focus().setTextAlign("center").run(),
pressed: editor.isActive({ textAlign: "center" }),
},
{
icon: ,
action: () => editor.chain().focus().setTextAlign("right").run(),
pressed: editor.isActive({ textAlign: "right" }),
},
// Lists
{
icon:
,
action: () => editor.chain().focus().toggleBulletList().run(),
pressed: editor.isActive("bulletList"),
},
{
icon: ,
action: () => editor.chain().focus().toggleOrderedList().run(),
pressed: editor.isActive("orderedList"),
},
// Table controls
{
icon: ,
action: () =>
editor.isActive("table")
? editor.chain().focus().deleteTable().run()
: editor
.chain()
.focus()
.insertTable({ rows: 3, cols: 2, withHeaderRow: true })
.run(),
pressed: editor.isActive("table"),
},
{
icon: ,
action: () => editor.chain().focus().addRowAfter().run(),
pressed: false,
},
{
icon: ,
action: () => editor.chain().focus().addColumnAfter().run(),
pressed: false,
},
{
icon: ,
action: () => editor.chain().focus().deleteRow().run(),
pressed: false,
},
{
icon: ,
action: () => editor.chain().focus().deleteColumn().run(),
pressed: false,
},
// History
{
icon: ,
action: () => editor.chain().focus().undo().run(),
pressed: false,
},
{
icon: ,
action: () => editor.chain().focus().redo().run(),
pressed: false,
},
];
return (
{opts.map((o, i) => (
o.action()}
aria-pressed={o.pressed}
className="data-[state=on]:bg-primary/10"
>
{o.icon}
))}
);
}