161 lines
4.1 KiB
TypeScript
161 lines
4.1 KiB
TypeScript
|
|
"use client";
|
||
|
|
import { type Editor } from "@tiptap/react";
|
||
|
|
|
||
|
|
import {
|
||
|
|
Bold,
|
||
|
|
Heading1,
|
||
|
|
Heading2,
|
||
|
|
Heading3,
|
||
|
|
Heading4,
|
||
|
|
Italic,
|
||
|
|
List,
|
||
|
|
ListOrdered,
|
||
|
|
Quote,
|
||
|
|
Redo,
|
||
|
|
SeparatorHorizontal,
|
||
|
|
StrikethroughIcon,
|
||
|
|
Text,
|
||
|
|
Underline,
|
||
|
|
Undo,
|
||
|
|
} from "lucide-react";
|
||
|
|
import { Toggle } from "~/components/ui/toggle";
|
||
|
|
import { Button } from "~/components/ui/button";
|
||
|
|
|
||
|
|
type Props = {
|
||
|
|
editor: Editor | null;
|
||
|
|
};
|
||
|
|
|
||
|
|
function ToolBar({ editor }: Props) {
|
||
|
|
if (!editor) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="border-input my-2 flex flex-wrap gap-3 rounded-lg border p-1">
|
||
|
|
<Toggle
|
||
|
|
onPressedChange={() => editor.chain().focus().setParagraph().run()}
|
||
|
|
pressed={editor.isActive("paragraph")}
|
||
|
|
>
|
||
|
|
<Text className="size-4" />
|
||
|
|
</Toggle>
|
||
|
|
<Toggle
|
||
|
|
size="sm"
|
||
|
|
pressed={editor.isActive("heading", { level: 1 })}
|
||
|
|
onPressedChange={() =>
|
||
|
|
editor.chain().focus().toggleHeading({ level: 1 }).run()
|
||
|
|
}
|
||
|
|
>
|
||
|
|
<Heading1 className="size-4" />
|
||
|
|
</Toggle>
|
||
|
|
<Toggle
|
||
|
|
size="sm"
|
||
|
|
pressed={editor.isActive("heading", { level: 2 })}
|
||
|
|
onPressedChange={() =>
|
||
|
|
editor.chain().focus().toggleHeading({ level: 2 }).run()
|
||
|
|
}
|
||
|
|
>
|
||
|
|
<Heading2 className="size-4" />
|
||
|
|
</Toggle>
|
||
|
|
<Toggle
|
||
|
|
size="sm"
|
||
|
|
pressed={editor.isActive("heading", { level: 3 })}
|
||
|
|
onPressedChange={() =>
|
||
|
|
editor.chain().focus().toggleHeading({ level: 3 }).run()
|
||
|
|
}
|
||
|
|
>
|
||
|
|
<Heading3 className="size-4" />
|
||
|
|
</Toggle>
|
||
|
|
<Toggle
|
||
|
|
size="sm"
|
||
|
|
pressed={editor.isActive("heading", { level: 4 })}
|
||
|
|
onPressedChange={() =>
|
||
|
|
editor.chain().focus().toggleHeading({ level: 4 }).run()
|
||
|
|
}
|
||
|
|
>
|
||
|
|
<Heading4 className="size-4" />
|
||
|
|
</Toggle>
|
||
|
|
|
||
|
|
<Toggle
|
||
|
|
size="sm"
|
||
|
|
pressed={editor.isActive("bold")}
|
||
|
|
onPressedChange={() => editor.chain().focus().toggleBold().run()}
|
||
|
|
>
|
||
|
|
<Bold className="size-4" />
|
||
|
|
</Toggle>
|
||
|
|
<Toggle
|
||
|
|
size="sm"
|
||
|
|
pressed={editor.isActive("italic")}
|
||
|
|
onPressedChange={() => editor.chain().focus().toggleItalic().run()}
|
||
|
|
>
|
||
|
|
<Italic className="size-4" />
|
||
|
|
</Toggle>
|
||
|
|
<Toggle
|
||
|
|
size="sm"
|
||
|
|
pressed={editor.isActive("underline")}
|
||
|
|
onPressedChange={() => editor.chain().focus().toggleUnderline().run()}
|
||
|
|
>
|
||
|
|
<Underline className="size-4" />
|
||
|
|
</Toggle>
|
||
|
|
<Toggle
|
||
|
|
size="sm"
|
||
|
|
pressed={editor.isActive("strike")}
|
||
|
|
onPressedChange={() => editor.chain().focus().toggleStrike().run()}
|
||
|
|
>
|
||
|
|
<StrikethroughIcon className="size-4" />
|
||
|
|
</Toggle>
|
||
|
|
<Toggle
|
||
|
|
size="sm"
|
||
|
|
pressed={editor.isActive("bulletList")}
|
||
|
|
onPressedChange={() => editor.chain().focus().toggleBulletList().run()}
|
||
|
|
>
|
||
|
|
<List className="size-4" />
|
||
|
|
</Toggle>
|
||
|
|
<Toggle
|
||
|
|
size="sm"
|
||
|
|
pressed={editor.isActive("orderedList")}
|
||
|
|
onPressedChange={() => editor.chain().focus().toggleOrderedList().run()}
|
||
|
|
>
|
||
|
|
<ListOrdered className="size-4" />
|
||
|
|
</Toggle>
|
||
|
|
<Toggle
|
||
|
|
size="sm"
|
||
|
|
pressed={editor.isActive("blockquote")}
|
||
|
|
onPressedChange={() => editor.chain().focus().toggleBlockquote().run()}
|
||
|
|
>
|
||
|
|
<Quote className="size-4" />
|
||
|
|
</Toggle>
|
||
|
|
<Button
|
||
|
|
variant="ghost"
|
||
|
|
type="button"
|
||
|
|
onClick={() => editor.chain().focus().setHorizontalRule().run()}
|
||
|
|
>
|
||
|
|
<SeparatorHorizontal className="size-4" />
|
||
|
|
</Button>
|
||
|
|
<Button
|
||
|
|
variant="ghost"
|
||
|
|
type="button"
|
||
|
|
onClick={() => editor.chain().focus().setHardBreak().run()}
|
||
|
|
>
|
||
|
|
Hard break
|
||
|
|
</Button>
|
||
|
|
|
||
|
|
<Button
|
||
|
|
variant="ghost"
|
||
|
|
type="button"
|
||
|
|
onClick={() => editor.chain().focus().undo().run()}
|
||
|
|
>
|
||
|
|
<Undo className="size-4" />
|
||
|
|
</Button>
|
||
|
|
<Button
|
||
|
|
variant="ghost"
|
||
|
|
type="button"
|
||
|
|
onClick={() => editor.chain().focus().redo().run()}
|
||
|
|
>
|
||
|
|
<Redo className="size-4" />
|
||
|
|
</Button>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
export default ToolBar;
|