[Feature] Combobox: animate the popover open and close

TV
1mo ago
+159-13

The Combobox popover opened and closed in a hard cut. It now animates in and out like the other overlays.

What changed

  • ComboboxPopover gets the data-state enter/exit classes from #506, duration-100 and the data-side slide-in — parity with shadcn/ui's Combobox.
  • The popover becomes popover="manual". A native auto popover's light dismiss hides it directly and the hide beforetoggle is not cancelable, so no exit could ever play. The controller now owns every close path (trigger, outside click, Escape, radio selection) through closePopover(), which waits for the exit animation before hidePopover() — the #506 block, copied unchanged. Positioning keeps running until the popover is hidden, so it does not drift while fading.
  • Escape works with focus anywhere (before: only inside the popover). Outside click and Escape are window actions on the root, guarded for a Combobox rendered without a popover.
  • Dropped role="popover" (not an ARIA role). API and examples unchanged.

Tested

  • cd gem && bundle exec rake
  • Headless Chrome over the docs examples (single + multiple): open/close via trigger, outside click, Escape (trigger / search input / body), radio selection, reopen mid-exit, close mid-open, positioning during the fade, flip → data-side=top, keyboard navigation and filtering.

Dialog and AlertDialog get their exit animations in sibling PRs.

šŸ¤– Generated with Claude Code


Summary by cubic

Animates the Combobox popover open and close instead of a hard cut. The controller now owns every close path (trigger, outside click, Escape, radio selection) and waits for the exit animation before hiding the popover.

New Features

  • Switches to popover="manual" so a single close path can wait for the exit animation.
  • Adds data-state enter/exit classes, duration-100, and data-side slide-in for parity with shadcn/ui.
  • Keeps positioning running until the popover is hidden, so it doesn't drift during the fade.
  • Removes the non-ARIA role="popover" and adds window-level outside-click and Escape handlers, guarded for comboboxes without a popover.