import { BubbleMenu, BubbleMenuProps } from "@tiptap/react"; import { FC, useState } from "react"; import { BoldIcon, ItalicIcon, UnderlineIcon, StrikethroughIcon, CodeIcon } from "lucide-react"; import { NodeSelector } from "./node-selector"; import { LinkSelector } from "./link-selector"; import { cn } from "../utils"; 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"), command: () => props.editor.chain().focus().toggleBold().run(), icon: BoldIcon, }, { name: "italic", isActive: () => props.editor.isActive("italic"), command: () => props.editor.chain().focus().toggleItalic().run(), icon: ItalicIcon, }, { name: "underline", isActive: () => props.editor.isActive("underline"), command: () => props.editor.chain().focus().toggleUnderline().run(), icon: UnderlineIcon, }, { name: "strike", isActive: () => props.editor.isActive("strike"), command: () => props.editor.chain().focus().toggleStrike().run(), icon: StrikethroughIcon, }, { name: "code", isActive: () => props.editor.isActive("code"), command: () => props.editor.chain().focus().toggleCode().run(), icon: CodeIcon, }, ]; const bubbleMenuProps: EditorBubbleMenuProps = { ...props, shouldShow: ({ editor }) => { if (!editor.isEditable) { return false; } if (editor.isActive("image")) { return false; } return editor.view.state.selection.content().size > 0; }, tippyOptions: { moveTransition: "transform 0.15s ease-out", onHidden: () => { setIsNodeSelectorOpen(false); setIsLinkSelectorOpen(false); }, }, }; const [isNodeSelectorOpen, setIsNodeSelectorOpen] = useState(false); const [isLinkSelectorOpen, setIsLinkSelectorOpen] = useState(false); return ( { setIsNodeSelectorOpen(!isNodeSelectorOpen); setIsLinkSelectorOpen(false); }} /> { setIsLinkSelectorOpen(!isLinkSelectorOpen); setIsNodeSelectorOpen(false); }} />
{items.map((item, index) => ( ))}
); };