import { NodeViewContent, NodeViewProps, NodeViewWrapper, } from "@tiptap/react"; import { ActionIcon, Menu, Tooltip } from "@mantine/core"; import { notifications } from "@mantine/notifications"; import { IconCheck, IconCopy, IconDots, IconLinkOff, IconTrash, } from "@tabler/icons-react"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import classes from "./transclusion.module.css"; import SyncBlockReferencesDropdown from "@/features/transclusion/components/sync-block-references-dropdown"; export default function TransclusionView(props: NodeViewProps) { const { editor, node, deleteNode } = props; const { t } = useTranslation(); const [openMenus, setOpenMenus] = useState(0); const trackOpen = (open: boolean) => setOpenMenus((n) => Math.max(0, n + (open ? 1 : -1))); const isEditable = editor.isEditable; // @ts-ignore - editor.storage.pageId is set by the host editor (page-editor.tsx onCreate) const sourcePageId: string | undefined = editor.storage?.pageId; const transclusionId: string | null = node.attrs.id ?? null; const [copied, setCopied] = useState(false); const handleCopy = async () => { if (!sourcePageId || !transclusionId) return; const html = `
`; try { await navigator.clipboard.write([ new ClipboardItem({ "text/html": new Blob([html], { type: "text/html" }), "text/plain": new Blob([html], { type: "text/plain" }), }), ]); } catch { // Fallback for browsers without ClipboardItem write support try { await navigator.clipboard.writeText(html); } catch { return; } } setCopied(true); window.setTimeout(() => setCopied(false), 2000); notifications.show({ message: t("Copied. Paste on any page to embed this synced block."), }); }; const handleUnsync = () => { editor.chain().focus().unsyncTransclusionSource().run(); }; return (