[Bug Fix] Dialog: only dismiss on clicks outside the panel (#570)

Merged
JA
1d ago
+604-45

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 new backdropPointerdown records whether the press started outside the panel's rect. backdropClick dismisses only when the press both started and ended outside it.
  • dialog_content.rb: data-action now also wires pointerdown->ruby-ui--dialog#backdropPointerdown.
  • mcp/data/registry.json rebuilt (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 the pointerdown action.
  • 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:
ScenariomainThis PR
Click on panel paddingcloses (bug)stays open
Click in gap between inputscloses (bug)stays open
Select text, drag outward, releasecloses (bug)stays open
Press on backdrop, release insiden/astays open
Click on backdropclosescloses
dialog-570-before-after

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, ::backdrop overlay, header, footer, and title (now <h2>); explicit size: is unchanged and the default width is now max-w-md at 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 before close(), with motion-reduce support.
  • The controller names the dialog from its title/description (aria-labelledby/aria-describedby) and sets aria-haspopup/aria-controls/aria-expanded on triggers.