Skip to content

feat(ui): add onNodeSelect and selectedId to ObjectGraph#40

Merged
moshloop merged 1 commit into
mainfrom
fix/objectgraph-node-select
Jul 6, 2026
Merged

feat(ui): add onNodeSelect and selectedId to ObjectGraph#40
moshloop merged 1 commit into
mainfrom
fix/objectgraph-node-select

Conversation

@moshloop

@moshloop moshloop commented Jul 6, 2026

Copy link
Copy Markdown
Member

Adds optional onNodeSelect and selectedId props to ObjectGraph.

  • onNodeSelect(node) makes a node label an actionable click target (drills its path) without toggling expansion — the chevron stays the only expand/collapse control.
  • selectedId highlights the currently-selected node's label.

Both props are optional; existing static trees render unchanged.

Consumed by oipa-cli's Arthas OGNL/Spring inspector (OgnlResultPanelArthasOgnlTab/ArthasSpringTab), whose docker build currently fails against published clicky-ui because these props are missing.

Tests: 3 new cases in ObjectGraph.test.tsx; all 6 ObjectGraph tests pass.

Summary by CodeRabbit

  • New Features

    • Added optional node selection in the object graph.
    • Selected nodes can now be visually highlighted.
  • Bug Fixes

    • Clicking a node label now selects it without expanding or collapsing the node.
    • When selection is not enabled, labels continue to display as static text.

Make ObjectGraph labels actionable: an optional onNodeSelect callback turns
each node label into a click target (drilling its path) without toggling
expansion, and selectedId highlights the active node. Both props are optional
so existing static trees are unaffected.
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds optional node selection support to ObjectGraph: new onNodeSelect and selectedId props, a refactored DefaultObjectLabel that renders a clickable button with selection highlighting when onSelect is provided, and new tests validating render behavior, click handling, and highlight application.

Changes

ObjectGraph Node Selection

Layer / File(s) Summary
Selection props contract
packages/ui/src/data/ObjectGraph.tsx
ObjectGraphProps gains onNodeSelect and selectedId, which are destructured in ObjectGraph.
Label rendering and highlight styling
packages/ui/src/data/ObjectGraph.tsx
Default label path passes selected/onSelect into DefaultObjectLabel, which now conditionally renders a <button> that stops row click propagation and applies selected styling, using a new cn import.
Selection behavior tests
packages/ui/src/data/ObjectGraph.test.tsx
New tests cover non-button label rendering without onNodeSelect, click-triggered onNodeSelect without invoking loadChildren, and highlight class assignment for selectedId matches.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant DefaultObjectLabel
  participant ObjectGraph

  User->>DefaultObjectLabel: click node label (button)
  DefaultObjectLabel->>DefaultObjectLabel: stop row click propagation
  DefaultObjectLabel->>ObjectGraph: onSelect(node)
  ObjectGraph->>ObjectGraph: invoke onNodeSelect(node)
  Note over ObjectGraph: expand/collapse and loadChildren not triggered
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely matches the main change: adding onNodeSelect and selectedId to ObjectGraph.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/objectgraph-node-select
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/objectgraph-node-select

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-07-06 10:58 UTC

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Gavel summary

Source Pass Fail Skip Duration
./apps/storybook 507 0 0 54.5s
./e2e 4 0 0 1m45s
./packages/ui 1392 0 0 1m24s
lint: betterleaks 0 0 1 -
lint: tsc 1 0 0 321ms

Totals: 1904 passed · 0 failed · 1 skipped · 4m4s

View full results

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/ui/src/data/ObjectGraph.tsx`:
- Around line 101-133: The selected label styling in DefaultObjectLabel is
currently tied to the onSelect button branch, so selectedId does not highlight
anything when onNodeSelect is omitted. Update DefaultObjectLabel in
ObjectGraph.tsx so the selected state affects both render paths, not just the
<button> case, and keep the selection styling independent of onSelect. Make sure
the selected prop is applied consistently whether the label renders as a button
or a plain span, and verify the ObjectGraph selectedId behavior still matches
the documented contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eb1418dc-de2a-406d-bcde-4405650db926

📥 Commits

Reviewing files that changed from the base of the PR and between 3880dab and 8566e30.

📒 Files selected for processing (2)
  • packages/ui/src/data/ObjectGraph.test.tsx
  • packages/ui/src/data/ObjectGraph.tsx

Comment on lines +101 to +133
function DefaultObjectLabel<T extends ObjectGraphNode>({
node,
onSelect,
selected = false,
}: {
node: T;
onSelect?: (node: T) => void;
selected?: boolean;
}) {
const label = onSelect ? (
// A button so the label is a first-class click target; stopPropagation keeps
// the row's onClick (which toggles the node) from firing, so selecting a node
// never expands or collapses it.
<button
type="button"
onClick={(e) => {
e.stopPropagation();
onSelect(node);
}}
title="Select this path"
className={cn(
"rounded px-0.5 text-left text-muted-foreground hover:text-foreground hover:underline",
selected && "bg-primary/15 text-foreground",
)}
>
{node.label}
</button>
) : (
<span className="text-muted-foreground">{node.label}</span>
);
return (
<>
<span className="text-muted-foreground">{node.label}</span>
{label}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

selectedId highlighting silently no-ops when onNodeSelect is omitted.

selected is computed unconditionally from selectedId (Line 85) and passed into DefaultObjectLabel, but the selected styling is only applied inside the onSelect-driven <button> branch (Lines 121-124). When onSelect is undefined, the label falls back to the plain <span> (Line 129), which never reads selected at all — so passing selectedId alone (without onNodeSelect) never highlights anything, contradicting the documented contract at Line 54 ("its label is highlighted").

The existing test suite doesn't catch this because the "highlights the label" test always pairs selectedId with a no-op onNodeSelect (ObjectGraph.test.tsx Lines 63-72).

🎨 Proposed fix to decouple selected styling from onSelect
   const label = onSelect ? (
     <button
       type="button"
       onClick={(e) => {
         e.stopPropagation();
         onSelect(node);
       }}
       title="Select this path"
       className={cn(
         "rounded px-0.5 text-left text-muted-foreground hover:text-foreground hover:underline",
         selected && "bg-primary/15 text-foreground",
       )}
     >
       {node.label}
     </button>
   ) : (
-    <span className="text-muted-foreground">{node.label}</span>
+    <span className={cn("text-muted-foreground", selected && "bg-primary/15 text-foreground")}>
+      {node.label}
+    </span>
   );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function DefaultObjectLabel<T extends ObjectGraphNode>({
node,
onSelect,
selected = false,
}: {
node: T;
onSelect?: (node: T) => void;
selected?: boolean;
}) {
const label = onSelect ? (
// A button so the label is a first-class click target; stopPropagation keeps
// the row's onClick (which toggles the node) from firing, so selecting a node
// never expands or collapses it.
<button
type="button"
onClick={(e) => {
e.stopPropagation();
onSelect(node);
}}
title="Select this path"
className={cn(
"rounded px-0.5 text-left text-muted-foreground hover:text-foreground hover:underline",
selected && "bg-primary/15 text-foreground",
)}
>
{node.label}
</button>
) : (
<span className="text-muted-foreground">{node.label}</span>
);
return (
<>
<span className="text-muted-foreground">{node.label}</span>
{label}
function DefaultObjectLabel<T extends ObjectGraphNode>({
node,
onSelect,
selected = false,
}: {
node: T;
onSelect?: (node: T) => void;
selected?: boolean;
}) {
const label = onSelect ? (
// A button so the label is a first-class click target; stopPropagation keeps
// the row's onClick (which toggles the node) from firing, so selecting a node
// never expands or collapses it.
<button
type="button"
onClick={(e) => {
e.stopPropagation();
onSelect(node);
}}
title="Select this path"
className={cn(
"rounded px-0.5 text-left text-muted-foreground hover:text-foreground hover:underline",
selected && "bg-primary/15 text-foreground",
)}
>
{node.label}
</button>
) : (
<span className={cn("text-muted-foreground", selected && "bg-primary/15 text-foreground")}>
{node.label}
</span>
);
return (
<>
{label}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/data/ObjectGraph.tsx` around lines 101 - 133, The selected
label styling in DefaultObjectLabel is currently tied to the onSelect button
branch, so selectedId does not highlight anything when onNodeSelect is omitted.
Update DefaultObjectLabel in ObjectGraph.tsx so the selected state affects both
render paths, not just the <button> case, and keep the selection styling
independent of onSelect. Make sure the selected prop is applied consistently
whether the label renders as a button or a plain span, and verify the
ObjectGraph selectedId behavior still matches the documented contract.

@moshloop moshloop merged commit 497ab24 into main Jul 6, 2026
12 of 13 checks passed
@moshloop moshloop deleted the fix/objectgraph-node-select branch July 6, 2026 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant