Skip to content

feat(Tree): add disabled for TreeItem - #2529

Merged
zernonia merged 1 commit into
unovue:v2from
kricsleo:feat/tree-item-disabled
Jun 10, 2026
Merged

zernonia merged 1 commit into
unovue:v2from
kricsleo:feat/tree-item-disabled

Conversation

@kricsleo

@kricsleo kricsleo commented Mar 20, 2026 •

Copy link
Copy Markdown
Collaborator

🔗 Linked issue

resolves #2528

❓ Type of change

  • 📖 Documentation (updates to the documentation, readme or JSdoc annotations)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

📸 Screenshots (if appropriate)

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

Summary by CodeRabbit

  • New Features
    • Tree items now support a disabled state that prevents user interactions, including selection, keyboard navigation, and focus management. Disabled items display appropriate accessibility attributes for assistive technologies.

@coderabbitai

coderabbitai Bot commented Mar 20, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This pull request adds a disabled feature to tree items, preventing user interaction when disabled. When a tree item has disabled: true, it blocks selection, navigation, focus management, and toggling while exposing the disabled state via ARIA attributes, data attributes, and slot properties.

Changes

Cohort / File(s) Summary
Documentation
docs/content/meta/TreeItem.md
Added disabled boolean prop and isDisabled slot property to API documentation.
Component Implementation
packages/core/src/Tree/TreeItem.vue
Added disabled prop, computed isDisabled combining root and local disabled state, early-return guards in keyboard/click handlers, ARIA/data attributes for disabled state, focus management binding, and slot prop exposure.
Virtualizer Focus Logic
packages/core/src/Tree/TreeVirtualizer.vue
Added post-filter to exclude items with data-disabled attribute when selecting first/last focusable items during virtual focus navigation.
Test Suite
packages/core/src/Tree/Tree.test.ts
Added comprehensive test suite verifying disabled item behavior: ARIA/data attributes, interaction blocking (selection, click, keydown), navigation guards, and optional root-level disable flag.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A gentle whisper through the tree—
Some branches now rest quietly.
With disabled touch, they cease to play,
While others dance the keyboard's way. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding a disabled feature to TreeItem component.
Linked Issues check ✅ Passed All coding requirements from issue #2528 are met: disabled prop added to TreeItem, disabled items are non-interactive, and disabled state is properly exposed.
Out of Scope Changes check ✅ Passed All changes directly support the disabled feature objective; no unrelated modifications detected across TreeItem, Tree tests, TreeVirtualizer, and documentation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Tip

You can enable review details to help with troubleshooting, context usage and more.

Enable the reviews.review_details setting to include review details such as the model used, the time taken for each step and more in the review comments.

@pkg-pr-new

pkg-pr-new Bot commented Mar 20, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/reka-ui@2529

commit: 06bf624

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/core/src/Tree/TreeItem.vue (1)

167-174: ⚠️ Potential issue | 🟡 Minor

Exposed handleToggle and handleSelect bypass the disabled check.

The handlers exposed via defineExpose directly call rootContext.onToggle() and rootContext.onSelect() without checking isDisabled. This allows programmatic access (via template refs) to toggle/select disabled items, which may be intentional for advanced use cases but could also be unexpected.

If this is intentional (allowing programmatic override), consider documenting this behavior. If disabled items should remain non-interactive even programmatically, the handlers should check isDisabled.

🛡️ Proposed fix if disabled should be enforced programmatically
 defineExpose({
   isExpanded,
   isSelected,
   isIndeterminate,
   isDisabled,
-  handleToggle: () => rootContext.onToggle(props.value),
-  handleSelect: () => rootContext.onSelect(props.value),
+  handleToggle: () => {
+    if (!isDisabled.value)
+      rootContext.onToggle(props.value)
+  },
+  handleSelect: () => {
+    if (!isDisabled.value)
+      rootContext.onSelect(props.value)
+  },
 })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/Tree/TreeItem.vue` around lines 167 - 174, The exposed
handlers in defineExpose (handleToggle and handleSelect) call
rootContext.onToggle/onSelect directly, allowing programmatic toggling/selecting
of disabled items; update these handlers to first check isDisabled (use
isDisabled.value if it's a ref/computed) and return/no-op when true before
calling rootContext.onToggle(props.value) or rootContext.onSelect(props.value),
ensuring disabled state is enforced programmatically; alternatively document
intentional override behavior if you want to allow it.
🧹 Nitpick comments (1)
packages/core/src/Tree/Tree.test.ts (1)

381-387: Consider adding navigation test coverage.

The current tests verify that disabled items don't respond to selection/toggle interactions. Consider adding a test that verifies keyboard navigation (ArrowUp/ArrowDown) skips over disabled items to reach the next enabled item, which would validate the focusable integration with RovingFocusItem.

💡 Example test for navigation skipping disabled items
it('should skip disabled items during keyboard navigation', async () => {
  // Disable the middle item 'banana'
  const { items } = mountTree(['banana'])
  
  // Focus first item and navigate down
  ;(items()[0].element as HTMLElement).focus()
  await items()[0].trigger('keydown', { key: kbd.ARROW_DOWN })
  
  // Should skip 'banana' and focus 'cherry'
  expect(document.activeElement).toBe(items()[2].element)
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/Tree/Tree.test.ts` around lines 381 - 387, Add a new test
in Tree.test.ts that verifies keyboard navigation skips disabled items by using
the existing mountTree helper and items() accessor: call mountTree(['banana'])
to disable the middle item, focus the first item via (items()[0].element as
HTMLElement).focus(), trigger a keydown on items()[0] with { key: kbd.ARROW_DOWN
}, and assert document.activeElement === items()[2].element; this ensures the
component's `focusable` behavior (RovingFocusItem integration) correctly skips
the disabled node during ArrowUp/ArrowDown navigation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/core/src/Tree/TreeItem.vue`:
- Around line 167-174: The exposed handlers in defineExpose (handleToggle and
handleSelect) call rootContext.onToggle/onSelect directly, allowing programmatic
toggling/selecting of disabled items; update these handlers to first check
isDisabled (use isDisabled.value if it's a ref/computed) and return/no-op when
true before calling rootContext.onToggle(props.value) or
rootContext.onSelect(props.value), ensuring disabled state is enforced
programmatically; alternatively document intentional override behavior if you
want to allow it.

---

Nitpick comments:
In `@packages/core/src/Tree/Tree.test.ts`:
- Around line 381-387: Add a new test in Tree.test.ts that verifies keyboard
navigation skips disabled items by using the existing mountTree helper and
items() accessor: call mountTree(['banana']) to disable the middle item, focus
the first item via (items()[0].element as HTMLElement).focus(), trigger a
keydown on items()[0] with { key: kbd.ARROW_DOWN }, and assert
document.activeElement === items()[2].element; this ensures the component's
`focusable` behavior (RovingFocusItem integration) correctly skips the disabled
node during ArrowUp/ArrowDown navigation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e8c4af0f-adfe-45fc-b8e3-2fe83ae2ef5a

📥 Commits

Reviewing files that changed from the base of the PR and between bc1db72 and c89b894.

📒 Files selected for processing (4)
  • docs/content/meta/TreeItem.md
  • packages/core/src/Tree/Tree.test.ts
  • packages/core/src/Tree/TreeItem.vue
  • packages/core/src/Tree/TreeVirtualizer.vue

@zernonia
zernonia force-pushed the feat/tree-item-disabled branch from c89b894 to 06bf624 Compare June 10, 2026 08:58
@zernonia
zernonia merged commit 7ef555b into unovue:v2 Jun 10, 2026
7 checks passed
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.

[Feature]: Allow tree items to be disabled

2 participants