fix: scroll the selected item into view by value, not stale aria-selected (#389)#409
Open
thatssoheil wants to merge 1 commit into
Open
fix: scroll the selected item into view by value, not stale aria-selected (#389)#409thatssoheil wants to merge 1 commit into
thatssoheil wants to merge 1 commit into
Conversation
…cted (dip#389) scrollSelectedIntoView resolved its target via `[aria-selected="true"]`, which lags one React commit behind a value change. cmdk's scheduler runs all scheduled callbacks in a single layout-effect pass, so on a search change the scroll fires in the same pass as selectFirstItem, before the re-render that moves aria-selected onto the new item commits. The list therefore scrolled to the previously-selected item. Resolve the scroll target from state.current.value (the source of truth) by matching data-value instead. Scoped to the scroll path, so getSelectedItem() and its other callers are unchanged. Comparing data-value in JS also avoids escaping arbitrary values into a selector (dip#387). Adds a Playwright regression test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Changing the search in
<Command>can scroll the list to the previously-selected item instead of the new first result (#389). It's most visible when a search broadens and the top result changes.Root cause
scrollSelectedIntoViewfinds its target via[aria-selected="true"]. cmdk's scheduler (useScheduleLayoutEffect) runs all scheduled callbacks in a single layout-effect pass, so on a search change the scroll fires in the same pass asselectFirstItem— before React commits the re-render that movesaria-selectedonto the newly-selected item. The scroll therefore reads the stale attribute and scrolls to the old selection.The element for the new selection is already in the DOM (it matched the search); only its
aria-selectedlags by one commit. Itsdata-valueis already correct.Fix
Resolve the scroll target from
state.current.value(the source of truth) by matchingdata-value, rather than the laggingaria-selected. Scoped to the scroll path, sogetSelectedItem()and its other callers are untouched. Comparingdata-valuein JS (instead of building a selector) also sidesteps escaping arbitrary values intoquerySelector(cf. #387).Test
Adds a Playwright regression (
test/scroll.test.ts+test/pages/scroll.tsx): narrow the search to an item far down the list, broaden it, and assert the list scrolls back to the new top selection. Fails onmain(scrollTopparks at the stale item), passes with this change.Notes
pnpm test:formatandpnpm buildpass. My environment can't run Playwright browsers, so I'm relying on CI for the browser run.Fixes #389
Implemented with AI assistance (Claude), reviewed and verified by me before submitting.