UNPKG

aura-glass

Version:

A comprehensive glassmorphism design system for React applications with 142+ production-ready components

170 lines (167 loc) 4.78 kB
'use client'; import { jsxs, jsx } from 'react/jsx-runtime'; import { forwardRef, useRef, useState, useEffect, useMemo } from 'react'; import { cn } from '../../lib/utilsComprehensive.js'; import { useReducedMotion } from '../../hooks/useReducedMotion.js'; import { createGlassStyle } from '../../core/mixins/glassMixins.js'; import styles from './VisualFeedback.module.css.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'; } }; /** * VisualFeedback Component Implementation */ function VisualFeedbackComponent(props, ref) { const { children, effect = 'highlight', active = false, color = 'primary', duration = 1000, glass = false, intensity = 0.5, className, style, ...rest } = props; // Check if reduced motion is preferred const prefersReducedMotion = useReducedMotion(); // Refs const containerRef = useRef(null); // State for ripple effect const [ripples, setRipples] = useState([]); const rippleCount = useRef(0); // Handle ripple effect const handleRipple = event => { if (effect !== 'ripple' || !active || prefersReducedMotion) return; const container = containerRef.current; if (!container) return; const rect = container.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = event.clientX - rect.left; const y = event.clientY - rect.top; // Add new ripple const id = rippleCount.current; rippleCount.current += 1; const newRipple = { id, x, y, size }; setRipples(prevRipples => [...prevRipples, newRipple]); // Remove ripple after animation completes setTimeout(() => { setRipples(prevRipples => prevRipples.filter(r => r.id !== id)); }, duration); }; // Clean up ripples when component unmounts useEffect(() => { return () => { setRipples([]); }; }, []); // Handle forwarded ref const setRefs = element => { containerRef.current = element; // Handle the forwarded ref if (typeof ref === 'function') { ref(element); } else if (ref) { ref.current = element; } }; const animationClass = useMemo(() => { if (!active || effect === 'none' || prefersReducedMotion) { return undefined; } switch (effect) { case 'pulse': return styles.pulse; case 'glow': return styles.glow; case 'highlight': return styles.highlight; case 'bounce': return styles.bounce; case 'shake': return styles.shake; default: return undefined; } }, [active, effect, prefersReducedMotion]); const containerClassName = cn(styles.container, effect === 'ripple' && styles.rippleOverflow, animationClass, 'glass-visual-feedback', className); const containerStyle = useMemo(() => ({ '--feedback-color-rgb': colorToRgb(color), animationDuration: `${duration}ms`, ...style }), [color, duration, style]); return jsxs("div", { ref: setRefs, className: containerClassName, style: containerStyle, onClick: effect === 'ripple' ? handleRipple : undefined, ...rest, children: [glass && active && !prefersReducedMotion ? jsx("div", { className: styles.glassOverlay, style: { opacity: intensity * 0.5, ...createGlassStyle({ intent: 'neutral', elevation: 'level2' }) } }) : null, jsx("div", { className: styles.content, children: children }), effect === 'ripple' && jsx("div", { className: styles.ripples, children: ripples.map(ripple => jsx("div", { className: styles.ripple, style: { top: ripple.y, left: ripple.x, width: ripple.size, height: ripple.size, animationDuration: `${duration}ms` } }, ripple.id)) })] }); } /** * VisualFeedback Component * * A component that provides visual feedback effects. */ const VisualFeedback = /*#__PURE__*/forwardRef(VisualFeedbackComponent); export { VisualFeedback as default }; //# sourceMappingURL=VisualFeedback.js.map