import { BubbleMenu as BaseBubbleMenu, findParentNode, posToDOMRect, } from "@tiptap/react"; import React, { useCallback } from "react"; import { sticky } from "tippy.js"; 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 { IconLayoutAlignCenter, IconLayoutAlignLeft, IconLayoutAlignRight, } from "@tabler/icons-react"; import { NodeWidthResize } from "@/features/editor/components/common/node-width-resize.tsx"; export function VideoMenu({ editor }: EditorMenuProps) { const shouldShow = useCallback( ({ state }: ShouldShowProps) => { if (!state) { return false; } return editor.isActive("video"); }, [editor], ); const getReferenceClientRect = useCallback(() => { const { selection } = editor.state; const predicate = (node: PMNode) => node.type.name === "video"; 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 alignVideoLeft = useCallback(() => { editor .chain() .focus(undefined, { scrollIntoView: false }) .setVideoAlign("left") .run(); }, [editor]); const alignVideoCenter = useCallback(() => { editor .chain() .focus(undefined, { scrollIntoView: false }) .setVideoAlign("center") .run(); }, [editor]); const alignVideoRight = useCallback(() => { editor .chain() .focus(undefined, { scrollIntoView: false }) .setVideoAlign("right") .run(); }, [editor]); const onWidthChange = useCallback( (value: number) => { editor .chain() .focus(undefined, { scrollIntoView: false }) .setVideoWidth(value) .run(); }, [editor], ); return ( {editor.getAttributes("video")?.width && ( )} ); } export default VideoMenu;