@giddaa-housing/ui 0.1.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 (248) hide show
  1. package/README.md +41 -0
  2. package/dist/accordion.d.ts +11 -0
  3. package/dist/accordion.js +124 -0
  4. package/dist/accordion.js.map +1 -0
  5. package/dist/alert.d.ts +18 -0
  6. package/dist/alert.js +152 -0
  7. package/dist/alert.js.map +1 -0
  8. package/dist/avatar.d.ts +14 -0
  9. package/dist/avatar.js +152 -0
  10. package/dist/avatar.js.map +1 -0
  11. package/dist/badge.d.ts +14 -0
  12. package/dist/badge.js +119 -0
  13. package/dist/badge.js.map +1 -0
  14. package/dist/bar-chart.d.ts +136 -0
  15. package/dist/bar-chart.js +302 -0
  16. package/dist/bar-chart.js.map +1 -0
  17. package/dist/base.css +32 -0
  18. package/dist/breadcrumb.d.ts +12 -0
  19. package/dist/breadcrumb.js +161 -0
  20. package/dist/breadcrumb.js.map +1 -0
  21. package/dist/bullet-chart.d.ts +98 -0
  22. package/dist/bullet-chart.js +189 -0
  23. package/dist/bullet-chart.js.map +1 -0
  24. package/dist/button-group.d.ts +18 -0
  25. package/dist/button-group.js +170 -0
  26. package/dist/button-group.js.map +1 -0
  27. package/dist/button.d.ts +19 -0
  28. package/dist/button.js +146 -0
  29. package/dist/button.js.map +1 -0
  30. package/dist/calendar.d.ts +9 -0
  31. package/dist/calendar.js +293 -0
  32. package/dist/calendar.js.map +1 -0
  33. package/dist/card.d.ts +18 -0
  34. package/dist/card.js +186 -0
  35. package/dist/card.js.map +1 -0
  36. package/dist/carousel.d.ts +53 -0
  37. package/dist/carousel.js +396 -0
  38. package/dist/carousel.js.map +1 -0
  39. package/dist/chart.d.ts +122 -0
  40. package/dist/chart.js +494 -0
  41. package/dist/chart.js.map +1 -0
  42. package/dist/checkbox.d.ts +73 -0
  43. package/dist/checkbox.js +87 -0
  44. package/dist/checkbox.js.map +1 -0
  45. package/dist/collapsible.d.ts +8 -0
  46. package/dist/collapsible.js +82 -0
  47. package/dist/collapsible.js.map +1 -0
  48. package/dist/combobox.d.ts +30 -0
  49. package/dist/combobox.js +713 -0
  50. package/dist/combobox.js.map +1 -0
  51. package/dist/date-picker.d.ts +22 -0
  52. package/dist/date-picker.js +528 -0
  53. package/dist/date-picker.js.map +1 -0
  54. package/dist/dialog.d.ts +30 -0
  55. package/dist/dialog.js +339 -0
  56. package/dist/dialog.js.map +1 -0
  57. package/dist/dropdown-menu.d.ts +35 -0
  58. package/dist/dropdown-menu.js +376 -0
  59. package/dist/dropdown-menu.js.map +1 -0
  60. package/dist/dropzone.d.ts +128 -0
  61. package/dist/dropzone.js +490 -0
  62. package/dist/dropzone.js.map +1 -0
  63. package/dist/empty-state.d.ts +17 -0
  64. package/dist/empty-state.js +146 -0
  65. package/dist/empty-state.js.map +1 -0
  66. package/dist/field.d.ts +29 -0
  67. package/dist/field.js +345 -0
  68. package/dist/field.js.map +1 -0
  69. package/dist/files/red-hat-display-latin-300-italic.woff +0 -0
  70. package/dist/files/red-hat-display-latin-300-italic.woff2 +0 -0
  71. package/dist/files/red-hat-display-latin-300-normal.woff +0 -0
  72. package/dist/files/red-hat-display-latin-300-normal.woff2 +0 -0
  73. package/dist/files/red-hat-display-latin-400-italic.woff +0 -0
  74. package/dist/files/red-hat-display-latin-400-italic.woff2 +0 -0
  75. package/dist/files/red-hat-display-latin-400-normal.woff +0 -0
  76. package/dist/files/red-hat-display-latin-400-normal.woff2 +0 -0
  77. package/dist/files/red-hat-display-latin-500-italic.woff +0 -0
  78. package/dist/files/red-hat-display-latin-500-italic.woff2 +0 -0
  79. package/dist/files/red-hat-display-latin-500-normal.woff +0 -0
  80. package/dist/files/red-hat-display-latin-500-normal.woff2 +0 -0
  81. package/dist/files/red-hat-display-latin-600-italic.woff +0 -0
  82. package/dist/files/red-hat-display-latin-600-italic.woff2 +0 -0
  83. package/dist/files/red-hat-display-latin-600-normal.woff +0 -0
  84. package/dist/files/red-hat-display-latin-600-normal.woff2 +0 -0
  85. package/dist/files/red-hat-display-latin-700-italic.woff +0 -0
  86. package/dist/files/red-hat-display-latin-700-italic.woff2 +0 -0
  87. package/dist/files/red-hat-display-latin-700-normal.woff +0 -0
  88. package/dist/files/red-hat-display-latin-700-normal.woff2 +0 -0
  89. package/dist/files/red-hat-display-latin-800-italic.woff +0 -0
  90. package/dist/files/red-hat-display-latin-800-italic.woff2 +0 -0
  91. package/dist/files/red-hat-display-latin-800-normal.woff +0 -0
  92. package/dist/files/red-hat-display-latin-800-normal.woff2 +0 -0
  93. package/dist/files/red-hat-display-latin-900-italic.woff +0 -0
  94. package/dist/files/red-hat-display-latin-900-italic.woff2 +0 -0
  95. package/dist/files/red-hat-display-latin-900-normal.woff +0 -0
  96. package/dist/files/red-hat-display-latin-900-normal.woff2 +0 -0
  97. package/dist/files/red-hat-display-latin-ext-300-italic.woff +0 -0
  98. package/dist/files/red-hat-display-latin-ext-300-italic.woff2 +0 -0
  99. package/dist/files/red-hat-display-latin-ext-300-normal.woff +0 -0
  100. package/dist/files/red-hat-display-latin-ext-300-normal.woff2 +0 -0
  101. package/dist/files/red-hat-display-latin-ext-400-italic.woff +0 -0
  102. package/dist/files/red-hat-display-latin-ext-400-italic.woff2 +0 -0
  103. package/dist/files/red-hat-display-latin-ext-400-normal.woff +0 -0
  104. package/dist/files/red-hat-display-latin-ext-400-normal.woff2 +0 -0
  105. package/dist/files/red-hat-display-latin-ext-500-italic.woff +0 -0
  106. package/dist/files/red-hat-display-latin-ext-500-italic.woff2 +0 -0
  107. package/dist/files/red-hat-display-latin-ext-500-normal.woff +0 -0
  108. package/dist/files/red-hat-display-latin-ext-500-normal.woff2 +0 -0
  109. package/dist/files/red-hat-display-latin-ext-600-italic.woff +0 -0
  110. package/dist/files/red-hat-display-latin-ext-600-italic.woff2 +0 -0
  111. package/dist/files/red-hat-display-latin-ext-600-normal.woff +0 -0
  112. package/dist/files/red-hat-display-latin-ext-600-normal.woff2 +0 -0
  113. package/dist/files/red-hat-display-latin-ext-700-italic.woff +0 -0
  114. package/dist/files/red-hat-display-latin-ext-700-italic.woff2 +0 -0
  115. package/dist/files/red-hat-display-latin-ext-700-normal.woff +0 -0
  116. package/dist/files/red-hat-display-latin-ext-700-normal.woff2 +0 -0
  117. package/dist/files/red-hat-display-latin-ext-800-italic.woff +0 -0
  118. package/dist/files/red-hat-display-latin-ext-800-italic.woff2 +0 -0
  119. package/dist/files/red-hat-display-latin-ext-800-normal.woff +0 -0
  120. package/dist/files/red-hat-display-latin-ext-800-normal.woff2 +0 -0
  121. package/dist/files/red-hat-display-latin-ext-900-italic.woff +0 -0
  122. package/dist/files/red-hat-display-latin-ext-900-italic.woff2 +0 -0
  123. package/dist/files/red-hat-display-latin-ext-900-normal.woff +0 -0
  124. package/dist/files/red-hat-display-latin-ext-900-normal.woff2 +0 -0
  125. package/dist/funnel-chart.d.ts +84 -0
  126. package/dist/funnel-chart.js +569 -0
  127. package/dist/funnel-chart.js.map +1 -0
  128. package/dist/index.d.ts +87 -0
  129. package/dist/index.js +10448 -0
  130. package/dist/index.js.map +1 -0
  131. package/dist/input-group.d.ts +31 -0
  132. package/dist/input-group.js +380 -0
  133. package/dist/input-group.js.map +1 -0
  134. package/dist/input-size-context.d.ts +11 -0
  135. package/dist/input-size-context.js +24 -0
  136. package/dist/input-size-context.js.map +1 -0
  137. package/dist/input.d.ts +13 -0
  138. package/dist/input.js +83 -0
  139. package/dist/input.js.map +1 -0
  140. package/dist/item.d.ts +8 -0
  141. package/dist/item.js +93 -0
  142. package/dist/item.js.map +1 -0
  143. package/dist/kpi-card.d.ts +24 -0
  144. package/dist/kpi-card.js +243 -0
  145. package/dist/kpi-card.js.map +1 -0
  146. package/dist/label.d.ts +8 -0
  147. package/dist/label.js +68 -0
  148. package/dist/label.js.map +1 -0
  149. package/dist/line-chart.d.ts +155 -0
  150. package/dist/line-chart.js +269 -0
  151. package/dist/line-chart.js.map +1 -0
  152. package/dist/logo.d.ts +6 -0
  153. package/dist/logo.js +146 -0
  154. package/dist/logo.js.map +1 -0
  155. package/dist/number-input.d.ts +41 -0
  156. package/dist/number-input.js +418 -0
  157. package/dist/number-input.js.map +1 -0
  158. package/dist/page-header.d.ts +13 -0
  159. package/dist/page-header.js +113 -0
  160. package/dist/page-header.js.map +1 -0
  161. package/dist/pagination.d.ts +35 -0
  162. package/dist/pagination.js +352 -0
  163. package/dist/pagination.js.map +1 -0
  164. package/dist/password-input.d.ts +13 -0
  165. package/dist/password-input.js +356 -0
  166. package/dist/password-input.js.map +1 -0
  167. package/dist/phone-input.d.ts +21 -0
  168. package/dist/phone-input.js +573 -0
  169. package/dist/phone-input.js.map +1 -0
  170. package/dist/photo-gallery.d.ts +42 -0
  171. package/dist/photo-gallery.js +756 -0
  172. package/dist/photo-gallery.js.map +1 -0
  173. package/dist/pie-chart.d.ts +125 -0
  174. package/dist/pie-chart.js +192 -0
  175. package/dist/pie-chart.js.map +1 -0
  176. package/dist/popover.d.ts +20 -0
  177. package/dist/popover.js +169 -0
  178. package/dist/popover.js.map +1 -0
  179. package/dist/progress.d.ts +28 -0
  180. package/dist/progress.js +315 -0
  181. package/dist/progress.js.map +1 -0
  182. package/dist/radio-group.d.ts +32 -0
  183. package/dist/radio-group.js +100 -0
  184. package/dist/radio-group.js.map +1 -0
  185. package/dist/red-hat-display.css +2 -0
  186. package/dist/rich-text-editor.d.ts +16 -0
  187. package/dist/rich-text-editor.js +1000 -0
  188. package/dist/rich-text-editor.js.map +1 -0
  189. package/dist/search-input.d.ts +19 -0
  190. package/dist/search-input.js +411 -0
  191. package/dist/search-input.js.map +1 -0
  192. package/dist/select.d.ts +21 -0
  193. package/dist/select.js +305 -0
  194. package/dist/select.js.map +1 -0
  195. package/dist/separator.d.ts +10 -0
  196. package/dist/separator.js +72 -0
  197. package/dist/separator.js.map +1 -0
  198. package/dist/sheet.d.ts +24 -0
  199. package/dist/sheet.js +282 -0
  200. package/dist/sheet.js.map +1 -0
  201. package/dist/sidebar.d.ts +70 -0
  202. package/dist/sidebar.js +1078 -0
  203. package/dist/sidebar.js.map +1 -0
  204. package/dist/size-context.d.ts +11 -0
  205. package/dist/size-context.js +22 -0
  206. package/dist/size-context.js.map +1 -0
  207. package/dist/skeleton.d.ts +5 -0
  208. package/dist/skeleton.js +48 -0
  209. package/dist/skeleton.js.map +1 -0
  210. package/dist/sparkline.d.ts +94 -0
  211. package/dist/sparkline.js +568 -0
  212. package/dist/sparkline.js.map +1 -0
  213. package/dist/stepper.d.ts +43 -0
  214. package/dist/stepper.js +296 -0
  215. package/dist/stepper.js.map +1 -0
  216. package/dist/styles.css +2 -0
  217. package/dist/switch.d.ts +29 -0
  218. package/dist/switch.js +108 -0
  219. package/dist/switch.js.map +1 -0
  220. package/dist/tab-list.d.ts +38 -0
  221. package/dist/tab-list.js +394 -0
  222. package/dist/tab-list.js.map +1 -0
  223. package/dist/table.d.ts +69 -0
  224. package/dist/table.js +197 -0
  225. package/dist/table.js.map +1 -0
  226. package/dist/tabs.d.ts +18 -0
  227. package/dist/tabs.js +159 -0
  228. package/dist/tabs.js.map +1 -0
  229. package/dist/tag.d.ts +25 -0
  230. package/dist/tag.js +160 -0
  231. package/dist/tag.js.map +1 -0
  232. package/dist/textarea.d.ts +12 -0
  233. package/dist/textarea.js +78 -0
  234. package/dist/textarea.js.map +1 -0
  235. package/dist/theme/giddaa.css +2 -0
  236. package/dist/time-picker.d.ts +13 -0
  237. package/dist/time-picker.js +472 -0
  238. package/dist/time-picker.js.map +1 -0
  239. package/dist/toast.d.ts +23 -0
  240. package/dist/toast.js +330 -0
  241. package/dist/toast.js.map +1 -0
  242. package/dist/tooltip.d.ts +11 -0
  243. package/dist/tooltip.js +96 -0
  244. package/dist/tooltip.js.map +1 -0
  245. package/dist/tree-map.d.ts +127 -0
  246. package/dist/tree-map.js +652 -0
  247. package/dist/tree-map.js.map +1 -0
  248. package/package.json +328 -0
package/dist/badge.js ADDED
@@ -0,0 +1,119 @@
1
+ // src/components/ui/badge.tsx
2
+ import { mergeProps } from "@base-ui/react/merge-props";
3
+ import { useRender } from "@base-ui/react/use-render";
4
+ import { cva } from "class-variance-authority";
5
+
6
+ // src/lib/cn.ts
7
+ import { clsx } from "clsx";
8
+ import { extendTailwindMerge } from "tailwind-merge";
9
+ var twMerge = extendTailwindMerge({
10
+ extend: {
11
+ classGroups: {
12
+ "font-size": [
13
+ {
14
+ text: [
15
+ "gdt-display",
16
+ "gdt-h1",
17
+ "gdt-h2",
18
+ "gdt-h3",
19
+ "gdt-h4",
20
+ "gdt-h5",
21
+ "gdt-xl",
22
+ "gdt-lg",
23
+ "gdt-md",
24
+ "gdt-sm",
25
+ "gdt-xs",
26
+ "gdt-subtext",
27
+ "gdt-capitalized"
28
+ ]
29
+ }
30
+ ]
31
+ }
32
+ }
33
+ });
34
+ function cn(...inputs) {
35
+ return twMerge(clsx(inputs));
36
+ }
37
+
38
+ // src/components/ui/size-context.tsx
39
+ import { createContext, useContext } from "react";
40
+ import { Fragment, jsx } from "react/jsx-runtime";
41
+ var SizeContext = createContext(void 0);
42
+ function useComponentSize(size, fallback = "md") {
43
+ const inheritedSize = useContext(SizeContext);
44
+ return size ?? inheritedSize ?? fallback;
45
+ }
46
+
47
+ // src/components/ui/badge.tsx
48
+ var badgeVariants = cva(
49
+ "group/badge inline-flex w-fit shrink-0 items-center justify-center overflow-hidden border font-bold leading-none whitespace-nowrap transition-[background-color,border-color,color,box-shadow] outline-none focus-visible:border-line-focus focus-visible:shadow-[0px_0px_0px_2px_var(--color-line-focus)] aria-invalid:border-line-danger aria-invalid:text-fg-danger [&>svg]:pointer-events-none [&>svg]:shrink-0 [&>svg]:text-current",
50
+ {
51
+ variants: {
52
+ variant: {
53
+ default: "border-line bg-surface-raised text-fg-secondary",
54
+ info: "border-status-info/40 bg-surface-info-subtle text-status-info",
55
+ success: "border-status-success/40 bg-surface-brand-subtle text-status-success",
56
+ warning: "border-status-warning/40 bg-surface-accent-subtle text-status-warning",
57
+ danger: "border-line-danger bg-surface-danger-subtle text-status-danger",
58
+ secondary: "border-status-info/40 bg-surface-info-subtle text-status-info",
59
+ destructive: "border-line-danger bg-surface-danger-subtle text-status-danger",
60
+ outline: "border-line bg-transparent text-fg-secondary"
61
+ },
62
+ size: {
63
+ sm: "gap-1 px-2.5 py-1 text-gdt-xs has-data-[icon=inline-start]:pl-2 has-data-[icon=inline-end]:pr-2 [&>svg]:size-3",
64
+ md: "gap-1.5 px-3 py-1.5 text-gdt-sm has-data-[icon=inline-start]:pl-2.5 has-data-[icon=inline-end]:pr-2.5 [&>svg]:size-3.5",
65
+ lg: "gap-2 px-4 py-2 text-gdt-md has-data-[icon=inline-start]:pl-3.5 has-data-[icon=inline-end]:pr-3.5 [&>svg]:size-4"
66
+ },
67
+ shape: {
68
+ round: "rounded-4xl",
69
+ box: "rounded-lg"
70
+ },
71
+ border: {
72
+ true: "",
73
+ false: "border-transparent"
74
+ }
75
+ },
76
+ defaultVariants: {
77
+ variant: "default",
78
+ size: "md",
79
+ shape: "round",
80
+ border: true
81
+ }
82
+ }
83
+ );
84
+ function Badge({
85
+ className,
86
+ variant = "default",
87
+ size,
88
+ shape = "round",
89
+ border = true,
90
+ render,
91
+ ...props
92
+ }) {
93
+ const resolvedSize = useComponentSize(size);
94
+ return useRender({
95
+ defaultTagName: "span",
96
+ props: mergeProps(
97
+ {
98
+ className: cn(
99
+ badgeVariants({ variant, size: resolvedSize, shape, border }),
100
+ className
101
+ )
102
+ },
103
+ props
104
+ ),
105
+ render,
106
+ state: {
107
+ slot: "badge",
108
+ variant,
109
+ size: resolvedSize,
110
+ shape,
111
+ border
112
+ }
113
+ });
114
+ }
115
+ export {
116
+ Badge,
117
+ badgeVariants
118
+ };
119
+ //# sourceMappingURL=badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/badge.tsx","../src/lib/cn.ts","../src/components/ui/size-context.tsx"],"sourcesContent":["import { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/cn\";\nimport { useComponentSize } from \"./size-context\";\n\nconst badgeVariants = cva(\n\t\"group/badge inline-flex w-fit shrink-0 items-center justify-center overflow-hidden border font-bold leading-none whitespace-nowrap transition-[background-color,border-color,color,box-shadow] outline-none focus-visible:border-line-focus focus-visible:shadow-[0px_0px_0px_2px_var(--color-line-focus)] aria-invalid:border-line-danger aria-invalid:text-fg-danger [&>svg]:pointer-events-none [&>svg]:shrink-0 [&>svg]:text-current\",\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: \"border-line bg-surface-raised text-fg-secondary\",\n\t\t\t\tinfo: \"border-status-info/40 bg-surface-info-subtle text-status-info\",\n\t\t\t\tsuccess:\n\t\t\t\t\t\"border-status-success/40 bg-surface-brand-subtle text-status-success\",\n\t\t\t\twarning:\n\t\t\t\t\t\"border-status-warning/40 bg-surface-accent-subtle text-status-warning\",\n\t\t\t\tdanger:\n\t\t\t\t\t\"border-line-danger bg-surface-danger-subtle text-status-danger\",\n\t\t\t\tsecondary:\n\t\t\t\t\t\"border-status-info/40 bg-surface-info-subtle text-status-info\",\n\t\t\t\tdestructive:\n\t\t\t\t\t\"border-line-danger bg-surface-danger-subtle text-status-danger\",\n\t\t\t\toutline: \"border-line bg-transparent text-fg-secondary\",\n\t\t\t},\n\t\t\tsize: {\n\t\t\t\tsm: \"gap-1 px-2.5 py-1 text-gdt-xs has-data-[icon=inline-start]:pl-2 has-data-[icon=inline-end]:pr-2 [&>svg]:size-3\",\n\t\t\t\tmd: \"gap-1.5 px-3 py-1.5 text-gdt-sm has-data-[icon=inline-start]:pl-2.5 has-data-[icon=inline-end]:pr-2.5 [&>svg]:size-3.5\",\n\t\t\t\tlg: \"gap-2 px-4 py-2 text-gdt-md has-data-[icon=inline-start]:pl-3.5 has-data-[icon=inline-end]:pr-3.5 [&>svg]:size-4\",\n\t\t\t},\n\t\t\tshape: {\n\t\t\t\tround: \"rounded-4xl\",\n\t\t\t\tbox: \"rounded-lg\",\n\t\t\t},\n\t\t\tborder: {\n\t\t\t\ttrue: \"\",\n\t\t\t\tfalse: \"border-transparent\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: \"default\",\n\t\t\tsize: \"md\",\n\t\t\tshape: \"round\",\n\t\t\tborder: true,\n\t\t},\n\t},\n);\n\nfunction Badge({\n\tclassName,\n\tvariant = \"default\",\n\tsize,\n\tshape = \"round\",\n\tborder = true,\n\trender,\n\t...props\n}: useRender.ComponentProps<\"span\"> & VariantProps<typeof badgeVariants>) {\n\tconst resolvedSize = useComponentSize(size);\n\n\treturn useRender({\n\t\tdefaultTagName: \"span\",\n\t\tprops: mergeProps<\"span\">(\n\t\t\t{\n\t\t\t\tclassName: cn(\n\t\t\t\t\tbadgeVariants({ variant, size: resolvedSize, shape, border }),\n\t\t\t\t\tclassName,\n\t\t\t\t),\n\t\t\t},\n\t\t\tprops,\n\t\t),\n\t\trender,\n\t\tstate: {\n\t\t\tslot: \"badge\",\n\t\t\tvariant,\n\t\t\tsize: resolvedSize,\n\t\t\tshape,\n\t\t\tborder,\n\t\t},\n\t});\n}\n\nexport { Badge, badgeVariants };\n","import { type ClassValue, clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({\n\textend: {\n\t\tclassGroups: {\n\t\t\t\"font-size\": [\n\t\t\t\t{\n\t\t\t\t\ttext: [\n\t\t\t\t\t\t\"gdt-display\",\n\t\t\t\t\t\t\"gdt-h1\",\n\t\t\t\t\t\t\"gdt-h2\",\n\t\t\t\t\t\t\"gdt-h3\",\n\t\t\t\t\t\t\"gdt-h4\",\n\t\t\t\t\t\t\"gdt-h5\",\n\t\t\t\t\t\t\"gdt-xl\",\n\t\t\t\t\t\t\"gdt-lg\",\n\t\t\t\t\t\t\"gdt-md\",\n\t\t\t\t\t\t\"gdt-sm\",\n\t\t\t\t\t\t\"gdt-xs\",\n\t\t\t\t\t\t\"gdt-subtext\",\n\t\t\t\t\t\t\"gdt-capitalized\",\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n});\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport { createContext, type ReactNode, useContext } from \"react\";\n\ntype ComponentSize = \"sm\" | \"md\" | \"lg\";\n\nconst SizeContext = createContext<ComponentSize | undefined>(undefined);\n\nfunction SizeProvider({\n\tchildren,\n\tsize,\n}: {\n\tchildren: ReactNode;\n\tsize?: ComponentSize | null;\n}) {\n\tif (!size) {\n\t\treturn <>{children}</>;\n\t}\n\n\treturn <SizeContext.Provider value={size}>{children}</SizeContext.Provider>;\n}\n\nfunction useComponentSize(\n\tsize?: ComponentSize | null,\n\tfallback: ComponentSize = \"md\",\n) {\n\tconst inheritedSize = useContext(SizeContext);\n\treturn size ?? inheritedSize ?? fallback;\n}\n\nexport { SizeProvider, useComponentSize, type ComponentSize };\n"],"mappings":";AAAA,SAAS,kBAAkB;AAC3B,SAAS,iBAAiB;AAC1B,SAAS,WAA8B;;;ACFvC,SAA0B,YAAY;AACtC,SAAS,2BAA2B;AAEpC,IAAM,UAAU,oBAAoB;AAAA,EACnC,QAAQ;AAAA,IACP,aAAa;AAAA,MACZ,aAAa;AAAA,QACZ;AAAA,UACC,MAAM;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD,CAAC;AAEM,SAAS,MAAM,QAAsB;AAC3C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC5B;;;AC7BA,SAAS,eAA+B,kBAAkB;AAcjD;AAVT,IAAM,cAAc,cAAyC,MAAS;AAgBtE,SAAS,iBACR,MACA,WAA0B,MACzB;AACD,QAAM,gBAAgB,WAAW,WAAW;AAC5C,SAAO,QAAQ,iBAAiB;AACjC;;;AFrBA,IAAM,gBAAgB;AAAA,EACrB;AAAA,EACA;AAAA,IACC,UAAU;AAAA,MACT,SAAS;AAAA,QACR,SAAS;AAAA,QACT,MAAM;AAAA,QACN,SACC;AAAA,QACD,SACC;AAAA,QACD,QACC;AAAA,QACD,WACC;AAAA,QACD,aACC;AAAA,QACD,SAAS;AAAA,MACV;AAAA,MACA,MAAM;AAAA,QACL,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACL;AAAA,MACA,OAAO;AAAA,QACN,OAAO;AAAA,QACP,KAAK;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,IACD;AAAA,IACA,iBAAiB;AAAA,MAChB,SAAS;AAAA,MACT,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,IACT;AAAA,EACD;AACD;AAEA,SAAS,MAAM;AAAA,EACd;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,EACT;AAAA,EACA,GAAG;AACJ,GAA0E;AACzE,QAAM,eAAe,iBAAiB,IAAI;AAE1C,SAAO,UAAU;AAAA,IAChB,gBAAgB;AAAA,IAChB,OAAO;AAAA,MACN;AAAA,QACC,WAAW;AAAA,UACV,cAAc,EAAE,SAAS,MAAM,cAAc,OAAO,OAAO,CAAC;AAAA,UAC5D;AAAA,QACD;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACD;AAAA,EACD,CAAC;AACF;","names":[]}
@@ -0,0 +1,136 @@
1
+ import * as React from 'react';
2
+ import { ComponentSize } from './size-context.js';
3
+
4
+ /**
5
+ * Bar charts are composed from recharts plot primitives directly — recharts
6
+ * identifies `Bar`, `XAxis`, `YAxis`, `CartesianGrid`, and `LabelList` by
7
+ * component identity, so they cannot be wrapped without breaking the chart.
8
+ * This module supplies the giddaa-specific defaults that would otherwise be
9
+ * copy-pasted into every bar chart: per-size layout numbers and a value-label
10
+ * renderer. Pair them with the shared frame and overlays from `./chart`.
11
+ *
12
+ * @example
13
+ * const chart = useBarChartLayout();
14
+ * <ChartCard size="md">
15
+ * <ChartHeader>
16
+ * <ChartTitle>Revenue Overview</ChartTitle>
17
+ * <ChartDescription>Monthly revenue · Jan–Jul</ChartDescription>
18
+ * </ChartHeader>
19
+ * <ChartContainer config={config} {...chart.container}>
20
+ * <BarChart data={data} {...chart.chart}>
21
+ * <CartesianGrid vertical={false} stroke="var(--color-line-subtle)" />
22
+ * <XAxis dataKey="month" {...chart.xAxis} />
23
+ * <YAxis {...chart.yAxis} />
24
+ * <ChartLegend verticalAlign="top" content={<ChartLegendContent />} />
25
+ * <ChartTooltip content={<ChartTooltipContent />} />
26
+ * <Bar dataKey="revenue" fill="var(--color-revenue)" {...chart.bar}>
27
+ * <LabelList dataKey="revenue" content={<BarValueLabel />} />
28
+ * </Bar>
29
+ * </BarChart>
30
+ * </ChartContainer>
31
+ * </ChartCard>
32
+ */
33
+ type BarChartLayout = {
34
+ /** Plot height in px. Width stays fluid via the ResponsiveContainer. */
35
+ height: number;
36
+ /** Outer margin — top leaves room for value labels above the tallest bar. */
37
+ margin: {
38
+ top: number;
39
+ right: number;
40
+ bottom: number;
41
+ left: number;
42
+ };
43
+ /** Cap on bar thickness so a few categories don't render slab-wide bars. */
44
+ maxBarSize: number;
45
+ /** Gap between categories (groups), as a percentage of the band. */
46
+ barCategoryGap: string;
47
+ /** Gap between bars within a group (grouped layout). */
48
+ barGap: number;
49
+ /** Corner radius for a bar. */
50
+ barRadius: number;
51
+ /** Axis tick label font size. */
52
+ tickFontSize: number;
53
+ /** Value label (on-bar number) font size. */
54
+ valueFontSize: number;
55
+ /** Reserved width for the value axis. */
56
+ yAxisWidth: number;
57
+ /** Space between an axis and its tick labels. */
58
+ tickMargin: number;
59
+ };
60
+ declare const BAR_CHART_LAYOUT: Record<ComponentSize, BarChartLayout>;
61
+ /**
62
+ * Resolve the bar-chart layout for an explicit or inherited component size. The
63
+ * returned object groups the giddaa defaults by the recharts component they
64
+ * belong to — spread each onto its element, then pass the data-specific props
65
+ * (`config`, `data`, `dataKey`, `fill`, …) directly afterwards to add or
66
+ * override anything:
67
+ *
68
+ * const chart = useBarChartLayout(size);
69
+ * <ChartContainer config={config} {...chart.container}>
70
+ * <BarChart data={data} {...chart.chart}>
71
+ * <XAxis dataKey="month" {...chart.xAxis} />
72
+ * <YAxis {...chart.yAxis} />
73
+ * <Bar dataKey="revenue" fill="var(--color-revenue)" {...chart.bar} />
74
+ */
75
+ declare function useBarChartLayout(size?: ComponentSize): {
76
+ container: {
77
+ className: string;
78
+ style: {
79
+ height: number;
80
+ };
81
+ };
82
+ chart: {
83
+ accessibilityLayer: boolean;
84
+ margin: {
85
+ top: number;
86
+ right: number;
87
+ bottom: number;
88
+ left: number;
89
+ };
90
+ barCategoryGap: string;
91
+ barGap: number;
92
+ };
93
+ xAxis: {
94
+ readonly tickLine: false;
95
+ readonly axisLine: false;
96
+ readonly tickMargin: number;
97
+ readonly tick: {
98
+ fontSize: number;
99
+ };
100
+ };
101
+ yAxis: {
102
+ readonly tickLine: false;
103
+ readonly axisLine: false;
104
+ readonly width: number;
105
+ readonly tick: {
106
+ fontSize: number;
107
+ };
108
+ };
109
+ bar: {
110
+ radius: [number, number, number, number];
111
+ maxBarSize: number;
112
+ };
113
+ };
114
+ /**
115
+ * Renderer for recharts `<LabelList content={<BarValueLabel />} />`. recharts
116
+ * injects the bar geometry (`x`, `y`, `width`, `height`, `value`); the rest are
117
+ * caller props. For a vertical bar the label sits above the bar; for a
118
+ * horizontal bar (`orientation="horizontal"`) it sits to the right of the bar.
119
+ */
120
+ type BarValueLabelProps = {
121
+ /** Bar layout direction — drives where the label is placed. */
122
+ orientation?: "vertical" | "horizontal";
123
+ /** Override the on-bar font size (defaults to the size-scaled value). */
124
+ fontSize?: number;
125
+ /** Format the raw value before display, e.g. `(v) => `₦${v}``. */
126
+ formatter?: (value: React.ReactNode) => React.ReactNode;
127
+ className?: string;
128
+ x?: string | number;
129
+ y?: string | number;
130
+ width?: string | number;
131
+ height?: string | number;
132
+ value?: React.ReactNode;
133
+ };
134
+ declare function BarValueLabel({ orientation, fontSize, formatter, className, x, y, width, height, value, }: BarValueLabelProps): React.JSX.Element | null;
135
+
136
+ export { BAR_CHART_LAYOUT, type BarChartLayout, BarValueLabel, type BarValueLabelProps, useBarChartLayout };
@@ -0,0 +1,302 @@
1
+ // src/lib/cn.ts
2
+ import { clsx } from "clsx";
3
+ import { extendTailwindMerge } from "tailwind-merge";
4
+ var twMerge = extendTailwindMerge({
5
+ extend: {
6
+ classGroups: {
7
+ "font-size": [
8
+ {
9
+ text: [
10
+ "gdt-display",
11
+ "gdt-h1",
12
+ "gdt-h2",
13
+ "gdt-h3",
14
+ "gdt-h4",
15
+ "gdt-h5",
16
+ "gdt-xl",
17
+ "gdt-lg",
18
+ "gdt-md",
19
+ "gdt-sm",
20
+ "gdt-xs",
21
+ "gdt-subtext",
22
+ "gdt-capitalized"
23
+ ]
24
+ }
25
+ ]
26
+ }
27
+ }
28
+ });
29
+ function cn(...inputs) {
30
+ return twMerge(clsx(inputs));
31
+ }
32
+
33
+ // src/components/ui/chart.tsx
34
+ import { cva } from "class-variance-authority";
35
+ import * as React from "react";
36
+ import * as RechartsPrimitive from "recharts";
37
+
38
+ // src/components/ui/size-context.tsx
39
+ import { createContext, useContext } from "react";
40
+ import { Fragment, jsx } from "react/jsx-runtime";
41
+ var SizeContext = createContext(void 0);
42
+ function useComponentSize(size, fallback = "md") {
43
+ const inheritedSize = useContext(SizeContext);
44
+ return size ?? inheritedSize ?? fallback;
45
+ }
46
+
47
+ // src/components/ui/chart.tsx
48
+ import { Fragment as Fragment2, jsx as jsx2, jsxs } from "react/jsx-runtime";
49
+ var ChartContext = React.createContext(null);
50
+ var chartCardVariants = cva(
51
+ "flex w-full min-w-0 flex-col rounded-2xl border border-line-subtle bg-surface-raised text-fg-primary shadow-1",
52
+ {
53
+ variants: {
54
+ size: {
55
+ sm: "gap-3 p-4",
56
+ md: "gap-4 p-5",
57
+ lg: "gap-5 p-6"
58
+ }
59
+ },
60
+ defaultVariants: { size: "md" }
61
+ }
62
+ );
63
+ var chartTitleVariants = cva("min-w-0 font-bold text-fg-primary", {
64
+ variants: {
65
+ size: {
66
+ sm: "text-gdt-md",
67
+ md: "text-gdt-lg",
68
+ lg: "text-gdt-h5"
69
+ }
70
+ },
71
+ defaultVariants: { size: "md" }
72
+ });
73
+ var chartDescriptionVariants = cva("min-w-0 font-normal text-fg-secondary", {
74
+ variants: {
75
+ size: {
76
+ sm: "text-gdt-xs",
77
+ md: "text-gdt-sm",
78
+ lg: "text-gdt-sm"
79
+ }
80
+ },
81
+ defaultVariants: { size: "md" }
82
+ });
83
+ var chartTooltipVariants = cva(
84
+ "flex flex-col bg-surface-overlay border border-line-subtle shadow-2",
85
+ {
86
+ variants: {
87
+ size: {
88
+ xs: "gap-0.5 rounded-md p-2",
89
+ sm: "gap-0.5 rounded-md p-2.5",
90
+ md: "gap-1 rounded-lg p-3",
91
+ lg: "gap-1 rounded-xl p-3.5"
92
+ }
93
+ },
94
+ defaultVariants: {
95
+ size: "md"
96
+ }
97
+ }
98
+ );
99
+ var chartTooltipDotVariants = cva("shrink-0 rounded-full", {
100
+ variants: {
101
+ size: {
102
+ xs: "size-1.5",
103
+ sm: "size-2",
104
+ md: "size-2.5",
105
+ lg: "size-2.5"
106
+ }
107
+ },
108
+ defaultVariants: {
109
+ size: "md"
110
+ }
111
+ });
112
+ var chartTooltipLabelVariants = cva("font-medium text-fg-secondary", {
113
+ variants: {
114
+ size: {
115
+ xs: "text-gdt-xs",
116
+ sm: "text-gdt-xs",
117
+ md: "text-gdt-sm",
118
+ lg: "text-gdt-sm"
119
+ }
120
+ },
121
+ defaultVariants: { size: "md" }
122
+ });
123
+ var chartTooltipValueVariants = cva(
124
+ "font-extrabold text-fg-primary tabular-nums",
125
+ {
126
+ variants: {
127
+ size: {
128
+ xs: "text-gdt-sm",
129
+ sm: "text-gdt-md",
130
+ md: "text-gdt-lg",
131
+ lg: "text-gdt-xl"
132
+ }
133
+ },
134
+ defaultVariants: { size: "md" }
135
+ }
136
+ );
137
+ var chartLegendItemVariants = cva(
138
+ "group/legend-item flex items-center rounded-md leading-none text-fg-primary transition-colors [&>svg]:shrink-0",
139
+ {
140
+ variants: {
141
+ size: {
142
+ sm: "gap-1.5 px-2 py-1 text-gdt-xs [&>svg]:size-3",
143
+ md: "gap-2 px-2.5 py-1.5 text-gdt-sm [&>svg]:size-3.5"
144
+ },
145
+ interactive: {
146
+ true: "cursor-pointer outline-none hover:bg-surface-raised focus-visible:bg-surface-raised",
147
+ false: ""
148
+ },
149
+ inactive: {
150
+ true: "text-fg-caption-placeholder line-through",
151
+ false: ""
152
+ }
153
+ },
154
+ defaultVariants: {
155
+ size: "md",
156
+ interactive: false,
157
+ inactive: false
158
+ }
159
+ }
160
+ );
161
+ var chartLegendMarkerSizeVariants = cva("shrink-0", {
162
+ variants: {
163
+ marker: {
164
+ dot: "rounded-full",
165
+ square: "rounded-[2px]",
166
+ line: "rounded-full"
167
+ },
168
+ size: {
169
+ sm: "",
170
+ md: ""
171
+ }
172
+ },
173
+ compoundVariants: [
174
+ { marker: ["dot", "square"], size: "sm", className: "size-2" },
175
+ { marker: ["dot", "square"], size: "md", className: "size-2.5" },
176
+ { marker: "line", size: "sm", className: "h-[3px] w-3" },
177
+ { marker: "line", size: "md", className: "h-[3px] w-3.5" }
178
+ ],
179
+ defaultVariants: { marker: "dot", size: "md" }
180
+ });
181
+ function cartesianAxisProps(layout) {
182
+ const tick = { fontSize: layout.tickFontSize };
183
+ return {
184
+ xAxis: {
185
+ tickLine: false,
186
+ axisLine: false,
187
+ tickMargin: layout.tickMargin,
188
+ tick
189
+ },
190
+ yAxis: {
191
+ tickLine: false,
192
+ axisLine: false,
193
+ width: layout.yAxisWidth,
194
+ tick
195
+ }
196
+ };
197
+ }
198
+
199
+ // src/components/ui/bar-chart.tsx
200
+ import { jsx as jsx3 } from "react/jsx-runtime";
201
+ var BAR_CHART_LAYOUT = {
202
+ sm: {
203
+ height: 180,
204
+ margin: { top: 20, right: 8, bottom: 0, left: 0 },
205
+ maxBarSize: 22,
206
+ barCategoryGap: "8%",
207
+ barGap: 4,
208
+ barRadius: 4,
209
+ tickFontSize: 10,
210
+ valueFontSize: 10,
211
+ yAxisWidth: 28,
212
+ tickMargin: 6
213
+ },
214
+ md: {
215
+ height: 220,
216
+ margin: { top: 24, right: 12, bottom: 0, left: 0 },
217
+ maxBarSize: 28,
218
+ barCategoryGap: "8%",
219
+ barGap: 6,
220
+ barRadius: 6,
221
+ tickFontSize: 11,
222
+ valueFontSize: 11,
223
+ yAxisWidth: 32,
224
+ tickMargin: 8
225
+ },
226
+ lg: {
227
+ height: 280,
228
+ margin: { top: 28, right: 16, bottom: 0, left: 0 },
229
+ maxBarSize: 36,
230
+ barCategoryGap: "8%",
231
+ barGap: 8,
232
+ barRadius: 8,
233
+ tickFontSize: 12,
234
+ valueFontSize: 12,
235
+ yAxisWidth: 36,
236
+ tickMargin: 10
237
+ }
238
+ };
239
+ function useBarChartLayout(size) {
240
+ const layout = BAR_CHART_LAYOUT[useComponentSize(size)];
241
+ const axes = cartesianAxisProps(layout);
242
+ return {
243
+ container: {
244
+ className: "aspect-auto w-full",
245
+ style: { height: layout.height }
246
+ },
247
+ chart: {
248
+ accessibilityLayer: true,
249
+ margin: layout.margin,
250
+ barCategoryGap: layout.barCategoryGap,
251
+ barGap: layout.barGap
252
+ },
253
+ xAxis: axes.xAxis,
254
+ yAxis: axes.yAxis,
255
+ bar: {
256
+ radius: [layout.barRadius, layout.barRadius, 0, 0],
257
+ maxBarSize: layout.maxBarSize
258
+ }
259
+ };
260
+ }
261
+ function BarValueLabel({
262
+ orientation = "vertical",
263
+ fontSize,
264
+ formatter,
265
+ className,
266
+ x,
267
+ y,
268
+ width,
269
+ height,
270
+ value
271
+ }) {
272
+ const valueFontSize = BAR_CHART_LAYOUT[useComponentSize()].valueFontSize;
273
+ if (value == null || x == null || y == null || width == null) {
274
+ return null;
275
+ }
276
+ const numX = Number(x);
277
+ const numY = Number(y);
278
+ const numWidth = Number(width);
279
+ const numHeight = Number(height ?? 0);
280
+ const gap = 6;
281
+ const isHorizontal = orientation === "horizontal";
282
+ const labelX = isHorizontal ? numX + numWidth + gap : numX + numWidth / 2;
283
+ const labelY = isHorizontal ? numY + numHeight / 2 : numY - gap;
284
+ return /* @__PURE__ */ jsx3(
285
+ "text",
286
+ {
287
+ x: labelX,
288
+ y: labelY,
289
+ textAnchor: isHorizontal ? "start" : "middle",
290
+ dominantBaseline: isHorizontal ? "central" : "auto",
291
+ className: cn("fill-fg-primary font-semibold tabular-nums", className),
292
+ style: { fontSize: fontSize ?? valueFontSize },
293
+ children: formatter ? formatter(value) : value
294
+ }
295
+ );
296
+ }
297
+ export {
298
+ BAR_CHART_LAYOUT,
299
+ BarValueLabel,
300
+ useBarChartLayout
301
+ };
302
+ //# sourceMappingURL=bar-chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/cn.ts","../src/components/ui/chart.tsx","../src/components/ui/size-context.tsx","../src/components/ui/bar-chart.tsx"],"sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({\n\textend: {\n\t\tclassGroups: {\n\t\t\t\"font-size\": [\n\t\t\t\t{\n\t\t\t\t\ttext: [\n\t\t\t\t\t\t\"gdt-display\",\n\t\t\t\t\t\t\"gdt-h1\",\n\t\t\t\t\t\t\"gdt-h2\",\n\t\t\t\t\t\t\"gdt-h3\",\n\t\t\t\t\t\t\"gdt-h4\",\n\t\t\t\t\t\t\"gdt-h5\",\n\t\t\t\t\t\t\"gdt-xl\",\n\t\t\t\t\t\t\"gdt-lg\",\n\t\t\t\t\t\t\"gdt-md\",\n\t\t\t\t\t\t\"gdt-sm\",\n\t\t\t\t\t\t\"gdt-xs\",\n\t\t\t\t\t\t\"gdt-subtext\",\n\t\t\t\t\t\t\"gdt-capitalized\",\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n});\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport type { TooltipValueType } from \"recharts\";\nimport * as RechartsPrimitive from \"recharts\";\nimport { cn } from \"../../lib/cn\";\nimport {\n\ttype ComponentSize,\n\tSizeProvider,\n\tuseComponentSize,\n} from \"./size-context\";\n\n/**\n * Markers use `--color-surface-brand` as a placeholder. Giddaa has no\n * categorical chart palette yet — add `chart-1`…`chart-N` tokens and bind each\n * series (its legend marker and tooltip dot) to its own colour once they exist.\n * Until then any series without an explicit colour paints brand-green.\n */\nconst SERIES_COLOR_PLACEHOLDER = \"var(--color-surface-brand)\";\n\n/** How a precise value is formatted in the tooltip and which prefix/suffix it carries. */\nexport type ChartValueType = \"number\" | \"percentage\" | \"currency\";\n\nfunction formatChartValue(\n\tvalue: TooltipValueType | undefined,\n\ttype: ChartValueType,\n) {\n\tif (Array.isArray(value)) {\n\t\treturn value.join(\", \");\n\t}\n\n\tif (typeof value !== \"number\") {\n\t\treturn value == null ? \"\" : String(value);\n\t}\n\n\tswitch (type) {\n\t\tcase \"currency\":\n\t\t\treturn `₦${value.toLocaleString(\"en-NG\")}`;\n\t\tcase \"percentage\":\n\t\t\treturn `${value.toLocaleString(\"en-NG\", {\n\t\t\t\tminimumFractionDigits: 1,\n\t\t\t\tmaximumFractionDigits: 1,\n\t\t\t})}%`;\n\t\tdefault:\n\t\t\treturn value.toLocaleString(\"en-NG\");\n\t}\n}\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: \"\", dark: \".dark\" } as const;\n\nconst INITIAL_DIMENSION = { width: 320, height: 200 } as const;\ntype TooltipNameType = number | string;\n\nexport type ChartConfig = Record<\n\tstring,\n\t{\n\t\tlabel?: React.ReactNode;\n\t\ticon?: React.ComponentType;\n\t} & (\n\t\t| { color?: string; theme?: never }\n\t\t| { color?: never; theme: Record<keyof typeof THEMES, string> }\n\t)\n>;\n\ntype ChartContextProps = {\n\tconfig: ChartConfig;\n};\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null);\n\nfunction useChart() {\n\tconst context = React.useContext(ChartContext);\n\n\tif (!context) {\n\t\tthrow new Error(\"useChart must be used within a <ChartContainer />\");\n\t}\n\n\treturn context;\n}\n\n/**\n * Shared chart frame — the chrome that surrounds the plot of any chart type\n * (bar, line, area, pie). These are presentational, domain-free, and size-aware:\n * a `size` flows through `SizeProvider` so the plot and its labels can scale\n * with the card. Compose them with the plot primitives:\n *\n * <ChartCard size=\"md\">\n * <ChartHeader>\n * <ChartTitle>Revenue Overview</ChartTitle>\n * <ChartDescription>Monthly revenue · Jan–Jul</ChartDescription>\n * </ChartHeader>\n * <ChartContainer config={config}>{/* recharts plot *\\/}</ChartContainer>\n * </ChartCard>\n */\nconst chartCardVariants = cva(\n\t\"flex w-full min-w-0 flex-col rounded-2xl border border-line-subtle bg-surface-raised text-fg-primary shadow-1\",\n\t{\n\t\tvariants: {\n\t\t\tsize: {\n\t\t\t\tsm: \"gap-3 p-4\",\n\t\t\t\tmd: \"gap-4 p-5\",\n\t\t\t\tlg: \"gap-5 p-6\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: { size: \"md\" },\n\t},\n);\n\nfunction ChartCard({\n\tclassName,\n\tsize,\n\tchildren,\n\t...props\n}: React.ComponentProps<\"section\"> & { size?: ComponentSize }) {\n\tconst resolvedSize = useComponentSize(size);\n\n\treturn (\n\t\t<SizeProvider size={resolvedSize}>\n\t\t\t<section\n\t\t\t\tdata-slot=\"chart-card\"\n\t\t\t\tclassName={cn(chartCardVariants({ size: resolvedSize }), className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</section>\n\t\t</SizeProvider>\n\t);\n}\n\nfunction ChartHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"chart-header\"\n\t\t\tclassName={cn(\"flex min-w-0 flex-col gap-1\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nconst chartTitleVariants = cva(\"min-w-0 font-bold text-fg-primary\", {\n\tvariants: {\n\t\tsize: {\n\t\t\tsm: \"text-gdt-md\",\n\t\t\tmd: \"text-gdt-lg\",\n\t\t\tlg: \"text-gdt-h5\",\n\t\t},\n\t},\n\tdefaultVariants: { size: \"md\" },\n});\n\nfunction ChartTitle({\n\tclassName,\n\tsize,\n\t...props\n}: React.ComponentProps<\"h3\"> & { size?: ComponentSize }) {\n\tconst resolvedSize = useComponentSize(size);\n\n\treturn (\n\t\t<h3\n\t\t\tdata-slot=\"chart-title\"\n\t\t\tclassName={cn(chartTitleVariants({ size: resolvedSize }), className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nconst chartDescriptionVariants = cva(\"min-w-0 font-normal text-fg-secondary\", {\n\tvariants: {\n\t\tsize: {\n\t\t\tsm: \"text-gdt-xs\",\n\t\t\tmd: \"text-gdt-sm\",\n\t\t\tlg: \"text-gdt-sm\",\n\t\t},\n\t},\n\tdefaultVariants: { size: \"md\" },\n});\n\nfunction ChartDescription({\n\tclassName,\n\tsize,\n\t...props\n}: React.ComponentProps<\"p\"> & { size?: ComponentSize }) {\n\tconst resolvedSize = useComponentSize(size);\n\n\treturn (\n\t\t<p\n\t\t\tdata-slot=\"chart-description\"\n\t\t\tclassName={cn(\n\t\t\t\tchartDescriptionVariants({ size: resolvedSize }),\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction ChartContainer({\n\tid,\n\tclassName,\n\tchildren,\n\tconfig,\n\tinitialDimension = INITIAL_DIMENSION,\n\t...props\n}: React.ComponentProps<\"div\"> & {\n\tconfig: ChartConfig;\n\tchildren: React.ComponentProps<\n\t\ttypeof RechartsPrimitive.ResponsiveContainer\n\t>[\"children\"];\n\tinitialDimension?: {\n\t\twidth: number;\n\t\theight: number;\n\t};\n}) {\n\tconst uniqueId = React.useId();\n\tconst chartId = `chart-${id ?? uniqueId.replace(/:/g, \"\")}`;\n\n\treturn (\n\t\t<ChartContext.Provider value={{ config }}>\n\t\t\t<div\n\t\t\t\tdata-slot=\"chart\"\n\t\t\t\tdata-chart={chartId}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<ChartStyle id={chartId} config={config} />\n\t\t\t\t<RechartsPrimitive.ResponsiveContainer\n\t\t\t\t\tinitialDimension={initialDimension}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</RechartsPrimitive.ResponsiveContainer>\n\t\t\t</div>\n\t\t</ChartContext.Provider>\n\t);\n}\n\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n\tconst colorConfig = Object.entries(config).filter(\n\t\t([, config]) => config.theme ?? config.color,\n\t);\n\n\tif (!colorConfig.length) {\n\t\treturn null;\n\t}\n\n\tconst styleContent = Object.entries(THEMES)\n\t\t.map(\n\t\t\t([theme, prefix]) => `\n${prefix} [data-chart=${id}] {\n${colorConfig\n\t.map(([key, itemConfig]) => {\n\t\tconst color =\n\t\t\titemConfig.theme?.[theme as keyof typeof itemConfig.theme] ??\n\t\t\titemConfig.color;\n\t\treturn color ? ` --color-${key}: ${color};` : null;\n\t})\n\t.join(\"\\n\")}\n}\n`,\n\t\t)\n\t\t.join(\"\\n\");\n\n\treturn <style>{styleContent}</style>;\n};\n\nconst ChartTooltip = RechartsPrimitive.Tooltip;\n\n/**\n * Hover tooltip for a chart data point. It surfaces a single precise value with\n * type-appropriate formatting — grouped integers, percentages, or ₦-prefixed\n * currency — sitting on an elevated overlay (bg-surface-overlay, Shadow-2,\n * 1px border-subtle) so users can read exact figures without leaving the chart.\n *\n * Anatomy: series dot · metric label · hero value · period caption.\n */\nconst chartTooltipVariants = cva(\n\t\"flex flex-col bg-surface-overlay border border-line-subtle shadow-2\",\n\t{\n\t\tvariants: {\n\t\t\tsize: {\n\t\t\t\txs: \"gap-0.5 rounded-md p-2\",\n\t\t\t\tsm: \"gap-0.5 rounded-md p-2.5\",\n\t\t\t\tmd: \"gap-1 rounded-lg p-3\",\n\t\t\t\tlg: \"gap-1 rounded-xl p-3.5\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tsize: \"md\",\n\t\t},\n\t},\n);\n\nconst chartTooltipDotVariants = cva(\"shrink-0 rounded-full\", {\n\tvariants: {\n\t\tsize: {\n\t\t\txs: \"size-1.5\",\n\t\t\tsm: \"size-2\",\n\t\t\tmd: \"size-2.5\",\n\t\t\tlg: \"size-2.5\",\n\t\t},\n\t},\n\tdefaultVariants: {\n\t\tsize: \"md\",\n\t},\n});\n\nconst chartTooltipLabelVariants = cva(\"font-medium text-fg-secondary\", {\n\tvariants: {\n\t\tsize: {\n\t\t\txs: \"text-gdt-xs\",\n\t\t\tsm: \"text-gdt-xs\",\n\t\t\tmd: \"text-gdt-sm\",\n\t\t\tlg: \"text-gdt-sm\",\n\t\t},\n\t},\n\tdefaultVariants: { size: \"md\" },\n});\n\nconst chartTooltipValueVariants = cva(\n\t\"font-extrabold text-fg-primary tabular-nums\",\n\t{\n\t\tvariants: {\n\t\t\tsize: {\n\t\t\t\txs: \"text-gdt-sm\",\n\t\t\t\tsm: \"text-gdt-md\",\n\t\t\t\tmd: \"text-gdt-lg\",\n\t\t\t\tlg: \"text-gdt-xl\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: { size: \"md\" },\n\t},\n);\n\nfunction ChartTooltipContent({\n\tactive,\n\tpayload,\n\tclassName,\n\thideIndicator = false,\n\tlabel,\n\tlabelFormatter,\n\tformatter,\n\tcolor,\n\tnameKey,\n\tvalueType = \"number\",\n\tsize = \"md\",\n}: React.ComponentProps<typeof RechartsPrimitive.Tooltip> &\n\tReact.ComponentProps<\"div\"> & {\n\t\thideIndicator?: boolean;\n\t\tnameKey?: string;\n\t\tvalueType?: ChartValueType;\n\t} & VariantProps<typeof chartTooltipVariants> &\n\tOmit<\n\t\tRechartsPrimitive.DefaultTooltipContentProps<\n\t\t\tTooltipValueType,\n\t\t\tTooltipNameType\n\t\t>,\n\t\t\"accessibilityLayer\"\n\t>) {\n\tconst { config } = useChart();\n\n\tif (!active || !payload?.length) {\n\t\treturn null;\n\t}\n\n\tconst [item] = payload.filter((entry) => entry.type !== \"none\");\n\n\tif (!item) {\n\t\treturn null;\n\t}\n\n\tconst key = `${nameKey ?? item.name ?? item.dataKey ?? \"value\"}`;\n\tconst itemConfig = getPayloadConfigFromPayload(config, item, key);\n\tconst dotColor =\n\t\tcolor ?? item.payload?.fill ?? item.color ?? SERIES_COLOR_PLACEHOLDER;\n\n\t// Metric label — the short name of the series being read, e.g. \"Total Revenue\".\n\tconst metricLabel = itemConfig?.label ?? item.name;\n\t// Hero value — the precise, formatted figure, the visual focus of the tooltip.\n\tconst heroValue = formatter\n\t\t? formatter(item.value, item.name ?? \"\", item, 0, item.payload)\n\t\t: formatChartValue(item.value, valueType);\n\t// Period caption — the time context for the value, e.g. \"March 2026\".\n\tconst periodCaption = labelFormatter\n\t\t? labelFormatter(label, payload)\n\t\t: ((typeof label === \"string\" ? config[label]?.label : null) ?? label);\n\n\treturn (\n\t\t<div className={cn(chartTooltipVariants({ size }), className)}>\n\t\t\t{metricLabel != null && (\n\t\t\t\t<div className=\"flex items-center gap-1.5 [&>svg]:size-3 [&>svg]:shrink-0\">\n\t\t\t\t\t{!hideIndicator &&\n\t\t\t\t\t\t(itemConfig?.icon ? (\n\t\t\t\t\t\t\t<itemConfig.icon />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\tclassName={cn(chartTooltipDotVariants({ size }))}\n\t\t\t\t\t\t\t\tstyle={{ backgroundColor: dotColor }}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t<span className={cn(chartTooltipLabelVariants({ size }))}>\n\t\t\t\t\t\t{metricLabel}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<p className={cn(chartTooltipValueVariants({ size }))}>{heroValue}</p>\n\t\t\t{periodCaption != null && periodCaption !== \"\" && (\n\t\t\t\t<p className=\"text-gdt-xs text-fg-caption-placeholder\">\n\t\t\t\t\t{periodCaption}\n\t\t\t\t</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nconst ChartLegend = RechartsPrimitive.Legend;\n\n/** Marker shape that ties a legend item to its series. */\ntype ChartLegendMarker = \"dot\" | \"square\" | \"line\";\n\nconst chartLegendItemVariants = cva(\n\t\"group/legend-item flex items-center rounded-md leading-none text-fg-primary transition-colors [&>svg]:shrink-0\",\n\t{\n\t\tvariants: {\n\t\t\tsize: {\n\t\t\t\tsm: \"gap-1.5 px-2 py-1 text-gdt-xs [&>svg]:size-3\",\n\t\t\t\tmd: \"gap-2 px-2.5 py-1.5 text-gdt-sm [&>svg]:size-3.5\",\n\t\t\t},\n\t\t\tinteractive: {\n\t\t\t\ttrue: \"cursor-pointer outline-none hover:bg-surface-raised focus-visible:bg-surface-raised\",\n\t\t\t\tfalse: \"\",\n\t\t\t},\n\t\t\tinactive: {\n\t\t\t\ttrue: \"text-fg-caption-placeholder line-through\",\n\t\t\t\tfalse: \"\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tsize: \"md\",\n\t\t\tinteractive: false,\n\t\t\tinactive: false,\n\t\t},\n\t},\n);\n\nconst chartLegendMarkerSizeVariants = cva(\"shrink-0\", {\n\tvariants: {\n\t\tmarker: {\n\t\t\tdot: \"rounded-full\",\n\t\t\tsquare: \"rounded-[2px]\",\n\t\t\tline: \"rounded-full\",\n\t\t},\n\t\tsize: {\n\t\t\tsm: \"\",\n\t\t\tmd: \"\",\n\t\t},\n\t},\n\tcompoundVariants: [\n\t\t{ marker: [\"dot\", \"square\"], size: \"sm\", className: \"size-2\" },\n\t\t{ marker: [\"dot\", \"square\"], size: \"md\", className: \"size-2.5\" },\n\t\t{ marker: \"line\", size: \"sm\", className: \"h-[3px] w-3\" },\n\t\t{ marker: \"line\", size: \"md\", className: \"h-[3px] w-3.5\" },\n\t],\n\tdefaultVariants: { marker: \"dot\", size: \"md\" },\n});\n\n/**\n * A shared legend for all chart types. Each item pairs a series marker with a\n * label and can be toggled to hide or show its series — the inactive state mutes\n * the marker and strikes through the label. Items compose into horizontal rows\n * or vertical columns, in two sizes, with dot, square, or line markers.\n *\n * Toggling: pass `onToggle` to make items interactive. Inactive items are read\n * from each payload entry's `inactive` flag (recharts sets this when wired) or\n * the controlled `inactiveKeys` set.\n */\nfunction ChartLegendContent({\n\tclassName,\n\thideIcon = false,\n\tpayload,\n\tverticalAlign = \"bottom\",\n\tnameKey,\n\tmarker = \"dot\",\n\tsize = \"md\",\n\torientation = \"horizontal\",\n\tinactiveKeys,\n\tonToggle,\n}: React.ComponentProps<\"div\"> & {\n\thideIcon?: boolean;\n\tnameKey?: string;\n\tmarker?: ChartLegendMarker;\n\tsize?: \"sm\" | \"md\";\n\torientation?: \"horizontal\" | \"vertical\";\n\tinactiveKeys?: Iterable<string>;\n\tonToggle?: (key: string) => void;\n} & RechartsPrimitive.DefaultLegendContentProps) {\n\tconst { config } = useChart();\n\n\tif (!payload?.length) {\n\t\treturn null;\n\t}\n\n\tconst inactiveSet = inactiveKeys ? new Set(inactiveKeys) : undefined;\n\tconst interactive = Boolean(onToggle);\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex\",\n\t\t\t\torientation === \"vertical\"\n\t\t\t\t\t? \"flex-col items-start gap-0.5\"\n\t\t\t\t\t: \"flex-row flex-wrap items-center justify-center gap-x-1 gap-y-0.5\",\n\t\t\t\tverticalAlign === \"top\" ? \"pb-3\" : \"pt-3\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t{payload\n\t\t\t\t.filter((item) => item.type !== \"none\")\n\t\t\t\t.map((item, index) => {\n\t\t\t\t\tconst key = `${nameKey ?? item.dataKey ?? \"value\"}`;\n\t\t\t\t\tconst itemKey = `${item.dataKey ?? item.value ?? index}`;\n\t\t\t\t\tconst itemConfig = getPayloadConfigFromPayload(config, item, key);\n\t\t\t\t\tconst inactive =\n\t\t\t\t\t\t(inactiveSet?.has(key) ?? false) || Boolean(item.inactive);\n\t\t\t\t\tconst markerColor = inactive\n\t\t\t\t\t\t? \"var(--color-fg-caption-placeholder)\"\n\t\t\t\t\t\t: (item.color ?? SERIES_COLOR_PLACEHOLDER);\n\n\t\t\t\t\tconst content = (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t{itemConfig?.icon && !hideIcon ? (\n\t\t\t\t\t\t\t\t<itemConfig.icon />\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\tchartLegendMarkerSizeVariants({ marker, size }),\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\tstyle={{ backgroundColor: markerColor }}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{itemConfig?.label ?? item.value}\n\t\t\t\t\t\t</>\n\t\t\t\t\t);\n\n\t\t\t\t\tif (interactive) {\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tkey={itemKey}\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\taria-pressed={!inactive}\n\t\t\t\t\t\t\t\tonClick={() => onToggle?.(key)}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\tchartLegendItemVariants({ size, interactive, inactive }),\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{content}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={itemKey}\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\tchartLegendItemVariants({ size, interactive, inactive }),\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{content}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t</div>\n\t);\n}\n\n/** The size-scaled layout numbers a cartesian chart needs to build axis props. */\ntype CartesianAxisLayout = {\n\ttickMargin: number;\n\ttickFontSize: number;\n\tyAxisWidth: number;\n};\n\n/**\n * Shared `<XAxis>`/`<YAxis>` props — the giddaa cartesian-axis defaults (no tick\n * or axis lines, a size-scaled tick font, and a reserved value-axis width) that\n * every bar and line chart would otherwise repeat per axis. Spread the result\n * onto the recharts axis, then add the chart-specific props (`dataKey`,\n * `domain`, `ticks`, a `width`/`type` override, …):\n *\n * const chart = useBarChartLayout();\n * <XAxis dataKey=\"month\" {...chart.xAxis} />\n * <YAxis domain={[0, 120]} {...chart.yAxis} />\n */\nfunction cartesianAxisProps(layout: CartesianAxisLayout) {\n\tconst tick = { fontSize: layout.tickFontSize };\n\treturn {\n\t\txAxis: {\n\t\t\ttickLine: false,\n\t\t\taxisLine: false,\n\t\t\ttickMargin: layout.tickMargin,\n\t\t\ttick,\n\t\t},\n\t\tyAxis: {\n\t\t\ttickLine: false,\n\t\t\taxisLine: false,\n\t\t\twidth: layout.yAxisWidth,\n\t\t\ttick,\n\t\t},\n\t} as const;\n}\n\nfunction getPayloadConfigFromPayload(\n\tconfig: ChartConfig,\n\tpayload: unknown,\n\tkey: string,\n) {\n\tif (typeof payload !== \"object\" || payload === null) {\n\t\treturn undefined;\n\t}\n\n\tconst payloadPayload =\n\t\t\"payload\" in payload &&\n\t\ttypeof payload.payload === \"object\" &&\n\t\tpayload.payload !== null\n\t\t\t? payload.payload\n\t\t\t: undefined;\n\n\tlet configLabelKey: string = key;\n\n\tif (\n\t\tkey in payload &&\n\t\ttypeof payload[key as keyof typeof payload] === \"string\"\n\t) {\n\t\tconfigLabelKey = payload[key as keyof typeof payload] as string;\n\t} else if (\n\t\tpayloadPayload &&\n\t\tkey in payloadPayload &&\n\t\ttypeof payloadPayload[key as keyof typeof payloadPayload] === \"string\"\n\t) {\n\t\tconfigLabelKey = payloadPayload[\n\t\t\tkey as keyof typeof payloadPayload\n\t\t] as string;\n\t}\n\n\treturn configLabelKey in config ? config[configLabelKey] : config[key];\n}\n\nexport {\n\tcartesianAxisProps,\n\tChartCard,\n\tChartContainer,\n\tChartDescription,\n\tChartHeader,\n\tChartLegend,\n\tChartLegendContent,\n\tChartStyle,\n\tChartTitle,\n\tChartTooltip,\n\tChartTooltipContent,\n};\nexport type { CartesianAxisLayout };\n","\"use client\";\n\nimport { createContext, type ReactNode, useContext } from \"react\";\n\ntype ComponentSize = \"sm\" | \"md\" | \"lg\";\n\nconst SizeContext = createContext<ComponentSize | undefined>(undefined);\n\nfunction SizeProvider({\n\tchildren,\n\tsize,\n}: {\n\tchildren: ReactNode;\n\tsize?: ComponentSize | null;\n}) {\n\tif (!size) {\n\t\treturn <>{children}</>;\n\t}\n\n\treturn <SizeContext.Provider value={size}>{children}</SizeContext.Provider>;\n}\n\nfunction useComponentSize(\n\tsize?: ComponentSize | null,\n\tfallback: ComponentSize = \"md\",\n) {\n\tconst inheritedSize = useContext(SizeContext);\n\treturn size ?? inheritedSize ?? fallback;\n}\n\nexport { SizeProvider, useComponentSize, type ComponentSize };\n","\"use client\";\n\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { cartesianAxisProps } from \"./chart\";\nimport { type ComponentSize, useComponentSize } from \"./size-context\";\n\n/**\n * Bar charts are composed from recharts plot primitives directly — recharts\n * identifies `Bar`, `XAxis`, `YAxis`, `CartesianGrid`, and `LabelList` by\n * component identity, so they cannot be wrapped without breaking the chart.\n * This module supplies the giddaa-specific defaults that would otherwise be\n * copy-pasted into every bar chart: per-size layout numbers and a value-label\n * renderer. Pair them with the shared frame and overlays from `./chart`.\n *\n * @example\n * const chart = useBarChartLayout();\n * <ChartCard size=\"md\">\n * <ChartHeader>\n * <ChartTitle>Revenue Overview</ChartTitle>\n * <ChartDescription>Monthly revenue · Jan–Jul</ChartDescription>\n * </ChartHeader>\n * <ChartContainer config={config} {...chart.container}>\n * <BarChart data={data} {...chart.chart}>\n * <CartesianGrid vertical={false} stroke=\"var(--color-line-subtle)\" />\n * <XAxis dataKey=\"month\" {...chart.xAxis} />\n * <YAxis {...chart.yAxis} />\n * <ChartLegend verticalAlign=\"top\" content={<ChartLegendContent />} />\n * <ChartTooltip content={<ChartTooltipContent />} />\n * <Bar dataKey=\"revenue\" fill=\"var(--color-revenue)\" {...chart.bar}>\n * <LabelList dataKey=\"revenue\" content={<BarValueLabel />} />\n * </Bar>\n * </BarChart>\n * </ChartContainer>\n * </ChartCard>\n */\n\ntype BarChartLayout = {\n\t/** Plot height in px. Width stays fluid via the ResponsiveContainer. */\n\theight: number;\n\t/** Outer margin — top leaves room for value labels above the tallest bar. */\n\tmargin: { top: number; right: number; bottom: number; left: number };\n\t/** Cap on bar thickness so a few categories don't render slab-wide bars. */\n\tmaxBarSize: number;\n\t/** Gap between categories (groups), as a percentage of the band. */\n\tbarCategoryGap: string;\n\t/** Gap between bars within a group (grouped layout). */\n\tbarGap: number;\n\t/** Corner radius for a bar. */\n\tbarRadius: number;\n\t/** Axis tick label font size. */\n\ttickFontSize: number;\n\t/** Value label (on-bar number) font size. */\n\tvalueFontSize: number;\n\t/** Reserved width for the value axis. */\n\tyAxisWidth: number;\n\t/** Space between an axis and its tick labels. */\n\ttickMargin: number;\n};\n\nconst BAR_CHART_LAYOUT: Record<ComponentSize, BarChartLayout> = {\n\tsm: {\n\t\theight: 180,\n\t\tmargin: { top: 20, right: 8, bottom: 0, left: 0 },\n\t\tmaxBarSize: 22,\n\t\tbarCategoryGap: \"8%\",\n\t\tbarGap: 4,\n\t\tbarRadius: 4,\n\t\ttickFontSize: 10,\n\t\tvalueFontSize: 10,\n\t\tyAxisWidth: 28,\n\t\ttickMargin: 6,\n\t},\n\tmd: {\n\t\theight: 220,\n\t\tmargin: { top: 24, right: 12, bottom: 0, left: 0 },\n\t\tmaxBarSize: 28,\n\t\tbarCategoryGap: \"8%\",\n\t\tbarGap: 6,\n\t\tbarRadius: 6,\n\t\ttickFontSize: 11,\n\t\tvalueFontSize: 11,\n\t\tyAxisWidth: 32,\n\t\ttickMargin: 8,\n\t},\n\tlg: {\n\t\theight: 280,\n\t\tmargin: { top: 28, right: 16, bottom: 0, left: 0 },\n\t\tmaxBarSize: 36,\n\t\tbarCategoryGap: \"8%\",\n\t\tbarGap: 8,\n\t\tbarRadius: 8,\n\t\ttickFontSize: 12,\n\t\tvalueFontSize: 12,\n\t\tyAxisWidth: 36,\n\t\ttickMargin: 10,\n\t},\n};\n\n/**\n * Resolve the bar-chart layout for an explicit or inherited component size. The\n * returned object groups the giddaa defaults by the recharts component they\n * belong to — spread each onto its element, then pass the data-specific props\n * (`config`, `data`, `dataKey`, `fill`, …) directly afterwards to add or\n * override anything:\n *\n * const chart = useBarChartLayout(size);\n * <ChartContainer config={config} {...chart.container}>\n * <BarChart data={data} {...chart.chart}>\n * <XAxis dataKey=\"month\" {...chart.xAxis} />\n * <YAxis {...chart.yAxis} />\n * <Bar dataKey=\"revenue\" fill=\"var(--color-revenue)\" {...chart.bar} />\n */\nfunction useBarChartLayout(size?: ComponentSize) {\n\tconst layout = BAR_CHART_LAYOUT[useComponentSize(size)];\n\tconst axes = cartesianAxisProps(layout);\n\n\treturn {\n\t\tcontainer: {\n\t\t\tclassName: \"aspect-auto w-full\",\n\t\t\tstyle: { height: layout.height },\n\t\t},\n\t\tchart: {\n\t\t\taccessibilityLayer: true,\n\t\t\tmargin: layout.margin,\n\t\t\tbarCategoryGap: layout.barCategoryGap,\n\t\t\tbarGap: layout.barGap,\n\t\t},\n\t\txAxis: axes.xAxis,\n\t\tyAxis: axes.yAxis,\n\t\tbar: {\n\t\t\tradius: [layout.barRadius, layout.barRadius, 0, 0] as [\n\t\t\t\tnumber,\n\t\t\t\tnumber,\n\t\t\t\tnumber,\n\t\t\t\tnumber,\n\t\t\t],\n\t\t\tmaxBarSize: layout.maxBarSize,\n\t\t},\n\t};\n}\n\n/**\n * Renderer for recharts `<LabelList content={<BarValueLabel />} />`. recharts\n * injects the bar geometry (`x`, `y`, `width`, `height`, `value`); the rest are\n * caller props. For a vertical bar the label sits above the bar; for a\n * horizontal bar (`orientation=\"horizontal\"`) it sits to the right of the bar.\n */\ntype BarValueLabelProps = {\n\t/** Bar layout direction — drives where the label is placed. */\n\torientation?: \"vertical\" | \"horizontal\";\n\t/** Override the on-bar font size (defaults to the size-scaled value). */\n\tfontSize?: number;\n\t/** Format the raw value before display, e.g. `(v) => `₦${v}``. */\n\tformatter?: (value: React.ReactNode) => React.ReactNode;\n\tclassName?: string;\n\t// Injected by recharts at render time.\n\tx?: string | number;\n\ty?: string | number;\n\twidth?: string | number;\n\theight?: string | number;\n\tvalue?: React.ReactNode;\n};\n\nfunction BarValueLabel({\n\torientation = \"vertical\",\n\tfontSize,\n\tformatter,\n\tclassName,\n\tx,\n\ty,\n\twidth,\n\theight,\n\tvalue,\n}: BarValueLabelProps) {\n\tconst valueFontSize = BAR_CHART_LAYOUT[useComponentSize()].valueFontSize;\n\n\tif (value == null || x == null || y == null || width == null) {\n\t\treturn null;\n\t}\n\n\tconst numX = Number(x);\n\tconst numY = Number(y);\n\tconst numWidth = Number(width);\n\tconst numHeight = Number(height ?? 0);\n\tconst gap = 6;\n\n\tconst isHorizontal = orientation === \"horizontal\";\n\tconst labelX = isHorizontal ? numX + numWidth + gap : numX + numWidth / 2;\n\tconst labelY = isHorizontal ? numY + numHeight / 2 : numY - gap;\n\n\treturn (\n\t\t<text\n\t\t\tx={labelX}\n\t\t\ty={labelY}\n\t\t\ttextAnchor={isHorizontal ? \"start\" : \"middle\"}\n\t\t\tdominantBaseline={isHorizontal ? \"central\" : \"auto\"}\n\t\t\tclassName={cn(\"fill-fg-primary font-semibold tabular-nums\", className)}\n\t\t\tstyle={{ fontSize: fontSize ?? valueFontSize }}\n\t\t>\n\t\t\t{formatter ? formatter(value) : value}\n\t\t</text>\n\t);\n}\n\nexport { BAR_CHART_LAYOUT, BarValueLabel, useBarChartLayout };\nexport type { BarChartLayout, BarValueLabelProps };\n"],"mappings":"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","names":["Fragment","jsx","jsx"]}