import { NodeViewWrapper } from "@tiptap/react"; import { useState, useRef, useCallback } from "react"; import type { NodeViewProps } from "@tiptap/react"; export function CitationView({ node, editor, getPos }: NodeViewProps) { const key = node.attrs.key as string; const label = (node.attrs.label as string) || `[${key}]`; const [showTooltip, setShowTooltip] = useState(false); const tooltipTimer = useRef>(); const wrapperRef = useRef(null); const getEntry = useCallback(() => { return (editor.storage.citation as any)?.citationsMap?.get(key) ?? null; }, [editor, key]); const handleMouseEnter = useCallback(() => { tooltipTimer.current = setTimeout(() => setShowTooltip(true), 300); }, []); const handleMouseLeave = useCallback(() => { clearTimeout(tooltipTimer.current); setShowTooltip(false); }, []); const removeCitation = useCallback(() => { const pos = getPos(); if (typeof pos === "number") { editor.chain().focus().deleteRange({ from: pos, to: pos + 1 }).run(); } setShowTooltip(false); }, [editor, getPos]); const entry = showTooltip ? getEntry() : null; return ( {label} {showTooltip && entry && (
{entry.title || key}
{entry["container-title"] && (
{entry["container-title"]} {entry.volume ? `, ${entry.volume}` : ""} {entry.page ? `, ${entry.page}` : ""}
)} {entry.DOI && (
doi: {entry.DOI}
)}
)}
); }