@mbao01/common 0.8.1 → 0.9.0

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 (269) hide show
  1. package/dist/types/components/ActivityFeed/ActivityFeed.d.ts +6 -0
  2. package/dist/types/components/ActivityFeed/constants.d.ts +6 -0
  3. package/dist/types/components/ActivityFeed/index.d.ts +2 -0
  4. package/dist/types/components/ActivityFeed/types.d.ts +21 -0
  5. package/dist/types/components/Amount/Amount.d.ts +6 -0
  6. package/dist/types/components/Amount/index.d.ts +2 -0
  7. package/dist/types/components/Amount/types.d.ts +19 -0
  8. package/dist/types/components/AnimatedCounter/AnimatedCounter.d.ts +6 -0
  9. package/dist/types/components/AnimatedCounter/index.d.ts +2 -0
  10. package/dist/types/components/AnimatedCounter/types.d.ts +13 -0
  11. package/dist/types/components/AnimatedGroup/AnimatedGroup.d.ts +6 -0
  12. package/dist/types/components/AnimatedGroup/index.d.ts +2 -0
  13. package/dist/types/components/AnimatedGroup/types.d.ts +22 -0
  14. package/dist/types/components/AnimatedList/AnimatedList.d.ts +6 -0
  15. package/dist/types/components/AnimatedList/index.d.ts +2 -0
  16. package/dist/types/components/AnimatedList/types.d.ts +13 -0
  17. package/dist/types/components/BorderBeam/BorderBeam.d.ts +6 -0
  18. package/dist/types/components/BorderBeam/index.d.ts +2 -0
  19. package/dist/types/components/BorderBeam/types.d.ts +13 -0
  20. package/dist/types/components/Box/Box.d.ts +4 -0
  21. package/dist/types/components/Box/constants.d.ts +4 -0
  22. package/dist/types/components/CalendarHeatmap/CalendarHeatmap.d.ts +6 -0
  23. package/dist/types/components/CalendarHeatmap/index.d.ts +2 -0
  24. package/dist/types/components/CalendarHeatmap/types.d.ts +25 -0
  25. package/dist/types/components/Chart/stories/examples/AreaChart.d.ts +6 -0
  26. package/dist/types/components/Chart/stories/examples/BarChart.d.ts +11 -0
  27. package/dist/types/components/Chart/stories/examples/LineChart.d.ts +10 -0
  28. package/dist/types/components/Chart/stories/examples/PieChart.d.ts +5 -0
  29. package/dist/types/components/Chart/stories/examples/RadialChart.d.ts +5 -0
  30. package/dist/types/components/CircularProgress/CircularProgress.d.ts +6 -0
  31. package/dist/types/components/CircularProgress/constants.d.ts +5 -0
  32. package/dist/types/components/CircularProgress/index.d.ts +2 -0
  33. package/dist/types/components/CircularProgress/types.d.ts +17 -0
  34. package/dist/types/components/ComparisonBar/ComparisonBar.d.ts +6 -0
  35. package/dist/types/components/ComparisonBar/constants.d.ts +4 -0
  36. package/dist/types/components/ComparisonBar/index.d.ts +2 -0
  37. package/dist/types/components/ComparisonBar/types.d.ts +21 -0
  38. package/dist/types/components/Confetti/Confetti.d.ts +6 -0
  39. package/dist/types/components/Confetti/index.d.ts +2 -0
  40. package/dist/types/components/Confetti/types.d.ts +19 -0
  41. package/dist/types/components/CountdownTimer/CountdownTimer.d.ts +6 -0
  42. package/dist/types/components/CountdownTimer/index.d.ts +2 -0
  43. package/dist/types/components/CountdownTimer/types.d.ts +13 -0
  44. package/dist/types/components/DataList/DataList.d.ts +6 -0
  45. package/dist/types/components/DataList/constants.d.ts +12 -0
  46. package/dist/types/components/DataList/index.d.ts +2 -0
  47. package/dist/types/components/DataList/types.d.ts +15 -0
  48. package/dist/types/components/DatePicker/DateRangePresetPicker.d.ts +2 -0
  49. package/dist/types/components/DatePicker/index.d.ts +1 -0
  50. package/dist/types/components/DatePicker/types.d.ts +19 -0
  51. package/dist/types/components/Description/Description.d.ts +2 -1
  52. package/dist/types/components/Description/DescriptionGroup.d.ts +6 -0
  53. package/dist/types/components/Description/constants.d.ts +23 -0
  54. package/dist/types/components/Description/index.d.ts +2 -0
  55. package/dist/types/components/Description/types.d.ts +28 -3
  56. package/dist/types/components/Form/DatetimeInput/DatetimeInput.d.ts +1 -1
  57. package/dist/types/components/GlowCard/GlowCard.d.ts +6 -0
  58. package/dist/types/components/GlowCard/index.d.ts +2 -0
  59. package/dist/types/components/GlowCard/types.d.ts +8 -0
  60. package/dist/types/components/GradientText/GradientText.d.ts +6 -0
  61. package/dist/types/components/GradientText/index.d.ts +2 -0
  62. package/dist/types/components/GradientText/types.d.ts +14 -0
  63. package/dist/types/components/Greeting/Greeting.d.ts +6 -0
  64. package/dist/types/components/Greeting/index.d.ts +2 -0
  65. package/dist/types/components/Greeting/types.d.ts +9 -0
  66. package/dist/types/components/KPICard/KPICard.d.ts +6 -0
  67. package/dist/types/components/KPICard/index.d.ts +2 -0
  68. package/dist/types/components/KPICard/types.d.ts +21 -0
  69. package/dist/types/components/Marquee/Marquee.d.ts +6 -0
  70. package/dist/types/components/Marquee/index.d.ts +2 -0
  71. package/dist/types/components/Marquee/types.d.ts +12 -0
  72. package/dist/types/components/Meteors/Meteors.d.ts +6 -0
  73. package/dist/types/components/Meteors/index.d.ts +2 -0
  74. package/dist/types/components/Meteors/types.d.ts +5 -0
  75. package/dist/types/components/MiniAreaChart/MiniAreaChart.d.ts +6 -0
  76. package/dist/types/components/MiniAreaChart/index.d.ts +2 -0
  77. package/dist/types/components/MiniAreaChart/types.d.ts +10 -0
  78. package/dist/types/components/MiniBarChart/MiniBarChart.d.ts +6 -0
  79. package/dist/types/components/MiniBarChart/index.d.ts +2 -0
  80. package/dist/types/components/MiniBarChart/types.d.ts +15 -0
  81. package/dist/types/components/MiniDonutChart/MiniDonutChart.d.ts +6 -0
  82. package/dist/types/components/MiniDonutChart/index.d.ts +2 -0
  83. package/dist/types/components/MiniDonutChart/types.d.ts +15 -0
  84. package/dist/types/components/MiniStackedBar/MiniStackedBar.d.ts +6 -0
  85. package/dist/types/components/MiniStackedBar/index.d.ts +2 -0
  86. package/dist/types/components/MiniStackedBar/types.d.ts +13 -0
  87. package/dist/types/components/NumberTicker/NumberTicker.d.ts +6 -0
  88. package/dist/types/components/NumberTicker/index.d.ts +2 -0
  89. package/dist/types/components/NumberTicker/types.d.ts +11 -0
  90. package/dist/types/components/Pulse/Pulse.d.ts +6 -0
  91. package/dist/types/components/Pulse/constants.d.ts +10 -0
  92. package/dist/types/components/Pulse/index.d.ts +2 -0
  93. package/dist/types/components/Pulse/types.d.ts +11 -0
  94. package/dist/types/components/ShinyButton/ShinyButton.d.ts +6 -0
  95. package/dist/types/components/ShinyButton/index.d.ts +2 -0
  96. package/dist/types/components/ShinyButton/types.d.ts +4 -0
  97. package/dist/types/components/Sparkline/Sparkline.d.ts +6 -0
  98. package/dist/types/components/Sparkline/index.d.ts +2 -0
  99. package/dist/types/components/Sparkline/types.d.ts +17 -0
  100. package/dist/types/components/SpotlightCard/SpotlightCard.d.ts +6 -0
  101. package/dist/types/components/SpotlightCard/index.d.ts +2 -0
  102. package/dist/types/components/SpotlightCard/types.d.ts +7 -0
  103. package/dist/types/components/StatCard/StatCard.d.ts +6 -0
  104. package/dist/types/components/StatCard/index.d.ts +2 -0
  105. package/dist/types/components/StatCard/types.d.ts +15 -0
  106. package/dist/types/components/TextShimmer/TextShimmer.d.ts +6 -0
  107. package/dist/types/components/TextShimmer/index.d.ts +2 -0
  108. package/dist/types/components/TextShimmer/types.d.ts +7 -0
  109. package/dist/types/components/TrendBadge/TrendBadge.d.ts +6 -0
  110. package/dist/types/components/TrendBadge/constants.d.ts +7 -0
  111. package/dist/types/components/TrendBadge/index.d.ts +2 -0
  112. package/dist/types/components/TrendBadge/types.d.ts +15 -0
  113. package/dist/types/components/WidgetShell/WidgetShell.d.ts +6 -0
  114. package/dist/types/components/WidgetShell/index.d.ts +2 -0
  115. package/dist/types/components/WidgetShell/types.d.ts +20 -0
  116. package/dist/types/index.d.ts +33 -0
  117. package/package.json +2 -1
  118. package/src/components/Accordion/constants.ts +1 -1
  119. package/src/components/ActivityFeed/ActivityFeed.tsx +51 -0
  120. package/src/components/ActivityFeed/constants.ts +19 -0
  121. package/src/components/ActivityFeed/index.ts +2 -0
  122. package/src/components/ActivityFeed/types.ts +23 -0
  123. package/src/components/Alert/constants.ts +1 -1
  124. package/src/components/AlertDialog/constants.ts +1 -1
  125. package/src/components/Amount/Amount.tsx +50 -0
  126. package/src/components/Amount/index.ts +2 -0
  127. package/src/components/Amount/types.ts +20 -0
  128. package/src/components/AnimatedCounter/AnimatedCounter.tsx +68 -0
  129. package/src/components/AnimatedCounter/index.ts +2 -0
  130. package/src/components/AnimatedCounter/types.ts +14 -0
  131. package/src/components/AnimatedGroup/AnimatedGroup.tsx +97 -0
  132. package/src/components/AnimatedGroup/index.ts +2 -0
  133. package/src/components/AnimatedGroup/types.ts +21 -0
  134. package/src/components/AnimatedList/AnimatedList.tsx +42 -0
  135. package/src/components/AnimatedList/index.ts +2 -0
  136. package/src/components/AnimatedList/types.ts +15 -0
  137. package/src/components/Badge/constants.ts +1 -1
  138. package/src/components/Banner/constants.ts +1 -1
  139. package/src/components/BorderBeam/BorderBeam.tsx +41 -0
  140. package/src/components/BorderBeam/index.ts +2 -0
  141. package/src/components/BorderBeam/types.ts +14 -0
  142. package/src/components/Box/Box.tsx +8 -2
  143. package/src/components/Box/constants.ts +35 -0
  144. package/src/components/Button/constants.ts +66 -63
  145. package/src/components/CalendarHeatmap/CalendarHeatmap.tsx +141 -0
  146. package/src/components/CalendarHeatmap/index.ts +2 -0
  147. package/src/components/CalendarHeatmap/types.ts +27 -0
  148. package/src/components/Card/constants.ts +24 -21
  149. package/src/components/Carousel/constants.ts +2 -2
  150. package/src/components/Chart/stories/examples/AreaChart.tsx +55 -0
  151. package/src/components/Chart/stories/examples/BarChart.tsx +95 -0
  152. package/src/components/Chart/stories/examples/LineChart.tsx +111 -0
  153. package/src/components/Chart/stories/examples/PieChart.tsx +55 -0
  154. package/src/components/Chart/stories/examples/RadialChart.tsx +65 -0
  155. package/src/components/CircularProgress/CircularProgress.tsx +46 -0
  156. package/src/components/CircularProgress/constants.ts +32 -0
  157. package/src/components/CircularProgress/index.ts +2 -0
  158. package/src/components/CircularProgress/types.ts +18 -0
  159. package/src/components/Command/constants.ts +1 -1
  160. package/src/components/ComparisonBar/ComparisonBar.tsx +65 -0
  161. package/src/components/ComparisonBar/constants.ts +23 -0
  162. package/src/components/ComparisonBar/index.ts +2 -0
  163. package/src/components/ComparisonBar/types.ts +23 -0
  164. package/src/components/Confetti/Confetti.tsx +82 -0
  165. package/src/components/Confetti/index.ts +2 -0
  166. package/src/components/Confetti/types.ts +20 -0
  167. package/src/components/CountdownTimer/CountdownTimer.tsx +91 -0
  168. package/src/components/CountdownTimer/index.ts +2 -0
  169. package/src/components/CountdownTimer/types.ts +14 -0
  170. package/src/components/DataList/DataList.tsx +32 -0
  171. package/src/components/DataList/constants.ts +47 -0
  172. package/src/components/DataList/index.ts +2 -0
  173. package/src/components/DataList/types.ts +17 -0
  174. package/src/components/DatePicker/DateRangePresetPicker.tsx +122 -0
  175. package/src/components/DatePicker/index.ts +1 -0
  176. package/src/components/DatePicker/types.ts +22 -0
  177. package/src/components/Description/Description.tsx +67 -5
  178. package/src/components/Description/DescriptionGroup.tsx +39 -0
  179. package/src/components/Description/constants.ts +128 -0
  180. package/src/components/Description/index.ts +10 -0
  181. package/src/components/Description/types.ts +31 -3
  182. package/src/components/Dialog/constants.ts +2 -2
  183. package/src/components/Dock/constants.ts +2 -2
  184. package/src/components/Drawer/constants.ts +2 -2
  185. package/src/components/Form/Checkbox/constants.ts +1 -1
  186. package/src/components/Form/DatetimeInput/constants.ts +1 -1
  187. package/src/components/Form/Input/constants.ts +1 -1
  188. package/src/components/Form/MultiSelect/constants.ts +1 -1
  189. package/src/components/Form/NativeSelect/constants.ts +1 -1
  190. package/src/components/Form/Radio/constants.ts +1 -1
  191. package/src/components/Form/Select/constants.ts +1 -1
  192. package/src/components/Form/Slider/constants.ts +1 -1
  193. package/src/components/Form/Switch/constants.ts +1 -1
  194. package/src/components/Form/Textarea/constants.ts +1 -1
  195. package/src/components/GlowCard/GlowCard.tsx +46 -0
  196. package/src/components/GlowCard/index.ts +2 -0
  197. package/src/components/GlowCard/types.ts +9 -0
  198. package/src/components/GradientText/GradientText.tsx +36 -0
  199. package/src/components/GradientText/index.ts +2 -0
  200. package/src/components/GradientText/types.ts +15 -0
  201. package/src/components/Greeting/Greeting.tsx +46 -0
  202. package/src/components/Greeting/index.ts +2 -0
  203. package/src/components/Greeting/types.ts +10 -0
  204. package/src/components/KPICard/KPICard.tsx +85 -0
  205. package/src/components/KPICard/index.ts +2 -0
  206. package/src/components/KPICard/types.ts +22 -0
  207. package/src/components/Marquee/Marquee.tsx +45 -0
  208. package/src/components/Marquee/index.ts +2 -0
  209. package/src/components/Marquee/types.ts +13 -0
  210. package/src/components/Menu/Menubar/constants.ts +2 -2
  211. package/src/components/Menu/NavigationMenu/constants.ts +2 -2
  212. package/src/components/Meteors/Meteors.tsx +38 -0
  213. package/src/components/Meteors/index.ts +2 -0
  214. package/src/components/Meteors/types.ts +6 -0
  215. package/src/components/MiniAreaChart/MiniAreaChart.tsx +68 -0
  216. package/src/components/MiniAreaChart/index.ts +2 -0
  217. package/src/components/MiniAreaChart/types.ts +11 -0
  218. package/src/components/MiniBarChart/MiniBarChart.tsx +49 -0
  219. package/src/components/MiniBarChart/index.ts +2 -0
  220. package/src/components/MiniBarChart/types.ts +16 -0
  221. package/src/components/MiniDonutChart/MiniDonutChart.tsx +87 -0
  222. package/src/components/MiniDonutChart/index.ts +2 -0
  223. package/src/components/MiniDonutChart/types.ts +17 -0
  224. package/src/components/MiniStackedBar/MiniStackedBar.tsx +61 -0
  225. package/src/components/MiniStackedBar/index.ts +2 -0
  226. package/src/components/MiniStackedBar/types.ts +15 -0
  227. package/src/components/NumberTicker/NumberTicker.tsx +58 -0
  228. package/src/components/NumberTicker/index.ts +2 -0
  229. package/src/components/NumberTicker/types.ts +12 -0
  230. package/src/components/Pagination/constants.ts +2 -2
  231. package/src/components/Progress/constants.ts +1 -1
  232. package/src/components/Pulse/Pulse.tsx +26 -0
  233. package/src/components/Pulse/constants.ts +55 -0
  234. package/src/components/Pulse/index.ts +2 -0
  235. package/src/components/Pulse/types.ts +12 -0
  236. package/src/components/Resizable/constants.ts +1 -1
  237. package/src/components/Sheet/constants.ts +1 -1
  238. package/src/components/ShinyButton/ShinyButton.tsx +57 -0
  239. package/src/components/ShinyButton/index.ts +2 -0
  240. package/src/components/ShinyButton/types.ts +8 -0
  241. package/src/components/Skeleton/constants.ts +1 -1
  242. package/src/components/Sonner/constants.ts +1 -1
  243. package/src/components/Sparkline/Sparkline.tsx +108 -0
  244. package/src/components/Sparkline/index.ts +2 -0
  245. package/src/components/Sparkline/types.ts +18 -0
  246. package/src/components/SpotlightCard/SpotlightCard.tsx +56 -0
  247. package/src/components/SpotlightCard/index.ts +2 -0
  248. package/src/components/SpotlightCard/types.ts +8 -0
  249. package/src/components/Stat/constants.ts +1 -1
  250. package/src/components/StatCard/StatCard.tsx +59 -0
  251. package/src/components/StatCard/index.ts +2 -0
  252. package/src/components/StatCard/types.ts +16 -0
  253. package/src/components/Tabs/constants.ts +1 -1
  254. package/src/components/TextShimmer/TextShimmer.tsx +34 -0
  255. package/src/components/TextShimmer/index.ts +2 -0
  256. package/src/components/TextShimmer/types.ts +8 -0
  257. package/src/components/Timeline/constants.ts +1 -1
  258. package/src/components/Toggle/constants.ts +1 -1
  259. package/src/components/Tooltip/constants.ts +1 -1
  260. package/src/components/TrendBadge/TrendBadge.tsx +40 -0
  261. package/src/components/TrendBadge/constants.ts +38 -0
  262. package/src/components/TrendBadge/index.ts +2 -0
  263. package/src/components/TrendBadge/types.ts +16 -0
  264. package/src/components/WidgetShell/WidgetShell.tsx +101 -0
  265. package/src/components/WidgetShell/index.ts +2 -0
  266. package/src/components/WidgetShell/types.ts +22 -0
  267. package/src/index.ts +35 -0
  268. package/src/stylesheets/tailwind.css +208 -0
  269. package/src/utilities/getSubpaths/getSubpaths.ts +1 -2
@@ -0,0 +1,87 @@
1
+ import { useMemo } from "react";
2
+ import { cn } from "../../utilities";
3
+ import type { MiniDonutChartProps } from "./types";
4
+
5
+ const DEFAULT_COLORS = [
6
+ "oklch(0.7 0.15 250)",
7
+ "oklch(0.7 0.15 150)",
8
+ "oklch(0.7 0.15 50)",
9
+ "oklch(0.7 0.15 330)",
10
+ "oklch(0.6 0.15 200)",
11
+ ];
12
+
13
+ const MiniDonutChart = ({
14
+ segments,
15
+ className,
16
+ size = 48,
17
+ thickness = 0.3,
18
+ label,
19
+ ...props
20
+ }: MiniDonutChartProps) => {
21
+ const paths = useMemo(() => {
22
+ const total = segments.reduce((sum, s) => sum + s.value, 0);
23
+ if (total === 0) return [];
24
+
25
+ const cx = size / 2;
26
+ const cy = size / 2;
27
+ const outerR = size / 2 - 1;
28
+ const innerR = outerR * (1 - thickness);
29
+
30
+ let startAngle = -90;
31
+ return segments.map((seg, i) => {
32
+ const sweepAngle = (seg.value / total) * 360;
33
+ const endAngle = startAngle + sweepAngle;
34
+
35
+ const startRad = (startAngle * Math.PI) / 180;
36
+ const endRad = (endAngle * Math.PI) / 180;
37
+
38
+ const x1 = cx + outerR * Math.cos(startRad);
39
+ const y1 = cy + outerR * Math.sin(startRad);
40
+ const x2 = cx + outerR * Math.cos(endRad);
41
+ const y2 = cy + outerR * Math.sin(endRad);
42
+ const x3 = cx + innerR * Math.cos(endRad);
43
+ const y3 = cy + innerR * Math.sin(endRad);
44
+ const x4 = cx + innerR * Math.cos(startRad);
45
+ const y4 = cy + innerR * Math.sin(startRad);
46
+
47
+ const largeArc = sweepAngle > 180 ? 1 : 0;
48
+
49
+ const d = [
50
+ `M ${x1} ${y1}`,
51
+ `A ${outerR} ${outerR} 0 ${largeArc} 1 ${x2} ${y2}`,
52
+ `L ${x3} ${y3}`,
53
+ `A ${innerR} ${innerR} 0 ${largeArc} 0 ${x4} ${y4}`,
54
+ "Z",
55
+ ].join(" ");
56
+
57
+ startAngle = endAngle;
58
+
59
+ return {
60
+ d,
61
+ color: seg.color ?? DEFAULT_COLORS[i % DEFAULT_COLORS.length],
62
+ title: seg.label ? `${seg.label}: ${seg.value}` : undefined,
63
+ };
64
+ });
65
+ }, [segments, size, thickness]);
66
+
67
+ return (
68
+ <div className={cn("relative inline-flex items-center justify-center", className)} {...props}>
69
+ <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} aria-hidden="true">
70
+ {paths.map((p, i) => (
71
+ <path key={i} d={p.d} fill={p.color}>
72
+ {p.title && <title>{p.title}</title>}
73
+ </path>
74
+ ))}
75
+ </svg>
76
+ {label && (
77
+ <span className="absolute inset-0 flex items-center justify-center text-[10px] font-semibold tabular-nums">
78
+ {label}
79
+ </span>
80
+ )}
81
+ </div>
82
+ );
83
+ };
84
+
85
+ MiniDonutChart.displayName = "MiniDonutChart";
86
+
87
+ export { MiniDonutChart };
@@ -0,0 +1,2 @@
1
+ export { MiniDonutChart } from "./MiniDonutChart";
2
+ export type { MiniDonutChartProps, DonutSegment } from "./types";
@@ -0,0 +1,17 @@
1
+ import type { HTMLAttributes, ReactNode } from "react";
2
+
3
+ export type DonutSegment = {
4
+ value: number;
5
+ color?: string;
6
+ label?: string;
7
+ };
8
+
9
+ export type MiniDonutChartProps = Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
10
+ segments: DonutSegment[];
11
+ /** Size in pixels */
12
+ size?: number;
13
+ /** Ring thickness as percentage of radius (0-1) */
14
+ thickness?: number;
15
+ /** Center label */
16
+ label?: ReactNode;
17
+ };
@@ -0,0 +1,61 @@
1
+ import { useMemo } from "react";
2
+ import { cn } from "../../utilities";
3
+ import type { MiniStackedBarProps } from "./types";
4
+
5
+ const DEFAULT_COLORS = [
6
+ "oklch(0.7 0.15 250)",
7
+ "oklch(0.7 0.15 150)",
8
+ "oklch(0.7 0.15 50)",
9
+ "oklch(0.7 0.15 330)",
10
+ "oklch(0.6 0.15 200)",
11
+ ];
12
+
13
+ const MiniStackedBar = ({
14
+ segments,
15
+ className,
16
+ height = 8,
17
+ showLabels = false,
18
+ ...props
19
+ }: MiniStackedBarProps) => {
20
+ const total = useMemo(() => segments.reduce((sum, s) => sum + s.value, 0), [segments]);
21
+
22
+ return (
23
+ <div className={cn("flex flex-col gap-1.5", className)} {...props}>
24
+ <div className="flex w-full overflow-hidden rounded-full" style={{ height }}>
25
+ {segments.map((seg, i) => {
26
+ const pct = total > 0 ? (seg.value / total) * 100 : 0;
27
+ return (
28
+ <div
29
+ key={i}
30
+ className="transition-all duration-500"
31
+ style={{
32
+ width: `${pct}%`,
33
+ backgroundColor: seg.color ?? DEFAULT_COLORS[i % DEFAULT_COLORS.length],
34
+ }}
35
+ title={seg.label ? `${seg.label}: ${pct.toFixed(1)}%` : `${pct.toFixed(1)}%`}
36
+ />
37
+ );
38
+ })}
39
+ </div>
40
+ {showLabels && (
41
+ <div className="flex gap-3">
42
+ {segments.map((seg, i) => (
43
+ <div key={i} className="flex items-center gap-1">
44
+ <span
45
+ className="size-2 rounded-full"
46
+ style={{ backgroundColor: seg.color ?? DEFAULT_COLORS[i % DEFAULT_COLORS.length] }}
47
+ />
48
+ <span className="text-[10px] text-base-content/60">
49
+ {seg.label ?? `${((seg.value / total) * 100).toFixed(0)}%`}
50
+ </span>
51
+ </div>
52
+ ))}
53
+ </div>
54
+ )}
55
+ </div>
56
+ );
57
+ };
58
+
59
+ MiniStackedBar.displayName = "MiniStackedBar";
60
+
61
+ export { MiniStackedBar };
@@ -0,0 +1,2 @@
1
+ export { MiniStackedBar } from "./MiniStackedBar";
2
+ export type { MiniStackedBarProps, StackedSegment } from "./types";
@@ -0,0 +1,15 @@
1
+ import type { HTMLAttributes } from "react";
2
+
3
+ export type StackedSegment = {
4
+ value: number;
5
+ color?: string;
6
+ label?: string;
7
+ };
8
+
9
+ export type MiniStackedBarProps = Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
10
+ segments: StackedSegment[];
11
+ /** Height in pixels */
12
+ height?: number;
13
+ /** Whether to show percentage labels below */
14
+ showLabels?: boolean;
15
+ };
@@ -0,0 +1,58 @@
1
+ "use client";
2
+
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { cn } from "../../utilities";
5
+ import type { NumberTickerProps } from "./types";
6
+
7
+ const NumberTicker = ({
8
+ value,
9
+ className,
10
+ duration = 2,
11
+ decimalPlaces = 0,
12
+ delay = 0,
13
+ ...props
14
+ }: NumberTickerProps) => {
15
+ const [displayValue, setDisplayValue] = useState(0);
16
+ const [hasStarted, setHasStarted] = useState(false);
17
+ const ref = useRef<HTMLSpanElement>(null);
18
+
19
+ useEffect(() => {
20
+ const timeout = setTimeout(() => setHasStarted(true), delay * 1000);
21
+ return () => clearTimeout(timeout);
22
+ }, [delay]);
23
+
24
+ useEffect(() => {
25
+ if (!hasStarted) return;
26
+
27
+ const startTime = performance.now();
28
+ const durationMs = duration * 1000;
29
+
30
+ const tick = (now: number) => {
31
+ const elapsed = now - startTime;
32
+ const progress = Math.min(elapsed / durationMs, 1);
33
+ // Ease out cubic
34
+ const eased = 1 - Math.pow(1 - progress, 3);
35
+ setDisplayValue(eased * value);
36
+
37
+ if (progress < 1) {
38
+ requestAnimationFrame(tick);
39
+ }
40
+ };
41
+
42
+ requestAnimationFrame(tick);
43
+ }, [value, duration, hasStarted]);
44
+
45
+ return (
46
+ <span
47
+ ref={ref}
48
+ className={cn("tabular-nums", className)}
49
+ {...props}
50
+ >
51
+ {displayValue.toFixed(decimalPlaces)}
52
+ </span>
53
+ );
54
+ };
55
+
56
+ NumberTicker.displayName = "NumberTicker";
57
+
58
+ export { NumberTicker };
@@ -0,0 +1,2 @@
1
+ export { NumberTicker } from "./NumberTicker";
2
+ export type { NumberTickerProps } from "./types";
@@ -0,0 +1,12 @@
1
+ import type { HTMLAttributes } from "react";
2
+
3
+ export type NumberTickerProps = Omit<HTMLAttributes<HTMLSpanElement>, "children"> & {
4
+ /** The target number to count to */
5
+ value: number;
6
+ /** Duration of the animation in seconds */
7
+ duration?: number;
8
+ /** Decimal places to show */
9
+ decimalPlaces?: number;
10
+ /** Delay before animation starts in seconds */
11
+ delay?: number;
12
+ };
@@ -6,6 +6,6 @@ export const getPaginationContentClasses = cva("flex flex-row items-center gap-1
6
6
 
7
7
  export const getPaginationEllipsisClasses = cva("flex h-9 w-9 items-center justify-center");
8
8
 
9
- export const getPaginationNextClasses = cva("gap-1 px-3");
9
+ export const getPaginationNextClasses = cva("gap-1 px-3 transition-colors duration-200");
10
10
 
11
- export const getPaginationPreviousClasses = cva("gap-1 px-3");
11
+ export const getPaginationPreviousClasses = cva("gap-1 px-3 transition-colors duration-200");
@@ -21,7 +21,7 @@ export const getProgressClasses = cva("relative h-2 w-full overflow-hidden round
21
21
  },
22
22
  });
23
23
 
24
- export const getProgressIndicatorClasses = cva("h-full w-full flex-1 transition-all", {
24
+ export const getProgressIndicatorClasses = cva("h-full w-full flex-1 rounded-full transition-all duration-500 ease-out", {
25
25
  variants: createVariants({
26
26
  variant: {
27
27
  accent: "bg-accent",
@@ -0,0 +1,26 @@
1
+ import { cn } from "../../utilities";
2
+ import { getPulseClasses, getPulseDotClasses, getPulseRingClasses } from "./constants";
3
+ import type { PulseProps } from "./types";
4
+
5
+ const Pulse = ({
6
+ variant = "success",
7
+ size = "sm",
8
+ animated = true,
9
+ label,
10
+ className,
11
+ ...props
12
+ }: PulseProps) => {
13
+ return (
14
+ <span className={cn(getPulseClasses({ size }), className)} {...props}>
15
+ <span className="relative inline-flex">
16
+ {animated && <span className={getPulseRingClasses({ variant })} />}
17
+ <span className={getPulseDotClasses({ variant, size })} />
18
+ </span>
19
+ {label && <span className="text-base-content/70">{label}</span>}
20
+ </span>
21
+ );
22
+ };
23
+
24
+ Pulse.displayName = "Pulse";
25
+
26
+ export { Pulse };
@@ -0,0 +1,55 @@
1
+ import { cva } from "../../libs";
2
+ import { createVariants } from "../../utilities";
3
+
4
+ export const getPulseClasses = cva("inline-flex items-center gap-1.5", {
5
+ variants: createVariants({
6
+ size: {
7
+ xs: "text-[10px]",
8
+ sm: "text-xs",
9
+ md: "text-sm",
10
+ lg: "text-base",
11
+ },
12
+ }),
13
+ defaultVariants: { size: "sm" },
14
+ });
15
+
16
+ export const getPulseDotClasses = cva("relative inline-flex rounded-full", {
17
+ variants: createVariants({
18
+ variant: {
19
+ success: "bg-success",
20
+ error: "bg-error",
21
+ warning: "bg-warning",
22
+ info: "bg-info",
23
+ primary: "bg-primary",
24
+ secondary: "bg-secondary",
25
+ accent: "bg-accent",
26
+ neutral: "bg-neutral",
27
+ },
28
+ size: {
29
+ xs: "size-1.5",
30
+ sm: "size-2",
31
+ md: "size-2.5",
32
+ lg: "size-3",
33
+ },
34
+ }),
35
+ defaultVariants: { variant: "success", size: "sm" },
36
+ });
37
+
38
+ export const getPulseRingClasses = cva(
39
+ "absolute inset-0 rounded-full animate-ping opacity-75",
40
+ {
41
+ variants: createVariants({
42
+ variant: {
43
+ success: "bg-success",
44
+ error: "bg-error",
45
+ warning: "bg-warning",
46
+ info: "bg-info",
47
+ primary: "bg-primary",
48
+ secondary: "bg-secondary",
49
+ accent: "bg-accent",
50
+ neutral: "bg-neutral",
51
+ },
52
+ }),
53
+ defaultVariants: { variant: "success" },
54
+ }
55
+ );
@@ -0,0 +1,2 @@
1
+ export { Pulse } from "./Pulse";
2
+ export type { PulseProps } from "./types";
@@ -0,0 +1,12 @@
1
+ import type { HTMLAttributes } from "react";
2
+
3
+ export type PulseProps = HTMLAttributes<HTMLSpanElement> & {
4
+ /** Color variant */
5
+ variant?: "success" | "error" | "warning" | "info" | "primary" | "secondary" | "accent" | "neutral";
6
+ /** Size variant */
7
+ size?: "xs" | "sm" | "md" | "lg";
8
+ /** Whether to animate */
9
+ animated?: boolean;
10
+ /** Optional label text */
11
+ label?: string;
12
+ };
@@ -6,7 +6,7 @@ export const getResizableClasses = cva(
6
6
  );
7
7
 
8
8
  export const getResizableHandleClasses = cva(
9
- "relative flex w-px items-center justify-center border-primary after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
9
+ "relative flex w-px items-center justify-center border-primary transition-colors duration-200 after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
10
10
  {
11
11
  variants: createVariants({
12
12
  bordered: {
@@ -30,7 +30,7 @@ export const getSheetClasses = cva(
30
30
  );
31
31
 
32
32
  export const getSheetOverlayClasses = cva(
33
- "fixed inset-0 z-40 bg-black/50 transition-opacity duration-300",
33
+ "fixed inset-0 z-40 bg-black/60 backdrop-blur-sm transition-opacity duration-300",
34
34
  {
35
35
  variants: createVariants({
36
36
  open: {
@@ -0,0 +1,57 @@
1
+ "use client";
2
+
3
+ import type { HTMLMotionProps } from "framer-motion";
4
+ import { motion } from "framer-motion";
5
+ import type { ShinyButtonProps } from "./types";
6
+ import { cn } from "../../utilities";
7
+
8
+ const animationProps = {
9
+ initial: { "--x": "100%" },
10
+ animate: { "--x": "-100%" },
11
+ transition: {
12
+ repeat: Infinity,
13
+ repeatType: "loop" as const,
14
+ repeatDelay: 1,
15
+ type: "spring",
16
+ stiffness: 20,
17
+ damping: 15,
18
+ mass: 2,
19
+ },
20
+ } satisfies HTMLMotionProps<"button">;
21
+
22
+ const ShinyButton = ({ children, className, ...props }: ShinyButtonProps) => {
23
+ return (
24
+ <motion.button
25
+ {...animationProps}
26
+ className={cn(
27
+ "relative rounded-lg px-6 py-2 font-medium backdrop-blur-xl transition-shadow duration-300 ease-in-out",
28
+ "bg-[radial-gradient(circle_at_50%_0%,oklch(0.8_0.1_250/0.1)_0%,transparent_60%)]",
29
+ "hover:shadow-[0_0_20px_oklch(0.7_0.15_250/0.3)]",
30
+ "dark:bg-[radial-gradient(circle_at_50%_0%,oklch(0.8_0.15_250/0.15)_0%,transparent_60%)]",
31
+ className
32
+ )}
33
+ {...props}
34
+ >
35
+ <span
36
+ className="relative block size-full text-sm tracking-wide"
37
+ style={{
38
+ maskImage:
39
+ "linear-gradient(-75deg, oklch(1 0 0) calc(var(--x) + 20%), transparent calc(var(--x) + 30%), oklch(1 0 0) calc(var(--x) + 100%))",
40
+ }}
41
+ >
42
+ {children}
43
+ </span>
44
+ <span
45
+ style={{
46
+ mask: "linear-gradient(oklch(0 0 0), oklch(0 0 0)) content-box, linear-gradient(oklch(0 0 0), oklch(0 0 0))",
47
+ maskComposite: "exclude",
48
+ }}
49
+ className="absolute inset-0 z-10 block rounded-[inherit] bg-[linear-gradient(-75deg,oklch(1_0_0/0.1)_calc(var(--x)+20%),oklch(1_0_0/0.5)_calc(var(--x)+25%),oklch(1_0_0/0.1)_calc(var(--x)+100%))] p-px"
50
+ />
51
+ </motion.button>
52
+ );
53
+ };
54
+
55
+ ShinyButton.displayName = "ShinyButton";
56
+
57
+ export { ShinyButton };
@@ -0,0 +1,2 @@
1
+ export { ShinyButton } from "./ShinyButton";
2
+ export type { ShinyButtonProps } from "./types";
@@ -0,0 +1,8 @@
1
+ import type { ButtonHTMLAttributes, ReactNode } from "react";
2
+
3
+ export type ShinyButtonProps = Omit<
4
+ ButtonHTMLAttributes<HTMLButtonElement>,
5
+ "onDrag" | "onDragStart" | "onDragEnd" | "onAnimationStart"
6
+ > & {
7
+ children: ReactNode;
8
+ };
@@ -1,7 +1,7 @@
1
1
  import { cva } from "../../libs";
2
2
  import { createVariants } from "../../utilities";
3
3
 
4
- export const getSkeletonClasses = cva("skeleton", {
4
+ export const getSkeletonClasses = cva("skeleton animate-pulse", {
5
5
  variants: createVariants({
6
6
  animate: { pulse: "animate-pulse" },
7
7
  width: {
@@ -1,7 +1,7 @@
1
1
  import { cva } from "../../libs";
2
2
  import { createVariants } from "../../utilities";
3
3
 
4
- export const getToastClasses = cva("sonner group", {
4
+ export const getToastClasses = cva("sonner group shadow-lg", {
5
5
  variants: createVariants({
6
6
  variant: {
7
7
  accent: "bg-accent text-accent-content border-accent",
@@ -0,0 +1,108 @@
1
+ import { useMemo } from "react";
2
+ import { cn } from "../../utilities";
3
+ import type { SparklineProps } from "./types";
4
+
5
+ const Sparkline = ({
6
+ data,
7
+ className,
8
+ width = 120,
9
+ height = 32,
10
+ color = "currentColor",
11
+ filled = false,
12
+ strokeWidth = 1.5,
13
+ animated = true,
14
+ ...props
15
+ }: SparklineProps) => {
16
+ const path = useMemo(() => {
17
+ if (data.length < 2) return "";
18
+ const min = Math.min(...data);
19
+ const max = Math.max(...data);
20
+ const range = max - min || 1;
21
+ const padding = strokeWidth;
22
+ const plotWidth = width - padding * 2;
23
+ const plotHeight = height - padding * 2;
24
+
25
+ const points = data.map((value, i) => ({
26
+ x: padding + (i / (data.length - 1)) * plotWidth,
27
+ y: padding + plotHeight - ((value - min) / range) * plotHeight,
28
+ }));
29
+
30
+ return points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
31
+ }, [data, width, height, strokeWidth]);
32
+
33
+ const areaPath = useMemo(() => {
34
+ if (!filled || !path) return "";
35
+ const padding = strokeWidth;
36
+ const firstX = padding;
37
+ const lastX = width - padding;
38
+ return `${path} L ${lastX} ${height - padding} L ${firstX} ${height - padding} Z`;
39
+ }, [filled, path, width, height, strokeWidth]);
40
+
41
+ const pathLength = useMemo(() => {
42
+ if (data.length < 2) return 0;
43
+ const min = Math.min(...data);
44
+ const max = Math.max(...data);
45
+ const range = max - min || 1;
46
+ const padding = strokeWidth;
47
+ const plotWidth = width - padding * 2;
48
+ const plotHeight = height - padding * 2;
49
+
50
+ let length = 0;
51
+ for (let i = 1; i < data.length; i++) {
52
+ const x1 = padding + ((i - 1) / (data.length - 1)) * plotWidth;
53
+ const y1 = padding + plotHeight - ((data[i - 1] - min) / range) * plotHeight;
54
+ const x2 = padding + (i / (data.length - 1)) * plotWidth;
55
+ const y2 = padding + plotHeight - ((data[i] - min) / range) * plotHeight;
56
+ length += Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
57
+ }
58
+ return Math.ceil(length);
59
+ }, [data, width, height, strokeWidth]);
60
+
61
+ if (data.length < 2) return null;
62
+
63
+ return (
64
+ <div className={cn("inline-flex items-center", className)} {...props}>
65
+ <svg
66
+ width={width}
67
+ height={height}
68
+ viewBox={`0 0 ${width} ${height}`}
69
+ fill="none"
70
+ aria-hidden="true"
71
+ >
72
+ {filled && areaPath && (
73
+ <path
74
+ d={areaPath}
75
+ fill={color}
76
+ opacity={0.1}
77
+ />
78
+ )}
79
+ <path
80
+ d={path}
81
+ stroke={color}
82
+ strokeWidth={strokeWidth}
83
+ strokeLinecap="round"
84
+ strokeLinejoin="round"
85
+ fill="none"
86
+ {...(animated
87
+ ? {
88
+ strokeDasharray: pathLength,
89
+ strokeDashoffset: pathLength,
90
+ style: {
91
+ animation: `sparkline-draw 1s ease-out forwards`,
92
+ },
93
+ }
94
+ : {})}
95
+ />
96
+ <style>{`
97
+ @keyframes sparkline-draw {
98
+ to { stroke-dashoffset: 0; }
99
+ }
100
+ `}</style>
101
+ </svg>
102
+ </div>
103
+ );
104
+ };
105
+
106
+ Sparkline.displayName = "Sparkline";
107
+
108
+ export { Sparkline };
@@ -0,0 +1,2 @@
1
+ export { Sparkline } from "./Sparkline";
2
+ export type { SparklineProps } from "./types";
@@ -0,0 +1,18 @@
1
+ import type { HTMLAttributes } from "react";
2
+
3
+ export type SparklineProps = Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
4
+ /** Array of numeric data points */
5
+ data: number[];
6
+ /** Width of the sparkline in pixels */
7
+ width?: number;
8
+ /** Height of the sparkline in pixels */
9
+ height?: number;
10
+ /** Stroke color (CSS color value) */
11
+ color?: string;
12
+ /** Whether to show a filled area under the line */
13
+ filled?: boolean;
14
+ /** Stroke width in pixels */
15
+ strokeWidth?: number;
16
+ /** Whether to animate the line drawing */
17
+ animated?: boolean;
18
+ };