import { BubbleMenu as BaseBubbleMenu, findParentNode, posToDOMRect, } from "@tiptap/react"; import React, { useCallback } from "react"; import { Node as PMNode } from "prosemirror-model"; import { EditorMenuProps, ShouldShowProps, } from "@/features/editor/components/table/types/types.ts"; import { ActionIcon, Tooltip } from "@mantine/core"; import { IconAlertTriangleFilled, IconCircleCheckFilled, IconCircleXFilled, IconInfoCircleFilled, } from "@tabler/icons-react"; import { CalloutType } from "@docmost/editor-ext"; export function CalloutMenu({ editor }: EditorMenuProps) { const shouldShow = useCallback( ({ state }: ShouldShowProps) => { if (!state) { return false; } return editor.isActive("callout"); }, [editor], ); const getReferenceClientRect = useCallback(() => { const { selection } = editor.state; const predicate = (node: PMNode) => node.type.name === "callout"; const parent = findParentNode(predicate)(selection); if (parent) { const dom = editor.view.nodeDOM(parent?.pos) as HTMLElement; return dom.getBoundingClientRect(); } return posToDOMRect(editor.view, selection.from, selection.to); }, [editor]); const setCalloutType = useCallback( (calloutType: CalloutType) => { editor .chain() .focus(undefined, { scrollIntoView: false }) .updateCalloutType(calloutType) .run(); }, [editor], ); return ( setCalloutType("info")} size="lg" aria-label="Info" variant={ editor.isActive("callout", { type: "info" }) ? "light" : "default" } > setCalloutType("success")} size="lg" aria-label="Success" variant={ editor.isActive("callout", { type: "success" }) ? "light" : "default" } > setCalloutType("warning")} size="lg" aria-label="Warning" variant={ editor.isActive("callout", { type: "warning" }) ? "light" : "default" } > setCalloutType("danger")} size="lg" aria-label="Danger" variant={ editor.isActive("callout", { type: "danger" }) ? "light" : "default" } > ); } export default CalloutMenu;