You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Summary
Please add an opt-out flag to the Dialog component that disables the automatic focus restoration when the dialog closes. This would prevent focus conflicts with downstream auto-focus logic in newly mounted content after destructive/confirm actions.
Problem
Current behavior: Dialog always restores focus to the previously focused element (FocusTrapFeatures.RestoreFocus), which is great for most cases.
Issue: In complex flows where closing a dialog triggers UI changes and mounts new focusable content with autoFocus (e.g., selecting a new tab panel, rendering an empty state with a Listbox autoFocus), the Dialog’s focus restoration frequently “wins” the race and steals focus back, causing the user-visible autoFocus to fail.
This is particularly noticeable after form submission with validation errors (extra renders), and destructive actions where entire sections are removed and replaced.
Reference
Headless UI Dialog currently unconditionally enables RestoreFocus when enabled: see source in Dialog (FocusTrapFeatures.RestoreFocus) HeadlessUI dialog.tsx.
Concrete Scenarios
Delete/Remove flow:
User clicks a delete icon → confirm dialog opens.
On confirmation, we remove a tab/panel and then render either a new active panel or an empty state with a Listbox that should immediately receive focus (autoFocus).
After the dialog closes, focus is restored to the trigger element instead of the new control, so autoFocus fails.
Post-submit error flow:
User submits a form (errors display), then performs an action (e.g., add/remove language tab) that mounts content with autoFocus.
The dialog’s restore focus step conflicts with the new content’s autoFocus, leaving focus in the wrong place.
Requested Change
Add a new optional prop to Dialog: restoreFocus?: boolean (default: true).
When restoreFocus is false, do not register FocusTrapFeatures.RestoreFocus. Other features (TabLock, InitialFocus, AutoFocus) remain unchanged.
Proposed API
Dialog props:
restoreFocus?: boolean
Default: true (preserving current behavior)
When false: no focus restoration to previously focused element.
This is an opt-out for advanced cases where the app intentionally manages focus after dialog close (e.g., deferring focus to newly mounted, primary controls).
The default remains the recommended accessible behavior.
Example (pseudo)
<Dialogopen={open}onClose={setOpen}restoreFocus={false}><Dialog.Panel>{/* ... confirm action ... */}</Dialog.Panel></Dialog>// After confirm:setOpen(false)// Mount new content with autoFocus – no competing restore now
Why not external workarounds?
Manually blurring or late focusing (multiple rAF ticks) is brittle and timing-dependent.
A dedicated restoreFocus flag is robust, explicit, and predictable.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
Please add an opt-out flag to the Dialog component that disables the automatic focus restoration when the dialog closes. This would prevent focus conflicts with downstream auto-focus logic in newly mounted content after destructive/confirm actions.
Problem
Reference
Concrete Scenarios
Requested Change
Proposed API
Backward Compatibility
Accessibility
Example (pseudo)
Why not external workarounds?
Beta Was this translation helpful? Give feedback.
All reactions