aura-glass
Version:
A comprehensive glassmorphism design system for React applications with 142+ production-ready components
86 lines (83 loc) • 2.81 kB
JavaScript
import { jsx } from 'react/jsx-runtime';
import { useContext, useState, useEffect, createContext } from 'react';
const MotionPreferenceContext = /*#__PURE__*/createContext({
prefersReducedMotion: false,
isMotionSafe: true,
motionPolicy: 'auto'
});
/**
* Hook to access motion preferences from context
*
* IMPORTANT: Use this instead of useReducedMotion() when you want centralized
* motion preferences controlled by MotionPreferenceProvider at the app root.
*/
const useMotionPreferenceContext = () => {
const context = useContext(MotionPreferenceContext);
if (!context) {
console.warn('useMotionPreferenceContext must be used within a MotionPreferenceProvider. Using default values.');
return {
prefersReducedMotion: false,
isMotionSafe: true,
motionPolicy: 'auto'
};
}
return context;
};
/**
* MotionPreferenceProvider - Centralized motion preference management
*
* CRITICAL for SSR: Wrap your app root with this provider to:
* 1. Prevent hydration mismatches from motion detection
* 2. Centralize motion preferences across all AuraGlass components
* 3. Control SSR behavior via props
*
* Example (SSR-safe):
* ```tsx
* <MotionPreferenceProvider initialMotionPolicy="always-safe">
* <App />
* </MotionPreferenceProvider>
* ```
*
* Example (respect user preference):
* ```tsx
* <MotionPreferenceProvider initialMotionPolicy="auto">
* <App />
* </MotionPreferenceProvider>
* ```
*/
const MotionPreferenceProvider = ({
children,
initialMotionPolicy = 'auto',
initialPrefersReducedMotion = false
}) => {
// CRITICAL FIX: Start with SSR-safe default to prevent hydration mismatch
const [prefersReducedMotion, setPrefersReducedMotion] = useState(initialPrefersReducedMotion);
const [motionPolicy] = useState(initialMotionPolicy);
useEffect(() => {
// Skip detection if motion policy is forced
if (motionPolicy !== 'auto') {
setPrefersReducedMotion(motionPolicy === 'never-safe');
return;
}
// Detect actual motion preference after hydration (client-side only)
if (typeof window === 'undefined') return;
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
setPrefersReducedMotion(mediaQuery.matches);
const handleChange = event => {
setPrefersReducedMotion(event.matches);
};
mediaQuery.addEventListener('change', handleChange);
return () => mediaQuery.removeEventListener('change', handleChange);
}, [motionPolicy]);
const value = {
prefersReducedMotion,
isMotionSafe: !prefersReducedMotion,
motionPolicy
};
return jsx(MotionPreferenceContext.Provider, {
value: value,
children: children
});
};
export { MotionPreferenceProvider, useMotionPreferenceContext };
//# sourceMappingURL=MotionPreferenceContext.js.map