@giddaa-housing/ui 1.1.0 → 2.0.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 (47) hide show
  1. package/css/generated/shared.css +1 -1
  2. package/css/giddaa.css +12 -2
  3. package/dist/badge.js +1 -1
  4. package/dist/bullet-chart.d.ts +8 -4
  5. package/dist/bullet-chart.js +10 -6
  6. package/dist/button.js +1 -1
  7. package/dist/card.js +1 -1
  8. package/dist/chart.d.ts +33 -5
  9. package/dist/chart.js +210 -13
  10. package/dist/checkbox.js +1 -1
  11. package/dist/data-table.d.ts +7 -3
  12. package/dist/data-table.js +8 -5
  13. package/dist/dialog-nesting.d.ts +9 -0
  14. package/dist/dialog-nesting.js +27 -0
  15. package/dist/dialog.js +9 -5
  16. package/dist/file-upload.d.ts +43 -0
  17. package/dist/file-upload.js +154 -0
  18. package/dist/funnel-chart.d.ts +11 -7
  19. package/dist/funnel-chart.js +11 -8
  20. package/dist/input-group.js +1 -1
  21. package/dist/input-otp.d.ts +23 -0
  22. package/dist/input-otp.js +56 -0
  23. package/dist/input.js +1 -1
  24. package/dist/line-chart.d.ts +113 -41
  25. package/dist/line-chart.js +217 -30
  26. package/dist/list-item.d.ts +22 -0
  27. package/dist/list-item.js +84 -0
  28. package/dist/number-input.js +20 -17
  29. package/dist/pie-chart.d.ts +83 -52
  30. package/dist/pie-chart.js +85 -43
  31. package/dist/purchase-option-card.d.ts +79 -0
  32. package/dist/purchase-option-card.js +176 -0
  33. package/dist/radio-group.js +1 -1
  34. package/dist/select.js +1 -1
  35. package/dist/sheet.d.ts +4 -2
  36. package/dist/sheet.js +22 -11
  37. package/dist/sparkline.d.ts +28 -15
  38. package/dist/sparkline.js +131 -37
  39. package/dist/styles.css +831 -119
  40. package/dist/switch.js +1 -1
  41. package/dist/table.js +6 -2
  42. package/dist/tabs.d.ts +21 -5
  43. package/dist/tabs.js +55 -12
  44. package/dist/textarea.js +1 -1
  45. package/dist/tree-map.d.ts +14 -14
  46. package/dist/tree-map.js +14 -15
  47. package/package.json +17 -1
@@ -1,7 +1,48 @@
1
1
  "use client";
2
- import { useComponentSize } from "./size-context.js";
3
- import { cartesianAxisProps } from "./chart.js";
2
+ import { t as cn } from "./cn-BI_4DMBf.js";
3
+ import { SizeProvider, useComponentSize } from "./size-context.js";
4
+ import { ChartContainer, cartesianAxisProps } from "./chart.js";
5
+ import { jsx } from "react/jsx-runtime";
6
+ import { Area, AreaChart as AreaChart$1, CartesianGrid, Line, LineChart as LineChart$1, XAxis, YAxis } from "recharts";
4
7
  //#region src/line-chart.tsx
8
+ /**
9
+ * Line and area charts are composable wrappers over the recharts cartesian
10
+ * primitives. recharts 3 registers graphical items through context when they
11
+ * render, so the primitives CAN be wrapped in our own components. Each wrapper
12
+ * bakes in the giddaa defaults (tokens, size-scaled type, mark specs) and
13
+ * forwards every recharts prop, so anything can be overridden in place or
14
+ * replaced with the raw recharts element.
15
+ *
16
+ * Anatomy: `LineChart`/`AreaChart` are the plot roots (frame + responsive box +
17
+ * recharts chart); compose the grid, axes, series, and the shared overlays from
18
+ * `./chart` as children. Both roots share the same axis and grid wrappers.
19
+ *
20
+ * @example
21
+ * <ChartCard size="md">
22
+ * <ChartHeader>
23
+ * <ChartTitle>Revenue Overview</ChartTitle>
24
+ * <ChartDescription>Monthly revenue · Jan–Jul</ChartDescription>
25
+ * </ChartHeader>
26
+ * <AreaChart config={config} data={data}>
27
+ * <LineChartGrid />
28
+ * <LineChartXAxis dataKey="month" />
29
+ * <LineChartYAxis />
30
+ * <ChartTooltip content={<ChartTooltipContent />} />
31
+ * <AreaChartSeries dataKey="revenue" name="Revenue" />
32
+ * </AreaChart>
33
+ * </ChartCard>
34
+ */
35
+ /**
36
+ * Categorical series palette — the theme-aware `chart-1`…`chart-3` tokens.
37
+ * Assign colours in this fixed order, never cycled: a fourth series folds into
38
+ * "Other" or becomes a second chart.
39
+ */
40
+ const LINE_CHART_PALETTE = [
41
+ "var(--color-chart-1)",
42
+ "var(--color-chart-2)",
43
+ "var(--color-chart-3)"
44
+ ];
45
+ const DEFAULT_SERIES_COLOR = LINE_CHART_PALETTE[0];
5
46
  const LINE_CHART_LAYOUT = {
6
47
  sm: {
7
48
  height: 64,
@@ -57,8 +98,8 @@ const LINE_CHART_LAYOUT = {
57
98
  left: 0
58
99
  },
59
100
  strokeWidth: 2,
60
- dotRadius: 4,
61
- activeDotRadius: 5.5,
101
+ dotRadius: 3.5,
102
+ activeDotRadius: 5,
62
103
  tickFontSize: 11,
63
104
  yAxisWidth: 28,
64
105
  tickMargin: 6
@@ -72,30 +113,143 @@ const LINE_CHART_LAYOUT = {
72
113
  left: 0
73
114
  },
74
115
  strokeWidth: 2,
75
- dotRadius: 4.5,
76
- activeDotRadius: 6,
116
+ dotRadius: 3.5,
117
+ activeDotRadius: 5,
77
118
  tickFontSize: 12,
78
119
  yAxisWidth: 30,
79
120
  tickMargin: 7
80
121
  }
81
122
  };
82
- /** Map the 5 line-chart sizes to the 3 ComponentSize values for ChartCard. */
123
+ /** Clamp the 5 line-chart sizes to the 3 `ComponentSize` values for children. */
83
124
  function toComponentSize(size) {
84
125
  if (size === "xl" || size === "huge") return "lg";
85
126
  return size;
86
127
  }
128
+ /** Resolve the layout for an explicit or inherited line-chart size. */
129
+ function useLineChartSize(size) {
130
+ const inherited = useComponentSize();
131
+ const resolved = size ?? inherited;
132
+ return {
133
+ size: resolved,
134
+ layout: LINE_CHART_LAYOUT[resolved] ?? LINE_CHART_LAYOUT.md
135
+ };
136
+ }
137
+ /**
138
+ * Plot root — wraps the shared `ChartContainer` (tooltip/legend theming,
139
+ * responsive box) around the recharts `LineChart` with a size-scaled height and
140
+ * margin. `size` flows to the child primitives through `SizeProvider` (clamped
141
+ * to `lg` for `xl`/`huge`). Extra props reach the recharts chart (`data`,
142
+ * `syncId`, …).
143
+ */
144
+ function LineChart({ config = {}, size, className, children, ...props }) {
145
+ const { size: resolved, layout } = useLineChartSize(size);
146
+ return /* @__PURE__ */ jsx(SizeProvider, {
147
+ size: toComponentSize(resolved),
148
+ children: /* @__PURE__ */ jsx(ChartContainer, {
149
+ config,
150
+ className: cn("aspect-auto w-full", className),
151
+ style: { height: layout.height },
152
+ children: /* @__PURE__ */ jsx(LineChart$1, {
153
+ accessibilityLayer: true,
154
+ margin: layout.margin,
155
+ ...props,
156
+ children
157
+ })
158
+ })
159
+ });
160
+ }
161
+ /**
162
+ * Plot root for filled trends — identical to `LineChart` but wraps the recharts
163
+ * `AreaChart`, so it hosts `AreaChartSeries` (and the same grid/axes/overlays).
164
+ */
165
+ function AreaChart({ config = {}, size, className, children, ...props }) {
166
+ const { size: resolved, layout } = useLineChartSize(size);
167
+ return /* @__PURE__ */ jsx(SizeProvider, {
168
+ size: toComponentSize(resolved),
169
+ children: /* @__PURE__ */ jsx(ChartContainer, {
170
+ config,
171
+ className: cn("aspect-auto w-full", className),
172
+ style: { height: layout.height },
173
+ children: /* @__PURE__ */ jsx(AreaChart$1, {
174
+ accessibilityLayer: true,
175
+ margin: layout.margin,
176
+ ...props,
177
+ children
178
+ })
179
+ })
180
+ });
181
+ }
182
+ /**
183
+ * Value reference lines — recharts `CartesianGrid` with vertical lines hidden
184
+ * and the visible grid painted with the `line` token (`line-subtle` matches the
185
+ * chart card surface in both themes, so it would vanish).
186
+ */
187
+ function LineChartGrid(props) {
188
+ return /* @__PURE__ */ jsx(CartesianGrid, {
189
+ vertical: false,
190
+ stroke: "var(--color-line)",
191
+ ...props
192
+ });
193
+ }
194
+ /**
195
+ * Category (time) axis — recharts `XAxis` with no axis/tick lines, a size-scaled
196
+ * tick margin, and caption-placeholder tick ink. Passing your own `tick`
197
+ * replaces the default styling entirely.
198
+ */
199
+ function LineChartXAxis({ size, tick, ...props }) {
200
+ const { layout } = useLineChartSize(size);
201
+ const axes = cartesianAxisProps({
202
+ tickMargin: layout.tickMargin,
203
+ tickFontSize: layout.tickFontSize,
204
+ yAxisWidth: layout.yAxisWidth
205
+ });
206
+ const defaultTick = {
207
+ ...axes.xAxis.tick,
208
+ fill: "var(--color-fg-caption-placeholder)"
209
+ };
210
+ return /* @__PURE__ */ jsx(XAxis, {
211
+ tickLine: axes.xAxis.tickLine,
212
+ axisLine: axes.xAxis.axisLine,
213
+ tickMargin: axes.xAxis.tickMargin,
214
+ tick: tick ?? defaultTick,
215
+ ...props
216
+ });
217
+ }
87
218
  /**
88
- * Build the colour-bound props for a `<Line>`/`<Area>` series at a given size:
89
- * the rounded stroke geometry plus the resting and active dots, all painted in
90
- * `color`. `area` adds the 15 %-opacity wash beneath the stroke.
219
+ * Value axis recharts `YAxis` with no axis/tick lines, size-scaled tick type,
220
+ * and reserved width for value labels. Override `width` for long labels.
91
221
  */
92
- function seriesProps(layout, color) {
222
+ function LineChartYAxis({ size, tick, ...props }) {
223
+ const { layout } = useLineChartSize(size);
224
+ const axes = cartesianAxisProps({
225
+ tickMargin: layout.tickMargin,
226
+ tickFontSize: layout.tickFontSize,
227
+ yAxisWidth: layout.yAxisWidth
228
+ });
229
+ const defaultTick = {
230
+ ...axes.yAxis.tick,
231
+ fill: "var(--color-fg-caption-placeholder)"
232
+ };
233
+ return /* @__PURE__ */ jsx(YAxis, {
234
+ tickLine: axes.yAxis.tickLine,
235
+ axisLine: axes.yAxis.axisLine,
236
+ width: axes.yAxis.width,
237
+ tick: tick ?? defaultTick,
238
+ ...props
239
+ });
240
+ }
241
+ /** The giddaa line mark spec: rounded 2px stroke, resting + surface-ringed active dots. */
242
+ function lineMarkProps(layout, color) {
93
243
  return {
94
244
  type: "linear",
95
245
  stroke: color,
96
246
  strokeWidth: layout.strokeWidth,
97
247
  strokeLinejoin: "round",
98
- strokeLinecap: "round",
248
+ strokeLinecap: "round"
249
+ };
250
+ }
251
+ function defaultDots(layout, color) {
252
+ return {
99
253
  dot: {
100
254
  r: layout.dotRadius,
101
255
  fill: color,
@@ -110,23 +264,56 @@ function seriesProps(layout, color) {
110
264
  };
111
265
  }
112
266
  /**
113
- * Resolve the line-chart layout for an explicit or inherited component size. The
114
- * returned object groups the giddaa defaults by the recharts component they
115
- * belong to. `line(color)`/`area(color)` return the full series props for a
116
- * given colour spread each onto its element, then pass the data-specific props
117
- * (`config`, `data`, `dataKey`, …) directly afterwards to add or override:
118
- *
119
- * const chart = useLineChartLayout(size);
120
- * <ChartContainer config={config} {...chart.container}>
121
- * <AreaChart data={data} {...chart.chart}>
122
- * <XAxis dataKey="month" {...chart.xAxis} />
123
- * <YAxis {...chart.yAxis} />
124
- * <Area dataKey="revenue" {...chart.area("var(--color-revenue)")} />
267
+ * One line series recharts `Line` with the giddaa mark spec: a 2px rounded
268
+ * stroke in `color`, solid resting dots, and a hover dot ringed in
269
+ * `surface-raised` so overlapping series stay separable. `color` drives all of
270
+ * them at once; `stroke`/`dot`/`activeDot` still win when passed directly.
271
+ */
272
+ function LineChartSeries({ color = DEFAULT_SERIES_COLOR, size, dot, activeDot, ...props }) {
273
+ const { layout } = useLineChartSize(size);
274
+ const dots = defaultDots(layout, color);
275
+ return /* @__PURE__ */ jsx(Line, {
276
+ ...lineMarkProps(layout, color),
277
+ dot: dot ?? dots.dot,
278
+ activeDot: activeDot ?? dots.activeDot,
279
+ ...props
280
+ });
281
+ }
282
+ /**
283
+ * One area series — recharts `Area` with the giddaa mark spec: the same rounded
284
+ * 2px stroke and dots as `LineChartSeries`, plus the series colour washed to 15%
285
+ * beneath the stroke. `color` drives stroke + fill + dots at once;
286
+ * `stroke`/`fill`/`dot` still win when passed directly.
287
+ */
288
+ function AreaChartSeries({ color = DEFAULT_SERIES_COLOR, size, dot, activeDot, ...props }) {
289
+ const { layout } = useLineChartSize(size);
290
+ const dots = defaultDots(layout, color);
291
+ return /* @__PURE__ */ jsx(Area, {
292
+ ...lineMarkProps(layout, color),
293
+ fill: color,
294
+ fillOpacity: .15,
295
+ dot: dot ?? dots.dot,
296
+ activeDot: activeDot ?? dots.activeDot,
297
+ ...props
298
+ });
299
+ }
300
+ /**
301
+ * @deprecated Compose the `<LineChart>`/`<AreaChart>` primitives instead — see
302
+ * the module example. This layout hook predates recharts 3 wrapping support and
303
+ * will be removed in the next major. It returns prop bags to spread onto raw
304
+ * recharts elements.
125
305
  */
126
306
  function useLineChartLayout(size) {
127
- const inheritedSize = useComponentSize();
128
- const layout = LINE_CHART_LAYOUT[size ?? inheritedSize] ?? LINE_CHART_LAYOUT.md;
129
- const axes = cartesianAxisProps(layout);
307
+ const { layout } = useLineChartSize(size);
308
+ const axes = cartesianAxisProps({
309
+ tickMargin: layout.tickMargin,
310
+ tickFontSize: layout.tickFontSize,
311
+ yAxisWidth: layout.yAxisWidth
312
+ });
313
+ const series = (color) => ({
314
+ ...lineMarkProps(layout, color),
315
+ ...defaultDots(layout, color)
316
+ });
130
317
  return {
131
318
  container: {
132
319
  className: "aspect-auto w-full",
@@ -138,13 +325,13 @@ function useLineChartLayout(size) {
138
325
  },
139
326
  xAxis: axes.xAxis,
140
327
  yAxis: axes.yAxis,
141
- line: (color) => seriesProps(layout, color),
328
+ line: (color) => series(color),
142
329
  area: (color) => ({
143
- ...seriesProps(layout, color),
330
+ ...series(color),
144
331
  fill: color,
145
332
  fillOpacity: .15
146
333
  })
147
334
  };
148
335
  }
149
336
  //#endregion
150
- export { LINE_CHART_LAYOUT, toComponentSize, useLineChartLayout };
337
+ export { AreaChart, AreaChartSeries, LINE_CHART_LAYOUT, LINE_CHART_PALETTE, LineChart, LineChartGrid, LineChartSeries, LineChartXAxis, LineChartYAxis, toComponentSize, useLineChartLayout };
@@ -0,0 +1,22 @@
1
+ import { Avatar } from "./avatar.js";
2
+ import { useRender } from "@base-ui/react/use-render";
3
+ import { VariantProps } from "class-variance-authority";
4
+ import { ComponentProps } from "react";
5
+ //#region src/list-item.d.ts
6
+ declare const listItemVariants: (props?: ({
7
+ size?: "lg" | "md" | null | undefined;
8
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
9
+ type ListItemSize = NonNullable<VariantProps<typeof listItemVariants>["size"]>;
10
+ type ListItemProps = useRender.ComponentProps<"div"> & VariantProps<typeof listItemVariants> & {
11
+ selected?: boolean;
12
+ };
13
+ declare function ListItem({ className, render, size, selected, ...props }: ListItemProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
14
+ declare function ListItemAvatar({ className, size, ...props }: ComponentProps<typeof Avatar>): import("react").JSX.Element;
15
+ declare function ListItemIcon({ className, ...props }: ComponentProps<"span">): import("react").JSX.Element;
16
+ declare function ListItemContent({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
17
+ declare function ListItemTitle({ className, ...props }: ComponentProps<"p">): import("react").JSX.Element;
18
+ declare function ListItemDescription({ className, ...props }: ComponentProps<"p">): import("react").JSX.Element;
19
+ declare function ListItemMeta({ className, ...props }: ComponentProps<"span">): import("react").JSX.Element;
20
+ declare function ListItemCount({ className, ...props }: ComponentProps<"span">): import("react").JSX.Element;
21
+ //#endregion
22
+ export { ListItem, ListItemAvatar, ListItemContent, ListItemCount, ListItemDescription, ListItemIcon, ListItemMeta, type ListItemProps, type ListItemSize, ListItemTitle, listItemVariants };
@@ -0,0 +1,84 @@
1
+ "use client";
2
+ import { t as cn } from "./cn-BI_4DMBf.js";
3
+ import { Avatar } from "./avatar.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { mergeProps } from "@base-ui/react/merge-props";
6
+ import { useRender } from "@base-ui/react/use-render";
7
+ import { cva } from "class-variance-authority";
8
+ //#region src/list-item.tsx
9
+ const listItemVariants = cva("group/list-item flex w-full min-w-0 items-center border-b border-line-subtle bg-surface text-left text-fg-primary transition-[background-color,color,opacity,box-shadow] outline-none data-[selected=true]:bg-surface-brand-subtle [button,a,[role=button],[role=link]]:cursor-pointer [button,a,[role=button],[role=link]]:select-none [button,a,[role=button],[role=link]]:hover:bg-surface-raised [button,a,[role=button],[role=link]]:active:bg-surface-raised data-[selected=true]:[button,a,[role=button],[role=link]]:hover:bg-surface-brand-subtle data-[selected=true]:[button,a,[role=button],[role=link]]:active:bg-surface-brand-subtle disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 focus-visible:border-line-focus focus-visible:shadow-[0px_0px_0px_2px_var(--color-line-focus)]", {
10
+ variants: { size: {
11
+ md: "gap-3 px-4 py-3.5",
12
+ lg: "gap-4 px-5 py-4.5"
13
+ } },
14
+ defaultVariants: { size: "md" }
15
+ });
16
+ function ListItem({ className, render, size = "md", selected = false, ...props }) {
17
+ return useRender({
18
+ defaultTagName: "div",
19
+ props: mergeProps({
20
+ className: cn(listItemVariants({ size }), className),
21
+ "data-selected": selected,
22
+ "data-size": size,
23
+ "data-slot": "list-item"
24
+ }, props),
25
+ render,
26
+ state: {
27
+ slot: "list-item",
28
+ size,
29
+ selected
30
+ }
31
+ });
32
+ }
33
+ function ListItemAvatar({ className, size = "sm", ...props }) {
34
+ return /* @__PURE__ */ jsx(Avatar, {
35
+ "data-slot": "list-item-avatar",
36
+ size,
37
+ className: cn("group-data-[size=md]/list-item:size-8 group-data-[size=lg]/list-item:size-10", "**:data-[slot=avatar-fallback]:bg-action-tertiary **:data-[slot=avatar-fallback]:text-fg-primary", "group-data-[selected=true]/list-item:**:data-[slot=avatar-fallback]:bg-surface-brand group-data-[selected=true]/list-item:**:data-[slot=avatar-fallback]:text-fg-on-brand", className),
38
+ ...props
39
+ });
40
+ }
41
+ function ListItemIcon({ className, ...props }) {
42
+ return /* @__PURE__ */ jsx("span", {
43
+ "data-slot": "list-item-icon",
44
+ className: cn("flex shrink-0 items-center justify-center text-fg-secondary [&>svg]:shrink-0", "group-data-[size=md]/list-item:size-5 group-data-[size=md]/list-item:[&>svg]:size-5", "group-data-[size=lg]/list-item:size-6 group-data-[size=lg]/list-item:[&>svg]:size-6", className),
45
+ ...props
46
+ });
47
+ }
48
+ function ListItemContent({ className, ...props }) {
49
+ return /* @__PURE__ */ jsx("div", {
50
+ "data-slot": "list-item-content",
51
+ className: cn("flex min-w-0 flex-1 flex-col gap-0.5", className),
52
+ ...props
53
+ });
54
+ }
55
+ function ListItemTitle({ className, ...props }) {
56
+ return /* @__PURE__ */ jsx("p", {
57
+ "data-slot": "list-item-title",
58
+ className: cn("min-w-0 truncate font-semibold text-fg-primary group-data-[selected=true]/list-item:text-fg-brand group-disabled/list-item:text-fg-caption-placeholder group-aria-disabled/list-item:text-fg-caption-placeholder", "group-data-[size=md]/list-item:text-gdt-sm", "group-data-[size=lg]/list-item:text-gdt-md", className),
59
+ ...props
60
+ });
61
+ }
62
+ function ListItemDescription({ className, ...props }) {
63
+ return /* @__PURE__ */ jsx("p", {
64
+ "data-slot": "list-item-description",
65
+ className: cn("min-w-0 truncate font-normal text-fg-secondary group-disabled/list-item:text-fg-caption-placeholder group-aria-disabled/list-item:text-fg-caption-placeholder", "group-data-[size=md]/list-item:text-gdt-xs", "group-data-[size=lg]/list-item:text-gdt-sm", className),
66
+ ...props
67
+ });
68
+ }
69
+ function ListItemMeta({ className, ...props }) {
70
+ return /* @__PURE__ */ jsx("span", {
71
+ "data-slot": "list-item-meta",
72
+ className: cn("shrink-0 whitespace-nowrap text-right font-normal text-fg-secondary group-data-[selected=true]/list-item:text-fg-brand group-disabled/list-item:text-fg-caption-placeholder group-aria-disabled/list-item:text-fg-caption-placeholder", "group-data-[size=md]/list-item:text-gdt-xs", "group-data-[size=lg]/list-item:text-gdt-sm", className),
73
+ ...props
74
+ });
75
+ }
76
+ function ListItemCount({ className, ...props }) {
77
+ return /* @__PURE__ */ jsx("span", {
78
+ "data-slot": "list-item-count",
79
+ className: cn("flex shrink-0 items-center justify-center rounded-full bg-action-primary px-2 py-0.5 text-gdt-xs font-bold whitespace-nowrap text-fg-on-brand group-disabled/list-item:bg-action-tertiary group-disabled/list-item:text-fg-caption-placeholder group-aria-disabled/list-item:bg-action-tertiary group-aria-disabled/list-item:text-fg-caption-placeholder", "group-data-[size=md]/list-item:min-h-5.5", "group-data-[size=lg]/list-item:min-h-6", className),
80
+ ...props
81
+ });
82
+ }
83
+ //#endregion
84
+ export { ListItem, ListItemAvatar, ListItemContent, ListItemCount, ListItemDescription, ListItemIcon, ListItemMeta, ListItemTitle, listItemVariants };
@@ -43,24 +43,27 @@ function NumberInput({ children, format, formatPreset, placeholder, size, thousa
43
43
  }
44
44
  function NumberInputControl() {
45
45
  const size = useComponentSize();
46
- return /* @__PURE__ */ jsxs(InputGroupAddon, {
46
+ return /* @__PURE__ */ jsx(InputGroupAddon, {
47
47
  align: "inline-end",
48
- className: cn("flex gap-0 flex-col h-[calc(100%-2px)] w-10 overflow-hidden rounded-r-full p-0! pr-1.5!", size === "lg" && "w-12"),
49
- children: [/* @__PURE__ */ jsx(NumberField.Increment, {
50
- className: "w-full flex-1 rounded-none rounded-tr-full",
51
- render: /* @__PURE__ */ jsx(InputGroupButton, { variant: "tertiary" }),
52
- children: /* @__PURE__ */ jsx(PlusIcon, { className: cn("size-1.5", {
53
- "size-3": size === "md",
54
- "size-3.5": size === "lg"
55
- }) })
56
- }), /* @__PURE__ */ jsx(NumberField.Decrement, {
57
- className: "w-full flex-1 rounded-none rounded-br-full",
58
- render: /* @__PURE__ */ jsx(InputGroupButton, { variant: "tertiary" }),
59
- children: /* @__PURE__ */ jsx(MinusIcon, { className: cn("size-1.5", {
60
- "size-3": size === "md",
61
- "size-3.5": size === "lg"
62
- }) })
63
- })]
48
+ className: cn("flex h-full w-10 overflow-hidden rounded-r-full p-0! group-focus-within/input-group:mr-px group-focus-within/input-group:h-[calc(100%-2px)]", size === "lg" && "w-12"),
49
+ children: /* @__PURE__ */ jsxs("div", {
50
+ className: "flex h-full w-full flex-col gap-0 group-focus-within/input-group:ml-px group-focus-within/input-group:h-[calc(100%+2px)]",
51
+ children: [/* @__PURE__ */ jsx(NumberField.Increment, {
52
+ className: "w-full flex-1 rounded-none rounded-tr-full",
53
+ render: /* @__PURE__ */ jsx(InputGroupButton, { variant: "tertiary" }),
54
+ children: /* @__PURE__ */ jsx(PlusIcon, { className: cn("size-1.5", {
55
+ "size-3": size === "md",
56
+ "size-3.5": size === "lg"
57
+ }) })
58
+ }), /* @__PURE__ */ jsx(NumberField.Decrement, {
59
+ className: "w-full flex-1 rounded-none rounded-br-full",
60
+ render: /* @__PURE__ */ jsx(InputGroupButton, { variant: "tertiary" }),
61
+ children: /* @__PURE__ */ jsx(MinusIcon, { className: cn("size-1.5", {
62
+ "size-3": size === "md",
63
+ "size-3.5": size === "lg"
64
+ }) })
65
+ })]
66
+ })
64
67
  });
65
68
  }
66
69
  //#endregion
@@ -1,39 +1,49 @@
1
1
  import { t as ComponentSize } from "./size-context-D4mYvcg8.js";
2
+ import { ChartConfig } from "./chart.js";
2
3
  import * as React from "react";
4
+ import { Pie, PieChart as PieChart$1 } from "recharts";
3
5
  //#region src/pie-chart.d.ts
4
6
  /**
5
- * Pie / donut charts are composed from recharts plot primitives directly —
6
- * recharts identifies `PieChart`, `Pie`, and `Cell` by component identity, so
7
- * they cannot be wrapped. This module supplies the giddaa-specific pieces that
8
- * would otherwise be copy-pasted: per-size layout numbers, a categorical
9
- * palette, the donut center label, and the rich legend (dot · name · value ·
10
- * percentage). Pair them with the shared frame from `./chart`.
7
+ * Pie / donut charts are composable wrappers over the recharts pie primitives.
8
+ * recharts 3 registers graphical items through context when they render, so the
9
+ * primitives CAN be wrapped in our own components. Each wrapper bakes in the
10
+ * giddaa defaults (square plot box, size-scaled radii, mark specs) and forwards
11
+ * every recharts prop, so anything can be overridden in place or replaced with
12
+ * the raw recharts element.
11
13
  *
12
- * A donut keeps an open center for a total label (`innerRadius` > 0); a pie
13
- * fills the circle (`innerRadius={0}`). Both read the same layout.
14
+ * A donut keeps an open center for a total label (`type="donut"`, the default);
15
+ * a pie fills the circle (`type="pie"`). Segment colours are assigned per `Cell`
16
+ * from `PIE_CHART_PALETTE` in slot order — a fourth+ category folds into "Other"
17
+ * (the palette has three validated categorical slots on purpose).
14
18
  *
15
19
  * @example
16
- * const chart = usePieChartLayout({ size: "md", type: "donut" });
17
20
  * <ChartCard size="md">
21
+ * <ChartHeader>
22
+ * <ChartTitle>Portfolio mix</ChartTitle>
23
+ * </ChartHeader>
18
24
  * <div className="flex items-center gap-4">
19
- * <ChartContainer config={config} {...chart.container}>
20
- * <PieChart>
21
- * <Pie data={data} dataKey="value" nameKey="label" {...chart.pie}>
22
- * {data.map((d) => <Cell key={d.label} fill={d.color} />)}
23
- * <Label content={<PieCenterLabel total="₦1.1M" caption="Total spend" />} />
24
- * </Pie>
25
- * </PieChart>
26
- * </ChartContainer>
25
+ * <PieChart config={config}>
26
+ * <PieChartSeries data={data} dataKey="value" nameKey="label" type="donut">
27
+ * {data.map((d, i) => <Cell key={d.label} fill={PIE_CHART_PALETTE[i]} />)}
28
+ * <Label content={<PieCenterLabel total="₦1.1M" caption="Total spend" />} />
29
+ * </PieChartSeries>
30
+ * </PieChart>
27
31
  * <PieChartLegend items={legendItems} />
28
32
  * </div>
29
33
  * </ChartCard>
30
34
  */
31
35
  /** Pie sizes line up with the three shared `ComponentSize` values. */
32
36
  type PieChartSize = ComponentSize;
37
+ /**
38
+ * Categorical segment palette — the theme-aware `chart-1`…`chart-3` tokens.
39
+ * Assign colours in this fixed slot order, never cycled: a fourth category folds
40
+ * into "Other". Override per segment with a `Cell` `fill`.
41
+ */
42
+ declare const PIE_CHART_PALETTE: readonly ["var(--color-chart-1)", "var(--color-chart-2)", "var(--color-chart-3)"];
33
43
  type PieChartLayout = {
34
44
  /** Square plot box in px (width = height); width is NOT parent-driven here. */
35
45
  size: number;
36
- /** Donut hole radius in px. Pass `0` to the `Pie` for a filled pie. */
46
+ /** Donut hole radius in px. `type="pie"` collapses it to 0. */
37
47
  innerRadius: number;
38
48
  /** Outer ring radius in px. */
39
49
  outerRadius: number;
@@ -47,46 +57,38 @@ type PieChartLayout = {
47
57
  captionFontSize: number;
48
58
  };
49
59
  declare const PIE_CHART_LAYOUT: Record<PieChartSize, PieChartLayout>;
60
+ type PieChartProps = Omit<React.ComponentProps<typeof PieChart$1>, "width" | "height"> & {
61
+ /** Series labels/icons for the shared tooltip and legend (see `ChartConfig`). */
62
+ config?: ChartConfig;
63
+ /** Plot scale; inherited from the nearest `SizeProvider` when omitted. */
64
+ size?: PieChartSize;
65
+ /** Applied to the square plot box, e.g. to override its dimensions. */
66
+ className?: string;
67
+ };
50
68
  /**
51
- * Categorical palette for pie/donut segments, ordered by share. Giddaa has no
52
- * `chart-1`…`chart-N` tokens yet, so these map to the brand scales: forest
53
- * brass moss clay stone. Assign by index, or override per `Cell`.
54
- */
55
- declare const PIE_CHART_PALETTE: readonly ["var(--color-forest-700)", "var(--color-brass-500)", "var(--color-moss-600)", "var(--color-clay-500)", "var(--color-stone-500)"];
56
- /**
57
- * Resolve the pie-chart layout for an explicit or inherited component size and
58
- * chart `type`. The returned object groups the giddaa defaults by the recharts
59
- * component they belong to — spread `container` onto `ChartContainer` and `pie`
60
- * onto `Pie`, then pass the data-specific props (`data`, `dataKey`, `nameKey`)
61
- * directly afterwards. `type="pie"` collapses the donut hole (`innerRadius` 0).
69
+ * Plot root wraps the shared `ChartContainer` (tooltip/legend theming,
70
+ * responsive box) around the recharts `PieChart` in a fixed square box from
71
+ * `PIE_CHART_LAYOUT` (unlike the cartesian roots, a pie's width is not
72
+ * parent-driven). `size` flows to the child primitives through `SizeProvider`.
62
73
  */
63
- declare function usePieChartLayout({ size, type }?: {
64
- size?: PieChartSize;
74
+ declare function PieChart({ config, size, className, children, ...props }: PieChartProps): React.JSX.Element;
75
+ type PieChartSeriesProps = React.ComponentProps<typeof Pie> & {
76
+ /** `donut` keeps an open center (default); `pie` fills the circle. */
65
77
  type?: "donut" | "pie";
66
- }): {
67
- container: {
68
- className: string;
69
- style: {
70
- width: number;
71
- height: number;
72
- };
73
- };
74
- pie: {
75
- innerRadius: number;
76
- outerRadius: number;
77
- paddingAngle: number;
78
- cornerRadius: number;
79
- strokeWidth: number;
80
- };
81
- label: {
82
- totalFontSize: number;
83
- captionFontSize: number;
84
- };
78
+ /** Explicit mark scale; otherwise inherited from the chart's `size`. */
79
+ size?: PieChartSize;
85
80
  };
81
+ /**
82
+ * One data series — recharts `Pie` with the giddaa mark spec: size-scaled
83
+ * radii, a small inter-segment gap, and no stroke. Pass `Cell` children for
84
+ * per-segment colours and a `Label` for the donut center. Each numeric prop is
85
+ * defaulted from the layout and still wins when passed directly.
86
+ */
87
+ declare function PieChartSeries({ type, size, innerRadius, outerRadius, paddingAngle, cornerRadius, strokeWidth, ...props }: PieChartSeriesProps): React.JSX.Element;
86
88
  /**
87
89
  * Center label for a donut — the hero total over a short caption. Pass it to
88
90
  * recharts as `<Label content={<PieCenterLabel total=… caption=… />} />` inside
89
- * the `Pie`; recharts injects the `viewBox` carrying the polar center (cx/cy).
91
+ * the `PieChartSeries`; recharts injects the `viewBox` carrying the polar center.
90
92
  */
91
93
  type PieCenterLabelProps = {
92
94
  /** Hero figure — pre-formatted, e.g. "₦1.1M". */
@@ -121,5 +123,34 @@ declare function PieChartLegend({ items, size, className, ...props }: React.Comp
121
123
  items: PieLegendItem[];
122
124
  size?: PieChartSize;
123
125
  }): React.JSX.Element;
126
+ /**
127
+ * @deprecated Compose the `<PieChart>`/`<PieChartSeries>` primitives instead —
128
+ * see the module example. This layout hook predates recharts 3 wrapping support
129
+ * and will be removed in the next major. It returns prop bags to spread onto raw
130
+ * recharts elements.
131
+ */
132
+ declare function usePieChartLayout({ size, type }?: {
133
+ size?: PieChartSize;
134
+ type?: "donut" | "pie";
135
+ }): {
136
+ container: {
137
+ className: string;
138
+ style: {
139
+ width: number;
140
+ height: number;
141
+ };
142
+ };
143
+ pie: {
144
+ innerRadius: number;
145
+ outerRadius: number;
146
+ paddingAngle: number;
147
+ cornerRadius: number;
148
+ strokeWidth: number;
149
+ };
150
+ label: {
151
+ totalFontSize: number;
152
+ captionFontSize: number;
153
+ };
154
+ };
124
155
  //#endregion
125
- export { PIE_CHART_LAYOUT, PIE_CHART_PALETTE, PieCenterLabel, type PieCenterLabelProps, type PieChartLayout, PieChartLegend, type PieChartSize, type PieLegendItem, usePieChartLayout };
156
+ export { PIE_CHART_LAYOUT, PIE_CHART_PALETTE, PieCenterLabel, type PieCenterLabelProps, PieChart, type PieChartLayout, PieChartLegend, type PieChartProps, PieChartSeries, type PieChartSeriesProps, type PieChartSize, type PieLegendItem, usePieChartLayout };