[Feature] Dialog: use native <dialog> element (#343)#435
Merged
Conversation
Replace the template-clone pattern with a native <dialog> element. DialogContent now renders as <dialog> opened via showModal() and closed via close(), gaining free top-layer rendering, native backdrop, built-in focus trapping, and Esc-to-close. Body scroll-lock is preserved. All existing public component API and Stimulus controller actions are backward-compatible.
There was a problem hiding this comment.
1 issue found across 3 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…P registry (#435) Clear overflow-hidden from body in disconnect() so Turbo navigation while a dialog is open does not leave a permanent scroll lock. Also rebuilt the MCP registry to include the native-dialog changes from this PR.
Contributor
Author
|
Addressed the code review finding from cubic (confidence 8): added |
cirdes
approved these changes
Jun 22, 2026
cirdes
left a comment
Collaborator
There was a problem hiding this comment.
Really clean PR. Native <dialog> is the right move!
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.
Closes #343
How to reproduce the original problem
Before this change, opening the browser devtools and inspecting an open Dialog revealed the modal rendered as nested
<div>elements cloned from a<template>tag — no native<dialog>semantics, no top-layer rendering, no built-in focus trap, and Esc required a manualkeydownlistener wired via a Stimulus action.Steps:
<div data-controller="ruby-ui--dialog">— no<dialog>element in the DOMWhat changed
gem/lib/ruby_ui/dialog/dialog_content.rb<template>wrapper and custom backdrop<div>;DialogContentnow renders directly as a native<dialog>element withdata-ruby-ui--dialog-target="dialog"and aclick->ruby-ui--dialog#backdropClickaction. The CSSbackdrop:pseudo-element replaces the manual overlay div.gem/lib/ruby_ui/dialog/dialog_controller.jsinsertAdjacentHTML/element.remove()pattern withdialogTarget.showModal()/dialogTarget.close(). Backdrop click is handled by comparingevent.target === dialogTarget. Acloseevent listener removesoverflow-hiddenfrom the body so Esc (which firesclosenatively) also unlocks scroll.gem/test/ruby_ui/dialog_test.rb<dialog>is rendered (not<div>/<template>), Stimulus target/action attributes, size variants,openvalue, trigger action, and close button action.Public API is fully preserved — all component names, size variants,
open:prop, and Stimulus action names (open,dismiss) remain unchanged.Testing instructions
Automated tests
Manual browser verification (docs site)
cd docs && bin/dev)/docs/dialog<dialog>element (not a<div>)overflow-hiddenis applied to<body>)Summary by cubic
Move Dialog to the native element using showModal()/close() for top-layer rendering, native backdrop, focus trap, and Esc‑to‑close while keeping the public API and Stimulus actions unchanged. Also clear body scroll lock on controller disconnect to avoid stuck scrolling during Turbo navigation.
Refactors
<dialog>:DialogContentrenders<dialog>withdata-ruby-ui--dialog-target="dialog"andclick->ruby-ui--dialog#backdropClick; controller usesshowModal()/close()and listens forcloseto restore body scroll.backdrop:/open:utilities; tests cover native<dialog>, attributes, size variants, and open/dismiss actions.Bug Fixes
overflow-hiddenindisconnect()so navigating with Turbo while a dialog is open doesn’t leave the page locked; rebuilt MCP registry to include native-dialog changes.Written for commit 9290140. Summary will update on new commits.