// Edit panel for the selected block — rename, change kind, add/remove properties, delete. "use client"; import { useState, useEffect } from "react"; import type { BlockKind } from "../../lib/fixtures/aristotle"; import type { BlockNodeData } from "./nodes/BlockNode"; interface NodeInspectorProps { nodeId: string; data: BlockNodeData; onChange: (patch: Partial) => void; onDelete: () => void; onClose: () => void; } const KINDS: Array = ["system", "block", "actor", "constraint"]; export function NodeInspector({ nodeId, data, onChange, onDelete, onClose }: NodeInspectorProps) { // Local label state for smooth typing — push on blur const [label, setLabel] = useState(data.label); const [expression, setExpression] = useState(data.expression ?? ""); useEffect(() => { setLabel(data.label); setExpression(data.expression ?? ""); }, [nodeId, data.label, data.expression]); function commitLabel() { if (label.trim() && label !== data.label) onChange({ label: label.trim() }); } function commitExpression() { onChange({ expression }); } function updateProp(idx: number, value: string) { const next = [...data.properties]; next[idx] = value; onChange({ properties: next }); } function removeProp(idx: number) { onChange({ properties: data.properties.filter((_, i) => i !== idx) }); } function addProp() { onChange({ properties: [...data.properties, "new_property"] }); } return (
e.stopPropagation()}>
Kind
Label setLabel(e.target.value)} onBlur={commitLabel} onKeyDown={e => { if (e.key === "Enter") { e.preventDefault(); (e.target as HTMLInputElement).blur(); } }} />
{data.kind === "constraint" ? (
Expression setExpression(e.target.value)} onBlur={commitExpression} placeholder="{ tenancy = institutional }" />
) : (
Properties
{data.properties.map((p, i) => (
updateProp(i, e.target.value)} onKeyDown={e => { if (e.key === "Enter") { e.preventDefault(); (e.target as HTMLInputElement).blur(); } }} />
))}
)}
); }