aura-glass
Version:
A comprehensive glassmorphism design system for React applications with 142+ production-ready components
144 lines (141 loc) • 4.69 kB
JavaScript
'use client';
import { jsx } from 'react/jsx-runtime';
import { forwardRef, useMemo } from 'react';
import { cn } from '../../lib/utilsComprehensive.js';
import { useReducedMotion } from '../../hooks/useReducedMotion.js';
import { useAnimationContext } from '../../contexts/AnimationContext.js';
import { useAccessibilitySettings } from '../../hooks/useAccessibilitySettings.js';
import { useMultiSpring } from '../../animations/hooks/useMultiSpringBasic.js';
import { SpringPresets } from '../../animations/physics/springPhysics.js';
// Convert color string to RGB values
const colorToRgb = color => {
// Convert named colors to their RGB values
switch (color) {
case 'primary':
return '99, 102, 241';
// Indigo
case 'secondary':
return '156, 39, 176';
// Purple
case 'error':
return '240, 82, 82';
// Red
case 'info':
return '3, 169, 244';
// Light Blue
case 'success':
return '76, 175, 80';
// Green
case 'warning':
return '255, 152, 0';
// Orange
default:
// If it's already an RGB value in format 'r, g, b'
if (/^\d+,\s*\d+,\s*\d+$/.test(color)) {
return color;
}
// Default color (white)
return '255, 255, 255';
}
};
/**
* FocusIndicator Component Implementation
*/
function FocusIndicatorComponent(props, ref) {
const {
children,
visible = false,
color: propColor,
thickness: propThickness,
style: propFocusStyle,
glass = false,
highContrast: propHighContrast,
className,
componentStyle,
disableAnimation: propDisableAnimation,
animationConfig: propAnimationConfig,
...rest
} = props;
// --- Get Context Defaults ---
const {
defaultSpring
} = useAnimationContext();
const {
settings: accessibilitySettings
} = useAccessibilitySettings();
// --- Determine Final Values ---
const finalFocusStyle = propFocusStyle ?? 'solid';
const finalColor = propColor ?? 'primary';
const finalHighContrast = propHighContrast ?? accessibilitySettings.highContrast ?? false;
useReducedMotion();
// --- Calculate Spring Config ---
const finalSpringConfig = useMemo(() => {
const baseConfig = SpringPresets.default;
let contextResolvedConfig = {};
if (typeof defaultSpring === 'object' && defaultSpring !== null) {
contextResolvedConfig = defaultSpring;
}
let propResolvedConfig = {};
if (typeof propAnimationConfig === 'string' && propAnimationConfig in SpringPresets) {
propResolvedConfig = SpringPresets[propAnimationConfig];
} else if (typeof propAnimationConfig === 'object' && propAnimationConfig !== null) {
propResolvedConfig = propAnimationConfig;
}
return {
...baseConfig,
...contextResolvedConfig,
...propResolvedConfig
};
}, [defaultSpring, propAnimationConfig]);
// --- Initialize Spring Hook ---
const {
values: animatedValues,
start: startFocusAnimation
} = useMultiSpring({
shadowSpread1: 0,
shadowSpread2: 0,
shadowOpacity: 0,
outlineWidth: 0,
outlineOpacity: 0
}, {
config: finalSpringConfig
});
// --- Construct Animated Style ---
const animatedStyle = useMemo(() => {
const rgbColor = colorToRgb(finalColor);
const hcColor = finalHighContrast ? '255, 255, 0' : rgbColor;
const outlineStyle = finalFocusStyle === 'dashed' ? 'dashed' : finalFocusStyle === 'dotted' ? 'dotted' : 'solid';
const style = {
...componentStyle,
boxShadow: `0 0 0 ${animatedValues.shadowSpread1}px rgba(${rgbColor}, ${animatedValues.shadowOpacity * 0.5}), 0 0 ${animatedValues.shadowSpread2}px rgba(${rgbColor}, ${animatedValues.shadowOpacity})`,
outline: `${animatedValues.outlineWidth}px ${outlineStyle} rgba(${hcColor}, ${animatedValues.outlineOpacity})`,
outlineOffset: '2px'
};
// Add blur for glow + glass
if (finalFocusStyle === 'glow' && glass) {
style.backdropFilter = 'blur(var(--glass-blur-sm))';
}
return style;
}, [componentStyle, animatedValues, finalFocusStyle, finalColor, finalHighContrast, glass]);
return jsx("div", {
ref: ref,
className: cn('glass-focus-indicator', className),
style: {
position: 'relative',
display: 'inline-block',
outline: 'none',
willChange: 'box-shadow, outline, opacity',
...animatedStyle
},
...rest,
children: children
});
}
/**
* FocusIndicator Component
*
* A component that provides accessible focus indicators.
*/
const FocusIndicator = /*#__PURE__*/forwardRef(FocusIndicatorComponent);
export { FocusIndicator, FocusIndicator as default };
//# sourceMappingURL=FocusIndicator.js.map