Skip to content

useFocusReturn

Category
Export Size
382 B
Last Changed
5 days ago

Return focus to the element that was active before an overlay opened.

Demo

Usage

tsx
import { 
useFocusReturn
} from '@reause/core'
import {
useState
} from 'react'
function
Modal
() {
const [
opened
,
setOpened
] =
useState
(false)
const
returnFocus
=
useFocusReturn
({
opened
})
return ( <
div
>
<
button
onClick={() =>
setOpened
(true)}>Open</button>
<input placeholder="Focus me before opening" /> {
opened
&& (
<
div
>
<
input
autoFocus placeholder="Inside the overlay" />
<
button
onClick={() => setOpened(false)}>Close</button>
</div> )} </div> ) }

The hook returns a function — call it yourself to restore focus, or let it run on the close:

tsx
const 
returnFocus
=
useFocusReturn
({
opened
})
returnFocus
() // focus the element that was active before the overlay opened

document.activeElement is snapshotted when opened flips to true, and the restore is deferred by a 10 ms timeout after opened flips to false so the closing transition can finish first. When that timeout fires, focus is restored only if nothing else claimed it during the close: the current active element has to be null, document.body (the overlay unmounted and focus fell back) or the element that was already active when the close rendered. A deliberate focus change wins over the snapshot. Restoring uses focus({ preventScroll: true }), and pressing Tab clears the pending timeout so a user who tabs away keeps their own focus target.

Pass shouldReturnFocus: false to keep the snapshot but never restore automatically — the returned function still works:

tsx
const 
returnFocus
=
useFocusReturn
({
opened
,
shouldReturnFocus
: false })

To place it next to its siblings: useFocus and useFocusWithin own an element you hand them and track its focus state, while this hook owns nothing and keeps no state — it only remembers the previously active element so it can hand it back.

Type Declarations

ts
export interface UseFocusReturnInput {
    opened: boolean;
    shouldReturnFocus?: boolean;
}

export type UseFocusReturnReturnValue = () => void

export function useFocusReturn({ opened, shouldReturnFocus = true, }: UseFocusReturnInput): UseFocusReturnReturnValue

Source

Source · Demo · Mantine

Contributors

hairyf

Changelog

v0.1.6 on
4ac9e - feat(core): add useFocusReturn (#935)

Released under the MIT License. v0.1.8