UNPKG

aura-glass

Version:

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

204 lines (201 loc) 7.8 kB
'use client'; import { jsx, jsxs } from 'react/jsx-runtime'; import { forwardRef, useState, useRef } from 'react'; import { cn } from '../../lib/utilsComprehensive.js'; import '../../primitives/GlassCore.js'; import '../../primitives/glass/GlassAdvanced.js'; import { OptimizedGlassCore } from '../../primitives/OptimizedGlassCore.js'; import '../../primitives/glass/OptimizedGlassAdvanced.js'; import '../../primitives/MotionNative.js'; import { MotionFramer } from '../../primitives/motion/MotionFramer.js'; import { useReducedMotion } from '../../hooks/useReducedMotion.js'; import { useGlassParallax } from '../../hooks/useGlassParallax.js'; /** * FrostedGlass Component * Modern implementation using OptimizedGlass with frost effects */ const FrostedGlass = /*#__PURE__*/forwardRef(({ children, className, style, elevation = "level2", blurStrength = "standard", opacity = "medium", borderOpacity = "medium", borderWidth = 1, fullWidth = false, fullHeight = false, borderRadius = "md", interactive = true, padding = 16, intensity = 0.5, frostColor = "rgba(var(--glass-color-white) / var(--glass-opacity-80))", animate = true, pattern = "noise", backgroundColor, specular = true, glow = false, lightAngle = 135, parallax = false, parallaxStrength = 10, ...rest }, ref) => { const prefersReducedMotion = useReducedMotion(); const shouldAnimate = animate && !prefersReducedMotion; const [isHovered, setIsHovered] = useState(false); const containerRef = useRef(null); // Handle parallax when enabled useGlassParallax(containerRef, { strength: parallaxStrength, enabled: parallax && !prefersReducedMotion }); // Map blur strength to intensity const intensityMap = { none: "subtle", light: "subtle", standard: "medium", heavy: "strong" }; // Map border radius const radiusMap = { none: "rounded-none", sm: "glass-radius-sm", md: "glass-radius-md", lg: "glass-radius-lg", xl: "glass-radius-xl", full: "glass-radius-full" }; // Map elevation to OptimizedGlass elevation levels const getElevationLevel = elev => { if (typeof elev === "string" && elev.startsWith("level")) { return elev; } const numElev = typeof elev === "number" ? elev : 2; if (numElev <= 1) return "level1"; if (numElev <= 2) return "level2"; if (numElev <= 3) return "level3"; return "level4"; }; // Generate frost pattern styles const getFrostPattern = () => { switch (pattern) { case "lines": return { backgroundImage: ` linear-gradient(90deg, ${frostColor} 1px, transparent 1px), linear-gradient(${frostColor} 1px, transparent 1px) `, backgroundSize: "20px 20px" }; case "crystals": return { backgroundImage: ` radial-gradient(${frostColor} 5%, transparent 5%), radial-gradient(${frostColor} 5%, transparent 5%) `, backgroundSize: "30px 30px", backgroundPosition: "0 0, 15px 15px" }; case "noise": default: return { backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E")`, backgroundSize: "100px 100px" }; } }; // Handle mouse events const handleMouseEnter = () => setIsHovered(true); const handleMouseLeave = () => setIsHovered(false); // Merge refs const setRefs = node => { containerRef.current = node; if (typeof ref === "function") ref(node);else if (ref) ref.current = node; }; const frostPatternStyles = getFrostPattern(); const glowColor = typeof glow === "string" ? glow : glow === true ? "primary" : false; return jsx(MotionFramer, { preset: shouldAnimate ? "fadeIn" : "none", className: 'relative isolate', children: jsxs(OptimizedGlassCore, { ref: setRefs, intent: "neutral", elevation: getElevationLevel(elevation), intensity: intensityMap[blurStrength], depth: 2, tint: "cool", border: borderOpacity === "none" ? "none" : "subtle", animation: shouldAnimate ? "breathe" : "none", performanceMode: "high", liftOnHover: interactive, press: interactive, className: cn( // Base styles "relative block box-border overflow-hidden isolate", "transition-all duration-300", // Size fullWidth && "w-full", fullHeight && "h-full", !fullWidth && !fullHeight && "w-auto h-auto", // Border radius typeof borderRadius === "string" ? radiusMap[borderRadius] : `rounded-[${borderRadius}px]`, // Padding typeof padding === "number" ? `p-${Math.round(padding / 4)}` : "glass-p-4", // Interactive styles interactive && ["cursor-pointer", "hover:-translate-y-0.5", "active:translate-y-0"], // Glow effect glowColor && { primary: "drop-shadow-[0_0_18px_var(--glass-color-primary,0.28)]", success: "drop-shadow-[0_0_18px_var(--glass-color-success,0.28)]", warning: "drop-shadow-[0_0_18px_var(--glass-color-warning,0.28)]", danger: "drop-shadow-[0_0_18px_var(--glass-color-danger,0.28)]", info: "drop-shadow-[0_0_18px_rgba(14,165,233,0.28)]" }[glowColor], className), style: { backgroundColor, borderWidth: borderWidth > 0 ? `${borderWidth}px` : undefined, ...style }, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ...rest, children: [jsx("div", { className: cn("absolute inset-0 pointer-events-none", shouldAnimate && "animate-frost-grow"), style: { ...frostPatternStyles, // Reduce overlay strength to avoid washing out label text opacity: 0.18 + intensity * 0.22, // Use soft-light for gentler interaction with backdrop mixBlendMode: "soft-light" } }), jsx("div", { className: cn("absolute inset-0 pointer-events-none", shouldAnimate && "animate-frost-sparkle"), style: { backgroundImage: `radial-gradient(${frostColor} 1px, transparent 1px)`, backgroundSize: "30px 30px", // Tone down sparkle overlay for readability opacity: Math.min(0.22, intensity * 0.25) } }), jsx("div", { className: 'absolute inset-0 pointer-events-none glass-radius-inherit', style: { // Edge frost (less aggressive) boxShadow: `inset 0 0 ${4 + intensity * 9}px ${frostColor}`, opacity: isHovered ? 0.24 + intensity * 0.25 : 0.18 + intensity * 0.2, // Specular highlight (dimmed) background: specular ? ` radial-gradient(${intensity * 70 + 40}% ${intensity * 35 + 40}% at 50% -10%, rgba(255,255,255, ${Math.min(0.25, 0.1 + intensity * 0.22)}) 0%, rgba(255,255,255,0.0) 60%), linear-gradient(${lightAngle}deg, rgba(255,255,255,0.12), rgba(255,255,255,0.00) 35%) ` : undefined, // Softer blending to preserve label contrast mixBlendMode: specular ? "overlay" : "normal", transform: parallax ? "translate(var(--glass-parallax-x), var(--glass-parallax-y))" : undefined, transition: "transform 150ms ease-out, opacity 300ms ease" } }), jsx("div", { className: 'relative z-10', children: children })] }) }); }); FrostedGlass.displayName = "FrostedGlass"; export { FrostedGlass, FrostedGlass as default }; //# sourceMappingURL=FrostedGlass.js.map