Dialog/Drawer: fix focus-restore scroll and dispose-while-open cleanup#42544
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses two usability/cleanup issues in the new native-<dialog>-based Dialog/Drawer components: preventing scroll jumps when restoring focus to the trigger, and ensuring body scroll is restored if a component is disposed while still open.
Changes:
- Restore focus to the trigger with
focus({ preventScroll: true })after Drawer/Dialog close via the data API, avoiding page scroll jumps. - Add
DialogBase.dispose()behavior to close an open native<dialog>and removedialog-openfrom<body>when disposing mid-open. - Extend unit tests to cover dispose-while-open cleanup and the new
preventScrollfocus behavior; adjust bundle size thresholds.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| js/src/drawer.js | Updates data-API focus restoration to use { preventScroll: true }. |
| js/src/dialog.js | Updates data-API focus restoration to use { preventScroll: true }. |
| js/src/dialog-base.js | Adds dispose() cleanup to close an open dialog and restore body scroll. |
| js/tests/unit/drawer.spec.js | Adds dispose-while-open test; updates focus expectation to include preventScroll. |
| js/tests/unit/dialog.spec.js | Adds dispose-while-open test; updates focus expectation to include preventScroll. |
| .bundlewatch.config.json | Updates max bundle size thresholds for generated JS artifacts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+120
to
+129
| dispose() { | ||
| // If disposed while still open, close the native <dialog> and restore body | ||
| // scroll. Otherwise `dialog-open` (overflow: hidden) would stay stuck on the | ||
| // body — e.g. when an SPA tears the component down mid-navigation. | ||
| if (this._element.open) { | ||
| this._closeAndCleanup() | ||
| } | ||
|
|
||
| super.dispose() | ||
| } |
This was referenced Jun 27, 2026
Closed
mdo
added a commit
that referenced
this pull request
Jun 27, 2026
…42575) * Tests: assert dialog-open on documentElement in dispose-while-open specs The dispose-while-open specs added in #42544 asserted the scroll-lock class on document.body, but #42545 moved the lock to the root element (documentElement). The two changes were each green in isolation but broke once both landed on v6-dev. Align these specs with the rest of the suite, which already asserts on documentElement. * Build: bump bundlewatch thresholds for cumulative JS growth on v6-dev bootstrap.bundle.js (83.15KB) and bootstrap.js (54.39KB) now exceed the prior thresholds after the dialog/drawer/tooltip/popover/menu fixes landed; each PR bumped only relative to its own base.
This was referenced Jun 27, 2026
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.
Two small dialog/drawer fixes, one per commit:
{ preventScroll: true }, so the page no longer jumps to the trigger (or to the top whenscroll-padding-topis set). Fixes offcanvas scrolls back to trigger element on close #38070, fixes [offcanvas] - triggers unexpected scroll to top when scroll-padding-top is set on html, body #41615, fixes Restore focus to modal triggering element using { preventScroll: true } #35391.dispose()now closes the native<dialog>and removes thedialog-openbody class if the instance is torn down while still open (e.g. an SPA route change), instead of leavingoverflow: hiddenstuck on the body. Fixes modal.dispose() does not fully clean up body element mutations #35934, fixes Offcanvas - dispose() not reseting scrollbars #39910.