diff options
Diffstat (limited to 'src/state/a11y.tsx')
-rw-r--r-- | src/state/a11y.tsx | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/state/a11y.tsx b/src/state/a11y.tsx new file mode 100644 index 000000000..aefcfd1ec --- /dev/null +++ b/src/state/a11y.tsx @@ -0,0 +1,65 @@ +import React from 'react' +import {AccessibilityInfo} from 'react-native' +import {isReducedMotion} from 'react-native-reanimated' + +import {isWeb} from '#/platform/detection' + +const Context = React.createContext({ + reduceMotionEnabled: false, + screenReaderEnabled: false, +}) + +export function useA11y() { + return React.useContext(Context) +} + +export function Provider({children}: React.PropsWithChildren<{}>) { + const [reduceMotionEnabled, setReduceMotionEnabled] = React.useState(() => + isReducedMotion(), + ) + const [screenReaderEnabled, setScreenReaderEnabled] = React.useState(false) + + React.useEffect(() => { + const reduceMotionChangedSubscription = AccessibilityInfo.addEventListener( + 'reduceMotionChanged', + enabled => { + setReduceMotionEnabled(enabled) + }, + ) + const screenReaderChangedSubscription = AccessibilityInfo.addEventListener( + 'screenReaderChanged', + enabled => { + setScreenReaderEnabled(enabled) + }, + ) + + ;(async () => { + const [_reduceMotionEnabled, _screenReaderEnabled] = await Promise.all([ + AccessibilityInfo.isReduceMotionEnabled(), + AccessibilityInfo.isScreenReaderEnabled(), + ]) + setReduceMotionEnabled(_reduceMotionEnabled) + setScreenReaderEnabled(_screenReaderEnabled) + })() + + return () => { + reduceMotionChangedSubscription.remove() + screenReaderChangedSubscription.remove() + } + }, []) + + const ctx = React.useMemo(() => { + return { + reduceMotionEnabled, + /** + * Always returns true on web. For now, we're using this for mobile a11y, + * so we reset to false on web. + * + * @see https://github.com/necolas/react-native-web/discussions/2072 + */ + screenReaderEnabled: isWeb ? false : screenReaderEnabled, + } + }, [reduceMotionEnabled, screenReaderEnabled]) + + return <Context.Provider value={ctx}>{children}</Context.Provider> +} |