aura-glass
Version:
A comprehensive glassmorphism design system for React applications with 142+ production-ready components
145 lines (142 loc) • 4.53 kB
JavaScript
'use client';
import { jsx } from 'react/jsx-runtime';
import { useState, useEffect, createContext, useContext } from 'react';
const defaultSettings = {
focusIndicators: true,
keyboardNavigation: true,
screenReaderOptimized: true,
highContrast: false,
reducedMotion: false,
largeText: false,
colorBlindness: 'none',
voiceCommands: false,
motionControls: false
};
// Create context
const AccessibilityContext = /*#__PURE__*/createContext(undefined);
function AccessibilityProvider({
children,
initialSettings = {},
storageKey = 'aura-glass-accessibility-settings'
}) {
// Merge default settings with initial settings
const [settings, setSettings] = useState({
...defaultSettings,
...initialSettings
});
// Load settings from localStorage on mount
useEffect(() => {
try {
const saved = localStorage.getItem(storageKey);
if (saved) {
const parsedSettings = JSON.parse(saved);
setSettings(prev => ({
...prev,
...parsedSettings
}));
}
} catch (error) {
console.warn('Failed to load accessibility settings:', error);
}
}, [storageKey]);
// Save settings to localStorage when they change
useEffect(() => {
try {
localStorage.setItem(storageKey, JSON.stringify(settings));
} catch (error) {
console.warn('Failed to save accessibility settings:', error);
}
}, [settings, storageKey]);
// Detect system preferences
const detectSystemPreferences = () => {
const mediaQueryReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
const mediaQueryHighContrast = window.matchMedia('(prefers-contrast: high)');
window.matchMedia('(prefers-color-scheme: dark)');
const newSettings = {};
if (mediaQueryReducedMotion.matches) {
newSettings.reducedMotion = true;
}
if (mediaQueryHighContrast.matches) {
newSettings.highContrast = true;
}
// Update settings with detected preferences
if (Object.keys(newSettings).length > 0) {
updateSettings(newSettings);
}
// Listen for changes in system preferences
const handlePreferenceChange = event => {
if (event.media === '(prefers-reduced-motion: reduce)') {
updateSettings({
reducedMotion: event.matches
});
} else if (event.media === '(prefers-contrast: high)') {
updateSettings({
highContrast: event.matches
});
}
};
mediaQueryReducedMotion.addEventListener('change', handlePreferenceChange);
mediaQueryHighContrast.addEventListener('change', handlePreferenceChange);
return () => {
mediaQueryReducedMotion.removeEventListener('change', handlePreferenceChange);
mediaQueryHighContrast.removeEventListener('change', handlePreferenceChange);
};
};
// Update settings
const updateSettings = newSettings => {
setSettings(prev => ({
...prev,
...newSettings
}));
};
// Reset to defaults
const resetToDefaults = () => {
setSettings(defaultSettings);
};
// Apply settings to document
useEffect(() => {
const root = document.documentElement;
// Apply reduced motion
if (settings.reducedMotion) {
root.style.setProperty('--animation-duration', '0.01ms');
root.style.setProperty('--animation-delay', '0.01ms');
} else {
root.style.removeProperty('--animation-duration');
root.style.removeProperty('--animation-delay');
}
// Apply high contrast
if (settings.highContrast) {
root.classList.add('high-contrast');
} else {
root.classList.remove('high-contrast');
}
// Apply large text
if (settings.largeText) {
root.classList.add('large-text');
} else {
root.classList.remove('large-text');
}
// Apply color blindness simulation
root.setAttribute('data-color-blindness', settings.colorBlindness);
}, [settings]);
const contextValue = {
settings,
updateSettings,
resetToDefaults,
detectSystemPreferences
};
return jsx(AccessibilityContext.Provider, {
value: contextValue,
children: children
});
}
// Hook to use accessibility context
function useAccessibility() {
const context = useContext(AccessibilityContext);
if (context === undefined) {
throw new Error('useAccessibility must be used within an AccessibilityProvider');
}
return context;
}
export { AccessibilityProvider, AccessibilityProvider as default, useAccessibility };
//# sourceMappingURL=AccessibilityProvider.js.map