This commit is contained in:
Eric Bailey
2025-08-04 13:12:01 -05:00
parent 51011bd758
commit bc02b00af7
2 changed files with 19 additions and 0 deletions
+14
View File
@@ -21,12 +21,26 @@ import {useLingui} from '@lingui/react'
import {useA11y} from '#/state/a11y'
/**
* Conditionally wraps children in a `FocusTrap` component based on whether
* screen reader support is enabled. THIS SHOULD BE USED SPARINGLY, only when
* no better option is available.
*/
export function FocusScope({children}: {children: ReactNode}) {
const {screenReaderEnabled} = useA11y()
return screenReaderEnabled ? <FocusTrap>{children}</FocusTrap> : children
}
/**
* `FocusTrap` is intended as a last-ditch effort to ensure that users keep
* focus within a certain section of the app, like an overlay.
*
* It works by placing "guards" at the start and end of the active content.
* Then when the user reaches either of those guards, it will announce that
* they have reached the start or end of the content and tell them how to
* remain within the active content section.
*/
function FocusTrap({children}: {children: ReactNode}) {
const {_} = useLingui()
const child = useRef<View>(null)
+5
View File
@@ -1,6 +1,11 @@
import {type ReactNode} from 'react'
import {FocusScope as RadixFocusScope} from 'radix-ui/internal'
/*
* The web version of the FocusScope component is a proper implementation, we
* use this in Dialogs and such already. It's here as a convenient counterpart
* to the hacky native solution.
*/
export function FocusScope({children}: {children: ReactNode}) {
return (
<RadixFocusScope.FocusScope loop asChild trapped>