Skip to content

Instantly share code, notes, and snippets.

@benvium
Last active December 2, 2023 09:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benvium/a530582a2ef61faa010d0e41e1071e7e to your computer and use it in GitHub Desktop.
Save benvium/a530582a2ef61faa010d0e41e1071e7e to your computer and use it in GitHub Desktop.
useReducedMotion hook - get if user has requested Prefers reduced motion (iOS) or Remove animations (Android). Live updates values
import {AccessibilityInfo} from 'react-native';
import {createContext, PropsWithChildren, useContext, useEffect, useState} from 'react';
type AccessibilitySettingsT = {
isReduceMotionEnabled: boolean;
};
const ReducedMotionContext = createContext<AccessibilitySettingsT>({isReduceMotionEnabled: false});
/**
* Wrap your root component in this to get access to the user's accessibility settings.
*/
export const AccessibilitySettingsProvider = (props: PropsWithChildren) => {
const [isReduceMotionEnabled, setIsReduceMotionEnabled] = useState(false);
useEffect(() => {
(async () => {
const isEnabled = await AccessibilityInfo.isReduceMotionEnabled();
setIsReduceMotionEnabled(isEnabled);
})();
// listen for changes
const listener = AccessibilityInfo.addEventListener('reduceMotionChanged', async isEnabled => {
setIsReduceMotionEnabled(isEnabled);
});
return () => {
listener.remove();
};
}, []);
return (
<ReducedMotionContext.Provider value={{isReduceMotionEnabled}}>{props.children}</ReducedMotionContext.Provider>
);
};
/**
* Returns true if the user has enabled reduced motion / remove animations in their OS settings.
* Listens for changes and will update live.
* Use this to turn on and off animated background, auto-playing videos etc.
*
* DEFAULTS TO OFF! i.e. you should ensure your animations can be disabled as we'll send false at the start before we've been able to read the value
*/
export const useReducedMotion = () => {
const context = useContext(ReducedMotionContext);
if (!context) {
throw new Error(
'useReducedMotion must be used within a AccessibilitySettingsProvider. Wrap your root component in <AccessibilitySettingsProvider> to fix this error.'
);
}
return context.isReduceMotionEnabled;
};
// add additional hooks if you want to monitor other accessibility settings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment