Skip to content

fix(Listbox): include disabled in ListboxItem v-memo deps - #2653

Merged
zernonia merged 1 commit into
unovue:v2from
zernonia:fix/listbox-item-disabled-memo
May 22, 2026
Merged

zernonia merged 1 commit into
unovue:v2from
zernonia:fix/listbox-item-disabled-memo

Conversation

@zernonia

@zernonia zernonia commented May 22, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Adds disabled and rootContext.focusable.value to the v-memo dependency list on ListboxItem's rendered Primitive.
  • Adds a regression test that toggles :disabled reactively without touching highlight/selection and asserts the DOM attributes update.

Problem

ListboxItem cached its VNode with v-memo="[isHighlighted, isSelected]", but the cached expression also reads disabled (for the disabled and data-disabled attributes) and rootContext.focusable.value (for the tabindex ternary). v-memo skips re-render when none of the listed deps change, so flipping :disabled at runtime left data-disabled / disabled stale on the DOM until something also changed the highlight or selection for that item.

Because Listbox.getCollectionItem() filters the navigable collection by reading dataset.disabled !== '' from the live DOM, a stale attribute kept disabled items in the keyboard-navigable set. In <ComboboxRoot> with a dynamic item set, this surfaced as "every other ArrowDown jumps back to the originally selected item" (issue reporter's downstream symptom in NuxtUI InputMenu).

Fix

-      v-memo="[isHighlighted, isSelected]"
+      v-memo="[isHighlighted, isSelected, disabled, rootContext.focusable.value]"

This is the only v-memo usage in packages/core/src (grepped), so the scope is limited to this single file.

Test plan

  • New regression test in Listbox.test.ts toggles disabled reactively and asserts data-disabled / disabled are reflected on the DOM both ways — confirmed red before the fix, green after.
  • All 32 existing Listbox tests still pass (pnpm vitest run src/Listbox/Listbox.test.ts).

Fixes #2644

Summary by CodeRabbit

Bug Fixes

  • Fixed Listbox component to properly handle disabled state changes, ensuring DOM attributes update correctly when toggling item disabled status without affecting focus or selection state.

Tests

  • Added regression test for issue #2644 to verify disabled state behavior in Listbox items.

Review Change Stack

…o deps

The `v-memo` on `ListboxItem` only listed `[isHighlighted, isSelected]`,
but the cached VNode also reads `disabled` (for both the `disabled` and
`data-disabled` attributes) and `rootContext.focusable.value` (for the
`tabindex` ternary). Because `v-memo` skips re-render when none of its
listed deps change, toggling `disabled` at runtime left the DOM stale
until something else also flipped the highlight or selection.

Since `Listbox.getCollectionItem()` filters the navigable collection by
reading `dataset.disabled` from the live DOM, the stale attribute caused
disabled items to keep participating in keyboard navigation — which in
Combobox surfaced as ArrowDown "snapping back" to the originally
selected item.

Closes #2644
@coderabbitai

coderabbitai Bot commented May 22, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 93732e7c-91c1-454a-bf6a-456bba3a1eaf

📥 Commits

Reviewing files that changed from the base of the PR and between 333707d and 85a17e7.

📒 Files selected for processing (2)
  • packages/core/src/Listbox/Listbox.test.ts
  • packages/core/src/Listbox/ListboxItem.vue

📝 Walkthrough

Walkthrough

This PR fixes a bug in ListboxItem.vue where reactive changes to the disabled prop were not updating DOM attributes because those dependencies were missing from the v-memo directive. A regression test validates the fix by toggling disabled state via a reactive ref.

Changes

ListboxItem disabled memo fix and test

Layer / File(s) Summary
v-memo dependency fix
packages/core/src/Listbox/ListboxItem.vue
v-memo now includes disabled and rootContext.focusable.value to invalidate the memoized VNode when those reactive values change, fixing stale data-disabled and disabled attributes.
Regression test for reactive disabled handling
packages/core/src/Listbox/Listbox.test.ts
Test imports defineComponent and mounts a ListboxRoot with a ListboxItem whose disabled prop is toggled via a ref, asserting that DOM attributes update on each toggle without intermediate highlight/selection changes.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Poem

A rabbit hops through memo land,
where deps once slipped through careless hands.
disabled found its rightful place,
the focusable now joins the race! 🐰✨

🚥 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 accurately describes the main change: adding disabled to ListboxItem's v-memo dependencies.
Linked Issues check ✅ Passed The PR fulfills the fix proposed in issue #2644: adds disabled and rootContext.focusable.value to v-memo deps and includes a regression test verifying DOM attribute updates.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing issue #2644: only ListboxItem.vue and its test file were modified, with no unrelated alterations.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

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

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: lockfile failed supply-chain policy check. Run pnpm install locally to update the lockfile.


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.

@pkg-pr-new

pkg-pr-new Bot commented May 22, 2026

Copy link
Copy Markdown

Open in StackBlitz

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

commit: 85a17e7

@zernonia
zernonia merged commit bf1f9e3 into unovue:v2 May 22, 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.

[Bug]: ListboxItem v-memo misses disabled dependency

1 participant