UNPKG

aura-glass

Version:

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

277 lines (274 loc) 9.27 kB
'use client'; import { jsx, jsxs } from 'react/jsx-runtime'; import { cn } from '../../../../lib/utilsComprehensive.js'; import { forwardRef } from 'react'; import { GlassCore } from '../../../../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 { GlassBadge } from '../../../data-display/GlassBadge.js'; import { VStack, HStack } from '../../../layout/GlassStack.js'; /** * MetricWidget component * Display key metrics with trends and targets */ const MetricWidget = /*#__PURE__*/forwardRef(({ data, variant = "default", size = "md", colorScheme = "default", showTrend = true, showTarget = false, trendIcons, className, ...props }, ref) => { const sizeClasses = { sm: { value: "glass-text-lg", label: "glass-text-xs", icon: "glass-text-lg", padding: "glass-p-3" }, md: { value: "glass-text-2xl", label: "glass-text-sm", icon: "glass-text-xl", padding: "glass-p-4" }, lg: { value: "text-3xl", label: "glass-text-base", icon: "glass-text-2xl", padding: "glass-p-6" } }; const colorSchemes = { default: { value: "text-foreground", change: { up: "text-success", down: "text-destructive", neutral: "glass-text-secondary" }, icon: "glass-text-secondary", background: "" }, primary: { value: "text-primary", change: { up: "text-success", down: "text-destructive", neutral: "glass-text-secondary" }, icon: "text-primary/70", background: "bg-primary/5" }, success: { value: "text-success", change: { up: "text-success", down: "text-destructive", neutral: "glass-text-secondary" }, icon: "text-success/70", background: "bg-success/5" }, warning: { value: "text-warning", change: { up: "text-success", down: "text-destructive", neutral: "glass-text-secondary" }, icon: "text-warning/70", background: "bg-warning/5" }, destructive: { value: "text-destructive", change: { up: "text-success", down: "text-destructive", neutral: "glass-text-secondary" }, icon: "text-destructive/70", background: "bg-destructive/5" } }; const config = sizeClasses?.[size]; const colors = colorSchemes?.[colorScheme]; const defaultTrendIcons = { up: "↗️", down: "↘️", neutral: "→" }; const icons = trendIcons || defaultTrendIcons; const formatValue = value => { if (typeof value === "number") { return new Intl.NumberFormat().format(value); } return value; }; const getTrendIcon = () => { if (!data?.trend) return null; return icons?.[data?.trend]; }; const getChangeColor = () => { if (!data?.change) return colors.change.neutral; if (data?.change > 0) return colors.change.up; if (data?.change < 0) return colors.change.down; return colors.change.neutral; }; const getTargetProgress = () => { if (!data?.target || typeof data?.value !== "number") return 0; return Math.min(data?.value / data?.target * 100, 100); }; const renderContent = () => { switch (variant) { case "minimal": return jsxs(HStack, { "data-glass-component": true, space: "sm", align: "center", children: [data?.icon && jsx("div", { className: cn(config.icon, colors.icon), children: data?.icon }), jsxs(VStack, { space: "none", children: [jsxs("div", { className: cn("font-bold", config.value, colors.value), children: [formatValue(data?.value), data?.unit] }), jsx("div", { className: cn("glass-text-secondary", config.label), children: data?.label || "Metric" })] }), showTrend && data?.change && jsxs(GlassBadge, { variant: "outline", size: "xs", className: getChangeColor(), children: [getTrendIcon(), " ", data?.change > 0 ? "+" : "", data?.change, "%"] })] }); case "featured": return jsxs(VStack, { space: "md", children: [jsxs(HStack, { space: "sm", align: "center", justify: "between", children: [jsx("div", { className: cn("glass-text-secondary", config.label), children: data?.label || "Metric" }), data?.icon && jsx("div", { className: cn(config.icon, colors.icon), children: data?.icon })] }), jsxs(VStack, { space: "xs", children: [jsxs("div", { className: cn("font-bold", config.value, colors.value), children: [formatValue(data?.value), data?.unit] }), showTarget && data?.target && jsxs("div", { className: "glass-w-full", children: [jsxs("div", { className: 'glass-flex glass-justify-between glass-text-xs glass-text-secondary mb-1', children: [jsx("span", { children: "Progress" }), jsxs("span", { children: [Math.round(getTargetProgress()), "%"] })] }), jsx("div", { className: 'glass-w-full glass-surface-subtle glass-radius-full h-2', children: jsx(MotionFramer, { className: cn("h-full glass-radius-full transition-all duration-500", getTargetProgress() >= 100 ? "bg-success" : "bg-primary"), style: { width: `${getTargetProgress()}%` } }) })] })] }), showTrend && (data?.change || data?.changeLabel) && jsxs(HStack, { space: "sm", align: "center", children: [data?.change && jsxs("div", { className: cn("glass-text-xs font-medium flex items-center glass-gap-1", getChangeColor()), children: [jsx("span", { children: getTrendIcon() }), jsxs("span", { children: [data?.change > 0 ? "+" : "", data?.change, "%"] })] }), data?.changeLabel && jsx("div", { className: "glass-text-xs glass-text-secondary", children: data?.changeLabel })] }), data?.description && jsx("div", { className: "glass-text-xs glass-text-secondary", children: data?.description })] }); case "compact": return jsxs(HStack, { space: "sm", align: "center", justify: "between", children: [jsxs(VStack, { space: "none", children: [jsxs("div", { className: cn("font-bold glass-text-lg", colors.value), children: [formatValue(data?.value), data?.unit] }), jsx("div", { className: "glass-text-xs glass-text-secondary", children: data?.label || "Metric" })] }), data?.icon && jsx("div", { className: cn("glass-text-lg", colors.icon), children: data?.icon })] }); default: return jsxs(VStack, { space: "md", children: [jsxs(HStack, { space: "sm", align: "center", justify: "between", children: [jsx("div", { className: cn("glass-text-secondary", config.label), children: data?.label || "Metric" }), data?.icon && jsx("div", { className: cn(config.icon, colors.icon), children: data?.icon })] }), jsxs("div", { className: cn("font-bold", config.value, colors.value), children: [formatValue(data?.value), data?.unit] }), showTrend && data?.change && jsxs(HStack, { space: "sm", align: "center", children: [jsxs("div", { className: cn("glass-text-sm font-medium flex items-center glass-gap-1", getChangeColor()), children: [jsx("span", { children: getTrendIcon() }), jsxs("span", { children: [data?.change > 0 ? "+" : "", data?.change, "%"] })] }), data?.changeLabel && jsx("div", { className: "glass-text-sm glass-text-secondary", children: data?.changeLabel })] })] }); } }; return jsx(GlassCore, { ref: ref, className: cn("w-full h-full glass-radius-lg", config.padding, colors.background, className), ...props, children: renderContent() }); }); MetricWidget.displayName = "MetricWidget"; export { MetricWidget }; //# sourceMappingURL=MetricWidget.js.map