framer-motion
Version:
A simple and powerful React animation library
77 lines (74 loc) • 2.46 kB
JavaScript
import { __read } from 'tslib';
import { useState, useContext } from 'react';
import { MotionConfigContext } from '../context/MotionConfigContext.mjs';
import { isBrowser } from './is-browser.mjs';
// Does this device prefer reduced motion? Returns `null` server-side.
var prefersReducedMotion = { current: null };
var hasDetected = false;
function initPrefersReducedMotion() {
hasDetected = true;
if (!isBrowser)
return;
if (window.matchMedia) {
var motionMediaQuery_1 = window.matchMedia("(prefers-reduced-motion)");
var setReducedMotionPreferences = function () {
return (prefersReducedMotion.current = motionMediaQuery_1.matches);
};
motionMediaQuery_1.addListener(setReducedMotionPreferences);
setReducedMotionPreferences();
}
else {
prefersReducedMotion.current = false;
}
}
/**
* A hook that returns `true` if we should be using reduced motion based on the current device's Reduced Motion setting.
*
* This can be used to implement changes to your UI based on Reduced Motion. For instance, replacing motion-sickness inducing
* `x`/`y` animations with `opacity`, disabling the autoplay of background videos, or turning off parallax motion.
*
* It will actively respond to changes and re-render your components with the latest setting.
*
* ```jsx
* export function Sidebar({ isOpen }) {
* const shouldReduceMotion = useReducedMotion()
* const closedX = shouldReduceMotion ? 0 : "-100%"
*
* return (
* <motion.div animate={{
* opacity: isOpen ? 1 : 0,
* x: isOpen ? 0 : closedX
* }} />
* )
* }
* ```
*
* @return boolean
*
* @public
*/
function useReducedMotion() {
/**
* Lazy initialisation of prefersReducedMotion
*/
!hasDetected && initPrefersReducedMotion();
var _a = __read(useState(prefersReducedMotion.current), 1), shouldReduceMotion = _a[0];
/**
* TODO See if people miss automatically updating shouldReduceMotion setting
*/
return shouldReduceMotion;
}
function useReducedMotionConfig() {
var reducedMotionPreference = useReducedMotion();
var reducedMotion = useContext(MotionConfigContext).reducedMotion;
if (reducedMotion === "never") {
return false;
}
else if (reducedMotion === "always") {
return true;
}
else {
return reducedMotionPreference;
}
}
export { useReducedMotion, useReducedMotionConfig };