[Bug Fix] Dialog: only dismiss on clicks outside the panel (#570)
Closes #570
Problem
DialogContent is the native <dialog> itself, with p-6 gap-4. backdropClick dismissed on any click whose target was the <dialog>, but clicks on the panel's own padding and on the gaps between children report the same target as a click on ::backdrop. So clicking inside the panel, between two fields, closed the dialog.
A related case: selecting text inside the dialog and releasing the mouse outside it also fires click on the <dialog>, which closed it mid-selection.
Fix
dialog_controller.js: a newbackdropPointerdownrecords whether the press started outside the panel's rect.backdropClickdismisses only when the press both started and ended outside it.dialog_content.rb:data-actionnow also wirespointerdown->ruby-ui--dialog#backdropPointerdown.mcp/data/registry.jsonrebuilt (rake mcp:build).
No markup or API change, so docs/app/views/docs/dialog.rb is unchanged. I kept the panel as the <dialog> instead of moving to a shadcn-style inner wrapper, which would change the DOM that users customize.
Testing
cd gem && bundle exec rake: 298 runs, 0 failures. standardrb: no offenses. Added a regression test for thepointerdownaction.- Browser: the dialog was rendered by the gem and driven with real CDP mouse events in headless Chrome, against
main's controller and this branch's:
| Scenario | main | This PR |
|---|---|---|
| Click on panel padding | closes (bug) | stays open |
| Click in gap between inputs | closes (bug) | stays open |
| Select text, drag outward, release | closes (bug) | stays open |
| Press on backdrop, release inside | n/a | stays open |
| Click on backdrop | closes | closes |
To test manually: open any Dialog on the docs site, click in the padding or between two fields (it should stay open), then click the backdrop (it should close).
Note
#517 (exit animation) also edits backdropClick. Whichever PR merges second gets a small conflict in that one method.
š¤ Generated with Claude Code
Summary by cubic
Brings the dialog to shadcn Base UI + vega parity and fixes clicks on the panel's own padding and gaps dismissing it ā those report the <dialog> as target, same as backdrop clicks, so a press now counts as a backdrop click only when it both starts and ends outside the panel's rect. Dragged text selections that release outside no longer close the dialog either.
- Vega classes for the panel,
::backdropoverlay, header, footer, and title (now<h2>); explicitsize:is unchanged and the default width is nowmax-w-mdat sm+. DialogContent(show_close_button:)toggles the corner close button;DialogFooter(show_close_button:)adds a footer Close button.- Open and close animate off
data-state; Esc, backdrop, and the close buttons play the exit animation beforeclose(), withmotion-reducesupport. - The controller names the dialog from its title/description (
aria-labelledby/aria-describedby) and setsaria-haspopup/aria-controls/aria-expandedon triggers.