@7onic-ui/react 0.3.9 → 0.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/README.md +2 -2
  2. package/dist/chart.mjs +3 -9
  3. package/dist/chart.mjs.map +1 -1
  4. package/dist/chunk-234NAXGV.mjs +252 -0
  5. package/dist/chunk-234NAXGV.mjs.map +1 -0
  6. package/dist/chunk-53MIUPSY.mjs +13 -0
  7. package/dist/chunk-53MIUPSY.mjs.map +1 -0
  8. package/dist/chunk-BN5BEA3V.mjs +195 -0
  9. package/dist/chunk-BN5BEA3V.mjs.map +1 -0
  10. package/dist/chunk-COW3B62M.mjs +214 -0
  11. package/dist/chunk-COW3B62M.mjs.map +1 -0
  12. package/dist/chunk-CTH6SN5Y.mjs +114 -0
  13. package/dist/chunk-CTH6SN5Y.mjs.map +1 -0
  14. package/dist/chunk-D3NTQNDW.mjs +440 -0
  15. package/dist/chunk-D3NTQNDW.mjs.map +1 -0
  16. package/dist/chunk-DDRYEJBJ.mjs +164 -0
  17. package/dist/chunk-DDRYEJBJ.mjs.map +1 -0
  18. package/dist/chunk-DJAEXCRU.mjs +190 -0
  19. package/dist/chunk-DJAEXCRU.mjs.map +1 -0
  20. package/dist/chunk-DRVHHEAY.mjs +145 -0
  21. package/dist/chunk-DRVHHEAY.mjs.map +1 -0
  22. package/dist/chunk-DTLNWOTR.mjs +482 -0
  23. package/dist/chunk-DTLNWOTR.mjs.map +1 -0
  24. package/dist/chunk-DYYQOHQR.mjs +214 -0
  25. package/dist/chunk-DYYQOHQR.mjs.map +1 -0
  26. package/dist/chunk-FHUAH6AJ.mjs +93 -0
  27. package/dist/chunk-FHUAH6AJ.mjs.map +1 -0
  28. package/dist/chunk-GD4YE5AE.mjs +209 -0
  29. package/dist/chunk-GD4YE5AE.mjs.map +1 -0
  30. package/dist/chunk-GRCJ35DX.mjs +144 -0
  31. package/dist/chunk-GRCJ35DX.mjs.map +1 -0
  32. package/dist/chunk-HHX4GABH.mjs +129 -0
  33. package/dist/chunk-HHX4GABH.mjs.map +1 -0
  34. package/dist/chunk-IPCIC2BI.mjs +148 -0
  35. package/dist/chunk-IPCIC2BI.mjs.map +1 -0
  36. package/dist/chunk-IY3R2VGB.mjs +272 -0
  37. package/dist/chunk-IY3R2VGB.mjs.map +1 -0
  38. package/dist/chunk-JCJEVXER.mjs +170 -0
  39. package/dist/chunk-JCJEVXER.mjs.map +1 -0
  40. package/dist/chunk-KBPYAMGS.mjs +157 -0
  41. package/dist/chunk-KBPYAMGS.mjs.map +1 -0
  42. package/dist/chunk-LJJ6K4IU.mjs +318 -0
  43. package/dist/chunk-LJJ6K4IU.mjs.map +1 -0
  44. package/dist/chunk-MRUVGHGP.mjs +375 -0
  45. package/dist/chunk-MRUVGHGP.mjs.map +1 -0
  46. package/dist/chunk-N4K2BDGM.mjs +153 -0
  47. package/dist/chunk-N4K2BDGM.mjs.map +1 -0
  48. package/dist/chunk-NWFMJWGX.mjs +165 -0
  49. package/dist/chunk-NWFMJWGX.mjs.map +1 -0
  50. package/dist/chunk-PTAPPOKU.mjs +117 -0
  51. package/dist/chunk-PTAPPOKU.mjs.map +1 -0
  52. package/dist/chunk-PVTBM7V7.mjs +316 -0
  53. package/dist/chunk-PVTBM7V7.mjs.map +1 -0
  54. package/dist/chunk-Q5WVLK2L.mjs +77 -0
  55. package/dist/chunk-Q5WVLK2L.mjs.map +1 -0
  56. package/dist/chunk-RKSB2N5L.mjs +206 -0
  57. package/dist/chunk-RKSB2N5L.mjs.map +1 -0
  58. package/dist/chunk-S4DGVKBK.mjs +151 -0
  59. package/dist/chunk-S4DGVKBK.mjs.map +1 -0
  60. package/dist/chunk-S4T4PU7F.mjs +114 -0
  61. package/dist/chunk-S4T4PU7F.mjs.map +1 -0
  62. package/dist/chunk-SZPZOGPC.mjs +394 -0
  63. package/dist/chunk-SZPZOGPC.mjs.map +1 -0
  64. package/dist/chunk-T546XBQG.mjs +443 -0
  65. package/dist/chunk-T546XBQG.mjs.map +1 -0
  66. package/dist/chunk-UWTT5AE6.mjs +145 -0
  67. package/dist/chunk-UWTT5AE6.mjs.map +1 -0
  68. package/dist/chunk-V5UFWYFI.mjs +255 -0
  69. package/dist/chunk-V5UFWYFI.mjs.map +1 -0
  70. package/dist/chunk-VUPGBB5X.mjs +150 -0
  71. package/dist/chunk-VUPGBB5X.mjs.map +1 -0
  72. package/dist/chunk-W6YNEU53.mjs +175 -0
  73. package/dist/chunk-W6YNEU53.mjs.map +1 -0
  74. package/dist/chunk-WWSN5YME.mjs +222 -0
  75. package/dist/chunk-WWSN5YME.mjs.map +1 -0
  76. package/dist/chunk-XK52LYR4.mjs +182 -0
  77. package/dist/chunk-XK52LYR4.mjs.map +1 -0
  78. package/dist/chunk-YIAH6KHV.mjs +164 -0
  79. package/dist/chunk-YIAH6KHV.mjs.map +1 -0
  80. package/dist/chunk-Z6JWWCNL.mjs +108 -0
  81. package/dist/chunk-Z6JWWCNL.mjs.map +1 -0
  82. package/dist/chunk-ZDRUTJ4T.mjs +119 -0
  83. package/dist/chunk-ZDRUTJ4T.mjs.map +1 -0
  84. package/dist/components/accordion.mjs +19 -0
  85. package/dist/components/accordion.mjs.map +1 -0
  86. package/dist/components/alert.mjs +15 -0
  87. package/dist/components/alert.mjs.map +1 -0
  88. package/dist/components/avatar.mjs +23 -0
  89. package/dist/components/avatar.mjs.map +1 -0
  90. package/dist/components/badge.mjs +11 -0
  91. package/dist/components/badge.mjs.map +1 -0
  92. package/dist/components/breadcrumb.mjs +23 -0
  93. package/dist/components/breadcrumb.mjs.map +1 -0
  94. package/dist/components/button-group.mjs +11 -0
  95. package/dist/components/button-group.mjs.map +1 -0
  96. package/dist/components/button.mjs +12 -0
  97. package/dist/components/button.mjs.map +1 -0
  98. package/dist/components/card.mjs +25 -0
  99. package/dist/components/card.mjs.map +1 -0
  100. package/dist/components/chat-input.mjs +15 -0
  101. package/dist/components/chat-input.mjs.map +1 -0
  102. package/dist/components/chat-message.mjs +17 -0
  103. package/dist/components/chat-message.mjs.map +1 -0
  104. package/dist/components/checkbox.mjs +12 -0
  105. package/dist/components/checkbox.mjs.map +1 -0
  106. package/dist/components/divider.mjs +11 -0
  107. package/dist/components/divider.mjs.map +1 -0
  108. package/dist/components/drawer.mjs +33 -0
  109. package/dist/components/drawer.mjs.map +1 -0
  110. package/dist/components/dropdown.mjs +35 -0
  111. package/dist/components/dropdown.mjs.map +1 -0
  112. package/dist/components/field.mjs +17 -0
  113. package/dist/components/field.mjs.map +1 -0
  114. package/dist/components/icon-button.mjs +12 -0
  115. package/dist/components/icon-button.mjs.map +1 -0
  116. package/dist/components/input.mjs +12 -0
  117. package/dist/components/input.mjs.map +1 -0
  118. package/dist/components/metric-card.mjs +23 -0
  119. package/dist/components/metric-card.mjs.map +1 -0
  120. package/dist/components/modal.mjs +57 -0
  121. package/dist/components/modal.mjs.map +1 -0
  122. package/dist/components/navigation-menu.mjs +27 -0
  123. package/dist/components/navigation-menu.mjs.map +1 -0
  124. package/dist/components/pagination.mjs +33 -0
  125. package/dist/components/pagination.mjs.map +1 -0
  126. package/dist/components/popover.mjs +23 -0
  127. package/dist/components/popover.mjs.map +1 -0
  128. package/dist/components/progress.mjs +11 -0
  129. package/dist/components/progress.mjs.map +1 -0
  130. package/dist/components/quick-reply.mjs +15 -0
  131. package/dist/components/quick-reply.mjs.map +1 -0
  132. package/dist/components/radio-group.mjs +16 -0
  133. package/dist/components/radio-group.mjs.map +1 -0
  134. package/dist/components/segmented.mjs +15 -0
  135. package/dist/components/segmented.mjs.map +1 -0
  136. package/dist/components/select.mjs +23 -0
  137. package/dist/components/select.mjs.map +1 -0
  138. package/dist/components/skeleton.mjs +11 -0
  139. package/dist/components/skeleton.mjs.map +1 -0
  140. package/dist/components/slider.mjs +11 -0
  141. package/dist/components/slider.mjs.map +1 -0
  142. package/dist/components/spinner.mjs +11 -0
  143. package/dist/components/spinner.mjs.map +1 -0
  144. package/dist/components/switch.mjs +12 -0
  145. package/dist/components/switch.mjs.map +1 -0
  146. package/dist/components/table.mjs +23 -0
  147. package/dist/components/table.mjs.map +1 -0
  148. package/dist/components/tabs.mjs +19 -0
  149. package/dist/components/tabs.mjs.map +1 -0
  150. package/dist/components/textarea.mjs +12 -0
  151. package/dist/components/textarea.mjs.map +1 -0
  152. package/dist/components/toast.mjs +13 -0
  153. package/dist/components/toast.mjs.map +1 -0
  154. package/dist/components/toggle-group.mjs +15 -0
  155. package/dist/components/toggle-group.mjs.map +1 -0
  156. package/dist/components/toggle.mjs +11 -0
  157. package/dist/components/toggle.mjs.map +1 -0
  158. package/dist/components/tooltip.mjs +21 -0
  159. package/dist/components/tooltip.mjs.map +1 -0
  160. package/dist/components/typing-indicator.mjs +11 -0
  161. package/dist/components/typing-indicator.mjs.map +1 -0
  162. package/dist/index.mjs +296 -7536
  163. package/dist/index.mjs.map +1 -1
  164. package/llms.txt +23 -23
  165. package/package.json +4 -3
  166. package/dist/chart.d.mts +0 -147
  167. package/dist/index.d.mts +0 -1535
@@ -0,0 +1,214 @@
1
+ "use client";
2
+ import {
3
+ cn
4
+ } from "./chunk-53MIUPSY.mjs";
5
+
6
+ // src/components/ui/metric-card.tsx
7
+ import * as React from "react";
8
+ import { cva } from "class-variance-authority";
9
+ var metricCardVariants = cva(
10
+ "transition-colors",
11
+ {
12
+ variants: {
13
+ variant: {
14
+ default: "bg-background-paper border border-border",
15
+ elevated: "bg-background-paper shadow-md",
16
+ ghost: "bg-transparent"
17
+ },
18
+ size: {
19
+ sm: "p-4",
20
+ default: "p-4 sm:p-5",
21
+ lg: "p-4 sm:p-6"
22
+ },
23
+ radius: {
24
+ none: "rounded-none",
25
+ // 0px
26
+ sm: "rounded-sm",
27
+ // 2px
28
+ base: "rounded",
29
+ // 4px
30
+ default: "rounded-xl",
31
+ // 12px - card default
32
+ lg: "rounded-lg",
33
+ // 8px
34
+ xl: "rounded-xl",
35
+ // 12px
36
+ "2xl": "rounded-2xl",
37
+ // 16px
38
+ "3xl": "rounded-3xl",
39
+ // 24px
40
+ full: "rounded-full"
41
+ // 9999px
42
+ }
43
+ },
44
+ defaultVariants: { variant: "default", size: "default", radius: "default" }
45
+ }
46
+ );
47
+ var valueSizes = {
48
+ sm: "text-xl",
49
+ default: "text-2xl",
50
+ lg: "text-3xl"
51
+ };
52
+ var titleSizes = {
53
+ sm: "text-xs",
54
+ default: "text-sm",
55
+ lg: "text-sm"
56
+ };
57
+ var iconWrapperSizes = {
58
+ sm: "[&>svg]:icon-sm",
59
+ default: "[&>svg]:icon-md",
60
+ lg: "[&>svg]:icon-lg"
61
+ };
62
+ var trendConfig = {
63
+ up: { color: "text-text-success", srLabel: "Increased" },
64
+ down: { color: "text-text-error", srLabel: "Decreased" },
65
+ neutral: { color: "text-text-muted", srLabel: "No change" }
66
+ };
67
+ var MetricCardContext = React.createContext({ size: "default", animated: false });
68
+ var MetricCard = React.forwardRef(
69
+ ({ className, variant, size, radius, animated = false, children, ...props }, ref) => {
70
+ const resolvedSize = size || "default";
71
+ return /* @__PURE__ */ React.createElement(MetricCardContext.Provider, { value: { size: resolvedSize, animated } }, /* @__PURE__ */ React.createElement(
72
+ "div",
73
+ {
74
+ ref,
75
+ className: cn(metricCardVariants({ variant, size, radius }), className),
76
+ ...props
77
+ },
78
+ children
79
+ ));
80
+ }
81
+ );
82
+ MetricCard.displayName = "MetricCard";
83
+ var MetricCardHeader = React.forwardRef(
84
+ ({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
85
+ "div",
86
+ {
87
+ ref,
88
+ className: cn("flex items-center justify-between gap-2", className),
89
+ ...props
90
+ }
91
+ )
92
+ );
93
+ MetricCardHeader.displayName = "MetricCardHeader";
94
+ var MetricCardTitle = React.forwardRef(
95
+ ({ className, ...props }, ref) => {
96
+ const { size } = React.useContext(MetricCardContext);
97
+ return /* @__PURE__ */ React.createElement(
98
+ "p",
99
+ {
100
+ ref,
101
+ className: cn(titleSizes[size], "font-semibold text-text-muted", className),
102
+ ...props
103
+ }
104
+ );
105
+ }
106
+ );
107
+ MetricCardTitle.displayName = "MetricCardTitle";
108
+ var MetricCardValue = React.forwardRef(
109
+ ({ className, children, ...props }, ref) => {
110
+ const { size, animated } = React.useContext(MetricCardContext);
111
+ const [display, setDisplay] = React.useState(children);
112
+ React.useEffect(() => {
113
+ if (!animated || typeof children !== "string") {
114
+ setDisplay(children);
115
+ return;
116
+ }
117
+ const numMatch = children.match(/[\d,.]+/);
118
+ if (!numMatch) {
119
+ setDisplay(children);
120
+ return;
121
+ }
122
+ const numStr = numMatch[0].replace(/,/g, "");
123
+ const target = parseFloat(numStr);
124
+ if (isNaN(target)) {
125
+ setDisplay(children);
126
+ return;
127
+ }
128
+ const prefix = children.slice(0, children.indexOf(numMatch[0]));
129
+ const suffix = children.slice(children.indexOf(numMatch[0]) + numMatch[0].length);
130
+ const steps = 24;
131
+ const duration = 700;
132
+ let step = 0;
133
+ setDisplay(prefix + "0" + suffix);
134
+ const timer = setInterval(() => {
135
+ step++;
136
+ const eased = 1 - Math.pow(1 - step / steps, 3);
137
+ const current = target * eased;
138
+ const formatted = target >= 1e3 ? Math.floor(current).toLocaleString() : current.toFixed(numStr.includes(".") ? 2 : 0);
139
+ setDisplay(prefix + formatted + suffix);
140
+ if (step >= steps) {
141
+ setDisplay(children);
142
+ clearInterval(timer);
143
+ }
144
+ }, duration / steps);
145
+ return () => clearInterval(timer);
146
+ }, [children, animated]);
147
+ return /* @__PURE__ */ React.createElement(
148
+ "p",
149
+ {
150
+ ref,
151
+ className: cn(valueSizes[size], "font-bold text-foreground mt-1", className),
152
+ ...props
153
+ },
154
+ display
155
+ );
156
+ }
157
+ );
158
+ MetricCardValue.displayName = "MetricCardValue";
159
+ var MetricCardTrend = React.forwardRef(
160
+ ({ className, direction, children, ...props }, ref) => {
161
+ const config = trendConfig[direction];
162
+ return /* @__PURE__ */ React.createElement(
163
+ "p",
164
+ {
165
+ ref,
166
+ className: cn("flex items-center gap-1 text-sm mt-2", config.color, className),
167
+ ...props
168
+ },
169
+ direction === "up" && /* @__PURE__ */ React.createElement("svg", { className: "icon-xs", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4.5 15.75l7.5-7.5 7.5 7.5" })),
170
+ direction === "down" && /* @__PURE__ */ React.createElement("svg", { className: "icon-xs", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19.5 8.25l-7.5 7.5-7.5-7.5" })),
171
+ direction === "neutral" && /* @__PURE__ */ React.createElement("svg", { className: "icon-xs", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 12h14" })),
172
+ /* @__PURE__ */ React.createElement("span", { className: "sr-only" }, config.srLabel),
173
+ children
174
+ );
175
+ }
176
+ );
177
+ MetricCardTrend.displayName = "MetricCardTrend";
178
+ var MetricCardDescription = React.forwardRef(
179
+ ({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
180
+ "p",
181
+ {
182
+ ref,
183
+ className: cn("text-xs text-text-muted mt-1", className),
184
+ ...props
185
+ }
186
+ )
187
+ );
188
+ MetricCardDescription.displayName = "MetricCardDescription";
189
+ var MetricCardSymbol = React.forwardRef(
190
+ ({ className, ...props }, ref) => {
191
+ const { size } = React.useContext(MetricCardContext);
192
+ return /* @__PURE__ */ React.createElement(
193
+ "div",
194
+ {
195
+ ref,
196
+ className: cn("text-text-muted", iconWrapperSizes[size], className),
197
+ ...props
198
+ }
199
+ );
200
+ }
201
+ );
202
+ MetricCardSymbol.displayName = "MetricCardSymbol";
203
+
204
+ export {
205
+ metricCardVariants,
206
+ MetricCard,
207
+ MetricCardHeader,
208
+ MetricCardTitle,
209
+ MetricCardValue,
210
+ MetricCardTrend,
211
+ MetricCardDescription,
212
+ MetricCardSymbol
213
+ };
214
+ //# sourceMappingURL=chunk-DYYQOHQR.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/metric-card.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\n// ── CVA Variants ──\n\nconst metricCardVariants = cva(\n 'transition-colors',\n {\n variants: {\n variant: {\n default: 'bg-background-paper border border-border',\n elevated: 'bg-background-paper shadow-md',\n ghost: 'bg-transparent',\n },\n size: {\n sm: 'p-4',\n default: 'p-4 sm:p-5',\n lg: 'p-4 sm:p-6',\n },\n radius: {\n none: 'rounded-none', // 0px\n sm: 'rounded-sm', // 2px\n base: 'rounded', // 4px\n default: 'rounded-xl', // 12px - card default\n lg: 'rounded-lg', // 8px\n xl: 'rounded-xl', // 12px\n '2xl': 'rounded-2xl', // 16px\n '3xl': 'rounded-3xl', // 24px\n full: 'rounded-full', // 9999px\n },\n },\n defaultVariants: { variant: 'default', size: 'default', radius: 'default' },\n }\n)\n\n// ── Size maps ──\n\nconst valueSizes = {\n sm: 'text-xl',\n default: 'text-2xl',\n lg: 'text-3xl',\n} as const\n\nconst titleSizes = {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-sm',\n} as const\n\nconst iconWrapperSizes = {\n sm: '[&>svg]:icon-sm',\n default: '[&>svg]:icon-md',\n lg: '[&>svg]:icon-lg',\n} as const\n\n// ── Trend config ──\n\nconst trendConfig = {\n up: { color: 'text-text-success', srLabel: 'Increased' },\n down: { color: 'text-text-error', srLabel: 'Decreased' },\n neutral: { color: 'text-text-muted', srLabel: 'No change' },\n} as const\n\n// ── Context ──\n\ntype MetricCardContextValue = { size: 'sm' | 'default' | 'lg'; animated: boolean }\nconst MetricCardContext = React.createContext<MetricCardContextValue>({ size: 'default', animated: false })\n\n// ── Types ──\n\nexport type MetricCardVariant = 'default' | 'elevated' | 'ghost'\nexport type MetricCardSize = 'sm' | 'default' | 'lg'\nexport type MetricCardRadius = 'none' | 'sm' | 'base' | 'default' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\nexport type MetricCardTrendDirection = 'up' | 'down' | 'neutral'\n\n// ── MetricCard (root) ──\n\nexport interface MetricCardProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof metricCardVariants> {\n animated?: boolean\n}\n\nconst MetricCard = React.forwardRef<HTMLDivElement, MetricCardProps>(\n ({ className, variant, size, radius, animated = false, children, ...props }, ref) => {\n const resolvedSize = (size || 'default') as MetricCardSize\n return (\n <MetricCardContext.Provider value={{ size: resolvedSize, animated }}>\n <div\n ref={ref}\n className={cn(metricCardVariants({ variant, size, radius }), className)}\n {...props}\n >\n {children}\n </div>\n </MetricCardContext.Provider>\n )\n }\n)\nMetricCard.displayName = 'MetricCard'\n\n// ── MetricCardHeader ──\n\nexport interface MetricCardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst MetricCardHeader = React.forwardRef<HTMLDivElement, MetricCardHeaderProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center justify-between gap-2', className)}\n {...props}\n />\n )\n)\nMetricCardHeader.displayName = 'MetricCardHeader'\n\n// ── MetricCardTitle ──\n\nexport interface MetricCardTitleProps extends React.HTMLAttributes<HTMLParagraphElement> {}\n\nconst MetricCardTitle = React.forwardRef<HTMLParagraphElement, MetricCardTitleProps>(\n ({ className, ...props }, ref) => {\n const { size } = React.useContext(MetricCardContext)\n return (\n <p\n ref={ref}\n className={cn(titleSizes[size], 'font-semibold text-text-muted', className)}\n {...props}\n />\n )\n }\n)\nMetricCardTitle.displayName = 'MetricCardTitle'\n\n// ── MetricCardValue ──\n\nexport interface MetricCardValueProps extends React.HTMLAttributes<HTMLParagraphElement> {}\n\nconst MetricCardValue = React.forwardRef<HTMLParagraphElement, MetricCardValueProps>(\n ({ className, children, ...props }, ref) => {\n const { size, animated } = React.useContext(MetricCardContext)\n const [display, setDisplay] = React.useState<React.ReactNode>(children)\n\n React.useEffect(() => {\n if (!animated || typeof children !== 'string') { setDisplay(children); return }\n const numMatch = children.match(/[\\d,.]+/)\n if (!numMatch) { setDisplay(children); return }\n const numStr = numMatch[0].replace(/,/g, '')\n const target = parseFloat(numStr)\n if (isNaN(target)) { setDisplay(children); return }\n const prefix = children.slice(0, children.indexOf(numMatch[0]))\n const suffix = children.slice(children.indexOf(numMatch[0]) + numMatch[0].length)\n const steps = 24\n const duration = 700\n let step = 0\n setDisplay(prefix + '0' + suffix)\n const timer = setInterval(() => {\n step++\n const eased = 1 - Math.pow(1 - step / steps, 3)\n const current = target * eased\n const formatted = target >= 1000\n ? Math.floor(current).toLocaleString()\n : current.toFixed(numStr.includes('.') ? 2 : 0)\n setDisplay(prefix + formatted + suffix)\n if (step >= steps) { setDisplay(children); clearInterval(timer) }\n }, duration / steps)\n return () => clearInterval(timer)\n }, [children, animated])\n\n return (\n <p\n ref={ref}\n className={cn(valueSizes[size], 'font-bold text-foreground mt-1', className)}\n {...props}\n >\n {display}\n </p>\n )\n }\n)\nMetricCardValue.displayName = 'MetricCardValue'\n\n// ── MetricCardTrend ──\n\nexport interface MetricCardTrendProps extends React.HTMLAttributes<HTMLParagraphElement> {\n direction: MetricCardTrendDirection\n}\n\nconst MetricCardTrend = React.forwardRef<HTMLParagraphElement, MetricCardTrendProps>(\n ({ className, direction, children, ...props }, ref) => {\n const config = trendConfig[direction]\n return (\n <p\n ref={ref}\n className={cn('flex items-center gap-1 text-sm mt-2', config.color, className)}\n {...props}\n >\n {direction === 'up' && (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.5} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4.5 15.75l7.5-7.5 7.5 7.5\" />\n </svg>\n )}\n {direction === 'down' && (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.5} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 8.25l-7.5 7.5-7.5-7.5\" />\n </svg>\n )}\n {direction === 'neutral' && (\n <svg className=\"icon-xs\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2.5} aria-hidden=\"true\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 12h14\" />\n </svg>\n )}\n <span className=\"sr-only\">{config.srLabel}</span>\n {children}\n </p>\n )\n }\n)\nMetricCardTrend.displayName = 'MetricCardTrend'\n\n// ── MetricCardDescription ──\n\nexport interface MetricCardDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {}\n\nconst MetricCardDescription = React.forwardRef<HTMLParagraphElement, MetricCardDescriptionProps>(\n ({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn('text-xs text-text-muted mt-1', className)}\n {...props}\n />\n )\n)\nMetricCardDescription.displayName = 'MetricCardDescription'\n\n// ── MetricCardSymbol ──\n\nexport interface MetricCardSymbolProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst MetricCardSymbol = React.forwardRef<HTMLDivElement, MetricCardSymbolProps>(\n ({ className, ...props }, ref) => {\n const { size } = React.useContext(MetricCardContext)\n return (\n <div\n ref={ref}\n className={cn('text-text-muted', iconWrapperSizes[size], className)}\n {...props}\n />\n )\n }\n)\nMetricCardSymbol.displayName = 'MetricCardSymbol'\n\n// ── Exports ──\nexport {\n MetricCard,\n MetricCardHeader,\n MetricCardTitle,\n MetricCardValue,\n MetricCardTrend,\n MetricCardDescription,\n MetricCardSymbol,\n metricCardVariants,\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,93 @@
1
+ "use client";
2
+ import {
3
+ cn
4
+ } from "./chunk-53MIUPSY.mjs";
5
+
6
+ // src/components/ui/tooltip.tsx
7
+ import * as React from "react";
8
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
9
+ import { cva } from "class-variance-authority";
10
+ var ANIMATION_CLASSES = {
11
+ top: "data-[state=delayed-open]:animate-tooltip-top-enter data-[state=instant-open]:animate-tooltip-top-enter data-[state=closed]:animate-tooltip-top-exit",
12
+ bottom: "data-[state=delayed-open]:animate-tooltip-bottom-enter data-[state=instant-open]:animate-tooltip-bottom-enter data-[state=closed]:animate-tooltip-bottom-exit",
13
+ left: "data-[state=delayed-open]:animate-tooltip-left-enter data-[state=instant-open]:animate-tooltip-left-enter data-[state=closed]:animate-tooltip-left-exit",
14
+ right: "data-[state=delayed-open]:animate-tooltip-right-enter data-[state=instant-open]:animate-tooltip-right-enter data-[state=closed]:animate-tooltip-right-exit"
15
+ };
16
+ var tooltipContentVariants = cva(
17
+ "z-tooltip rounded-lg font-normal select-none max-w-72",
18
+ {
19
+ variants: {
20
+ variant: {
21
+ default: "bg-foreground text-background shadow-lg",
22
+ inverted: "bg-background-paper/95 text-foreground border border-border-subtle shadow-lg backdrop-blur-sm"
23
+ },
24
+ size: {
25
+ sm: "text-xs px-2.5 py-1",
26
+ default: "text-sm px-3 py-1.5"
27
+ }
28
+ },
29
+ defaultVariants: {
30
+ variant: "default",
31
+ size: "default"
32
+ }
33
+ }
34
+ );
35
+ var ARROW_FILL = {
36
+ default: "fill-foreground drop-shadow-sm",
37
+ inverted: "fill-background-paper drop-shadow-sm"
38
+ };
39
+ var TooltipProvider = TooltipPrimitive.Provider;
40
+ function Tooltip({ delayDuration = 200, ...props }) {
41
+ return /* @__PURE__ */ React.createElement(TooltipPrimitive.Root, { delayDuration, ...props });
42
+ }
43
+ var TooltipTrigger = TooltipPrimitive.Trigger;
44
+ var TooltipPortal = TooltipPrimitive.Portal;
45
+ var TooltipContent = React.forwardRef(({ className, variant = "default", size, side = "top", sideOffset = 6, showArrow = true, children, ...props }, ref) => {
46
+ const resolvedSide = side;
47
+ return /* @__PURE__ */ React.createElement(TooltipPrimitive.Portal, null, /* @__PURE__ */ React.createElement(
48
+ TooltipPrimitive.Content,
49
+ {
50
+ ref,
51
+ side,
52
+ sideOffset,
53
+ className: cn(
54
+ tooltipContentVariants({ variant, size }),
55
+ ANIMATION_CLASSES[resolvedSide],
56
+ className
57
+ ),
58
+ ...props
59
+ },
60
+ children,
61
+ showArrow && /* @__PURE__ */ React.createElement(
62
+ TooltipPrimitive.Arrow,
63
+ {
64
+ className: ARROW_FILL[variant || "default"],
65
+ width: 10,
66
+ height: 5
67
+ }
68
+ )
69
+ ));
70
+ });
71
+ TooltipContent.displayName = "TooltipContent";
72
+ var TooltipArrow = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
73
+ TooltipPrimitive.Arrow,
74
+ {
75
+ ref,
76
+ className: cn("fill-foreground", className),
77
+ width: 8,
78
+ height: 4,
79
+ ...props
80
+ }
81
+ ));
82
+ TooltipArrow.displayName = "TooltipArrow";
83
+
84
+ export {
85
+ tooltipContentVariants,
86
+ TooltipProvider,
87
+ Tooltip,
88
+ TooltipTrigger,
89
+ TooltipPortal,
90
+ TooltipContent,
91
+ TooltipArrow
92
+ };
93
+ //# sourceMappingURL=chunk-FHUAH6AJ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/tooltip.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\n// ─── Types ──────────────────────────────────────────────────\nexport type TooltipSide = 'top' | 'right' | 'bottom' | 'left'\n\n// ─── Animation class mapping (static strings for Tailwind scanner) ──\nconst ANIMATION_CLASSES: Record<TooltipSide, string> = {\n top: 'data-[state=delayed-open]:animate-tooltip-top-enter data-[state=instant-open]:animate-tooltip-top-enter data-[state=closed]:animate-tooltip-top-exit',\n bottom: 'data-[state=delayed-open]:animate-tooltip-bottom-enter data-[state=instant-open]:animate-tooltip-bottom-enter data-[state=closed]:animate-tooltip-bottom-exit',\n left: 'data-[state=delayed-open]:animate-tooltip-left-enter data-[state=instant-open]:animate-tooltip-left-enter data-[state=closed]:animate-tooltip-left-exit',\n right: 'data-[state=delayed-open]:animate-tooltip-right-enter data-[state=instant-open]:animate-tooltip-right-enter data-[state=closed]:animate-tooltip-right-exit',\n}\n\n// ─── Content variants ────────────────────────────────────────\nconst tooltipContentVariants = cva(\n 'z-tooltip rounded-lg font-normal select-none max-w-72',\n {\n variants: {\n variant: {\n default: 'bg-foreground text-background shadow-lg',\n inverted: 'bg-background-paper/95 text-foreground border border-border-subtle shadow-lg backdrop-blur-sm',\n },\n size: {\n sm: 'text-xs px-2.5 py-1',\n default: 'text-sm px-3 py-1.5',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n)\n\n// ─── Arrow fill mapping (matches content variant background) ──\nconst ARROW_FILL: Record<string, string> = {\n default: 'fill-foreground drop-shadow-sm',\n inverted: 'fill-background-paper drop-shadow-sm',\n}\n\n// ═══════════════════════════════════════════════════════════════\n// Tooltip\n// ═══════════════════════════════════════════════════════════════\n\n// ─── TooltipProvider ─────────────────────────────────────────\nconst TooltipProvider = TooltipPrimitive.Provider\n\n// ─── Tooltip (Root) — Props type ──\nexport interface TooltipRootProps extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root> {\n /** Delay in ms before tooltip appears */\n delayDuration?: number\n}\n\n// ─── Tooltip (Root) — thin wrapper to expose as named export with default delayDuration ──\nfunction Tooltip({ delayDuration = 200, ...props }: TooltipRootProps) {\n return <TooltipPrimitive.Root delayDuration={delayDuration} {...props} />\n}\n\n// ─── TooltipTrigger ──────────────────────────────────────────\nconst TooltipTrigger = TooltipPrimitive.Trigger\n\n// ─── TooltipPortal ───────────────────────────────────────────\nconst TooltipPortal = TooltipPrimitive.Portal\n\n// ─── TooltipContent ──────────────────────────────────────────\nexport interface TooltipContentProps\n extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>,\n VariantProps<typeof tooltipContentVariants> {\n /** Show arrow pointing to trigger */\n showArrow?: boolean\n}\n\nconst TooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n TooltipContentProps\n>(({ className, variant = 'default', size, side = 'top', sideOffset = 6, showArrow = true, children, ...props }, ref) => {\n const resolvedSide = side as TooltipSide\n\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n side={side}\n sideOffset={sideOffset}\n className={cn(\n tooltipContentVariants({ variant, size }),\n ANIMATION_CLASSES[resolvedSide],\n className,\n )}\n {...props}\n >\n {children}\n {showArrow && (\n <TooltipPrimitive.Arrow\n className={ARROW_FILL[variant || 'default']}\n width={10}\n height={5}\n />\n )}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n})\nTooltipContent.displayName = 'TooltipContent'\n\n// ─── TooltipArrow (standalone, for manual placement outside Content) ──\nconst TooltipArrow = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Arrow>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Arrow>\n>(({ className, ...props }, ref) => (\n <TooltipPrimitive.Arrow\n ref={ref}\n className={cn('fill-foreground', className)}\n width={8}\n height={4}\n {...props}\n />\n))\nTooltipArrow.displayName = 'TooltipArrow'\n\n// ─── Exports ────────────────────────────────────────────────\nexport {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n TooltipArrow,\n TooltipPortal,\n TooltipProvider,\n tooltipContentVariants,\n}\n"],"mappings":";;;;;;AAEA,YAAY,WAAW;AACvB,YAAY,sBAAsB;AAClC,SAAS,WAA8B;AAOvC,IAAM,oBAAiD;AAAA,EACrD,KAAQ;AAAA,EACR,QAAQ;AAAA,EACR,MAAQ;AAAA,EACR,OAAQ;AACV;AAGA,IAAM,yBAAyB;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAAA,MACA,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,SAAS;AAAA,MACX;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAGA,IAAM,aAAqC;AAAA,EACzC,SAAS;AAAA,EACT,UAAU;AACZ;AAOA,IAAM,kBAAmC;AASzC,SAAS,QAAQ,EAAE,gBAAgB,KAAK,GAAG,MAAM,GAAqB;AACpE,SAAO,oCAAkB,uBAAjB,EAAsB,eAA+B,GAAG,OAAO;AACzE;AAGA,IAAM,iBAAkC;AAGxC,IAAM,gBAAiC;AAUvC,IAAM,iBAAuB,iBAG3B,CAAC,EAAE,WAAW,UAAU,WAAW,MAAM,OAAO,OAAO,aAAa,GAAG,YAAY,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ;AACvH,QAAM,eAAe;AAErB,SACE,oCAAkB,yBAAjB,MACC;AAAA,IAAkB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT,uBAAuB,EAAE,SAAS,KAAK,CAAC;AAAA,QACxC,kBAAkB,YAAY;AAAA,QAC9B;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,IAEH;AAAA,IACA,aACC;AAAA,MAAkB;AAAA,MAAjB;AAAA,QACC,WAAW,WAAW,WAAW,SAAS;AAAA,QAC1C,OAAO;AAAA,QACP,QAAQ;AAAA;AAAA,IACV;AAAA,EAEJ,CACF;AAEJ,CAAC;AACD,eAAe,cAAc;AAG7B,IAAM,eAAqB,iBAGzB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B;AAAA,EAAkB;AAAA,EAAjB;AAAA,IACC;AAAA,IACA,WAAW,GAAG,mBAAmB,SAAS;AAAA,IAC1C,OAAO;AAAA,IACP,QAAQ;AAAA,IACP,GAAG;AAAA;AACN,CACD;AACD,aAAa,cAAc;","names":[]}
@@ -0,0 +1,209 @@
1
+ "use client";
2
+ import {
3
+ cn
4
+ } from "./chunk-53MIUPSY.mjs";
5
+
6
+ // src/components/ui/avatar.tsx
7
+ import * as React from "react";
8
+ import * as AvatarPrimitive from "@radix-ui/react-avatar";
9
+ import { cva } from "class-variance-authority";
10
+ var avatarVariants = cva(
11
+ "relative inline-flex items-center justify-center overflow-hidden bg-background-muted select-none",
12
+ {
13
+ variants: {
14
+ size: {
15
+ xs: "w-6 h-6",
16
+ // 24px
17
+ sm: "w-8 h-8",
18
+ // 32px
19
+ default: "w-10 h-10",
20
+ // 40px
21
+ lg: "w-12 h-12",
22
+ // 48px
23
+ xl: "w-16 h-16",
24
+ // 64px
25
+ "2xl": "w-20 h-20"
26
+ // 80px
27
+ },
28
+ shape: {
29
+ circle: "rounded-full",
30
+ square: "rounded-xl"
31
+ }
32
+ },
33
+ defaultVariants: { size: "default", shape: "circle" }
34
+ }
35
+ );
36
+ var statusDotSizes = {
37
+ xs: "w-1.5 h-1.5",
38
+ sm: "w-2 h-2",
39
+ default: "w-2.5 h-2.5",
40
+ lg: "w-3 h-3",
41
+ xl: "w-3.5 h-3.5",
42
+ "2xl": "w-4 h-4"
43
+ };
44
+ var statusColors = {
45
+ online: "bg-success",
46
+ offline: "bg-text-muted",
47
+ busy: "bg-error",
48
+ away: "bg-warning"
49
+ };
50
+ var fallbackFontSizes = {
51
+ xs: "text-2xs",
52
+ sm: "text-xs",
53
+ default: "text-sm",
54
+ lg: "text-base",
55
+ xl: "text-xl",
56
+ "2xl": "text-2xl"
57
+ };
58
+ var groupNegativeMargins = {
59
+ xs: "-space-x-1.5",
60
+ sm: "-space-x-2",
61
+ default: "-space-x-2.5",
62
+ lg: "-space-x-3",
63
+ xl: "-space-x-4",
64
+ "2xl": "-space-x-5"
65
+ };
66
+ var avatarColors = [
67
+ { vivid: { bg: "bg-[#DC2626]", text: "text-white" }, soft: { bg: "bg-[#FEE2E2]", text: "text-[#DC2626]" } },
68
+ // red
69
+ { vivid: { bg: "bg-[#EA580C]", text: "text-white" }, soft: { bg: "bg-[#FFEDD5]", text: "text-[#EA580C]" } },
70
+ // orange
71
+ { vivid: { bg: "bg-[#D97706]", text: "text-white" }, soft: { bg: "bg-[#FEF3C7]", text: "text-[#B45309]" } },
72
+ // amber
73
+ { vivid: { bg: "bg-[#CA8A04]", text: "text-white" }, soft: { bg: "bg-[#FEF9C3]", text: "text-[#A16207]" } },
74
+ // yellow
75
+ { vivid: { bg: "bg-[#059669]", text: "text-white" }, soft: { bg: "bg-[#D1FAE5]", text: "text-[#047857]" } },
76
+ // emerald
77
+ { vivid: { bg: "bg-[#0D9488]", text: "text-white" }, soft: { bg: "bg-[#CCFBF1]", text: "text-[#0F766E]" } },
78
+ // teal
79
+ { vivid: { bg: "bg-[#0891B2]", text: "text-white" }, soft: { bg: "bg-[#CFFAFE]", text: "text-[#0E7490]" } },
80
+ // cyan
81
+ { vivid: { bg: "bg-[#2563EB]", text: "text-white" }, soft: { bg: "bg-[#DBEAFE]", text: "text-[#1D4ED8]" } },
82
+ // blue
83
+ { vivid: { bg: "bg-[#4F46E5]", text: "text-white" }, soft: { bg: "bg-[#E0E7FF]", text: "text-[#4338CA]" } },
84
+ // indigo
85
+ { vivid: { bg: "bg-[#7C3AED]", text: "text-white" }, soft: { bg: "bg-[#EDE9FE]", text: "text-[#6D28D9]" } },
86
+ // violet
87
+ { vivid: { bg: "bg-[#9333EA]", text: "text-white" }, soft: { bg: "bg-[#F3E8FF]", text: "text-[#7E22CE]" } },
88
+ // purple
89
+ { vivid: { bg: "bg-[#DB2777]", text: "text-white" }, soft: { bg: "bg-[#FCE7F3]", text: "text-[#BE185D]" } }
90
+ // pink
91
+ ];
92
+ function getAvatarInitials(name, maxChars = 2) {
93
+ const trimmed = name.trim();
94
+ if (!trimmed) return "";
95
+ const cjkRegex = /[\u3000-\u9fff\uac00-\ud7af\uff00-\uffef]/;
96
+ if (cjkRegex.test(trimmed.charAt(0))) {
97
+ return trimmed.slice(0, maxChars);
98
+ }
99
+ const parts = trimmed.split(/[\s\-_.]+/).filter(Boolean);
100
+ if (parts.length === 1) {
101
+ return parts[0].charAt(0).toUpperCase();
102
+ }
103
+ return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase().slice(0, maxChars);
104
+ }
105
+ function getAvatarColor(name, variant = "vivid") {
106
+ let hash = 5381;
107
+ for (let i = 0; i < name.length; i++) {
108
+ hash = (hash << 5) + hash ^ name.charCodeAt(i);
109
+ }
110
+ return avatarColors[(hash >>> 0) % avatarColors.length][variant];
111
+ }
112
+ var Avatar = React.forwardRef(({ className, size, shape, status, children, ...props }, ref) => {
113
+ const resolvedSize = size || "default";
114
+ if (!status) {
115
+ return /* @__PURE__ */ React.createElement(
116
+ AvatarPrimitive.Root,
117
+ {
118
+ ref,
119
+ className: cn(avatarVariants({ size, shape }), className),
120
+ ...props
121
+ },
122
+ children
123
+ );
124
+ }
125
+ return /* @__PURE__ */ React.createElement("span", { className: "relative inline-flex" }, /* @__PURE__ */ React.createElement(
126
+ AvatarPrimitive.Root,
127
+ {
128
+ ref,
129
+ className: cn(avatarVariants({ size, shape }), className),
130
+ ...props
131
+ },
132
+ children
133
+ ), /* @__PURE__ */ React.createElement(
134
+ "span",
135
+ {
136
+ className: cn(
137
+ "absolute bottom-0 right-0 rounded-full ring-2 ring-background",
138
+ statusDotSizes[resolvedSize],
139
+ statusColors[status]
140
+ )
141
+ }
142
+ ));
143
+ });
144
+ Avatar.displayName = "Avatar";
145
+ var AvatarImage = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
146
+ AvatarPrimitive.Image,
147
+ {
148
+ ref,
149
+ className: cn("object-cover w-full h-full", className),
150
+ ...props
151
+ }
152
+ ));
153
+ AvatarImage.displayName = "AvatarImage";
154
+ var AvatarFallback = React.forwardRef(({ className, size, name, colorized, colorVariant = "vivid", children, ...props }, ref) => {
155
+ const resolvedSize = size || "default";
156
+ const colorKey = name || colorized;
157
+ const color = colorKey ? getAvatarColor(colorKey, colorVariant) : null;
158
+ const resolvedChildren = children ?? (name ? getAvatarInitials(name) : void 0);
159
+ return /* @__PURE__ */ React.createElement(
160
+ AvatarPrimitive.Fallback,
161
+ {
162
+ ref,
163
+ className: cn(
164
+ "flex items-center justify-center w-full h-full font-semibold",
165
+ color ? [color.bg, color.text] : "bg-background-muted text-text-muted",
166
+ fallbackFontSizes[resolvedSize],
167
+ className
168
+ ),
169
+ ...props
170
+ },
171
+ resolvedChildren
172
+ );
173
+ });
174
+ AvatarFallback.displayName = "AvatarFallback";
175
+ var AvatarGroup = React.forwardRef(
176
+ ({ className, max, size = "default", shape = "circle", children, ...props }, ref) => {
177
+ const childArray = React.Children.toArray(children);
178
+ const visibleChildren = max ? childArray.slice(0, max) : childArray;
179
+ const overflowCount = max ? childArray.length - max : 0;
180
+ return /* @__PURE__ */ React.createElement(
181
+ "div",
182
+ {
183
+ ref,
184
+ className: cn(
185
+ "flex items-center",
186
+ groupNegativeMargins[size],
187
+ "[&>*]:ring-2 [&>*]:ring-background",
188
+ className
189
+ ),
190
+ ...props
191
+ },
192
+ visibleChildren,
193
+ overflowCount > 0 && /* @__PURE__ */ React.createElement(Avatar, { size, shape }, /* @__PURE__ */ React.createElement(AvatarFallback, { size }, "+", overflowCount))
194
+ );
195
+ }
196
+ );
197
+ AvatarGroup.displayName = "AvatarGroup";
198
+
199
+ export {
200
+ avatarVariants,
201
+ avatarColors,
202
+ getAvatarInitials,
203
+ getAvatarColor,
204
+ Avatar,
205
+ AvatarImage,
206
+ AvatarFallback,
207
+ AvatarGroup
208
+ };
209
+ //# sourceMappingURL=chunk-GD4YE5AE.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/avatar.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as AvatarPrimitive from '@radix-ui/react-avatar'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\n// Avatar root variants\nconst avatarVariants = cva(\n 'relative inline-flex items-center justify-center overflow-hidden bg-background-muted select-none',\n {\n variants: {\n size: {\n xs: 'w-6 h-6', // 24px\n sm: 'w-8 h-8', // 32px\n default: 'w-10 h-10', // 40px\n lg: 'w-12 h-12', // 48px\n xl: 'w-16 h-16', // 64px\n '2xl': 'w-20 h-20', // 80px\n },\n shape: {\n circle: 'rounded-full',\n square: 'rounded-xl',\n },\n },\n defaultVariants: { size: 'default', shape: 'circle' },\n }\n)\n\n// Status dot sizes per avatar size\nconst statusDotSizes = {\n xs: 'w-1.5 h-1.5',\n sm: 'w-2 h-2',\n default: 'w-2.5 h-2.5',\n lg: 'w-3 h-3',\n xl: 'w-3.5 h-3.5',\n '2xl': 'w-4 h-4',\n}\n\n// Status dot colors\nconst statusColors = {\n online: 'bg-success',\n offline: 'bg-text-muted',\n busy: 'bg-error',\n away: 'bg-warning',\n}\n\n// Fallback font sizes per avatar size\nconst fallbackFontSizes = {\n xs: 'text-2xs',\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-base',\n xl: 'text-xl',\n '2xl': 'text-2xl',\n}\n\n// Negative margin per size for AvatarGroup overlap\nconst groupNegativeMargins = {\n xs: '-space-x-1.5',\n sm: '-space-x-2',\n default: '-space-x-2.5',\n lg: '-space-x-3',\n xl: '-space-x-4',\n '2xl': '-space-x-5',\n}\n\n// Colorized fallback palette (12 colors × 2 variants) — exception 13 in TOKEN-EXCEPTIONS.md\nconst avatarColors = [\n { vivid: { bg: 'bg-[#DC2626]', text: 'text-white' }, soft: { bg: 'bg-[#FEE2E2]', text: 'text-[#DC2626]' } }, // red\n { vivid: { bg: 'bg-[#EA580C]', text: 'text-white' }, soft: { bg: 'bg-[#FFEDD5]', text: 'text-[#EA580C]' } }, // orange\n { vivid: { bg: 'bg-[#D97706]', text: 'text-white' }, soft: { bg: 'bg-[#FEF3C7]', text: 'text-[#B45309]' } }, // amber\n { vivid: { bg: 'bg-[#CA8A04]', text: 'text-white' }, soft: { bg: 'bg-[#FEF9C3]', text: 'text-[#A16207]' } }, // yellow\n { vivid: { bg: 'bg-[#059669]', text: 'text-white' }, soft: { bg: 'bg-[#D1FAE5]', text: 'text-[#047857]' } }, // emerald\n { vivid: { bg: 'bg-[#0D9488]', text: 'text-white' }, soft: { bg: 'bg-[#CCFBF1]', text: 'text-[#0F766E]' } }, // teal\n { vivid: { bg: 'bg-[#0891B2]', text: 'text-white' }, soft: { bg: 'bg-[#CFFAFE]', text: 'text-[#0E7490]' } }, // cyan\n { vivid: { bg: 'bg-[#2563EB]', text: 'text-white' }, soft: { bg: 'bg-[#DBEAFE]', text: 'text-[#1D4ED8]' } }, // blue\n { vivid: { bg: 'bg-[#4F46E5]', text: 'text-white' }, soft: { bg: 'bg-[#E0E7FF]', text: 'text-[#4338CA]' } }, // indigo\n { vivid: { bg: 'bg-[#7C3AED]', text: 'text-white' }, soft: { bg: 'bg-[#EDE9FE]', text: 'text-[#6D28D9]' } }, // violet\n { vivid: { bg: 'bg-[#9333EA]', text: 'text-white' }, soft: { bg: 'bg-[#F3E8FF]', text: 'text-[#7E22CE]' } }, // purple\n { vivid: { bg: 'bg-[#DB2777]', text: 'text-white' }, soft: { bg: 'bg-[#FCE7F3]', text: 'text-[#BE185D]' } }, // pink\n] as const\n\nexport type AvatarColorVariant = 'vivid' | 'soft'\n\n/** Extract initials from a name string (e.g. \"John Doe\" → \"JD\", \"김민수\" → \"김민\") */\nfunction getAvatarInitials(name: string, maxChars = 2): string {\n const trimmed = name.trim()\n if (!trimmed) return ''\n\n // CJK: use first character(s) directly\n const cjkRegex = /[\\u3000-\\u9fff\\uac00-\\ud7af\\uff00-\\uffef]/\n if (cjkRegex.test(trimmed.charAt(0))) {\n return trimmed.slice(0, maxChars)\n }\n\n // Split on spaces, hyphens, underscores, dots\n const parts = trimmed.split(/[\\s\\-_.]+/).filter(Boolean)\n if (parts.length === 1) {\n return parts[0].charAt(0).toUpperCase()\n }\n\n // First + last part initials\n return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0))\n .toUpperCase()\n .slice(0, maxChars)\n}\n\n/** Hash a name string to a deterministic avatar color pair (djb2 xor variant) */\nfunction getAvatarColor(name: string, variant: AvatarColorVariant = 'vivid') {\n let hash = 5381\n for (let i = 0; i < name.length; i++) {\n hash = ((hash << 5) + hash) ^ name.charCodeAt(i)\n }\n return avatarColors[(hash >>> 0) % avatarColors.length][variant]\n}\n\nexport type AvatarSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl' | '2xl'\nexport type AvatarShape = 'circle' | 'square'\nexport type AvatarStatus = 'online' | 'offline' | 'busy' | 'away'\n\nexport interface AvatarProps\n extends React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>,\n VariantProps<typeof avatarVariants> {\n status?: AvatarStatus\n}\n\nconst Avatar = React.forwardRef<\n React.ElementRef<typeof AvatarPrimitive.Root>,\n AvatarProps\n>(({ className, size, shape, status, children, ...props }, ref) => {\n const resolvedSize = size || 'default'\n\n if (!status) {\n return (\n <AvatarPrimitive.Root\n ref={ref}\n className={cn(avatarVariants({ size, shape }), className)}\n {...props}\n >\n {children}\n </AvatarPrimitive.Root>\n )\n }\n\n // Wrap with an outer span so the status dot is not clipped by overflow-hidden\n return (\n <span className=\"relative inline-flex\">\n <AvatarPrimitive.Root\n ref={ref}\n className={cn(avatarVariants({ size, shape }), className)}\n {...props}\n >\n {children}\n </AvatarPrimitive.Root>\n <span\n className={cn(\n 'absolute bottom-0 right-0 rounded-full ring-2 ring-background',\n statusDotSizes[resolvedSize],\n statusColors[status]\n )}\n />\n </span>\n )\n})\nAvatar.displayName = 'Avatar'\n\nexport interface AvatarImageProps\n extends React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image> {}\n\nconst AvatarImage = React.forwardRef<\n React.ElementRef<typeof AvatarPrimitive.Image>,\n AvatarImageProps\n>(({ className, ...props }, ref) => (\n <AvatarPrimitive.Image\n ref={ref}\n className={cn('object-cover w-full h-full', className)}\n {...props}\n />\n))\nAvatarImage.displayName = 'AvatarImage'\n\nexport interface AvatarFallbackProps\n extends React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback> {\n size?: AvatarSize\n /** Shorthand: auto-generates initials + color from a name. Children override auto-initials. */\n name?: string\n /** Pass a name/key to enable colorized mode. The string is hashed to pick a deterministic color. */\n colorized?: string\n /** Color style: \"vivid\" (strong bg + white text) or \"soft\" (pastel bg + dark text). Default: \"vivid\" */\n colorVariant?: AvatarColorVariant\n}\n\nconst AvatarFallback = React.forwardRef<\n React.ElementRef<typeof AvatarPrimitive.Fallback>,\n AvatarFallbackProps\n>(({ className, size, name, colorized, colorVariant = 'vivid', children, ...props }, ref) => {\n const resolvedSize = size || 'default'\n const colorKey = name || colorized\n const color = colorKey ? getAvatarColor(colorKey, colorVariant) : null\n const resolvedChildren = children ?? (name ? getAvatarInitials(name) : undefined)\n return (\n <AvatarPrimitive.Fallback\n ref={ref}\n className={cn(\n 'flex items-center justify-center w-full h-full font-semibold',\n color ? [color.bg, color.text] : 'bg-background-muted text-text-muted',\n fallbackFontSizes[resolvedSize],\n className\n )}\n {...props}\n >\n {resolvedChildren}\n </AvatarPrimitive.Fallback>\n )\n})\nAvatarFallback.displayName = 'AvatarFallback'\n\nexport interface AvatarGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n max?: number\n size?: AvatarSize\n shape?: AvatarShape\n}\n\nconst AvatarGroup = React.forwardRef<HTMLDivElement, AvatarGroupProps>(\n ({ className, max, size = 'default', shape = 'circle', children, ...props }, ref) => {\n const childArray = React.Children.toArray(children)\n const visibleChildren = max ? childArray.slice(0, max) : childArray\n const overflowCount = max ? childArray.length - max : 0\n\n return (\n <div\n ref={ref}\n className={cn(\n 'flex items-center',\n groupNegativeMargins[size],\n '[&>*]:ring-2 [&>*]:ring-background',\n className\n )}\n {...props}\n >\n {visibleChildren}\n {overflowCount > 0 && (\n <Avatar size={size} shape={shape}>\n <AvatarFallback size={size}>+{overflowCount}</AvatarFallback>\n </Avatar>\n )}\n </div>\n )\n }\n)\nAvatarGroup.displayName = 'AvatarGroup'\n\nexport { Avatar, AvatarImage, AvatarFallback, AvatarGroup, avatarVariants, avatarColors, getAvatarColor, getAvatarInitials }\n"],"mappings":"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","names":[]}