Skip to content

fix(select,filter-dropdown): keep Clear all's menu open and a searching Select's side - #163

Merged
tmccoy14 merged 1 commit into
mainfrom
fix/dropdown-clear-all-and-select-side
Sep 24, 2026
Merged

tmccoy14 merged 1 commit into
mainfrom
fix/dropdown-clear-all-and-select-side

Conversation

@tmccoy14

Copy link
Copy Markdown
Contributor

What

Two regressions from 4.3.0 that showed up while adopting it in Guardian Studio:

  • FilterDropdown's "Clear all" closes the menu. It used to leave it open.
  • A searchable Select switches sides during a search. In Studio's Apply Policy dialog, the project select opens above its trigger. Type a query that matches nothing, clear it, and the list is now below the trigger, squeezed into the space left there.

Why

Clear all. In 4.3.0 "Clear all" became a DropdownMenuItem, so keyboard users can reach it. Radix closes a menu whenever an item's onSelect doesn't call preventDefault. The item also unmounts once nothing is selected. When the focused element disappears, focus falls back to an enclosing Dialog, and the browser draws its focus ring around the whole dialog.

Select side. Radix positions the popper with flip() and then size(), and max-height is set to the space available on the side it picked. When the list first opens it is too tall for the side below, so it flips above. A query that matches little shrinks the list enough to fit below, so it flips there. When the query is cleared, size() has already capped it to the space below. Nothing overflows, so flip() never moves it back.

Changes

  • filter-dropdown.tsx: "Clear all" prevents the close. It moves focus before the item unmounts: to the search box if there is one, otherwise to the menu.
  • select.tsx: once a query starts, SelectContent reads the side it was placed on (data-side). It then passes that side back with avoidCollisions={false} until the select closes. The lock lives in Select's context and is cleared when the select opens. With avoidCollisions off, Radix also stops shift(), so while locked the list isn't nudged sideways back on screen. That only matters for a select at the very edge of the viewport.
  • New tests: "Clear all" keeps the menu open and moves focus to the right place, with and without search. Both fail without the fix. jsdom has no layout, so the side lock can't be unit-tested; it was checked in the browser (see below).
  • 4.3.2, with a CHANGELOG entry.

Verification

  • pnpm format:check, pnpm lint, pnpm test (40 passing), pnpm build.

  • In Studio, with this build in place, measured with Playwright in the Apply Policy dialog. Each cell is the list's side and height:

    Viewport Open No matches Cleared
    1280×900, before top, 524px bottom, 99px bottom, 317px
    1280×900, after top, 524px top, 99px top, 524px
    1280×560, after top, 354px top, 99px top, 354px
  • In Studio, "Clear all" on the policy type filter inside the dialog leaves the menu open with every filter cleared. Focus is on the menu and no focus ring appears on the dialog.

🤖 Generated with Claude Code

…ng Select's side

FilterDropdown's "Clear all" became a menu item in 4.3.0, so Radix closed the
menu on select. It now prevents that and moves focus before the item unmounts:
to the search box, or to the menu without search. Left to fall, focus landed on
an enclosing dialog, which drew the browser's focus ring around it.

A searchable Select could flip sides mid-search: a query that shrank the list
let it fit on the preferred side, and once there the size cap followed that
side's space, so clearing the query never flipped it back. The side it was
placed on is now locked from the first query until it closes.

4.3.2, with a CHANGELOG entry.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@tmccoy14
tmccoy14 merged commit 921df04 into main Sep 24, 2026
1 check passed
@tmccoy14
tmccoy14 deleted the fix/dropdown-clear-all-and-select-side branch September 24, 2026 18:53
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