// React NodeView for the chip TipTap node. // Renders identically to the static Chip via the same CSS classes. "use client"; import { NodeViewWrapper } from "@tiptap/react"; import type { NodeViewProps } from "@tiptap/react"; import type { ChipKind } from "../../lib/fixtures/aristotle"; import type { MarkupStyle } from "./Chip"; import { useChipFocus } from "./FocusContext"; const KIND_LABEL: Record = { block: "block", property: "property", association: "assoc", requirement: "req", }; function kindGlyph(kind: ChipKind): string { switch (kind) { case "block": return "▢"; case "property": return "·"; case "association": return "→"; case "requirement": return "§"; } } export function ChipView({ node, selected, editor }: NodeViewProps) { const kind = (node.attrs.kind as ChipKind) ?? "block"; const label = (node.attrs.label as string) ?? "untitled"; const refId = (node.attrs.refId as string | null) ?? null; // Read the current markup style from the editor's storage; defaults to "color". const markupStyle = ((editor.storage as unknown as Record).markupStyle as MarkupStyle | undefined) ?? "color"; const { focusBlockId, setFocusBlockId } = useChipFocus(); const isFocused = (refId !== null && refId === focusBlockId) || selected; const cls = `chip chip-${kind} chip-style-${markupStyle}${isFocused ? " chip-focus" : ""}`; const handlers = refId ? { onMouseEnter: () => setFocusBlockId(refId), onMouseLeave: () => setFocusBlockId(null), onClick: () => setFocusBlockId(refId), } : {}; if (markupStyle === "bracket") { return ( [ {KIND_LABEL[kind]}: {label} ] ); } if (markupStyle === "underline") { return ( {kindGlyph(kind)} {label} ); } return ( {kindGlyph(kind)} {label} ); }