UNPKG

aura-glass

Version:

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

178 lines (175 loc) 5.49 kB
'use client'; import { jsx, jsxs } from 'react/jsx-runtime'; import { forwardRef, useState, useEffect, useMemo } from 'react'; import { cn } from '../../lib/utilsComprehensive.js'; import { useReducedMotion } from '../../hooks/useReducedMotion.js'; import { GlassButton } from '../button/GlassButton.js'; import '../button/GlassFab.js'; import '../button/GlassMagneticButton.js'; import { Typography } from '../data-display/Typography.js'; import { useGalileoStateSpring } from '../../hooks/useGalileoStateSpring.js'; import { useAnimationContext } from '../../contexts/AnimationContext.js'; import { SpringPresets } from '../../animations/physics/springPhysics.js'; import styles from './CompactCookieNotice.module.css.js'; // Cookie management utility const setCookie = (name, value, days) => { const date = new Date(); date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); const expires = `expires=${date.toUTCString()}`; document.cookie = `${name}=${value};${expires};path=/`; }; const getCookie = name => { const nameEQ = `${name}=`; const ca = document.cookie.split(';'); for (let i = 0; i < ca.length; i++) { let c = ca[i]; while (c.charAt(0) === ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); } return null; }; const POSITION_CLASS_MAP = { bottom: styles.positionBottom, top: styles.positionTop, 'bottom-left': styles.positionBottomLeft, 'bottom-right': styles.positionBottomRight, 'top-left': styles.positionTopLeft, 'top-right': styles.positionTopRight }; /** * A compact cookie consent notice that takes minimal screen space */ const CompactCookieNotice = /*#__PURE__*/forwardRef(({ message = 'We use cookies for a better experience.', acceptText = 'Accept', moreInfoText = 'More Info', onAccept, onMoreInfo, style, className, glassIntensity = 0.6, position = 'bottom-left', animate = true, ...rest }, ref) => { const [visible, setVisible] = useState(false); const prefersReducedMotion = useReducedMotion(); const { defaultSpring } = useAnimationContext(); const shouldAnimate = animate && !prefersReducedMotion; useEffect(() => { // Check if user has already made a choice const consentValue = getCookie('cookie-consent'); if (!consentValue) { // Show the notice setVisible(true); } }, []); const handleAccept = () => { setCookie('cookie-consent', 'accepted', 365); setVisible(false); if (onAccept) { onAccept(); } }; const handleMoreInfo = () => { if (onMoreInfo) { onMoreInfo(); } }; // --- Animation Setup --- const finalSpringConfig = useMemo(() => { const baseConfig = SpringPresets.default; let contextConfig = {}; if (typeof defaultSpring === 'string' && defaultSpring in SpringPresets) { contextConfig = SpringPresets[defaultSpring]; } else if (typeof defaultSpring === 'object') { contextConfig = defaultSpring ?? {}; } return { ...baseConfig, ...contextConfig }; }, [defaultSpring]); const isTop = position?.startsWith('top'); const exitY = isTop ? -15 : 15; // Spring for Opacity const { value: animatedOpacity } = useGalileoStateSpring(visible ? 1 : 0, { ...finalSpringConfig, immediate: !shouldAnimate }); // Spring for TranslateY const { value: animatedTranslateY } = useGalileoStateSpring(visible ? 0 : exitY, { ...finalSpringConfig, immediate: !shouldAnimate }); // Calculate transform const isCentered = position === 'top' || position === 'bottom'; const animatedStyle = { opacity: animatedOpacity, transform: `translateY(${animatedTranslateY}px)${isCentered ? ' translateX(-50%)' : ''}` }; const positionClass = POSITION_CLASS_MAP[position ?? 'bottom-left'] ?? styles.positionBottomLeft; const depth = Math.max(0.5, Math.min(2, glassIntensity)); const shadowDepth = (24 * depth).toFixed(2); const containerStyleVars = { '--cookie-blur-scale': depth, '--cookie-box-shadow': `0 10px ${shadowDepth}px rgba(15, 23, 42, 0.16)` }; if (!visible) { return jsx("div", { ref: ref, className: cn(styles.container, positionClass, className), style: { ...containerStyleVars, display: 'none', ...style }, "aria-hidden": true, ...rest }); } return jsxs("div", { ref: ref, className: cn(styles.container, positionClass, className), style: { ...containerStyleVars, ...animatedStyle, ...style }, "aria-hidden": !visible, ...rest, children: [jsx(Typography, { variant: "p", children: message }), jsxs("div", { className: styles.buttonGroup, children: [jsx(GlassButton, { variant: "link", onClick: handleMoreInfo, size: "sm", children: moreInfoText }), jsx(GlassButton, { variant: "primary", onClick: handleAccept, size: "sm", children: acceptText })] })] }); }); CompactCookieNotice.displayName = 'CompactCookieNotice'; // Glass version of the CompactCookieNotice const GlassCompactCookieNotice = /*#__PURE__*/forwardRef((props, ref) => jsx(CompactCookieNotice, { ref: ref, glassIntensity: 0.75, ...props })); GlassCompactCookieNotice.displayName = 'GlassCompactCookieNotice'; export { CompactCookieNotice, GlassCompactCookieNotice }; //# sourceMappingURL=CompactCookieNotice.js.map