UNPKG

aura-glass

Version:

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

303 lines (300 loc) 11.7 kB
'use client'; import { jsx, jsxs } from 'react/jsx-runtime'; import { cn } from '../../lib/utilsComprehensive.js'; import { TrendingUp, TrendingDown, Minus, Target, Activity, Users, DollarSign } from 'lucide-react'; import { forwardRef } from 'react'; import '../../primitives/GlassCore.js'; import '../../primitives/glass/GlassAdvanced.js'; import '../../primitives/OptimizedGlassCore.js'; import '../../primitives/glass/OptimizedGlassAdvanced.js'; import '../../primitives/MotionNative.js'; import { MotionFramer } from '../../primitives/motion/MotionFramer.js'; import { CardHeader, CardTitle, CardContent } from '../card/index.js'; import { GlassCard } from '../card/GlassCard.js'; /** * GlassMetricCard component * A glassmorphism metric card for displaying various dashboard metrics */ const GlassMetricCard = /*#__PURE__*/forwardRef(({ // TODO: Integrate ContrastGuard for table cells, list items, badges, card titles, and other text content for WCAG AA compliance title, value, unit = "", description, icon, type = "custom", variant = "default", size = "md", layout = "vertical", showProgress = false, progress = 0, progressLabel, trend, comparison, children, loading = false, onClick, className, ...props }, ref) => { // Size configurations const sizeConfigs = { sm: { cardClass: "glass-p-4", titleClass: "glass-text-sm font-medium", valueClass: "glass-text-xl font-bold", iconSize: "w-6 h-6", progressHeight: "h-1" }, md: { cardClass: "glass-p-6", titleClass: "glass-text-base font-medium", valueClass: "glass-text-2xl font-bold", iconSize: "w-8 h-8", progressHeight: "h-2" }, lg: { cardClass: "p-8", titleClass: "glass-text-lg font-semibold", valueClass: "text-3xl font-bold", iconSize: "w-10 h-10", progressHeight: "h-3" }, xl: { cardClass: "glass-p-10", titleClass: "glass-text-xl font-semibold", valueClass: "text-4xl font-bold", iconSize: "w-12 h-12", progressHeight: "h-4" } }; // Get automatic icon based on type const getTypeIcon = () => { switch (type) { case "revenue": return jsx(DollarSign, { className: sizeConfigs[size].iconSize }); case "users": return jsx(Users, { className: sizeConfigs[size].iconSize }); case "conversion": return jsx(Target, { className: sizeConfigs[size].iconSize }); case "performance": return jsx(Activity, { className: sizeConfigs[size].iconSize }); case "growth": return jsx(TrendingUp, { className: sizeConfigs[size].iconSize }); case "target": return jsx(Target, { className: sizeConfigs[size].iconSize }); default: return null; } }; // Variant color configurations const variantConfigs = { default: { iconColor: "glass-text-primary/70", valueColor: "glass-text-primary", trendUpColor: "text-green-400", trendDownColor: "text-red-400", trendNeutralColor: "text-yellow-400", progressBg: "bg-white/20", progressFill: "bg-white/60" }, success: { iconColor: "text-green-400", valueColor: "text-green-200", trendUpColor: "text-green-300", trendDownColor: "text-red-400", trendNeutralColor: "text-yellow-400", progressBg: "bg-green-500/20", progressFill: "bg-green-500" }, warning: { iconColor: "text-yellow-400", valueColor: "text-yellow-200", trendUpColor: "text-green-400", trendDownColor: "text-red-400", trendNeutralColor: "text-yellow-300", progressBg: "bg-yellow-500/20", progressFill: "bg-yellow-500" }, error: { iconColor: "text-red-400", valueColor: "text-red-200", trendUpColor: "text-red-400", trendDownColor: "text-red-300", trendNeutralColor: "text-yellow-400", progressBg: "bg-red-500/20", progressFill: "bg-red-500" }, info: { iconColor: "text-blue-400", valueColor: "text-blue-200", trendUpColor: "text-green-400", trendDownColor: "text-red-400", trendNeutralColor: "text-yellow-400", progressBg: "bg-blue-500/20", progressFill: "bg-blue-500" }, primary: { iconColor: "text-primary", valueColor: "text-primary-foreground", trendUpColor: "text-green-400", trendDownColor: "text-red-400", trendNeutralColor: "text-yellow-400", progressBg: "bg-primary/20", progressFill: "bg-primary" } }; const config = sizeConfigs?.[size]; const variantConfig = variantConfigs?.[variant]; const displayIcon = icon || getTypeIcon(); // Loading skeleton if (loading) { return jsx(GlassCard, { "data-glass-component": true, className: cn("animate-pulse", config.cardClass, className), children: jsxs("div", { className: "glass-gap-4", children: [jsxs("div", { className: "glass-flex glass-items-center glass-justify-between", children: [jsx("div", { className: 'h-4 glass-surface-subtle/20 glass-radius-md w-24' }), jsx("div", { className: 'w-8 h-8 glass-surface-subtle/20 glass-radius-md' })] }), jsxs("div", { className: "glass-gap-2", children: [jsx("div", { className: 'h-8 glass-surface-subtle/20 glass-radius-md w-32' }), jsx("div", { className: 'h-4 glass-surface-subtle/20 glass-radius-md w-20' })] }), showProgress && jsx("div", { className: 'h-2 glass-surface-subtle/10 glass-radius-md' })] }) }); } return jsx(MotionFramer, { preset: "fadeIn", className: "glass-w-full glass-metric-card", children: jsxs(GlassCard, { ref: ref, elevation: "level2", intensity: "medium", depth: 2, tint: "neutral", border: "subtle", animation: "none", performanceMode: "medium", hoverable: !!onClick, clickable: !!onClick, onClick: onClick, className: cn(config.cardClass, "group relative overflow-hidden", onClick && ["cursor-pointer", "hover:shadow-2xl hover:shadow-blue-500/20", "transition-all duration-500 ease-out"], className), ...props, children: [jsx(CardHeader, { className: 'pb-2', children: jsxs("div", { className: cn("flex items-start justify-between", layout === "horizontal" ? "flex-row items-center" : "flex-col"), children: [jsxs("div", { className: "glass-flex-1", children: [jsxs(CardTitle, { className: cn(config.titleClass, "glass-text-primary/90 flex items-center glass-gap-2"), children: [displayIcon && jsxs("div", { className: cn("inline-flex items-center justify-center glass-radius-lg", "bg-gradient-to-br from-white/10 to-white/5", "border border-white/20 glass-p-2 mr-3", "group-hover:from-white/15 group-hover:to-white/8", "group-hover:border-white/30 group-hover:shadow-lg", "group-hover:scale-110 group-hover:-rotate-2", "transition-all duration-300 ease-out", variantConfig.iconColor), children: [jsx("div", { className: 'absolute inset-0 glass-gradient-primary glass-gradient-primary glass-gradient-primary glass-radius-lg opacity-0 group-hover:opacity-100 transition-opacity duration-300' }), jsx("span", { className: cn(config.iconSize, "relative z-10 transition-transform duration-300 group-hover:scale-110"), children: displayIcon })] }), title] }), description && jsx("p", { className: 'glass-text-sm text-primary/60 glass-mt-1', children: description })] }), trend && jsxs("div", { className: "glass-flex glass-items-center glass-gap-1 glass-mt-2", children: [trend.direction === "up" && jsx(TrendingUp, { className: cn("w-4 h-4", variantConfig.trendUpColor) }), trend.direction === "down" && jsx(TrendingDown, { className: cn("w-4 h-4", variantConfig.trendDownColor) }), trend.direction === "neutral" && jsx(Minus, { className: cn("w-4 h-4", variantConfig.trendNeutralColor) }), jsxs("span", { className: cn("glass-text-sm font-medium", trend.direction === "up" ? variantConfig.trendUpColor : trend.direction === "down" ? variantConfig.trendDownColor : variantConfig.trendNeutralColor), children: [trend.value > 0 ? "+" : "", trend.value, "% ", trend.label] })] })] }) }), jsxs(CardContent, { className: 'pt-0', children: [jsxs("div", { className: cn("flex items-baseline glass-gap-2 glass-mb-4 relative", layout === "horizontal" ? "justify-start" : "justify-center"), children: [jsxs("div", { className: 'relative', children: [jsx("div", { className: 'absolute inset-0 glass-gradient-primary glass-gradient-primary via-purple-400/30 glass-gradient-primary glass-blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500 -z-10 scale-150' }), jsx("span", { className: cn(config.valueClass, variantConfig.valueColor, "relative z-10 font-bold tracking-tight", "group-hover:scale-105 group-hover:glass-text-primary", "transition-all duration-300 ease-out", "drop-shadow-sm group-hover:drop-shadow-lg"), children: value })] }), unit && jsx("span", { className: cn("glass-text-lg glass-text-primary/70 font-medium relative", "group-hover:glass-text-primary/90 transition-colors duration-300"), children: unit })] }), showProgress && jsxs("div", { className: 'mb-4', children: [jsx("div", { className: cn("w-full glass-radius-full overflow-hidden", config.progressHeight, variantConfig.progressBg), children: jsx(MotionFramer, { preset: "slideRight", className: cn("h-full", variantConfig.progressFill), style: { width: `${Math.min(progress, 100)}%` } }) }), progressLabel && jsxs("div", { className: "glass-flex glass-justify-between glass-items-center glass-mt-2", children: [jsx("span", { className: 'glass-text-xs text-primary/60', children: progressLabel }), jsxs("span", { className: 'glass-text-xs text-primary/60', children: [Math.round(progress), "%"] })] })] }), comparison && jsx("div", { className: 'mb-4 glass-p-3 glass-surface-subtle/5 glass-radius-lg', children: jsxs("div", { className: "glass-flex glass-items-center glass-justify-between", children: [jsx("span", { className: 'glass-text-sm text-primary/70', children: comparison.label }), jsx("span", { className: 'glass-text-sm font-medium text-primary', children: comparison.value })] }) }), children && jsx("div", { className: "glass-mt-4", children: children })] })] }) }); }); GlassMetricCard.displayName = "GlassMetricCard"; export { GlassMetricCard, GlassMetricCard as default }; //# sourceMappingURL=GlassMetricCard.js.map