import { BubbleMenu, BubbleMenuProps } from "@tiptap/react"; import clsx from "clsx"; import { FC, Fragment, useState } from "react"; import { BoldIcon, ItalicIcon, UnderlineIcon, CodeIcon } from "lucide-react"; import { NodeSelector } from "./NodeSelector"; import { ColorSelector } from "./ColorSelector"; export interface BubbleMenuItem { name: string; isActive: () => boolean; command: () => void; icon: typeof BoldIcon; } type EditorBubbleMenuProps = Omit & {}; export const EditorBubbleMenu: FC = (props) => { const items: BubbleMenuItem[] = [ { name: "bold", isActive: () => props.editor?.isActive("bold") ?? false, command: () => props.editor?.chain().focus().toggleBold().run(), icon: BoldIcon, }, { name: "italic", isActive: () => props.editor?.isActive("italic") ?? false, command: () => props.editor?.chain().focus().toggleItalic().run(), icon: ItalicIcon, }, { name: "underline", isActive: () => props.editor?.isActive("underline") ?? false, command: () => props.editor?.chain().focus().toggleUnderline().run(), icon: UnderlineIcon, }, // { // name: "strike", // isActive: () => props.editor?.isActive("strike") ?? false, // command: () => props.editor?.chain().focus().toggleStrike().run(), // icon: StrikethroughIcon, // }, { name: "code", isActive: () => props.editor?.isActive("code") ?? false, command: () => props.editor?.chain().focus().toggleCode().run(), icon: CodeIcon, }, ]; const bubbleMenuProps: EditorBubbleMenuProps = { ...props, shouldShow: ({ editor }) => { // don't show if image is selected if (editor?.isActive("image")) { return false; } return editor.view.state.selection.content().size > 0; }, tippyOptions: { moveTransition: "transform 0.15s ease-out", onHidden: () => { setIsNodeSelectorOpen(false); setIsColorSelectorOpen(false); }, }, }; const [isNodeSelectorOpen, setIsNodeSelectorOpen] = useState(false); const [isColorSelectorOpen, setIsColorSelectorOpen] = useState(false); return ( {props.editor && ( { setIsNodeSelectorOpen(!isNodeSelectorOpen); setIsColorSelectorOpen(false); }} /> {items.map((item, index) => ( ))} { setIsColorSelectorOpen(!isColorSelectorOpen); setIsNodeSelectorOpen(false); }} /> )} ); };