@zentauri-ui/zentauri-components 1.8.1 → 1.8.3

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 (195) hide show
  1. package/README.md +123 -25
  2. package/cli/cli.integration.test.ts +77 -2
  3. package/cli/index.mjs +53 -0
  4. package/cli/registry.json +136 -0
  5. package/cli/rewrite-imports.mjs +4 -1
  6. package/dist/charts/area.js +9 -10
  7. package/dist/charts/area.js.map +1 -1
  8. package/dist/charts/area.mjs +2 -3
  9. package/dist/charts/area.mjs.map +1 -1
  10. package/dist/charts/bar.js +10 -95
  11. package/dist/charts/bar.js.map +1 -1
  12. package/dist/charts/bar.mjs +2 -95
  13. package/dist/charts/bar.mjs.map +1 -1
  14. package/dist/charts/bubble.js +8 -9
  15. package/dist/charts/bubble.js.map +1 -1
  16. package/dist/charts/bubble.mjs +2 -3
  17. package/dist/charts/bubble.mjs.map +1 -1
  18. package/dist/charts/funnel/Funnel.d.ts +6 -0
  19. package/dist/charts/funnel/Funnel.d.ts.map +1 -0
  20. package/dist/charts/funnel/index.d.ts +4 -0
  21. package/dist/charts/funnel/index.d.ts.map +1 -0
  22. package/dist/charts/funnel.js +102 -0
  23. package/dist/charts/funnel.js.map +1 -0
  24. package/dist/charts/funnel.mjs +89 -0
  25. package/dist/charts/funnel.mjs.map +1 -0
  26. package/dist/charts/line.js +8 -9
  27. package/dist/charts/line.js.map +1 -1
  28. package/dist/charts/line.mjs +2 -3
  29. package/dist/charts/line.mjs.map +1 -1
  30. package/dist/charts/pie/Pie.d.ts +1 -1
  31. package/dist/charts/pie/Pie.d.ts.map +1 -1
  32. package/dist/charts/pie.js +19 -6
  33. package/dist/charts/pie.js.map +1 -1
  34. package/dist/charts/pie.mjs +17 -4
  35. package/dist/charts/pie.mjs.map +1 -1
  36. package/dist/charts/radar/Radar.d.ts +6 -0
  37. package/dist/charts/radar/Radar.d.ts.map +1 -0
  38. package/dist/charts/radar/index.d.ts +4 -0
  39. package/dist/charts/radar/index.d.ts.map +1 -0
  40. package/dist/charts/radar.js +94 -0
  41. package/dist/charts/radar.js.map +1 -0
  42. package/dist/charts/radar.mjs +81 -0
  43. package/dist/charts/radar.mjs.map +1 -0
  44. package/dist/charts/scatter/Scatter.d.ts +6 -0
  45. package/dist/charts/scatter/Scatter.d.ts.map +1 -0
  46. package/dist/charts/scatter/index.d.ts +4 -0
  47. package/dist/charts/scatter/index.d.ts.map +1 -0
  48. package/dist/charts/scatter.js +116 -0
  49. package/dist/charts/scatter.js.map +1 -0
  50. package/dist/charts/scatter.mjs +103 -0
  51. package/dist/charts/scatter.mjs.map +1 -0
  52. package/dist/charts/shared/chart-frame.d.ts +2 -1
  53. package/dist/charts/shared/chart-frame.d.ts.map +1 -1
  54. package/dist/charts/shared/types.d.ts +22 -2
  55. package/dist/charts/shared/types.d.ts.map +1 -1
  56. package/dist/charts/stacked-bar/StackedBar.d.ts +6 -0
  57. package/dist/charts/stacked-bar/StackedBar.d.ts.map +1 -0
  58. package/dist/charts/stacked-bar/index.d.ts +4 -0
  59. package/dist/charts/stacked-bar/index.d.ts.map +1 -0
  60. package/dist/charts/stacked-bar.js +29 -0
  61. package/dist/charts/stacked-bar.js.map +1 -0
  62. package/dist/charts/stacked-bar.mjs +15 -0
  63. package/dist/charts/stacked-bar.mjs.map +1 -0
  64. package/dist/{chunk-ABOZ5QIX.js → chunk-466QDL44.js} +5 -12
  65. package/dist/chunk-466QDL44.js.map +1 -0
  66. package/dist/chunk-4ZP444GA.mjs +19 -0
  67. package/dist/chunk-4ZP444GA.mjs.map +1 -0
  68. package/dist/{chunk-HDO5ZM2S.mjs → chunk-CIEZFHCO.mjs} +3 -10
  69. package/dist/chunk-CIEZFHCO.mjs.map +1 -0
  70. package/dist/chunk-F3V4POW3.mjs +8 -0
  71. package/dist/chunk-F3V4POW3.mjs.map +1 -0
  72. package/dist/{chunk-G2WARVAM.mjs → chunk-HZIRD3SR.mjs} +35 -15
  73. package/dist/chunk-HZIRD3SR.mjs.map +1 -0
  74. package/dist/{chunk-G66SXATZ.js → chunk-IL4LH2XX.js} +50 -4
  75. package/dist/chunk-IL4LH2XX.js.map +1 -0
  76. package/dist/{chunk-QQ6F4LZK.js → chunk-JFS5PJSH.js} +5 -5
  77. package/dist/{chunk-QQ6F4LZK.js.map → chunk-JFS5PJSH.js.map} +1 -1
  78. package/dist/chunk-LREMK2XR.js +97 -0
  79. package/dist/chunk-LREMK2XR.js.map +1 -0
  80. package/dist/chunk-MUP7DVQR.js +26 -0
  81. package/dist/chunk-MUP7DVQR.js.map +1 -0
  82. package/dist/chunk-O2KM3ETC.mjs +95 -0
  83. package/dist/chunk-O2KM3ETC.mjs.map +1 -0
  84. package/dist/{chunk-ZIFMIS7D.mjs → chunk-OL3BJSRC.mjs} +51 -5
  85. package/dist/chunk-OL3BJSRC.mjs.map +1 -0
  86. package/dist/{chunk-QNUDODDX.js → chunk-PWPMKXEG.js} +36 -14
  87. package/dist/chunk-PWPMKXEG.js.map +1 -0
  88. package/dist/{chunk-ASJQP53L.mjs → chunk-VARQ7W4G.mjs} +3 -3
  89. package/dist/{chunk-ASJQP53L.mjs.map → chunk-VARQ7W4G.mjs.map} +1 -1
  90. package/dist/chunk-XRM7GOIE.js +10 -0
  91. package/dist/chunk-XRM7GOIE.js.map +1 -0
  92. package/dist/design-system/tokens.js +32 -0
  93. package/dist/design-system/tokens.js.map +1 -0
  94. package/dist/design-system/tokens.mjs +3 -0
  95. package/dist/design-system/tokens.mjs.map +1 -0
  96. package/dist/hooks/index.d.ts +2 -0
  97. package/dist/hooks/index.d.ts.map +1 -1
  98. package/dist/hooks/useIsomorphicLayoutEffect.js +6 -4
  99. package/dist/hooks/useIsomorphicLayoutEffect.js.map +1 -1
  100. package/dist/hooks/useIsomorphicLayoutEffect.mjs +1 -6
  101. package/dist/hooks/useIsomorphicLayoutEffect.mjs.map +1 -1
  102. package/dist/hooks/useTableFilter/index.d.ts +3 -0
  103. package/dist/hooks/useTableFilter/index.d.ts.map +1 -0
  104. package/dist/hooks/useTableFilter/types.d.ts +20 -0
  105. package/dist/hooks/useTableFilter/types.d.ts.map +1 -0
  106. package/dist/hooks/useTableFilter/useTableFilter.d.ts +3 -0
  107. package/dist/hooks/useTableFilter/useTableFilter.d.ts.map +1 -0
  108. package/dist/hooks/useTableFilter.js +124 -0
  109. package/dist/hooks/useTableFilter.js.map +1 -0
  110. package/dist/hooks/useTableFilter.mjs +122 -0
  111. package/dist/hooks/useTableFilter.mjs.map +1 -0
  112. package/dist/hooks/useTableSort/index.d.ts +3 -0
  113. package/dist/hooks/useTableSort/index.d.ts.map +1 -0
  114. package/dist/hooks/useTableSort/types.d.ts +15 -0
  115. package/dist/hooks/useTableSort/types.d.ts.map +1 -0
  116. package/dist/hooks/useTableSort/useTableSort.d.ts +3 -0
  117. package/dist/hooks/useTableSort/useTableSort.d.ts.map +1 -0
  118. package/dist/hooks/useTableSort.js +99 -0
  119. package/dist/hooks/useTableSort.js.map +1 -0
  120. package/dist/hooks/useTableSort.mjs +97 -0
  121. package/dist/hooks/useTableSort.mjs.map +1 -0
  122. package/dist/ui/buttons/animated.js +4 -3
  123. package/dist/ui/buttons/animated.js.map +1 -1
  124. package/dist/ui/buttons/animated.mjs +2 -1
  125. package/dist/ui/buttons/animated.mjs.map +1 -1
  126. package/dist/ui/buttons.js +5 -4
  127. package/dist/ui/buttons.mjs +3 -2
  128. package/dist/ui/dynamic-stepper.js +5 -4
  129. package/dist/ui/dynamic-stepper.js.map +1 -1
  130. package/dist/ui/dynamic-stepper.mjs +3 -2
  131. package/dist/ui/dynamic-stepper.mjs.map +1 -1
  132. package/dist/ui/marquee/marquee.d.ts.map +1 -1
  133. package/dist/ui/marquee.js +82 -21
  134. package/dist/ui/marquee.js.map +1 -1
  135. package/dist/ui/marquee.mjs +83 -22
  136. package/dist/ui/marquee.mjs.map +1 -1
  137. package/dist/ui/pagination.js +5 -4
  138. package/dist/ui/pagination.js.map +1 -1
  139. package/dist/ui/pagination.mjs +2 -1
  140. package/dist/ui/pagination.mjs.map +1 -1
  141. package/dist/ui/table/animated.js +8 -8
  142. package/dist/ui/table/animated.mjs +2 -2
  143. package/dist/ui/table/index.d.ts +1 -1
  144. package/dist/ui/table/index.d.ts.map +1 -1
  145. package/dist/ui/table/table-base.d.ts +2 -2
  146. package/dist/ui/table/table-base.d.ts.map +1 -1
  147. package/dist/ui/table/types.d.ts +9 -1
  148. package/dist/ui/table/types.d.ts.map +1 -1
  149. package/dist/ui/table.js +14 -14
  150. package/dist/ui/table.mjs +1 -1
  151. package/package.json +8 -2
  152. package/src/charts/charts.test.tsx +80 -0
  153. package/src/charts/funnel/Funnel.tsx +105 -0
  154. package/src/charts/funnel/index.ts +14 -0
  155. package/src/charts/pie/Pie.tsx +28 -1
  156. package/src/charts/radar/Radar.tsx +84 -0
  157. package/src/charts/radar/index.ts +16 -0
  158. package/src/charts/scatter/Scatter.tsx +104 -0
  159. package/src/charts/scatter/index.ts +16 -0
  160. package/src/charts/shared/chart-frame.tsx +4 -2
  161. package/src/charts/shared/types.ts +42 -2
  162. package/src/charts/stacked-bar/StackedBar.tsx +12 -0
  163. package/src/charts/stacked-bar/index.ts +16 -0
  164. package/src/hooks/index.ts +12 -0
  165. package/src/hooks/useTableFilter/index.ts +7 -0
  166. package/src/hooks/useTableFilter/types.ts +28 -0
  167. package/src/hooks/useTableFilter/useTableFilter.test.ts +141 -0
  168. package/src/hooks/useTableFilter/useTableFilter.ts +153 -0
  169. package/src/hooks/useTableSort/index.ts +5 -0
  170. package/src/hooks/useTableSort/types.ts +23 -0
  171. package/src/hooks/useTableSort/useTableSort.test.ts +150 -0
  172. package/src/hooks/useTableSort/useTableSort.ts +121 -0
  173. package/src/ui/context-menu/context-menu.test.tsx +30 -0
  174. package/src/ui/divider/divider.test.tsx +55 -0
  175. package/src/ui/empty-state/empty-state.test.tsx +88 -0
  176. package/src/ui/marquee/marquee.test.tsx +45 -4
  177. package/src/ui/marquee/marquee.tsx +100 -18
  178. package/src/ui/modal/modal.test.tsx +24 -0
  179. package/src/ui/peer-isolation.test.ts +81 -0
  180. package/src/ui/select/select.test.tsx +98 -2
  181. package/src/ui/skeleton/skeleton.test.tsx +85 -0
  182. package/src/ui/table/index.ts +3 -0
  183. package/src/ui/table/table-base.tsx +69 -4
  184. package/src/ui/table/table.test.tsx +207 -0
  185. package/src/ui/table/types.ts +13 -1
  186. package/dist/chunk-ABOZ5QIX.js.map +0 -1
  187. package/dist/chunk-G2WARVAM.mjs.map +0 -1
  188. package/dist/chunk-G66SXATZ.js.map +0 -1
  189. package/dist/chunk-HDO5ZM2S.mjs.map +0 -1
  190. package/dist/chunk-OULU7OC4.mjs +0 -21
  191. package/dist/chunk-OULU7OC4.mjs.map +0 -1
  192. package/dist/chunk-QNUDODDX.js.map +0 -1
  193. package/dist/chunk-Z6S36PDD.js +0 -24
  194. package/dist/chunk-Z6S36PDD.js.map +0 -1
  195. package/dist/chunk-ZIFMIS7D.mjs.map +0 -1
@@ -0,0 +1,105 @@
1
+ "use client";
2
+
3
+ import {
4
+ Funnel,
5
+ FunnelChart as RechartsFunnelChart,
6
+ FunnelTrapezoidItem,
7
+ LabelList,
8
+ Legend,
9
+ Tooltip,
10
+ Trapezoid,
11
+ } from "recharts";
12
+
13
+ import { ChartFrame } from "../shared/chart-frame";
14
+ import { resolveColor } from "../shared/colors";
15
+ import type { FunnelChartProps } from "../shared/types";
16
+
17
+ export function FunnelChart<
18
+ TDatum extends Record<string, number | string | null | undefined>,
19
+ >({
20
+ appearance,
21
+ className,
22
+ colorKey = "color" as keyof TDatum & string,
23
+ containerStyle,
24
+ data,
25
+ dataKey,
26
+ density,
27
+ emptyState = null,
28
+ fill,
29
+ height = 320,
30
+ label = true,
31
+ nameKey,
32
+ showLegend = false,
33
+ showTooltip = true,
34
+ stroke = "#ffffff",
35
+ style,
36
+ tooltipColor = "#0f172a",
37
+ ...props
38
+ }: FunnelChartProps<TDatum>) {
39
+ const hasData = data.length > 0;
40
+ const renderDefaultShape = (
41
+ shapeProps: FunnelTrapezoidItem & { index?: number },
42
+ ) => {
43
+ const payload = shapeProps.payload as TDatum | undefined;
44
+ const dataIndex =
45
+ typeof shapeProps.index === "number" && shapeProps.index >= 0
46
+ ? shapeProps.index
47
+ : payload
48
+ ? data.indexOf(payload)
49
+ : -1;
50
+ const datumColor = payload?.[colorKey];
51
+ const color = resolveColor(
52
+ typeof datumColor === "string"
53
+ ? datumColor
54
+ : typeof fill === "string"
55
+ ? fill
56
+ : undefined,
57
+ dataIndex >= 0 ? dataIndex : 0,
58
+ );
59
+
60
+ return <Trapezoid {...shapeProps} fill={color.fill} stroke={stroke} />;
61
+ };
62
+
63
+ return (
64
+ <ChartFrame
65
+ appearance={appearance}
66
+ className={className}
67
+ containerStyle={containerStyle}
68
+ density={density}
69
+ emptyState={emptyState}
70
+ hasData={hasData}
71
+ height={height}
72
+ style={style}
73
+ {...props}
74
+ >
75
+ <RechartsFunnelChart>
76
+ {showTooltip ? (
77
+ <Tooltip
78
+ contentStyle={{ color: tooltipColor }}
79
+ labelStyle={{ color: tooltipColor }}
80
+ itemStyle={{ color: tooltipColor }}
81
+ />
82
+ ) : null}
83
+ {showLegend ? <Legend /> : null}
84
+ <Funnel
85
+ data={data}
86
+ dataKey={String(dataKey)}
87
+ nameKey={String(nameKey)}
88
+ shape={renderDefaultShape}
89
+ >
90
+ {label ? (
91
+ <LabelList
92
+ dataKey={String(nameKey)}
93
+ position="right"
94
+ fill="currentColor"
95
+ stroke="none"
96
+ fontSize={12}
97
+ />
98
+ ) : null}
99
+ </Funnel>
100
+ </RechartsFunnelChart>
101
+ </ChartFrame>
102
+ );
103
+ }
104
+
105
+ FunnelChart.displayName = "FunnelChart";
@@ -0,0 +1,14 @@
1
+ "use client";
2
+
3
+ export { FunnelChart } from "./Funnel";
4
+ export type {
5
+ ChartColor,
6
+ ChartDatum,
7
+ ChartSharedStatic,
8
+ FunnelChartProps,
9
+ } from "../shared/types";
10
+ export {
11
+ chartColorValues,
12
+ chartPalette,
13
+ chartVariants,
14
+ } from "../shared/variants";
@@ -4,11 +4,14 @@ import {
4
4
  Legend,
5
5
  Pie,
6
6
  PieLabelRenderProps,
7
+ PieSectorShapeProps,
7
8
  PieChart as RechartsPieChart,
9
+ Sector,
8
10
  Tooltip,
9
11
  } from "recharts";
10
12
 
11
13
  import { ChartFrame } from "../shared/chart-frame";
14
+ import { resolveColor } from "../shared/colors";
12
15
  import type { PieChartProps } from "../shared/types";
13
16
 
14
17
  const RADIAN = Math.PI / 180;
@@ -51,8 +54,10 @@ export function PieChart<
51
54
  className,
52
55
  containerStyle,
53
56
  cornerRadius = 10,
57
+ center,
54
58
  data,
55
59
  dataKey,
60
+ colorKey = "color" as keyof TDatum & string,
56
61
  density,
57
62
  emptyState = null,
58
63
  height = 320,
@@ -73,6 +78,21 @@ export function PieChart<
73
78
  ...props
74
79
  }: PieChartProps<TDatum>) {
75
80
  const hasData = data.length > 0;
81
+ const renderDefaultShape = (props: PieSectorShapeProps, index: number) => {
82
+ const payload = props.payload as TDatum | undefined;
83
+ const shapeDatum = props as unknown as TDatum;
84
+ const datumColor = payload?.[colorKey] ?? shapeDatum[colorKey];
85
+ const color = resolveColor(
86
+ typeof datumColor === "string"
87
+ ? datumColor
88
+ : typeof fill === "string"
89
+ ? fill
90
+ : undefined,
91
+ typeof index === "number" ? index : props.index,
92
+ );
93
+
94
+ return <Sector {...props} fill={color.fill} stroke={stroke} />;
95
+ };
76
96
 
77
97
  return (
78
98
  <ChartFrame
@@ -83,6 +103,13 @@ export function PieChart<
83
103
  emptyState={emptyState}
84
104
  hasData={hasData}
85
105
  height={height}
106
+ overlay={
107
+ center ? (
108
+ <div className="pointer-events-none absolute inset-0 flex items-center justify-center text-center">
109
+ {center}
110
+ </div>
111
+ ) : null
112
+ }
86
113
  style={style}
87
114
  {...props}
88
115
  >
@@ -112,7 +139,7 @@ export function PieChart<
112
139
  }
113
140
  stroke={stroke}
114
141
  fill={fill}
115
- shape={shape}
142
+ shape={shape ?? renderDefaultShape}
116
143
  />
117
144
  </RechartsPieChart>
118
145
  </ChartFrame>
@@ -0,0 +1,84 @@
1
+ "use client";
2
+
3
+ import {
4
+ Legend,
5
+ PolarAngleAxis,
6
+ PolarGrid,
7
+ PolarRadiusAxis,
8
+ Radar,
9
+ RadarChart as RechartsRadarChart,
10
+ Tooltip,
11
+ } from "recharts";
12
+
13
+ import { ChartFrame } from "../shared/chart-frame";
14
+ import { getSeriesFill, resolveColor } from "../shared/colors";
15
+ import type { RadarChartProps } from "../shared/types";
16
+
17
+ export function RadarChart<
18
+ TDatum extends Record<string, number | string | null | undefined>,
19
+ >({
20
+ appearance,
21
+ className,
22
+ containerStyle,
23
+ data,
24
+ density,
25
+ emptyState = null,
26
+ height = 320,
27
+ series,
28
+ showGrid = true,
29
+ showLegend = false,
30
+ showTooltip = true,
31
+ tooltipColor = "#0f172a",
32
+ style,
33
+ xKey,
34
+ ...props
35
+ }: RadarChartProps<TDatum>) {
36
+ const hasData = data.length > 0 && series.length > 0;
37
+
38
+ return (
39
+ <ChartFrame
40
+ appearance={appearance}
41
+ className={className}
42
+ containerStyle={containerStyle}
43
+ density={density}
44
+ emptyState={emptyState}
45
+ hasData={hasData}
46
+ height={height}
47
+ style={style}
48
+ {...props}
49
+ >
50
+ <RechartsRadarChart data={data}>
51
+ {showGrid ? <PolarGrid stroke="currentColor" opacity={0.18} /> : null}
52
+ <PolarAngleAxis
53
+ dataKey={String(xKey)}
54
+ tick={{ fill: "currentColor", fontSize: 12 }}
55
+ />
56
+ <PolarRadiusAxis tick={{ fill: "currentColor", fontSize: 11 }} />
57
+ {showTooltip ? (
58
+ <Tooltip
59
+ contentStyle={{ color: tooltipColor }}
60
+ labelStyle={{ color: tooltipColor }}
61
+ itemStyle={{ color: tooltipColor }}
62
+ />
63
+ ) : null}
64
+ {showLegend ? <Legend /> : null}
65
+ {series.map((item, index) => {
66
+ const color = resolveColor(item.color, index);
67
+ const fill = getSeriesFill(item, index, 0.24);
68
+ return (
69
+ <Radar
70
+ key={item.dataKey}
71
+ dataKey={item.dataKey}
72
+ name={item.name}
73
+ stroke={item.stroke ?? color.stroke}
74
+ fill={fill ?? color.fill}
75
+ fillOpacity={0.72}
76
+ />
77
+ );
78
+ })}
79
+ </RechartsRadarChart>
80
+ </ChartFrame>
81
+ );
82
+ }
83
+
84
+ RadarChart.displayName = "RadarChart";
@@ -0,0 +1,16 @@
1
+ "use client";
2
+
3
+ export { RadarChart } from "./Radar";
4
+ export type {
5
+ ChartColor,
6
+ ChartDatum,
7
+ ChartMargin,
8
+ ChartSeries,
9
+ ChartSharedStatic,
10
+ RadarChartProps,
11
+ } from "../shared/types";
12
+ export {
13
+ chartColorValues,
14
+ chartPalette,
15
+ chartVariants,
16
+ } from "../shared/variants";
@@ -0,0 +1,104 @@
1
+ "use client";
2
+
3
+ import {
4
+ Scatter,
5
+ ScatterChart as RechartsScatterChart,
6
+ XAxis,
7
+ YAxis,
8
+ } from "recharts";
9
+
10
+ import {
11
+ ChartDecorators,
12
+ ChartFrame,
13
+ defaultChartMargin,
14
+ } from "../shared/chart-frame";
15
+ import { resolveColor } from "../shared/colors";
16
+ import type { ScatterChartProps } from "../shared/types";
17
+
18
+ export function ScatterChart<
19
+ TDatum extends Record<string, number | string | null | undefined>,
20
+ >({
21
+ appearance,
22
+ className,
23
+ containerStyle,
24
+ data,
25
+ density,
26
+ emptyState = null,
27
+ height = 320,
28
+ margin = defaultChartMargin,
29
+ series,
30
+ showGrid = true,
31
+ showLegend = false,
32
+ showTooltip = true,
33
+ tooltipColor = "#0f172a",
34
+ style,
35
+ syncId,
36
+ xKey,
37
+ ...props
38
+ }: ScatterChartProps<TDatum>) {
39
+ const hasData = data.length > 0 && series.length > 0;
40
+ const xAxisKey = String(xKey);
41
+ const isNumericX = typeof data[0]?.[xAxisKey] === "number";
42
+
43
+ return (
44
+ <ChartFrame
45
+ appearance={appearance}
46
+ className={className}
47
+ containerStyle={containerStyle}
48
+ density={density}
49
+ emptyState={emptyState}
50
+ hasData={hasData}
51
+ height={height}
52
+ style={style}
53
+ {...props}
54
+ >
55
+ <RechartsScatterChart data={data} margin={margin} syncId={syncId}>
56
+ <ChartDecorators
57
+ axis={
58
+ <>
59
+ <XAxis
60
+ dataKey={xAxisKey}
61
+ type={isNumericX ? "number" : "category"}
62
+ minTickGap={24}
63
+ tickLine={false}
64
+ tickMargin={10}
65
+ axisLine={false}
66
+ fontSize={12}
67
+ />
68
+ <YAxis
69
+ dataKey="__chartY"
70
+ type="number"
71
+ width={40}
72
+ tickLine={false}
73
+ tickMargin={8}
74
+ axisLine={false}
75
+ fontSize={12}
76
+ />
77
+ </>
78
+ }
79
+ showGrid={showGrid}
80
+ showLegend={showLegend}
81
+ showTooltip={showTooltip}
82
+ tooltipColor={tooltipColor}
83
+ />
84
+ {series.map((item, index) => {
85
+ const color = resolveColor(item.color, index);
86
+ return (
87
+ <Scatter
88
+ key={item.dataKey}
89
+ data={data.map((entry) => ({
90
+ ...entry,
91
+ __chartY: entry[item.dataKey],
92
+ }))}
93
+ name={item.name}
94
+ fill={item.fill ?? color.stroke}
95
+ line={item.stroke ? { stroke: item.stroke } : false}
96
+ />
97
+ );
98
+ })}
99
+ </RechartsScatterChart>
100
+ </ChartFrame>
101
+ );
102
+ }
103
+
104
+ ScatterChart.displayName = "ScatterChart";
@@ -0,0 +1,16 @@
1
+ "use client";
2
+
3
+ export { ScatterChart } from "./Scatter";
4
+ export type {
5
+ ChartColor,
6
+ ChartDatum,
7
+ ChartMargin,
8
+ ChartSeries,
9
+ ChartSharedStatic,
10
+ ScatterChartProps,
11
+ } from "../shared/types";
12
+ export {
13
+ chartColorValues,
14
+ chartPalette,
15
+ chartVariants,
16
+ } from "../shared/variants";
@@ -39,6 +39,7 @@ type ChartFrameProps = HTMLAttributes<HTMLDivElement> & {
39
39
  emptyState?: ReactNode;
40
40
  hasData: boolean;
41
41
  height: number;
42
+ overlay?: ReactNode;
42
43
  style?: CSSProperties;
43
44
  children: ReactNode;
44
45
  };
@@ -54,6 +55,7 @@ export function ChartFrame({
54
55
  emptyState = null,
55
56
  hasData,
56
57
  height,
58
+ overlay,
57
59
  style,
58
60
  ...props
59
61
  }: ChartFrameProps) {
@@ -63,8 +65,7 @@ export function ChartFrame({
63
65
  "--chart-height": `${height}px`,
64
66
  ...style,
65
67
  } as CSSProperties;
66
- const canRenderChart =
67
- (size?.width ?? 0) > 0 && (size?.height ?? 0) > 0;
68
+ const canRenderChart = (size?.width ?? 0) > 0 && (size?.height ?? 0) > 0;
68
69
 
69
70
  if (!hasData) {
70
71
  return (
@@ -99,6 +100,7 @@ export function ChartFrame({
99
100
  </ResponsiveContainer>
100
101
  ) : null}
101
102
  </div>
103
+ {overlay}
102
104
  </div>
103
105
  );
104
106
  }
@@ -2,9 +2,18 @@ import type { VariantProps } from "class-variance-authority";
2
2
  import type { CSSProperties, HTMLAttributes, ReactNode } from "react";
3
3
 
4
4
  import type { chartPalette, chartVariants } from "./variants";
5
- import { PieProps } from "recharts";
5
+ import type { PieProps } from "recharts";
6
6
 
7
- export type ChartType = "area" | "bar" | "bubble" | "line" | "pie";
7
+ export type ChartType =
8
+ | "area"
9
+ | "bar"
10
+ | "bubble"
11
+ | "funnel"
12
+ | "line"
13
+ | "pie"
14
+ | "radar"
15
+ | "scatter"
16
+ | "stacked-bar";
8
17
 
9
18
  export type ChartColor = keyof typeof chartPalette;
10
19
 
@@ -61,6 +70,17 @@ export type LineChartProps<TDatum extends ChartDatum = ChartDatum> =
61
70
  export type BubbleChartProps<TDatum extends ChartDatum = ChartDatum> =
62
71
  BaseChartProps<TDatum>;
63
72
 
73
+ export type RadarChartProps<TDatum extends ChartDatum = ChartDatum> =
74
+ BaseChartProps<TDatum>;
75
+
76
+ export type ScatterChartProps<TDatum extends ChartDatum = ChartDatum> =
77
+ BaseChartProps<TDatum>;
78
+
79
+ export type StackedBarChartProps<TDatum extends ChartDatum = ChartDatum> = Omit<
80
+ BaseChartProps<TDatum>,
81
+ "stacked"
82
+ >;
83
+
64
84
  export type PieChartProps<TDatum extends ChartDatum = ChartDatum> =
65
85
  ChartSharedStatic &
66
86
  Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
@@ -75,6 +95,8 @@ export type PieChartProps<TDatum extends ChartDatum = ChartDatum> =
75
95
  containerStyle?: CSSProperties;
76
96
  paddingAngle?: PieProps["paddingAngle"];
77
97
  cornerRadius?: PieProps["cornerRadius"];
98
+ center?: ReactNode;
99
+ colorKey?: keyof TDatum & string;
78
100
  label?: boolean;
79
101
  labelLine?: boolean;
80
102
  labelColor?: string;
@@ -84,3 +106,21 @@ export type PieChartProps<TDatum extends ChartDatum = ChartDatum> =
84
106
  outerRadius?: PieProps["outerRadius"];
85
107
  shape?: PieProps["shape"];
86
108
  };
109
+
110
+ export type FunnelChartProps<TDatum extends ChartDatum = ChartDatum> =
111
+ ChartSharedStatic &
112
+ Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
113
+ data: TDatum[];
114
+ dataKey: keyof TDatum & string;
115
+ nameKey: keyof TDatum & string;
116
+ height?: number;
117
+ showLegend?: boolean;
118
+ showTooltip?: boolean;
119
+ tooltipColor?: string;
120
+ emptyState?: ReactNode;
121
+ containerStyle?: CSSProperties;
122
+ colorKey?: keyof TDatum & string;
123
+ label?: boolean;
124
+ stroke?: string;
125
+ fill?: string;
126
+ };
@@ -0,0 +1,12 @@
1
+ "use client";
2
+
3
+ import { BarChart } from "../bar/Bar";
4
+ import type { StackedBarChartProps } from "../shared/types";
5
+
6
+ export function StackedBarChart<
7
+ TDatum extends Record<string, number | string | null | undefined>,
8
+ >(props: StackedBarChartProps<TDatum>) {
9
+ return <BarChart {...props} stacked />;
10
+ }
11
+
12
+ StackedBarChart.displayName = "StackedBarChart";
@@ -0,0 +1,16 @@
1
+ "use client";
2
+
3
+ export { StackedBarChart } from "./StackedBar";
4
+ export type {
5
+ ChartColor,
6
+ ChartDatum,
7
+ ChartMargin,
8
+ ChartSeries,
9
+ ChartSharedStatic,
10
+ StackedBarChartProps,
11
+ } from "../shared/types";
12
+ export {
13
+ chartColorValues,
14
+ chartPalette,
15
+ chartVariants,
16
+ } from "../shared/variants";
@@ -49,6 +49,18 @@ export {
49
49
  useSessionStorage,
50
50
  type UseSessionStorageResult,
51
51
  } from "./useSessionStorage";
52
+ export {
53
+ useTableFilter,
54
+ type TableFilterPredicate,
55
+ type TableFilterState,
56
+ type UseTableFilterParams,
57
+ type UseTableFilterResult,
58
+ } from "./useTableFilter";
59
+ export {
60
+ useTableSort,
61
+ type UseTableSortParams,
62
+ type UseTableSortResult,
63
+ } from "./useTableSort";
52
64
  export { useThrottledCallback } from "./useThrottledCallback";
53
65
  export { useToggle } from "./useToggle";
54
66
  export { useWindowSize, type WindowSize } from "./useWindowSize";
@@ -0,0 +1,7 @@
1
+ export {
2
+ type TableFilterPredicate,
3
+ type TableFilterState,
4
+ type UseTableFilterParams,
5
+ type UseTableFilterResult,
6
+ } from "./types";
7
+ export { useTableFilter } from "./useTableFilter";
@@ -0,0 +1,28 @@
1
+ export type TableFilterState<TKey extends string = string> = Partial<
2
+ Record<TKey, string>
3
+ >;
4
+
5
+ export type TableFilterPredicate<TData, TKey extends string = string> = (
6
+ row: TData,
7
+ filterValue: string,
8
+ filterKey: TKey,
9
+ ) => boolean;
10
+
11
+ export type UseTableFilterParams<TData, TKey extends string = string> = {
12
+ data: readonly TData[];
13
+ filters?: TableFilterState<TKey>;
14
+ defaultFilters?: TableFilterState<TKey>;
15
+ onFiltersChange?: (filters: TableFilterState<TKey>) => void;
16
+ getColumnValue?: (row: TData, filterKey: TKey) => unknown;
17
+ filterPredicate?: TableFilterPredicate<TData, TKey>;
18
+ };
19
+
20
+ export type UseTableFilterResult<TData, TKey extends string = string> = {
21
+ filters: TableFilterState<TKey>;
22
+ filteredData: TData[];
23
+ hasActiveFilters: boolean;
24
+ setFilter: (filterKey: TKey, value: string) => void;
25
+ setFilters: (filters: TableFilterState<TKey>) => void;
26
+ clearFilter: (filterKey: TKey) => void;
27
+ clearFilters: () => void;
28
+ };