UNPKG

aura-glass

Version:

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

211 lines (205 loc) 6.1 kB
'use client'; import { jsxs, jsx } from 'react/jsx-runtime'; import { forwardRef, useRef, useState, useEffect } from 'react'; import { useReducedMotion } from '../../hooks/useReducedMotion.js'; import { GlassContainer } from '../layout/GlassContainer.js'; /** * Dimensional Dashboard Container Component */ const DimensionalDashboardContainer = /*#__PURE__*/forwardRef(({ children, className = "", style = {}, perspective = 1200, depth = 100, parallax = false, autoRotate = false, rotationSpeed = 10, layers = [], onLayerClick }, ref) => { const prefersReducedMotion = useReducedMotion(); const containerRef = useRef(null); const [rotation, setRotation] = useState({ x: 0, y: 0 }); const [scrollPosition, setScrollPosition] = useState(0); const animationFrameRef = useRef(null); /** * Handle auto-rotation */ useEffect(() => { if (!autoRotate || prefersReducedMotion) return; let lastTime = Date.now(); const rotate = () => { const currentTime = Date.now(); const delta = (currentTime - lastTime) / 1000; lastTime = currentTime; setRotation(prev => ({ x: prev.x, y: (prev.y + rotationSpeed * delta) % 360 })); animationFrameRef.current = requestAnimationFrame(rotate); }; animationFrameRef.current = requestAnimationFrame(rotate); return () => { if (animationFrameRef.current) { cancelAnimationFrame(animationFrameRef.current); } }; }, [autoRotate, rotationSpeed, prefersReducedMotion]); /** * Handle mouse move for interactive rotation */ const handleMouseMove = e => { if (autoRotate || prefersReducedMotion) return; const container = containerRef.current; if (!container) return; const rect = container.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; const rotateY = (e.clientX - centerX) / (rect.width / 2) * 15; const rotateX = -((e.clientY - centerY) / (rect.height / 2)) * 15; setRotation({ x: rotateX, y: rotateY }); }; /** * Reset rotation on mouse leave */ const handleMouseLeave = () => { if (!autoRotate) { setRotation({ x: 0, y: 0 }); } }; /** * Handle parallax scrolling */ useEffect(() => { if (!parallax || prefersReducedMotion) return; const handleScroll = () => { setScrollPosition(window.scrollY); }; window.addEventListener("scroll", handleScroll, { passive: true }); return () => { window.removeEventListener("scroll", handleScroll); }; }, [parallax, prefersReducedMotion]); /** * Container styles */ const containerStyles = { ...style, position: "relative", perspective: `${perspective}px`, transformStyle: "preserve-3d" }; /** * Content wrapper styles */ const contentStyles = { transformStyle: "preserve-3d", transform: prefersReducedMotion ? "none" : ` rotateX(${rotation.x}deg) rotateY(${rotation.y}deg) translateZ(${parallax ? scrollPosition * -0.2 : 0}px) `, transition: autoRotate ? "none" : "transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)" }; /** * Calculate layer Z position */ const getLayerZPosition = (index, total) => { if (total <= 1) return 0; return (index - (total - 1) / 2) * depth / (total - 1); }; return jsxs("div", { ref: ref, className: `dimensional-dashboard-container ${className}`, style: containerStyles, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, children: [jsx("div", { ref: containerRef, className: 'dimensional-dashboard-content', style: contentStyles, children: layers.length > 0 ? layers.map((layer, index) => { const zPosition = getLayerZPosition(index, layers.length); return jsx("div", { className: 'dimensional-dashboard-layer', style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%", transform: `translateZ(${zPosition}px)`, transformStyle: "preserve-3d", cursor: onLayerClick ? "pointer" : "default" }, onClick: () => onLayerClick?.(index), role: onLayerClick ? "button" : undefined, tabIndex: onLayerClick ? 0 : undefined, onKeyDown: onLayerClick ? e => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); onLayerClick(index); } } : undefined, children: jsx(GlassContainer, { style: { width: "100%", height: "100%", opacity: 1 - Math.abs(zPosition) / (depth * 2) }, children: layer }) }, index); }) : // Single content layer jsx(GlassContainer, { style: { width: "100%", height: "100%" }, children: children }) }), jsx("style", { children: ` .dimensional-dashboard-container { width: 100%; height: 100%; overflow: hidden; } .dimensional-dashboard-content { width: 100%; height: 100%; position: relative; } .dimensional-dashboard-layer:focus-visible { outline: 2px solid var(--aura-accent-color, #00d4ff); outline-offset: 4px; } @media (prefers-reduced-motion: reduce) { .dimensional-dashboard-content { transform: none !important; transition: none !important; } .dimensional-dashboard-layer { transform: none !important; } } ` })] }); }); DimensionalDashboardContainer.displayName = "DimensionalDashboardContainer"; export { DimensionalDashboardContainer }; //# sourceMappingURL=DimensionalDashboardContainer.js.map