"use client"; import { type PlaitBoard, type PlaitElement, toHostPointFromViewBoxPoint, toScreenPointFromHostPoint, } from "@plait/core"; import { getRectangleByNode, MindElement } from "@plait/mind"; import { MoreHorizontal, X } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import { getNoteDocument, type NoteDocument, } from "@/lib/flow-board/topic-notes"; import { getTopicTitle } from "@/lib/flow-board/topic-details"; import { XmindNotesEditor } from "./xmind-notes-editor"; export function XmindNotesPopover({ board, topic, viewport, onChange, onDetails, onClose, }: { board: PlaitBoard | null; topic: PlaitElement | null; viewport: unknown; onChange: (doc: NoteDocument) => void; onDetails: () => void; onClose: () => void; }) { const ref = useRef(null); const [position, setPosition] = useState({ left: 400, top: 300 }); useEffect(() => { if (!board || !topic) return; const update = () => { const node = MindElement.getNode(topic as MindElement); if (!node) return; const rect = getRectangleByNode(node), point = toScreenPointFromHostPoint( board, toHostPointFromViewBoxPoint(board, [ rect.x + rect.width / 2, rect.y + rect.height, ]) ); const host = ref.current?.parentElement?.getBoundingClientRect(); const width = Math.min(360, window.innerWidth - 32); const right = window.innerWidth > 800 ? 240 : 0; const left = Math.max( 12, Math.min(window.innerWidth - right - width - 16, point[0] - width / 2) ); const top = Math.max( 78, Math.min(window.innerHeight - 340, point[1] + 12) ); setPosition({ left: left - (host?.x || 0), top: top - (host?.y || 0) }); }; const frame = requestAnimationFrame(update); window.addEventListener("resize", update); return () => { cancelAnimationFrame(frame); window.removeEventListener("resize", update); }; }, [board, topic?.id, topic?.data, viewport]); return ( ); }