refactor(expr): JsonTree — un-pickable trees still expand + drop dead clickable var

This commit is contained in:
Claude
2026-08-30 11:13:39 +00:00
parent 6fd517c630
commit 38aa05bc96
2 changed files with 14 additions and 6 deletions

View File

@@ -54,6 +54,13 @@ describe("JsonTree", () => {
expect(onPick).not.toHaveBeenCalled();
});
it("branches still expand when pickable is false (an un-pickable tree stays browsable)", async () => {
render(<JsonTree value={{ a: { b: 2 } }} pickable={false} />);
expect(screen.queryByText("b")).not.toBeInTheDocument();
await userEvent.click(screen.getByText("a"));
expect(screen.getByText("b")).toBeInTheDocument();
});
it("renders empty state for empty object", () => {
render(<JsonTree value={{}} />);
expect(screen.getByText(/no data/i)).toBeInTheDocument();

View File

@@ -54,11 +54,12 @@ function Node({ label, value, path, depth, pickable, onPick }: NodeProps) {
function BranchOrLeaf({ label, value, path, depth, pickable, onPick }: NodeProps) {
const branch = isBranch(value);
const [open, setOpen] = useState(false);
const clickable = pickable;
// Branches always expand/collapse (so an un-pickable tree can still be
// browsed — e.g. the Output column in the node editor dialog). Only leaf
// clicks are gated by `pickable`.
const pickHandler = () => {
if (!pickable) return;
if (branch) setOpen((o) => !o);
else onPick?.(path);
if (branch) { setOpen((o) => !o); return; }
if (pickable) onPick?.(path);
};
return (
<li>
@@ -67,8 +68,8 @@ function BranchOrLeaf({ label, value, path, depth, pickable, onPick }: NodeProps
onClick={pickHandler}
className={
"flex items-center gap-1 w-full text-left py-0.5 px-1 rounded " +
(pickable ? "hover:bg-slate-800/80 " : "opacity-50 cursor-default ") +
(clickable ? "" : "cursor-default")
"hover:bg-slate-800/80 " +
(!pickable && !branch ? "opacity-50 cursor-default" : "")
}
>
{branch ? (open ? <ChevronDown size={12} /> : <ChevronRight size={12} />) : <span className="w-3" />}