@explita/editor
Version:
`@explita/editor` is a versatile, modern rich-text editor built on TipTap for seamless integration into React applications. It provides extensive customization options and advanced features to cater to diverse content creation needs.
139 lines (138 loc) • 6.7 kB
JavaScript
"use client";
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { cn } from "../lib/utils";
import { LuBold, LuItalic, LuListTodo, LuPrinter, LuRedo2, LuRemoveFormatting, LuSave, LuSpellCheck, LuStrikethrough, LuSubscript, LuSuperscript, LuUnderline, LuUndo2, } from "react-icons/lu";
import { GoHorizontalRule } from "react-icons/go";
import { ImPageBreak } from "react-icons/im";
import { Separator } from "./ui/separator";
import { FontFamily } from "./FontFamily";
import { Heading } from "./Heading";
import { TextColor } from "./TextColor";
import { useEditorStore } from "../store/useEditorState";
import { HighlightColor } from "./HighlightColor";
import { Link } from "./Link";
import { LinkUnset } from "./LinkUnset";
import { Image } from "./Image";
import { TextAlignment } from "./TextAlignment";
import { List } from "./List";
import { FontSize } from "./FontSize";
import { LineHeight } from "./LineHeight";
import { TablePopupMenu } from "./TablePopUpMenu";
import { Table } from "./Table";
import { RxTable } from "react-icons/rx";
import { Menu } from "./Menu";
import { WordImport } from "./WorldImport";
function ToolbarButton({ label, onClick, isActive, icon: Icon, }) {
return (_jsx("button", { type: "button", onClick: onClick, className: cn("toolbar-button", isActive && "editor-item-active"), title: label, children: _jsx(Icon, { size: 16 }) }));
}
export function Toolbar({ onCreateNew, onSave, onClose, toolbarRight, isMini = false, }) {
const { editor } = useEditorStore();
const sections = [
[
{
label: "Undo",
icon: LuUndo2,
onClick: () => editor?.chain().focus().undo().run(),
},
{
label: "Redo",
icon: LuRedo2,
onClick: () => editor?.chain().focus().redo().run(),
},
{
label: "Save",
icon: LuSave,
onClick: () => onSave?.(editor?.getHTML() || ""),
},
{
label: "Print",
icon: LuPrinter,
onClick: () => window.print(),
},
{
label: "Spell Check",
icon: LuSpellCheck,
isActive: editor?.view.dom.getAttribute("spellcheck") === "true",
onClick: () => {
const current = editor?.view.dom.getAttribute("spellcheck");
editor?.view.dom.setAttribute("spellcheck", current === "true" ? "false" : "true");
editor?.chain().focus().run();
},
},
],
[
{
label: "Bold",
icon: LuBold,
isActive: editor?.isActive("bold"),
onClick: () => editor?.chain().focus().toggleBold().run(),
},
{
label: "Italic",
icon: LuItalic,
isActive: editor?.isActive("italic"),
onClick: () => editor?.chain().focus().toggleItalic().run(),
},
{
label: "Underline",
icon: LuUnderline,
isActive: editor?.isActive("underline"),
onClick: () => editor?.chain().focus().toggleUnderline().run(),
},
{
label: "Strikethrough",
icon: LuStrikethrough,
isActive: editor?.isActive("strike"),
onClick: () => editor?.chain().focus().toggleStrike().run(),
},
{
label: "Superscript",
icon: LuSuperscript,
isActive: editor?.isActive("superscript"),
onClick: () => editor?.chain().focus().toggleSuperscript().run(),
},
{
label: "Subscript",
icon: LuSubscript,
isActive: editor?.isActive("subscript"),
onClick: () => editor?.chain().focus().toggleSubscript().run(),
},
{
label: "Horizontal Rule",
icon: GoHorizontalRule,
onClick: () => editor?.chain().focus().setHorizontalRule().run(),
},
],
[
{
label: "Todo List",
icon: LuListTodo,
isActive: editor?.isActive("taskList"),
onClick: () => editor?.chain().focus().toggleTaskList().run(),
},
{
label: "Clear Formatting",
icon: LuRemoveFormatting,
onClick: () => editor?.chain().focus().unsetAllMarks().run(),
},
// {
// label: "Comment",
// icon: LuMessageSquare,
// onClick: () => console.log("comment clicked"),
// },
],
];
if (!isMini) {
sections[2].push({
label: "Inser Page Break",
icon: ImPageBreak,
onClick: () => editor?.commands.insertPageBreak(),
});
}
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "toolbar-container", children: [_jsxs("div", { className: "toolbar-content", "data-mini": isMini, children: [!isMini && _jsx(Menu, { onCreateNew: onCreateNew, onClose: onClose }), !isMini && (_jsxs(_Fragment, { children: [sections[0].map((section) => (_jsx(ToolbarButton, { ...section }, section.label))), _jsx(Separator, { className: "separator" })] })), _jsx(FontFamily, {}), _jsx(Separator, { className: "separator" }), _jsx(FontSize, {}), _jsx(Separator, { className: "separator" }), _jsx(Heading, {}), _jsx(Separator, { className: "separator" }), sections[1].map((section) => (_jsx(ToolbarButton, { ...section }, section.label))), _jsx(TextAlignment, {}), _jsx(LineHeight, {}), _jsx(TextColor, {}), _jsx(HighlightColor, {}), _jsx(Separator, { className: "separator" }), _jsx(Link, {}), _jsx(LinkUnset, {}), _jsx(Image, {}), _jsx(List, {}), _jsx(Table, { isToolbar: true, children: _jsx("button", { title: "Insert Table", className: "toolbar-button", children: _jsx(RxTable, { size: 16 }) }) }), _jsx(Separator, { className: "separator" }), sections[2].map((section) => (_jsx(ToolbarButton, { ...section }, section.label))), !isMini && (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "separator" }), _jsx(WordImport, {})] }))] }), toolbarRight] }), editor?.isActive("table") && !isMini && _jsx(TablePopupMenu, {}), editor?.isActive("table") && isMini && _jsx(TablePopupMenu.Mini, {})] }));
}
Toolbar.defaultProps = {
onSave: () => { },
toolbarRight: null,
isMini: false,
};