@fanvue/ui 1.20.1 → 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 (256) hide show
  1. package/dist/charts.d.ts +1 -1
  2. package/dist/cjs/components/Accordion/AccordionContent.cjs +1 -1
  3. package/dist/cjs/components/Accordion/AccordionContent.cjs.map +1 -1
  4. package/dist/cjs/components/Accordion/AccordionItem.cjs +1 -1
  5. package/dist/cjs/components/Accordion/AccordionItem.cjs.map +1 -1
  6. package/dist/cjs/components/Accordion/AccordionTrigger.cjs +5 -5
  7. package/dist/cjs/components/Accordion/AccordionTrigger.cjs.map +1 -1
  8. package/dist/cjs/components/Alert/Alert.cjs +11 -11
  9. package/dist/cjs/components/Alert/Alert.cjs.map +1 -1
  10. package/dist/cjs/components/AudioUpload/AudioUpload.cjs +12 -12
  11. package/dist/cjs/components/AudioUpload/AudioUpload.cjs.map +1 -1
  12. package/dist/cjs/components/AudioUpload/AudioWaveform.cjs +1 -1
  13. package/dist/cjs/components/AudioUpload/AudioWaveform.cjs.map +1 -1
  14. package/dist/cjs/components/Autocomplete/Autocomplete.cjs +12 -12
  15. package/dist/cjs/components/Autocomplete/Autocomplete.cjs.map +1 -1
  16. package/dist/cjs/components/Autocomplete/AutocompleteDropdownContent.cjs +3 -3
  17. package/dist/cjs/components/Autocomplete/AutocompleteDropdownContent.cjs.map +1 -1
  18. package/dist/cjs/components/Autocomplete/AutocompleteOptionItem.cjs +3 -3
  19. package/dist/cjs/components/Autocomplete/AutocompleteOptionItem.cjs.map +1 -1
  20. package/dist/cjs/components/Autocomplete/AutocompleteTag.cjs +2 -2
  21. package/dist/cjs/components/Autocomplete/AutocompleteTag.cjs.map +1 -1
  22. package/dist/cjs/components/Avatar/Avatar.cjs +3 -3
  23. package/dist/cjs/components/Avatar/Avatar.cjs.map +1 -1
  24. package/dist/cjs/components/Badge/Badge.cjs +23 -23
  25. package/dist/cjs/components/Badge/Badge.cjs.map +1 -1
  26. package/dist/cjs/components/Banner/Banner.cjs +71 -0
  27. package/dist/cjs/components/Banner/Banner.cjs.map +1 -0
  28. package/dist/cjs/components/BottomNavigation/BottomNavigation.cjs +1 -1
  29. package/dist/cjs/components/BottomNavigation/BottomNavigation.cjs.map +1 -1
  30. package/dist/cjs/components/BottomNavigation/BottomNavigationAction.cjs +2 -2
  31. package/dist/cjs/components/BottomNavigation/BottomNavigationAction.cjs.map +1 -1
  32. package/dist/cjs/components/Breadcrumb/Breadcrumb.cjs +3 -3
  33. package/dist/cjs/components/Breadcrumb/Breadcrumb.cjs.map +1 -1
  34. package/dist/cjs/components/Button/Button.cjs +10 -10
  35. package/dist/cjs/components/Button/Button.cjs.map +1 -1
  36. package/dist/cjs/components/Card/Card.cjs +6 -6
  37. package/dist/cjs/components/Card/Card.cjs.map +1 -1
  38. package/dist/cjs/components/Chart/ChartCard.cjs +6 -6
  39. package/dist/cjs/components/Chart/ChartCard.cjs.map +1 -1
  40. package/dist/cjs/components/Chart/ChartCenterLabel.cjs +2 -2
  41. package/dist/cjs/components/Chart/ChartCenterLabel.cjs.map +1 -1
  42. package/dist/cjs/components/Chart/ChartContainer.cjs +7 -7
  43. package/dist/cjs/components/Chart/ChartContainer.cjs.map +1 -1
  44. package/dist/cjs/components/Chart/ChartLegend.cjs +1 -1
  45. package/dist/cjs/components/Chart/ChartLegend.cjs.map +1 -1
  46. package/dist/cjs/components/Chart/ChartLoadingOverlay.cjs +1 -1
  47. package/dist/cjs/components/Chart/ChartLoadingOverlay.cjs.map +1 -1
  48. package/dist/cjs/components/Chart/ChartPieLegend.cjs +2 -2
  49. package/dist/cjs/components/Chart/ChartPieLegend.cjs.map +1 -1
  50. package/dist/cjs/components/Chart/ChartSeriesToggle.cjs +2 -2
  51. package/dist/cjs/components/Chart/ChartSeriesToggle.cjs.map +1 -1
  52. package/dist/cjs/components/Chart/ChartTooltip.cjs +4 -4
  53. package/dist/cjs/components/Chart/ChartTooltip.cjs.map +1 -1
  54. package/dist/cjs/components/Checkbox/Checkbox.cjs +13 -13
  55. package/dist/cjs/components/Checkbox/Checkbox.cjs.map +1 -1
  56. package/dist/cjs/components/Chip/Chip.cjs +7 -7
  57. package/dist/cjs/components/Chip/Chip.cjs.map +1 -1
  58. package/dist/cjs/components/Count/Count.cjs +7 -7
  59. package/dist/cjs/components/Count/Count.cjs.map +1 -1
  60. package/dist/cjs/components/DatePicker/DatePicker.cjs +14 -14
  61. package/dist/cjs/components/DatePicker/DatePicker.cjs.map +1 -1
  62. package/dist/cjs/components/Dialog/Dialog.cjs +6 -6
  63. package/dist/cjs/components/Dialog/Dialog.cjs.map +1 -1
  64. package/dist/cjs/components/Divider/Divider.cjs +4 -4
  65. package/dist/cjs/components/Divider/Divider.cjs.map +1 -1
  66. package/dist/cjs/components/Drawer/Drawer.cjs +5 -5
  67. package/dist/cjs/components/Drawer/Drawer.cjs.map +1 -1
  68. package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs +111 -0
  69. package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs.map +1 -0
  70. package/dist/cjs/components/IconButton/IconButton.cjs +10 -10
  71. package/dist/cjs/components/IconButton/IconButton.cjs.map +1 -1
  72. package/dist/cjs/components/Icons/LockerOffIcon.cjs +1 -1
  73. package/dist/cjs/components/Icons/LockerOffIcon.cjs.map +1 -1
  74. package/dist/cjs/components/Icons/LockerOnIcon.cjs +1 -1
  75. package/dist/cjs/components/Icons/LockerOnIcon.cjs.map +1 -1
  76. package/dist/cjs/components/InfoBox/InfoBox.cjs +6 -6
  77. package/dist/cjs/components/InfoBox/InfoBox.cjs.map +1 -1
  78. package/dist/cjs/components/Loader/Loader.cjs +1 -1
  79. package/dist/cjs/components/Loader/Loader.cjs.map +1 -1
  80. package/dist/cjs/components/Logo/Logo.cjs +13 -13
  81. package/dist/cjs/components/Logo/Logo.cjs.map +1 -1
  82. package/dist/cjs/components/MobileStepper/MobileStepper.cjs +2 -2
  83. package/dist/cjs/components/MobileStepper/MobileStepper.cjs.map +1 -1
  84. package/dist/cjs/components/OnlineBlinkingIcon/OnlineBlinkingIcon.cjs +45 -0
  85. package/dist/cjs/components/OnlineBlinkingIcon/OnlineBlinkingIcon.cjs.map +1 -0
  86. package/dist/cjs/components/Pagination/Pagination.cjs +3 -3
  87. package/dist/cjs/components/Pagination/Pagination.cjs.map +1 -1
  88. package/dist/cjs/components/PasswordField/PasswordField.cjs +1 -1
  89. package/dist/cjs/components/PasswordField/PasswordField.cjs.map +1 -1
  90. package/dist/cjs/components/Pill/Pill.cjs +10 -10
  91. package/dist/cjs/components/Pill/Pill.cjs.map +1 -1
  92. package/dist/cjs/components/ProgressBar/ProgressBar.cjs +13 -13
  93. package/dist/cjs/components/ProgressBar/ProgressBar.cjs.map +1 -1
  94. package/dist/cjs/components/Radio/Radio.cjs +4 -4
  95. package/dist/cjs/components/Radio/Radio.cjs.map +1 -1
  96. package/dist/cjs/components/Select/Select.cjs +13 -13
  97. package/dist/cjs/components/Select/Select.cjs.map +1 -1
  98. package/dist/cjs/components/Skeleton/Skeleton.cjs +2 -2
  99. package/dist/cjs/components/Skeleton/Skeleton.cjs.map +1 -1
  100. package/dist/cjs/components/Slider/Slider.cjs +1 -1
  101. package/dist/cjs/components/Slider/Slider.cjs.map +1 -1
  102. package/dist/cjs/components/Slider/SliderLayout.cjs +5 -12
  103. package/dist/cjs/components/Slider/SliderLayout.cjs.map +1 -1
  104. package/dist/cjs/components/Slider/SliderThumb.cjs +6 -6
  105. package/dist/cjs/components/Slider/SliderThumb.cjs.map +1 -1
  106. package/dist/cjs/components/Snackbar/Snackbar.cjs +9 -9
  107. package/dist/cjs/components/Snackbar/Snackbar.cjs.map +1 -1
  108. package/dist/cjs/components/Switch/Switch.cjs +3 -3
  109. package/dist/cjs/components/Switch/Switch.cjs.map +1 -1
  110. package/dist/cjs/components/SwitchField/SwitchField.cjs +5 -5
  111. package/dist/cjs/components/SwitchField/SwitchField.cjs.map +1 -1
  112. package/dist/cjs/components/SwitchToggle/SwitchToggle.cjs +4 -4
  113. package/dist/cjs/components/SwitchToggle/SwitchToggle.cjs.map +1 -1
  114. package/dist/cjs/components/Tabs/TabsList.cjs +3 -3
  115. package/dist/cjs/components/Tabs/TabsList.cjs.map +1 -1
  116. package/dist/cjs/components/Tabs/TabsTrigger.cjs +8 -8
  117. package/dist/cjs/components/Tabs/TabsTrigger.cjs.map +1 -1
  118. package/dist/cjs/components/TextArea/TextArea.cjs +7 -7
  119. package/dist/cjs/components/TextArea/TextArea.cjs.map +1 -1
  120. package/dist/cjs/components/TextField/TextField.cjs +11 -11
  121. package/dist/cjs/components/TextField/TextField.cjs.map +1 -1
  122. package/dist/cjs/components/Toast/Toast.cjs +7 -7
  123. package/dist/cjs/components/Toast/Toast.cjs.map +1 -1
  124. package/dist/cjs/components/Tooltip/Tooltip.cjs +1 -1
  125. package/dist/cjs/components/Tooltip/Tooltip.cjs.map +1 -1
  126. package/dist/cjs/index.cjs +12 -0
  127. package/dist/cjs/index.cjs.map +1 -1
  128. package/dist/components/Accordion/AccordionContent.mjs +1 -1
  129. package/dist/components/Accordion/AccordionContent.mjs.map +1 -1
  130. package/dist/components/Accordion/AccordionItem.mjs +1 -1
  131. package/dist/components/Accordion/AccordionItem.mjs.map +1 -1
  132. package/dist/components/Accordion/AccordionTrigger.mjs +5 -5
  133. package/dist/components/Accordion/AccordionTrigger.mjs.map +1 -1
  134. package/dist/components/Alert/Alert.mjs +11 -11
  135. package/dist/components/Alert/Alert.mjs.map +1 -1
  136. package/dist/components/AudioUpload/AudioUpload.mjs +12 -12
  137. package/dist/components/AudioUpload/AudioUpload.mjs.map +1 -1
  138. package/dist/components/AudioUpload/AudioWaveform.mjs +1 -1
  139. package/dist/components/AudioUpload/AudioWaveform.mjs.map +1 -1
  140. package/dist/components/Autocomplete/Autocomplete.mjs +12 -12
  141. package/dist/components/Autocomplete/Autocomplete.mjs.map +1 -1
  142. package/dist/components/Autocomplete/AutocompleteDropdownContent.mjs +3 -3
  143. package/dist/components/Autocomplete/AutocompleteDropdownContent.mjs.map +1 -1
  144. package/dist/components/Autocomplete/AutocompleteOptionItem.mjs +3 -3
  145. package/dist/components/Autocomplete/AutocompleteOptionItem.mjs.map +1 -1
  146. package/dist/components/Autocomplete/AutocompleteTag.mjs +2 -2
  147. package/dist/components/Autocomplete/AutocompleteTag.mjs.map +1 -1
  148. package/dist/components/Avatar/Avatar.mjs +3 -3
  149. package/dist/components/Avatar/Avatar.mjs.map +1 -1
  150. package/dist/components/Badge/Badge.mjs +23 -23
  151. package/dist/components/Badge/Badge.mjs.map +1 -1
  152. package/dist/components/Banner/Banner.mjs +54 -0
  153. package/dist/components/Banner/Banner.mjs.map +1 -0
  154. package/dist/components/BottomNavigation/BottomNavigation.mjs +1 -1
  155. package/dist/components/BottomNavigation/BottomNavigation.mjs.map +1 -1
  156. package/dist/components/BottomNavigation/BottomNavigationAction.mjs +2 -2
  157. package/dist/components/BottomNavigation/BottomNavigationAction.mjs.map +1 -1
  158. package/dist/components/Breadcrumb/Breadcrumb.mjs +3 -3
  159. package/dist/components/Breadcrumb/Breadcrumb.mjs.map +1 -1
  160. package/dist/components/Button/Button.mjs +10 -10
  161. package/dist/components/Button/Button.mjs.map +1 -1
  162. package/dist/components/Card/Card.mjs +6 -6
  163. package/dist/components/Card/Card.mjs.map +1 -1
  164. package/dist/components/Chart/ChartCard.mjs +6 -6
  165. package/dist/components/Chart/ChartCard.mjs.map +1 -1
  166. package/dist/components/Chart/ChartCenterLabel.mjs +2 -2
  167. package/dist/components/Chart/ChartCenterLabel.mjs.map +1 -1
  168. package/dist/components/Chart/ChartContainer.mjs +7 -7
  169. package/dist/components/Chart/ChartContainer.mjs.map +1 -1
  170. package/dist/components/Chart/ChartLegend.mjs +1 -1
  171. package/dist/components/Chart/ChartLegend.mjs.map +1 -1
  172. package/dist/components/Chart/ChartLoadingOverlay.mjs +1 -1
  173. package/dist/components/Chart/ChartLoadingOverlay.mjs.map +1 -1
  174. package/dist/components/Chart/ChartPieLegend.mjs +2 -2
  175. package/dist/components/Chart/ChartPieLegend.mjs.map +1 -1
  176. package/dist/components/Chart/ChartSeriesToggle.mjs +2 -2
  177. package/dist/components/Chart/ChartSeriesToggle.mjs.map +1 -1
  178. package/dist/components/Chart/ChartTooltip.mjs +4 -4
  179. package/dist/components/Chart/ChartTooltip.mjs.map +1 -1
  180. package/dist/components/Checkbox/Checkbox.mjs +13 -13
  181. package/dist/components/Checkbox/Checkbox.mjs.map +1 -1
  182. package/dist/components/Chip/Chip.mjs +7 -7
  183. package/dist/components/Chip/Chip.mjs.map +1 -1
  184. package/dist/components/Count/Count.mjs +7 -7
  185. package/dist/components/Count/Count.mjs.map +1 -1
  186. package/dist/components/DatePicker/DatePicker.mjs +14 -14
  187. package/dist/components/DatePicker/DatePicker.mjs.map +1 -1
  188. package/dist/components/Dialog/Dialog.mjs +6 -6
  189. package/dist/components/Dialog/Dialog.mjs.map +1 -1
  190. package/dist/components/Divider/Divider.mjs +4 -4
  191. package/dist/components/Divider/Divider.mjs.map +1 -1
  192. package/dist/components/Drawer/Drawer.mjs +5 -5
  193. package/dist/components/Drawer/Drawer.mjs.map +1 -1
  194. package/dist/components/DropdownMenu/DropdownMenu.mjs +93 -0
  195. package/dist/components/DropdownMenu/DropdownMenu.mjs.map +1 -0
  196. package/dist/components/IconButton/IconButton.mjs +10 -10
  197. package/dist/components/IconButton/IconButton.mjs.map +1 -1
  198. package/dist/components/Icons/LockerOffIcon.mjs +1 -1
  199. package/dist/components/Icons/LockerOffIcon.mjs.map +1 -1
  200. package/dist/components/Icons/LockerOnIcon.mjs +1 -1
  201. package/dist/components/Icons/LockerOnIcon.mjs.map +1 -1
  202. package/dist/components/InfoBox/InfoBox.mjs +6 -6
  203. package/dist/components/InfoBox/InfoBox.mjs.map +1 -1
  204. package/dist/components/Loader/Loader.mjs +1 -1
  205. package/dist/components/Loader/Loader.mjs.map +1 -1
  206. package/dist/components/Logo/Logo.mjs +13 -13
  207. package/dist/components/Logo/Logo.mjs.map +1 -1
  208. package/dist/components/MobileStepper/MobileStepper.mjs +2 -2
  209. package/dist/components/MobileStepper/MobileStepper.mjs.map +1 -1
  210. package/dist/components/OnlineBlinkingIcon/OnlineBlinkingIcon.mjs +28 -0
  211. package/dist/components/OnlineBlinkingIcon/OnlineBlinkingIcon.mjs.map +1 -0
  212. package/dist/components/Pagination/Pagination.mjs +3 -3
  213. package/dist/components/Pagination/Pagination.mjs.map +1 -1
  214. package/dist/components/PasswordField/PasswordField.mjs +1 -1
  215. package/dist/components/PasswordField/PasswordField.mjs.map +1 -1
  216. package/dist/components/Pill/Pill.mjs +10 -10
  217. package/dist/components/Pill/Pill.mjs.map +1 -1
  218. package/dist/components/ProgressBar/ProgressBar.mjs +13 -13
  219. package/dist/components/ProgressBar/ProgressBar.mjs.map +1 -1
  220. package/dist/components/Radio/Radio.mjs +4 -4
  221. package/dist/components/Radio/Radio.mjs.map +1 -1
  222. package/dist/components/Select/Select.mjs +13 -13
  223. package/dist/components/Select/Select.mjs.map +1 -1
  224. package/dist/components/Skeleton/Skeleton.mjs +2 -2
  225. package/dist/components/Skeleton/Skeleton.mjs.map +1 -1
  226. package/dist/components/Slider/Slider.mjs +1 -1
  227. package/dist/components/Slider/Slider.mjs.map +1 -1
  228. package/dist/components/Slider/SliderLayout.mjs +5 -12
  229. package/dist/components/Slider/SliderLayout.mjs.map +1 -1
  230. package/dist/components/Slider/SliderThumb.mjs +6 -6
  231. package/dist/components/Slider/SliderThumb.mjs.map +1 -1
  232. package/dist/components/Snackbar/Snackbar.mjs +9 -9
  233. package/dist/components/Snackbar/Snackbar.mjs.map +1 -1
  234. package/dist/components/Switch/Switch.mjs +3 -3
  235. package/dist/components/Switch/Switch.mjs.map +1 -1
  236. package/dist/components/SwitchField/SwitchField.mjs +5 -5
  237. package/dist/components/SwitchField/SwitchField.mjs.map +1 -1
  238. package/dist/components/SwitchToggle/SwitchToggle.mjs +4 -4
  239. package/dist/components/SwitchToggle/SwitchToggle.mjs.map +1 -1
  240. package/dist/components/Tabs/TabsList.mjs +3 -3
  241. package/dist/components/Tabs/TabsList.mjs.map +1 -1
  242. package/dist/components/Tabs/TabsTrigger.mjs +8 -8
  243. package/dist/components/Tabs/TabsTrigger.mjs.map +1 -1
  244. package/dist/components/TextArea/TextArea.mjs +7 -7
  245. package/dist/components/TextArea/TextArea.mjs.map +1 -1
  246. package/dist/components/TextField/TextField.mjs +11 -11
  247. package/dist/components/TextField/TextField.mjs.map +1 -1
  248. package/dist/components/Toast/Toast.mjs +7 -7
  249. package/dist/components/Toast/Toast.mjs.map +1 -1
  250. package/dist/components/Tooltip/Tooltip.mjs +1 -1
  251. package/dist/components/Tooltip/Tooltip.mjs.map +1 -1
  252. package/dist/index.d.ts +152 -0
  253. package/dist/index.mjs +12 -0
  254. package/dist/index.mjs.map +1 -1
  255. package/dist/styles/theme.css +378 -253
  256. package/package.json +2 -1
@@ -5,32 +5,32 @@ import * as React from "react";
5
5
  import { cn } from "../../utils/cn.mjs";
6
6
  const badgeVariants = {
7
7
  variant: {
8
- default: "bg-neutral-100 text-foreground-secondary",
9
- dark: "bg-neutral-50 text-foreground-inverse dark:text-foreground-onaccentinverse",
10
- success: "bg-neutral-100 text-foreground-secondary",
11
- warning: "bg-neutral-100 text-foreground-secondary",
12
- error: "bg-neutral-100 text-foreground-secondary",
13
- special: "bg-neutral-100 text-foreground-secondary",
14
- info: "bg-neutral-100 text-foreground-secondary",
15
- online: "bg-neutral-100 text-brand-accent-default",
16
- brand: "bg-brand-accent-default text-foreground-onaccent",
17
- pink: "bg-brand-secondary-default text-foreground-onaccent",
18
- brandLight: "bg-brand-accent-muted text-foreground-onaccent",
19
- pinkLight: "bg-brand-secondary-muted text-foreground-onaccent"
8
+ default: "bg-neutral-alphas-50 text-content-secondary",
9
+ dark: "bg-neutral-alphas-150 text-content-on-brand-inverted",
10
+ success: "bg-neutral-alphas-50 text-content-secondary",
11
+ warning: "bg-neutral-alphas-50 text-content-secondary",
12
+ error: "bg-neutral-alphas-50 text-content-secondary",
13
+ special: "bg-neutral-alphas-50 text-content-secondary",
14
+ info: "bg-neutral-alphas-50 text-content-secondary",
15
+ online: "bg-bg-primary text-brand-primary-default",
16
+ brand: "bg-brand-primary-default text-content-on-brand",
17
+ pink: "bg-brand-secondary-default text-content-on-brand",
18
+ brandLight: "bg-brand-primary-muted text-content-on-brand",
19
+ pinkLight: "bg-brand-secondary-muted text-content-on-brand"
20
20
  },
21
21
  dotColor: {
22
- default: "bg-foreground-onaccent",
23
- dark: "bg-foreground-inverse dark:bg-foreground-onaccentinverse",
24
- success: "bg-success-default",
25
- warning: "bg-warning-default",
26
- error: "bg-error-default",
22
+ default: "bg-content-on-brand",
23
+ dark: "bg-content-primary-inverted",
24
+ success: "bg-success-content",
25
+ warning: "bg-warning-content",
26
+ error: "bg-error-content",
27
27
  special: "bg-special-default",
28
- info: "bg-info-default",
29
- online: "bg-brand-accent-default",
30
- brand: "bg-foreground-onaccent",
31
- pink: "bg-foreground-onaccent",
32
- brandLight: "bg-foreground-onaccent",
33
- pinkLight: "bg-foreground-onaccent"
28
+ info: "bg-info-content",
29
+ online: "bg-brand-primary-default",
30
+ brand: "bg-content-on-brand",
31
+ pink: "bg-content-on-brand",
32
+ brandLight: "bg-content-on-brand",
33
+ pinkLight: "bg-content-on-brand"
34
34
  }
35
35
  };
36
36
  const Badge = React.forwardRef(
@@ -1 +1 @@
1
- {"version":3,"file":"Badge.mjs","sources":["../../../src/components/Badge/Badge.tsx"],"sourcesContent":["import { Slot, Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nconst badgeVariants = {\n variant: {\n default: \"bg-neutral-100 text-foreground-secondary\",\n dark: \"bg-neutral-50 text-foreground-inverse dark:text-foreground-onaccentinverse\",\n success: \"bg-neutral-100 text-foreground-secondary\",\n warning: \"bg-neutral-100 text-foreground-secondary\",\n error: \"bg-neutral-100 text-foreground-secondary\",\n special: \"bg-neutral-100 text-foreground-secondary\",\n info: \"bg-neutral-100 text-foreground-secondary\",\n online: \"bg-neutral-100 text-brand-accent-default\",\n brand: \"bg-brand-accent-default text-foreground-onaccent\",\n pink: \"bg-brand-secondary-default text-foreground-onaccent\",\n brandLight: \"bg-brand-accent-muted text-foreground-onaccent\",\n pinkLight: \"bg-brand-secondary-muted text-foreground-onaccent\",\n },\n dotColor: {\n default: \"bg-foreground-onaccent\",\n dark: \"bg-foreground-inverse dark:bg-foreground-onaccentinverse\",\n success: \"bg-success-default\",\n warning: \"bg-warning-default\",\n error: \"bg-error-default\",\n special: \"bg-special-default\",\n info: \"bg-info-default\",\n online: \"bg-brand-accent-default\",\n brand: \"bg-foreground-onaccent\",\n pink: \"bg-foreground-onaccent\",\n brandLight: \"bg-foreground-onaccent\",\n pinkLight: \"bg-foreground-onaccent\",\n },\n} as const;\n\n/** Visual style variant of the badge. */\nexport type BadgeVariant =\n | \"default\"\n | \"dark\"\n | \"success\"\n | \"warning\"\n | \"error\"\n | \"special\"\n | \"info\"\n | \"online\"\n | \"brand\"\n | \"pink\"\n | \"brandLight\"\n | \"pinkLight\";\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Visual style variant of the badge. @default \"default\" */\n variant?: BadgeVariant;\n /** Whether to show a coloured status dot at the leading edge. @default true */\n leftDot?: boolean;\n /** Icon element displayed before the label. */\n leftIcon?: React.ReactNode;\n /** Icon element displayed after the label. */\n rightIcon?: React.ReactNode;\n /** Merge props onto a child element instead of rendering a `<span>`. @default false */\n asChild?: boolean;\n}\n\n/**\n * A small inline label for status, category, or metadata information.\n *\n * @example\n * ```tsx\n * <Badge variant=\"success\">Active</Badge>\n * ```\n */\nexport const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(\n (\n {\n className,\n variant = \"default\",\n leftDot = true,\n leftIcon,\n rightIcon,\n asChild = false,\n onClick,\n children,\n ...props\n },\n ref,\n ) => {\n const Comp = asChild ? Slot : \"span\";\n\n return (\n <Comp\n ref={ref}\n data-testid=\"badge\"\n className={cn(\n // Base styles\n \"typography-semibold-body-sm inline-flex h-5 min-w-0 items-center gap-2 rounded-full px-2\",\n // Variant styles\n badgeVariants.variant[variant],\n // Interactive\n onClick && \"cursor-pointer\",\n // Manual CSS overrides\n className,\n )}\n onClick={onClick}\n {...props}\n >\n {leftIcon && (\n <span className=\"flex size-3\" aria-hidden=\"true\">\n {leftIcon}\n </span>\n )}\n {leftDot && (\n <span\n className={cn(\"size-1 shrink-0 rounded-full\", badgeVariants.dotColor[variant])}\n aria-hidden=\"true\"\n />\n )}\n {asChild ? (\n <Slottable>{children}</Slottable>\n ) : (\n <span className=\"min-w-0 truncate\">{children}</span>\n )}\n {rightIcon && (\n <span className=\"flex size-3\" aria-hidden=\"true\">\n {rightIcon}\n </span>\n )}\n </Comp>\n );\n },\n);\n\nBadge.displayName = \"Badge\";\n"],"names":[],"mappings":";;;;;AAIA,MAAM,gBAAgB;AAAA,EACpB,SAAS;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,EAAA;AAAA,EAEb,UAAU;AAAA,IACR,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,EAAA;AAEf;AAsCO,MAAM,QAAQ,MAAM;AAAA,EACzB,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,OAAO,UAAU,OAAO;AAE9B,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAY;AAAA,QACZ,WAAW;AAAA;AAAA,UAET;AAAA;AAAA,UAEA,cAAc,QAAQ,OAAO;AAAA;AAAA,UAE7B,WAAW;AAAA;AAAA,UAEX;AAAA,QAAA;AAAA,QAEF;AAAA,QACC,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,gCACE,QAAA,EAAK,WAAU,eAAc,eAAY,QACvC,UAAA,UACH;AAAA,UAED,WACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW,GAAG,gCAAgC,cAAc,SAAS,OAAO,CAAC;AAAA,cAC7E,eAAY;AAAA,YAAA;AAAA,UAAA;AAAA,UAGf,8BACE,WAAA,EAAW,SAAA,CAAS,IAErB,oBAAC,QAAA,EAAK,WAAU,oBAAoB,SAAA,CAAS;AAAA,UAE9C,aACC,oBAAC,QAAA,EAAK,WAAU,eAAc,eAAY,QACvC,UAAA,UAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,MAAM,cAAc;"}
1
+ {"version":3,"file":"Badge.mjs","sources":["../../../src/components/Badge/Badge.tsx"],"sourcesContent":["import { Slot, Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nconst badgeVariants = {\n variant: {\n default: \"bg-neutral-alphas-50 text-content-secondary\",\n dark: \"bg-neutral-alphas-150 text-content-on-brand-inverted\",\n success: \"bg-neutral-alphas-50 text-content-secondary\",\n warning: \"bg-neutral-alphas-50 text-content-secondary\",\n error: \"bg-neutral-alphas-50 text-content-secondary\",\n special: \"bg-neutral-alphas-50 text-content-secondary\",\n info: \"bg-neutral-alphas-50 text-content-secondary\",\n online: \"bg-bg-primary text-brand-primary-default\",\n brand: \"bg-brand-primary-default text-content-on-brand\",\n pink: \"bg-brand-secondary-default text-content-on-brand\",\n brandLight: \"bg-brand-primary-muted text-content-on-brand\",\n pinkLight: \"bg-brand-secondary-muted text-content-on-brand\",\n },\n dotColor: {\n default: \"bg-content-on-brand\",\n dark: \"bg-content-primary-inverted\",\n success: \"bg-success-content\",\n warning: \"bg-warning-content\",\n error: \"bg-error-content\",\n special: \"bg-special-default\",\n info: \"bg-info-content\",\n online: \"bg-brand-primary-default\",\n brand: \"bg-content-on-brand\",\n pink: \"bg-content-on-brand\",\n brandLight: \"bg-content-on-brand\",\n pinkLight: \"bg-content-on-brand\",\n },\n} as const;\n\n/** Visual style variant of the badge. */\nexport type BadgeVariant =\n | \"default\"\n | \"dark\"\n | \"success\"\n | \"warning\"\n | \"error\"\n | \"special\"\n | \"info\"\n | \"online\"\n | \"brand\"\n | \"pink\"\n | \"brandLight\"\n | \"pinkLight\";\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Visual style variant of the badge. @default \"default\" */\n variant?: BadgeVariant;\n /** Whether to show a coloured status dot at the leading edge. @default true */\n leftDot?: boolean;\n /** Icon element displayed before the label. */\n leftIcon?: React.ReactNode;\n /** Icon element displayed after the label. */\n rightIcon?: React.ReactNode;\n /** Merge props onto a child element instead of rendering a `<span>`. @default false */\n asChild?: boolean;\n}\n\n/**\n * A small inline label for status, category, or metadata information.\n *\n * @example\n * ```tsx\n * <Badge variant=\"success\">Active</Badge>\n * ```\n */\nexport const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(\n (\n {\n className,\n variant = \"default\",\n leftDot = true,\n leftIcon,\n rightIcon,\n asChild = false,\n onClick,\n children,\n ...props\n },\n ref,\n ) => {\n const Comp = asChild ? Slot : \"span\";\n\n return (\n <Comp\n ref={ref}\n data-testid=\"badge\"\n className={cn(\n // Base styles\n \"typography-semibold-body-sm inline-flex h-5 min-w-0 items-center gap-2 rounded-full px-2\",\n // Variant styles\n badgeVariants.variant[variant],\n // Interactive\n onClick && \"cursor-pointer\",\n // Manual CSS overrides\n className,\n )}\n onClick={onClick}\n {...props}\n >\n {leftIcon && (\n <span className=\"flex size-3\" aria-hidden=\"true\">\n {leftIcon}\n </span>\n )}\n {leftDot && (\n <span\n className={cn(\"size-1 shrink-0 rounded-full\", badgeVariants.dotColor[variant])}\n aria-hidden=\"true\"\n />\n )}\n {asChild ? (\n <Slottable>{children}</Slottable>\n ) : (\n <span className=\"min-w-0 truncate\">{children}</span>\n )}\n {rightIcon && (\n <span className=\"flex size-3\" aria-hidden=\"true\">\n {rightIcon}\n </span>\n )}\n </Comp>\n );\n },\n);\n\nBadge.displayName = \"Badge\";\n"],"names":[],"mappings":";;;;;AAIA,MAAM,gBAAgB;AAAA,EACpB,SAAS;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,EAAA;AAAA,EAEb,UAAU;AAAA,IACR,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,EAAA;AAEf;AAsCO,MAAM,QAAQ,MAAM;AAAA,EACzB,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,OAAO,UAAU,OAAO;AAE9B,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAY;AAAA,QACZ,WAAW;AAAA;AAAA,UAET;AAAA;AAAA,UAEA,cAAc,QAAQ,OAAO;AAAA;AAAA,UAE7B,WAAW;AAAA;AAAA,UAEX;AAAA,QAAA;AAAA,QAEF;AAAA,QACC,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,gCACE,QAAA,EAAK,WAAU,eAAc,eAAY,QACvC,UAAA,UACH;AAAA,UAED,WACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW,GAAG,gCAAgC,cAAc,SAAS,OAAO,CAAC;AAAA,cAC7E,eAAY;AAAA,YAAA;AAAA,UAAA;AAAA,UAGf,8BACE,WAAA,EAAW,SAAA,CAAS,IAErB,oBAAC,QAAA,EAAK,WAAU,oBAAoB,SAAA,CAAS;AAAA,UAE9C,aACC,oBAAC,QAAA,EAAK,WAAU,eAAc,eAAY,QACvC,UAAA,UAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,MAAM,cAAc;"}
@@ -0,0 +1,54 @@
1
+ "use client";
2
+ import { jsxs, jsx } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "../../utils/cn.mjs";
5
+ import { Badge } from "../Badge/Badge.mjs";
6
+ import { Button } from "../Button/Button.mjs";
7
+ import { ArrowRightIcon } from "../Icons/ArrowRightIcon.mjs";
8
+ const VARIANT_GRADIENTS = {
9
+ primary: "from-[var(--primitives-color-green-50)] to-[var(--primitives-color-purple-50)]",
10
+ secondary: "from-[var(--primitives-color-purple-50)] to-[var(--primitives-color-pink-50)]",
11
+ tertiary: "from-[var(--primitives-color-pink-50)] to-[var(--primitives-color-info-50)]"
12
+ };
13
+ const LIGHT_MODE_OVERRIDES = {
14
+ "--color-content-primary": "#151515ff",
15
+ "--color-content-secondary": "#404040ff",
16
+ "--color-neutral-alphas-100": "#1515150a"
17
+ };
18
+ const Banner = React.forwardRef(
19
+ ({ className, variant = "primary", badgeLabel, heading, description, cta, style, ...props }, ref) => {
20
+ return /* @__PURE__ */ jsxs(
21
+ "div",
22
+ {
23
+ ref,
24
+ className: cn(
25
+ "flex flex-col items-start gap-2 overflow-hidden rounded-2xl bg-gradient-to-br p-3 text-content-primary",
26
+ VARIANT_GRADIENTS[variant],
27
+ className
28
+ ),
29
+ style: { ...LIGHT_MODE_OVERRIDES, ...style },
30
+ ...props,
31
+ children: [
32
+ badgeLabel && /* @__PURE__ */ jsx(Badge, { children: badgeLabel }),
33
+ heading && /* @__PURE__ */ jsx("h3", { className: "typography-semibold-body-md", children: heading }),
34
+ description && /* @__PURE__ */ jsx("p", { className: "typography-regular-body-sm", children: description }),
35
+ cta && /* @__PURE__ */ jsx(
36
+ Button,
37
+ {
38
+ variant: "text",
39
+ onClick: cta.onClick,
40
+ size: "24",
41
+ rightIcon: cta.icon ?? /* @__PURE__ */ jsx(ArrowRightIcon, {}),
42
+ children: cta.label
43
+ }
44
+ )
45
+ ]
46
+ }
47
+ );
48
+ }
49
+ );
50
+ Banner.displayName = "Banner";
51
+ export {
52
+ Banner
53
+ };
54
+ //# sourceMappingURL=Banner.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Banner.mjs","sources":["../../../src/components/Banner/Banner.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Badge } from \"../Badge/Badge\";\nimport { Button } from \"../Button/Button\";\nimport { ArrowRightIcon } from \"../Icons/ArrowRightIcon\";\n\n/** Gradient variant of the banner. */\nexport type BannerVariant = \"primary\" | \"secondary\" | \"tertiary\";\n\nconst VARIANT_GRADIENTS: Record<BannerVariant, string> = {\n primary: \"from-[var(--primitives-color-green-50)] to-[var(--primitives-color-purple-50)]\",\n secondary: \"from-[var(--primitives-color-purple-50)] to-[var(--primitives-color-pink-50)]\",\n tertiary: \"from-[var(--primitives-color-pink-50)] to-[var(--primitives-color-info-50)]\",\n};\n\nexport interface BannerProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Gradient variant controlling the background colours. @default \"primary\" */\n variant?: BannerVariant;\n /** Text rendered inside a `Badge` at the top of the banner. */\n badgeLabel?: string;\n /** Primary heading displayed below the badge. Rendered as an `<h3>`. */\n heading?: React.ReactNode;\n /** Supporting copy displayed below the heading. */\n description?: React.ReactNode;\n /**\n * Call-to-action button config. Renders a text-style `Button` with an arrow icon.\n * Pass `icon` to override the default `ArrowRightIcon`.\n */\n cta?: { label: string; onClick: () => void; icon?: React.ReactNode };\n}\n\n/**\n * Force light-mode semantic tokens on the Banner since its gradient\n * backgrounds are always light regardless of the current colour scheme.\n */\nconst LIGHT_MODE_OVERRIDES: React.CSSProperties = {\n \"--color-content-primary\": \"#151515ff\",\n \"--color-content-secondary\": \"#404040ff\",\n \"--color-neutral-alphas-100\": \"#1515150a\",\n} as React.CSSProperties;\n\n/**\n * A promotional banner card with gradient backgrounds, optional badge,\n * heading, description, and call-to-action button.\n *\n * @example\n * ```tsx\n * <Banner\n * variant=\"primary\"\n * badgeLabel=\"New\"\n * heading=\"Boost your earnings\"\n * description=\"Try our latest feature to grow faster.\"\n * cta={{ label: \"Learn more\", onClick: handleClick }}\n * />\n * ```\n */\nexport const Banner = React.forwardRef<HTMLDivElement, BannerProps>(\n (\n { className, variant = \"primary\", badgeLabel, heading, description, cta, style, ...props },\n ref,\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\n \"flex flex-col items-start gap-2 overflow-hidden rounded-2xl bg-gradient-to-br p-3 text-content-primary\",\n VARIANT_GRADIENTS[variant],\n className,\n )}\n style={{ ...LIGHT_MODE_OVERRIDES, ...style }}\n {...props}\n >\n {badgeLabel && <Badge>{badgeLabel}</Badge>}\n {heading && <h3 className=\"typography-semibold-body-md\">{heading}</h3>}\n {description && <p className=\"typography-regular-body-sm\">{description}</p>}\n {cta && (\n <Button\n variant=\"text\"\n onClick={cta.onClick}\n size=\"24\"\n rightIcon={cta.icon ?? <ArrowRightIcon />}\n >\n {cta.label}\n </Button>\n )}\n </div>\n );\n },\n);\n\nBanner.displayName = \"Banner\";\n"],"names":[],"mappings":";;;;;;;AASA,MAAM,oBAAmD;AAAA,EACvD,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU;AACZ;AAsBA,MAAM,uBAA4C;AAAA,EAChD,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,8BAA8B;AAChC;AAiBO,MAAM,SAAS,MAAM;AAAA,EAC1B,CACE,EAAE,WAAW,UAAU,WAAW,YAAY,SAAS,aAAa,KAAK,OAAO,GAAG,MAAA,GACnF,QACG;AACH,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA,kBAAkB,OAAO;AAAA,UACzB;AAAA,QAAA;AAAA,QAEF,OAAO,EAAE,GAAG,sBAAsB,GAAG,MAAA;AAAA,QACpC,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,cAAc,oBAAC,SAAO,UAAA,WAAA,CAAW;AAAA,UACjC,WAAW,oBAAC,MAAA,EAAG,WAAU,+BAA+B,UAAA,SAAQ;AAAA,UAChE,eAAe,oBAAC,KAAA,EAAE,WAAU,8BAA8B,UAAA,aAAY;AAAA,UACtE,OACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,SAAS,IAAI;AAAA,cACb,MAAK;AAAA,cACL,WAAW,IAAI,QAAQ,oBAAC,gBAAA,CAAA,CAAe;AAAA,cAEtC,UAAA,IAAI;AAAA,YAAA;AAAA,UAAA;AAAA,QACP;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,OAAO,cAAc;"}
@@ -19,7 +19,7 @@ const BottomNavigation = React.forwardRef(
19
19
  className: cn(
20
20
  "fixed inset-x-0 bottom-0",
21
21
  "flex h-[calc(env(safe-area-inset-bottom,0px)+68px)] items-center justify-around",
22
- "border-neutral-200 border-t bg-surface-page",
22
+ "border-neutral-alphas-200 border-t bg-bg-primary",
23
23
  "pb-[env(safe-area-inset-bottom,0px)]",
24
24
  hideOnDesktop && "md:hidden",
25
25
  className
@@ -1 +1 @@
1
- {"version":3,"file":"BottomNavigation.mjs","sources":["../../../src/components/BottomNavigation/BottomNavigation.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface BottomNavigationProps extends React.HTMLAttributes<HTMLElement> {\n /** The currently selected action value. */\n value?: string;\n /** Called when the selected action changes. */\n onValueChange?: (value: string) => void;\n /** When `true`, the navigation bar is hidden on viewports wider than `md` (768 px). @default false */\n hideOnDesktop?: boolean;\n}\n\ninterface BottomNavigationContextValue {\n value?: string;\n onValueChange?: (value: string) => void;\n}\n\nconst BottomNavigationContext = React.createContext<BottomNavigationContextValue>({});\n\nexport function useBottomNavigationContext(): BottomNavigationContextValue {\n return React.useContext(BottomNavigationContext);\n}\n\nexport const BottomNavigation = React.forwardRef<HTMLElement, BottomNavigationProps>(\n ({ className, children, value, onValueChange, hideOnDesktop = false, ...props }, ref) => {\n const contextValue = React.useMemo<BottomNavigationContextValue>(\n () => ({ value, onValueChange }),\n [value, onValueChange],\n );\n\n return (\n <BottomNavigationContext.Provider value={contextValue}>\n <nav\n ref={ref}\n className={cn(\n \"fixed inset-x-0 bottom-0\",\n \"flex h-[calc(env(safe-area-inset-bottom,0px)+68px)] items-center justify-around\",\n \"border-neutral-200 border-t bg-surface-page\",\n \"pb-[env(safe-area-inset-bottom,0px)]\",\n hideOnDesktop && \"md:hidden\",\n className,\n )}\n style={{ zIndex: \"var(--fanvue-ui-portal-z-index, 50)\", ...props.style }}\n {...props}\n >\n {children}\n </nav>\n </BottomNavigationContext.Provider>\n );\n },\n);\n\nBottomNavigation.displayName = \"BottomNavigation\";\n"],"names":[],"mappings":";;;;AAiBA,MAAM,0BAA0B,MAAM,cAA4C,EAAE;AAE7E,SAAS,6BAA2D;AACzE,SAAO,MAAM,WAAW,uBAAuB;AACjD;AAEO,MAAM,mBAAmB,MAAM;AAAA,EACpC,CAAC,EAAE,WAAW,UAAU,OAAO,eAAe,gBAAgB,OAAO,GAAG,MAAA,GAAS,QAAQ;AACvF,UAAM,eAAe,MAAM;AAAA,MACzB,OAAO,EAAE,OAAO;MAChB,CAAC,OAAO,aAAa;AAAA,IAAA;AAGvB,WACE,oBAAC,wBAAwB,UAAxB,EAAiC,OAAO,cACvC,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,QAAA;AAAA,QAEF,OAAO,EAAE,QAAQ,uCAAuC,GAAG,MAAM,MAAA;AAAA,QAChE,GAAG;AAAA,QAEH;AAAA,MAAA;AAAA,IAAA,GAEL;AAAA,EAEJ;AACF;AAEA,iBAAiB,cAAc;"}
1
+ {"version":3,"file":"BottomNavigation.mjs","sources":["../../../src/components/BottomNavigation/BottomNavigation.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport interface BottomNavigationProps extends React.HTMLAttributes<HTMLElement> {\n /** The currently selected action value. */\n value?: string;\n /** Called when the selected action changes. */\n onValueChange?: (value: string) => void;\n /** When `true`, the navigation bar is hidden on viewports wider than `md` (768 px). @default false */\n hideOnDesktop?: boolean;\n}\n\ninterface BottomNavigationContextValue {\n value?: string;\n onValueChange?: (value: string) => void;\n}\n\nconst BottomNavigationContext = React.createContext<BottomNavigationContextValue>({});\n\nexport function useBottomNavigationContext(): BottomNavigationContextValue {\n return React.useContext(BottomNavigationContext);\n}\n\nexport const BottomNavigation = React.forwardRef<HTMLElement, BottomNavigationProps>(\n ({ className, children, value, onValueChange, hideOnDesktop = false, ...props }, ref) => {\n const contextValue = React.useMemo<BottomNavigationContextValue>(\n () => ({ value, onValueChange }),\n [value, onValueChange],\n );\n\n return (\n <BottomNavigationContext.Provider value={contextValue}>\n <nav\n ref={ref}\n className={cn(\n \"fixed inset-x-0 bottom-0\",\n \"flex h-[calc(env(safe-area-inset-bottom,0px)+68px)] items-center justify-around\",\n \"border-neutral-alphas-200 border-t bg-bg-primary\",\n \"pb-[env(safe-area-inset-bottom,0px)]\",\n hideOnDesktop && \"md:hidden\",\n className,\n )}\n style={{ zIndex: \"var(--fanvue-ui-portal-z-index, 50)\", ...props.style }}\n {...props}\n >\n {children}\n </nav>\n </BottomNavigationContext.Provider>\n );\n },\n);\n\nBottomNavigation.displayName = \"BottomNavigation\";\n"],"names":[],"mappings":";;;;AAiBA,MAAM,0BAA0B,MAAM,cAA4C,EAAE;AAE7E,SAAS,6BAA2D;AACzE,SAAO,MAAM,WAAW,uBAAuB;AACjD;AAEO,MAAM,mBAAmB,MAAM;AAAA,EACpC,CAAC,EAAE,WAAW,UAAU,OAAO,eAAe,gBAAgB,OAAO,GAAG,MAAA,GAAS,QAAQ;AACvF,UAAM,eAAe,MAAM;AAAA,MACzB,OAAO,EAAE,OAAO;MAChB,CAAC,OAAO,aAAa;AAAA,IAAA;AAGvB,WACE,oBAAC,wBAAwB,UAAxB,EAAiC,OAAO,cACvC,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,QAAA;AAAA,QAEF,OAAO,EAAE,QAAQ,uCAAuC,GAAG,MAAM,MAAA;AAAA,QAChE,GAAG;AAAA,QAEH;AAAA,MAAA;AAAA,IAAA,GAEL;AAAA,EAEJ;AACF;AAEA,iBAAiB,cAAc;"}
@@ -22,9 +22,9 @@ const BottomNavigationAction = React.forwardRef(({ className, value, icon, label
22
22
  "data-state": isActive ? "active" : "inactive",
23
23
  className: cn(
24
24
  "relative flex min-w-0 flex-1 cursor-pointer flex-col items-center justify-center gap-0.5 overflow-hidden px-2 py-2",
25
- "text-foreground-default",
25
+ "text-content-primary",
26
26
  "motion-safe:transition-colors motion-safe:duration-150 motion-safe:ease-in-out",
27
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-page",
27
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-interaction-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary",
28
28
  className
29
29
  ),
30
30
  onClick: handleClick,
@@ -1 +1 @@
1
- {"version":3,"file":"BottomNavigationAction.mjs","sources":["../../../src/components/BottomNavigation/BottomNavigationAction.tsx"],"sourcesContent":["import { Slot, Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useBottomNavigationContext } from \"./BottomNavigation\";\n\nexport interface BottomNavigationActionProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"value\"> {\n /** Unique value that identifies this action. */\n value: string;\n /** Icon element displayed in the action. */\n icon: React.ReactElement;\n /** Accessible label applied as `aria-label`. */\n label?: string;\n /** Optional badge element (e.g. {@link Count}) rendered at the top-end corner of the icon. */\n badge?: React.ReactNode;\n /** Merge props onto a child element instead of rendering a `<button>`. @default false */\n asChild?: boolean;\n}\n\nexport const BottomNavigationAction = React.forwardRef<\n HTMLButtonElement,\n BottomNavigationActionProps\n>(({ className, value, icon, label, badge, onClick, asChild = false, children, ...props }, ref) => {\n const { value: selectedValue, onValueChange } = useBottomNavigationContext();\n\n const isActive = selectedValue === value;\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n onValueChange?.(value);\n onClick?.(e);\n };\n\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n ref={ref}\n {...(!asChild && { type: \"button\" as const })}\n aria-current={isActive ? \"page\" : undefined}\n aria-label={label}\n data-state={isActive ? \"active\" : \"inactive\"}\n className={cn(\n \"relative flex min-w-0 flex-1 cursor-pointer flex-col items-center justify-center gap-0.5 overflow-hidden px-2 py-2\",\n \"text-foreground-default\",\n \"motion-safe:transition-colors motion-safe:duration-150 motion-safe:ease-in-out\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-page\",\n className,\n )}\n onClick={handleClick}\n {...props}\n >\n {asChild && <Slottable>{children}</Slottable>}\n <span className=\"relative inline-flex\">\n <span className=\"flex items-center justify-center [&>svg]:size-7\" aria-hidden=\"true\">\n {icon}\n </span>\n {badge && <span className=\"absolute -end-1 -top-2.5\">{badge}</span>}\n </span>\n </Comp>\n );\n});\n\nBottomNavigationAction.displayName = \"BottomNavigationAction\";\n"],"names":[],"mappings":";;;;;;AAmBO,MAAM,yBAAyB,MAAM,WAG1C,CAAC,EAAE,WAAW,OAAO,MAAM,OAAO,OAAO,SAAS,UAAU,OAAO,UAAU,GAAG,MAAA,GAAS,QAAQ;AACjG,QAAM,EAAE,OAAO,eAAe,cAAA,IAAkB,2BAAA;AAEhD,QAAM,WAAW,kBAAkB;AAEnC,QAAM,cAAc,CAAC,MAA2C;AAC9D,oBAAgB,KAAK;AACrB,cAAU,CAAC;AAAA,EACb;AAEA,QAAM,OAAO,UAAU,OAAO;AAE9B,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACC,GAAI,CAAC,WAAW,EAAE,MAAM,SAAA;AAAA,MACzB,gBAAc,WAAW,SAAS;AAAA,MAClC,cAAY;AAAA,MACZ,cAAY,WAAW,WAAW;AAAA,MAClC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAEF,SAAS;AAAA,MACR,GAAG;AAAA,MAEH,UAAA;AAAA,QAAA,WAAW,oBAAC,aAAW,SAAA,CAAS;AAAA,QACjC,qBAAC,QAAA,EAAK,WAAU,wBACd,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAK,WAAU,mDAAkD,eAAY,QAC3E,UAAA,MACH;AAAA,UACC,SAAS,oBAAC,QAAA,EAAK,WAAU,4BAA4B,UAAA,MAAA,CAAM;AAAA,QAAA,EAAA,CAC9D;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN,CAAC;AAED,uBAAuB,cAAc;"}
1
+ {"version":3,"file":"BottomNavigationAction.mjs","sources":["../../../src/components/BottomNavigation/BottomNavigationAction.tsx"],"sourcesContent":["import { Slot, Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useBottomNavigationContext } from \"./BottomNavigation\";\n\nexport interface BottomNavigationActionProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"value\"> {\n /** Unique value that identifies this action. */\n value: string;\n /** Icon element displayed in the action. */\n icon: React.ReactElement;\n /** Accessible label applied as `aria-label`. */\n label?: string;\n /** Optional badge element (e.g. {@link Count}) rendered at the top-end corner of the icon. */\n badge?: React.ReactNode;\n /** Merge props onto a child element instead of rendering a `<button>`. @default false */\n asChild?: boolean;\n}\n\nexport const BottomNavigationAction = React.forwardRef<\n HTMLButtonElement,\n BottomNavigationActionProps\n>(({ className, value, icon, label, badge, onClick, asChild = false, children, ...props }, ref) => {\n const { value: selectedValue, onValueChange } = useBottomNavigationContext();\n\n const isActive = selectedValue === value;\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n onValueChange?.(value);\n onClick?.(e);\n };\n\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n ref={ref}\n {...(!asChild && { type: \"button\" as const })}\n aria-current={isActive ? \"page\" : undefined}\n aria-label={label}\n data-state={isActive ? \"active\" : \"inactive\"}\n className={cn(\n \"relative flex min-w-0 flex-1 cursor-pointer flex-col items-center justify-center gap-0.5 overflow-hidden px-2 py-2\",\n \"text-content-primary\",\n \"motion-safe:transition-colors motion-safe:duration-150 motion-safe:ease-in-out\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-interaction-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary\",\n className,\n )}\n onClick={handleClick}\n {...props}\n >\n {asChild && <Slottable>{children}</Slottable>}\n <span className=\"relative inline-flex\">\n <span className=\"flex items-center justify-center [&>svg]:size-7\" aria-hidden=\"true\">\n {icon}\n </span>\n {badge && <span className=\"absolute -end-1 -top-2.5\">{badge}</span>}\n </span>\n </Comp>\n );\n});\n\nBottomNavigationAction.displayName = \"BottomNavigationAction\";\n"],"names":[],"mappings":";;;;;;AAmBO,MAAM,yBAAyB,MAAM,WAG1C,CAAC,EAAE,WAAW,OAAO,MAAM,OAAO,OAAO,SAAS,UAAU,OAAO,UAAU,GAAG,MAAA,GAAS,QAAQ;AACjG,QAAM,EAAE,OAAO,eAAe,cAAA,IAAkB,2BAAA;AAEhD,QAAM,WAAW,kBAAkB;AAEnC,QAAM,cAAc,CAAC,MAA2C;AAC9D,oBAAgB,KAAK;AACrB,cAAU,CAAC;AAAA,EACb;AAEA,QAAM,OAAO,UAAU,OAAO;AAE9B,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACC,GAAI,CAAC,WAAW,EAAE,MAAM,SAAA;AAAA,MACzB,gBAAc,WAAW,SAAS;AAAA,MAClC,cAAY;AAAA,MACZ,cAAY,WAAW,WAAW;AAAA,MAClC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAEF,SAAS;AAAA,MACR,GAAG;AAAA,MAEH,UAAA;AAAA,QAAA,WAAW,oBAAC,aAAW,SAAA,CAAS;AAAA,QACjC,qBAAC,QAAA,EAAK,WAAU,wBACd,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAK,WAAU,mDAAkD,eAAY,QAC3E,UAAA,MACH;AAAA,UACC,SAAS,oBAAC,QAAA,EAAK,WAAU,4BAA4B,UAAA,MAAA,CAAM;AAAA,QAAA,EAAA,CAC9D;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN,CAAC;AAED,uBAAuB,cAAc;"}
@@ -34,7 +34,7 @@ const BreadcrumbLink = React.forwardRef(
34
34
  {
35
35
  ref,
36
36
  className: cn(
37
- "typography-regular-body-sm rounded-sm text-foreground-secondary underline-offset-2 transition-colors hover:text-foreground-default hover:underline focus-visible:shadow-focus-ring focus-visible:outline-none",
37
+ "typography-regular-body-sm rounded-[2px] text-content-secondary underline-offset-2 transition-colors hover:text-content-primary hover:underline focus-visible:shadow-focus-ring focus-visible:outline-none",
38
38
  className
39
39
  ),
40
40
  ...props
@@ -49,7 +49,7 @@ const BreadcrumbPage = React.forwardRef(
49
49
  {
50
50
  ref,
51
51
  "aria-current": "page",
52
- className: cn("typography-semibold-body-sm text-foreground-default", className),
52
+ className: cn("typography-semibold-body-sm text-content-primary", className),
53
53
  ...props
54
54
  }
55
55
  )
@@ -61,7 +61,7 @@ const BreadcrumbSeparator = React.forwardRef(
61
61
  {
62
62
  ref,
63
63
  "aria-hidden": "true",
64
- className: cn("flex items-center text-foreground-secondary", className),
64
+ className: cn("flex items-center text-content-secondary", className),
65
65
  ...props,
66
66
  children: children ?? /* @__PURE__ */ jsx(ChevronRightIcon, { className: "size-4" })
67
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Breadcrumb.mjs","sources":["../../../src/components/Breadcrumb/Breadcrumb.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { ChevronRightIcon } from \"../Icons/ChevronRightIcon\";\n\nexport interface BreadcrumbProps extends React.ComponentPropsWithoutRef<\"nav\"> {\n /** Accessible label for the breadcrumb navigation landmark. @default \"breadcrumb\" */\n \"aria-label\"?: string;\n}\n\n/**\n * Root navigation wrapper for the breadcrumb trail.\n *\n * @example\n * ```tsx\n * <Breadcrumb>\n * <BreadcrumbList>\n * <BreadcrumbItem><BreadcrumbLink href=\"/\">Home</BreadcrumbLink></BreadcrumbItem>\n * <BreadcrumbSeparator />\n * <BreadcrumbItem><BreadcrumbPage>Current Page</BreadcrumbPage></BreadcrumbItem>\n * </BreadcrumbList>\n * </Breadcrumb>\n * ```\n */\nexport const Breadcrumb = React.forwardRef<HTMLElement, BreadcrumbProps>(\n ({ \"aria-label\": ariaLabel = \"breadcrumb\", ...props }, ref) => (\n <nav ref={ref} aria-label={ariaLabel} {...props} />\n ),\n);\n\nBreadcrumb.displayName = \"Breadcrumb\";\n\nexport interface BreadcrumbListProps extends React.ComponentPropsWithoutRef<\"ol\"> {\n /** Custom separator element rendered between items. @default ChevronRightIcon */\n separator?: React.ReactNode;\n}\n\n/**\n * Ordered list container for breadcrumb items. Automatically injects a\n * separator between each child item.\n */\nexport const BreadcrumbList = React.forwardRef<HTMLOListElement, BreadcrumbListProps>(\n ({ className, children, separator, ...props }, ref) => {\n const items = React.Children.toArray(children);\n const withSeparators = items.flatMap((child, index) => {\n const childKey = React.isValidElement(child) ? child.key : index;\n return index === 0\n ? [child]\n : [\n <BreadcrumbSeparator key={`sep-before-${childKey}`}>{separator}</BreadcrumbSeparator>,\n child,\n ];\n });\n\n return (\n <ol ref={ref} className={cn(\"flex flex-wrap items-center gap-2\", className)} {...props}>\n {withSeparators}\n </ol>\n );\n },\n);\n\nBreadcrumbList.displayName = \"BreadcrumbList\";\n\nexport interface BreadcrumbItemProps extends React.ComponentPropsWithoutRef<\"li\"> {}\n\n/**\n * List item wrapper for a single breadcrumb entry or separator.\n */\nexport const BreadcrumbItem = React.forwardRef<HTMLLIElement, BreadcrumbItemProps>(\n ({ className, ...props }, ref) => (\n <li ref={ref} className={cn(\"inline-flex items-center gap-2\", className)} {...props} />\n ),\n);\n\nBreadcrumbItem.displayName = \"BreadcrumbItem\";\n\nexport interface BreadcrumbLinkProps extends React.ComponentPropsWithoutRef<\"a\"> {\n /** Render the link as a child element (e.g. a router `Link`). @default false */\n asChild?: boolean;\n}\n\n/**\n * Anchor element for a non-current breadcrumb step. Supports `asChild` for\n * router-aware link components.\n */\nexport const BreadcrumbLink = React.forwardRef<HTMLAnchorElement, BreadcrumbLinkProps>(\n ({ asChild = false, className, ...props }, ref) => {\n const Comp = asChild ? Slot : \"a\";\n return (\n <Comp\n ref={ref}\n className={cn(\n \"typography-regular-body-sm rounded-sm text-foreground-secondary underline-offset-2 transition-colors hover:text-foreground-default hover:underline focus-visible:shadow-focus-ring focus-visible:outline-none\",\n className,\n )}\n {...props}\n />\n );\n },\n);\n\nBreadcrumbLink.displayName = \"BreadcrumbLink\";\n\nexport interface BreadcrumbPageProps extends React.ComponentPropsWithoutRef<\"span\"> {}\n\n/**\n * Non-interactive label representing the current page in the breadcrumb trail.\n */\nexport const BreadcrumbPage = React.forwardRef<HTMLSpanElement, BreadcrumbPageProps>(\n ({ className, ...props }, ref) => (\n <span\n ref={ref}\n aria-current=\"page\"\n className={cn(\"typography-semibold-body-sm text-foreground-default\", className)}\n {...props}\n />\n ),\n);\n\nBreadcrumbPage.displayName = \"BreadcrumbPage\";\n\nexport interface BreadcrumbSeparatorProps extends React.ComponentPropsWithoutRef<\"li\"> {}\n\n/**\n * Visual separator rendered between breadcrumb items.\n * Renders a right-pointing chevron icon and is hidden from assistive technology.\n */\nexport const BreadcrumbSeparator = React.forwardRef<HTMLLIElement, BreadcrumbSeparatorProps>(\n ({ className, children, ...props }, ref) => (\n <li\n ref={ref}\n aria-hidden=\"true\"\n className={cn(\"flex items-center text-foreground-secondary\", className)}\n {...props}\n >\n {children ?? <ChevronRightIcon className=\"size-4\" />}\n </li>\n ),\n);\n\nBreadcrumbSeparator.displayName = \"BreadcrumbSeparator\";\n"],"names":[],"mappings":";;;;;;AAwBO,MAAM,aAAa,MAAM;AAAA,EAC9B,CAAC,EAAE,cAAc,YAAY,cAAc,GAAG,MAAA,GAAS,4BACpD,OAAA,EAAI,KAAU,cAAY,WAAY,GAAG,MAAA,CAAO;AAErD;AAEA,WAAW,cAAc;AAWlB,MAAM,iBAAiB,MAAM;AAAA,EAClC,CAAC,EAAE,WAAW,UAAU,WAAW,GAAG,MAAA,GAAS,QAAQ;AACrD,UAAM,QAAQ,MAAM,SAAS,QAAQ,QAAQ;AAC7C,UAAM,iBAAiB,MAAM,QAAQ,CAAC,OAAO,UAAU;AACrD,YAAM,WAAW,MAAM,eAAe,KAAK,IAAI,MAAM,MAAM;AAC3D,aAAO,UAAU,IACb,CAAC,KAAK,IACN;AAAA,QACE,oBAAC,qBAAA,EAAoD,UAAA,UAAA,GAA3B,cAAc,QAAQ,EAAe;AAAA,QAC/D;AAAA,MAAA;AAAA,IAER,CAAC;AAED,WACE,oBAAC,MAAA,EAAG,KAAU,WAAW,GAAG,qCAAqC,SAAS,GAAI,GAAG,OAC9E,UAAA,eAAA,CACH;AAAA,EAEJ;AACF;AAEA,eAAe,cAAc;AAOtB,MAAM,iBAAiB,MAAM;AAAA,EAClC,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QACxB,oBAAC,MAAA,EAAG,KAAU,WAAW,GAAG,kCAAkC,SAAS,GAAI,GAAG,MAAA,CAAO;AAEzF;AAEA,eAAe,cAAc;AAWtB,MAAM,iBAAiB,MAAM;AAAA,EAClC,CAAC,EAAE,UAAU,OAAO,WAAW,GAAG,MAAA,GAAS,QAAQ;AACjD,UAAM,OAAO,UAAU,OAAO;AAC9B,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,MAAA;AAAA,IAAA;AAAA,EAGV;AACF;AAEA,eAAe,cAAc;AAOtB,MAAM,iBAAiB,MAAM;AAAA,EAClC,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QACxB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,gBAAa;AAAA,MACb,WAAW,GAAG,uDAAuD,SAAS;AAAA,MAC7E,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,eAAe,cAAc;AAQtB,MAAM,sBAAsB,MAAM;AAAA,EACvC,CAAC,EAAE,WAAW,UAAU,GAAG,MAAA,GAAS,QAClC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,eAAY;AAAA,MACZ,WAAW,GAAG,+CAA+C,SAAS;AAAA,MACrE,GAAG;AAAA,MAEH,UAAA,YAAY,oBAAC,kBAAA,EAAiB,WAAU,SAAA,CAAS;AAAA,IAAA;AAAA,EAAA;AAGxD;AAEA,oBAAoB,cAAc;"}
1
+ {"version":3,"file":"Breadcrumb.mjs","sources":["../../../src/components/Breadcrumb/Breadcrumb.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { ChevronRightIcon } from \"../Icons/ChevronRightIcon\";\n\nexport interface BreadcrumbProps extends React.ComponentPropsWithoutRef<\"nav\"> {\n /** Accessible label for the breadcrumb navigation landmark. @default \"breadcrumb\" */\n \"aria-label\"?: string;\n}\n\n/**\n * Root navigation wrapper for the breadcrumb trail.\n *\n * @example\n * ```tsx\n * <Breadcrumb>\n * <BreadcrumbList>\n * <BreadcrumbItem><BreadcrumbLink href=\"/\">Home</BreadcrumbLink></BreadcrumbItem>\n * <BreadcrumbSeparator />\n * <BreadcrumbItem><BreadcrumbPage>Current Page</BreadcrumbPage></BreadcrumbItem>\n * </BreadcrumbList>\n * </Breadcrumb>\n * ```\n */\nexport const Breadcrumb = React.forwardRef<HTMLElement, BreadcrumbProps>(\n ({ \"aria-label\": ariaLabel = \"breadcrumb\", ...props }, ref) => (\n <nav ref={ref} aria-label={ariaLabel} {...props} />\n ),\n);\n\nBreadcrumb.displayName = \"Breadcrumb\";\n\nexport interface BreadcrumbListProps extends React.ComponentPropsWithoutRef<\"ol\"> {\n /** Custom separator element rendered between items. @default ChevronRightIcon */\n separator?: React.ReactNode;\n}\n\n/**\n * Ordered list container for breadcrumb items. Automatically injects a\n * separator between each child item.\n */\nexport const BreadcrumbList = React.forwardRef<HTMLOListElement, BreadcrumbListProps>(\n ({ className, children, separator, ...props }, ref) => {\n const items = React.Children.toArray(children);\n const withSeparators = items.flatMap((child, index) => {\n const childKey = React.isValidElement(child) ? child.key : index;\n return index === 0\n ? [child]\n : [\n <BreadcrumbSeparator key={`sep-before-${childKey}`}>{separator}</BreadcrumbSeparator>,\n child,\n ];\n });\n\n return (\n <ol ref={ref} className={cn(\"flex flex-wrap items-center gap-2\", className)} {...props}>\n {withSeparators}\n </ol>\n );\n },\n);\n\nBreadcrumbList.displayName = \"BreadcrumbList\";\n\nexport interface BreadcrumbItemProps extends React.ComponentPropsWithoutRef<\"li\"> {}\n\n/**\n * List item wrapper for a single breadcrumb entry or separator.\n */\nexport const BreadcrumbItem = React.forwardRef<HTMLLIElement, BreadcrumbItemProps>(\n ({ className, ...props }, ref) => (\n <li ref={ref} className={cn(\"inline-flex items-center gap-2\", className)} {...props} />\n ),\n);\n\nBreadcrumbItem.displayName = \"BreadcrumbItem\";\n\nexport interface BreadcrumbLinkProps extends React.ComponentPropsWithoutRef<\"a\"> {\n /** Render the link as a child element (e.g. a router `Link`). @default false */\n asChild?: boolean;\n}\n\n/**\n * Anchor element for a non-current breadcrumb step. Supports `asChild` for\n * router-aware link components.\n */\nexport const BreadcrumbLink = React.forwardRef<HTMLAnchorElement, BreadcrumbLinkProps>(\n ({ asChild = false, className, ...props }, ref) => {\n const Comp = asChild ? Slot : \"a\";\n return (\n <Comp\n ref={ref}\n className={cn(\n \"typography-regular-body-sm rounded-[2px] text-content-secondary underline-offset-2 transition-colors hover:text-content-primary hover:underline focus-visible:shadow-focus-ring focus-visible:outline-none\",\n className,\n )}\n {...props}\n />\n );\n },\n);\n\nBreadcrumbLink.displayName = \"BreadcrumbLink\";\n\nexport interface BreadcrumbPageProps extends React.ComponentPropsWithoutRef<\"span\"> {}\n\n/**\n * Non-interactive label representing the current page in the breadcrumb trail.\n */\nexport const BreadcrumbPage = React.forwardRef<HTMLSpanElement, BreadcrumbPageProps>(\n ({ className, ...props }, ref) => (\n <span\n ref={ref}\n aria-current=\"page\"\n className={cn(\"typography-semibold-body-sm text-content-primary\", className)}\n {...props}\n />\n ),\n);\n\nBreadcrumbPage.displayName = \"BreadcrumbPage\";\n\nexport interface BreadcrumbSeparatorProps extends React.ComponentPropsWithoutRef<\"li\"> {}\n\n/**\n * Visual separator rendered between breadcrumb items.\n * Renders a right-pointing chevron icon and is hidden from assistive technology.\n */\nexport const BreadcrumbSeparator = React.forwardRef<HTMLLIElement, BreadcrumbSeparatorProps>(\n ({ className, children, ...props }, ref) => (\n <li\n ref={ref}\n aria-hidden=\"true\"\n className={cn(\"flex items-center text-content-secondary\", className)}\n {...props}\n >\n {children ?? <ChevronRightIcon className=\"size-4\" />}\n </li>\n ),\n);\n\nBreadcrumbSeparator.displayName = \"BreadcrumbSeparator\";\n"],"names":[],"mappings":";;;;;;AAwBO,MAAM,aAAa,MAAM;AAAA,EAC9B,CAAC,EAAE,cAAc,YAAY,cAAc,GAAG,MAAA,GAAS,4BACpD,OAAA,EAAI,KAAU,cAAY,WAAY,GAAG,MAAA,CAAO;AAErD;AAEA,WAAW,cAAc;AAWlB,MAAM,iBAAiB,MAAM;AAAA,EAClC,CAAC,EAAE,WAAW,UAAU,WAAW,GAAG,MAAA,GAAS,QAAQ;AACrD,UAAM,QAAQ,MAAM,SAAS,QAAQ,QAAQ;AAC7C,UAAM,iBAAiB,MAAM,QAAQ,CAAC,OAAO,UAAU;AACrD,YAAM,WAAW,MAAM,eAAe,KAAK,IAAI,MAAM,MAAM;AAC3D,aAAO,UAAU,IACb,CAAC,KAAK,IACN;AAAA,QACE,oBAAC,qBAAA,EAAoD,UAAA,UAAA,GAA3B,cAAc,QAAQ,EAAe;AAAA,QAC/D;AAAA,MAAA;AAAA,IAER,CAAC;AAED,WACE,oBAAC,MAAA,EAAG,KAAU,WAAW,GAAG,qCAAqC,SAAS,GAAI,GAAG,OAC9E,UAAA,eAAA,CACH;AAAA,EAEJ;AACF;AAEA,eAAe,cAAc;AAOtB,MAAM,iBAAiB,MAAM;AAAA,EAClC,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QACxB,oBAAC,MAAA,EAAG,KAAU,WAAW,GAAG,kCAAkC,SAAS,GAAI,GAAG,MAAA,CAAO;AAEzF;AAEA,eAAe,cAAc;AAWtB,MAAM,iBAAiB,MAAM;AAAA,EAClC,CAAC,EAAE,UAAU,OAAO,WAAW,GAAG,MAAA,GAAS,QAAQ;AACjD,UAAM,OAAO,UAAU,OAAO;AAC9B,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,MAAA;AAAA,IAAA;AAAA,EAGV;AACF;AAEA,eAAe,cAAc;AAOtB,MAAM,iBAAiB,MAAM;AAAA,EAClC,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QACxB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,gBAAa;AAAA,MACb,WAAW,GAAG,oDAAoD,SAAS;AAAA,MAC1E,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,eAAe,cAAc;AAQtB,MAAM,sBAAsB,MAAM;AAAA,EACvC,CAAC,EAAE,WAAW,UAAU,GAAG,MAAA,GAAS,QAClC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,eAAY;AAAA,MACZ,WAAW,GAAG,4CAA4C,SAAS;AAAA,MAClE,GAAG;AAAA,MAEH,UAAA,YAAY,oBAAC,kBAAA,EAAiB,WAAU,SAAA,CAAS;AAAA,IAAA;AAAA,EAAA;AAGxD;AAEA,oBAAoB,cAAc;"}
@@ -23,15 +23,15 @@ const ICON_WRAPPER_CLASS = {
23
23
  "24": "[&>svg]:size-3.5"
24
24
  };
25
25
  const VARIANT_CLASSES = {
26
- primary: "bg-neutral-solid text-foreground-inverse hover:bg-brand-accent-muted hover:text-foreground-default active:bg-brand-accent-muted active:text-foreground-default",
27
- secondary: "border-foreground-default border border-1 border-foreground-default bg-transparent text-foreground-default hover:bg-brand-accent-muted active:bg-brand-accent-muted",
28
- tertiary: "bg-transparent text-foreground-default hover:bg-brand-accent-muted active:bg-brand-accent-muted",
29
- link: "bg-transparent text-foreground-default underline decoration-solid hover:bg-brand-accent-muted active:bg-brand-accent-muted",
30
- brand: "bg-brand-accent-default text-foreground-onaccent hover:bg-brand-accent-muted hover:text-foreground-default active:bg-brand-accent-muted active:text-foreground-default",
31
- destructive: "bg-error-default text-foreground-onaccentinverse hover:bg-brand-accent-muted hover:text-foreground-default active:bg-brand-accent-muted active:text-foreground-default",
32
- white: "bg-foreground-onaccentinverse text-foreground-onaccent hover:bg-brand-accent-muted hover:text-foreground-default active:bg-brand-accent-muted active:text-foreground-default",
33
- tertiaryDestructive: "bg-transparent text-error-default hover:bg-error-background active:bg-error-background",
34
- text: "bg-transparent text-foreground-default hover:underline active:underline"
26
+ primary: "bg-buttons-primary text-content-primary-inverted hover:bg-buttons-primary-hover hover:text-content-primary-inverted active:bg-buttons-primary-hover active:text-content-primary-inverted",
27
+ secondary: "border-content-primary border bg-transparent text-content-primary hover:bg-brand-primary-muted active:bg-brand-primary-muted",
28
+ tertiary: "bg-transparent text-content-primary hover:bg-brand-primary-muted active:bg-brand-primary-muted",
29
+ link: "bg-transparent text-content-primary underline decoration-solid hover:bg-brand-primary-muted active:bg-brand-primary-muted",
30
+ brand: "bg-buttons-brand text-content-on-brand hover:bg-buttons-brand-hover hover:text-content-on-brand active:bg-buttons-brand-hover active:text-content-on-brand",
31
+ destructive: "bg-error-content text-content-on-brand-inverted hover:bg-brand-primary-muted hover:text-content-primary active:bg-brand-primary-muted active:text-content-primary",
32
+ white: "bg-content-on-brand-inverted text-content-on-brand hover:bg-brand-primary-muted hover:text-content-primary active:bg-brand-primary-muted active:text-content-primary",
33
+ tertiaryDestructive: "bg-transparent text-error-content hover:bg-error-surface active:bg-error-surface",
34
+ text: "bg-transparent text-content-primary hover:underline active:underline"
35
35
  };
36
36
  function getTextContent(node) {
37
37
  if (typeof node === "string") return node;
@@ -84,7 +84,7 @@ function renderContent({
84
84
  ),
85
85
  React.Children.map(
86
86
  children,
87
- (child) => typeof child === "string" || typeof child === "number" ? /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: child }) : child
87
+ (child) => typeof child === "string" ? child.trim() ? /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: child }) : null : typeof child === "number" ? /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: child }) : child
88
88
  ),
89
89
  rightIcon && /* @__PURE__ */ jsx(
90
90
  "span",
@@ -1 +1 @@
1
- {"version":3,"file":"Button.mjs","sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { SpinnerIcon } from \"../Icons/SpinnerIcon\";\n\n/** Visual style variant of the button. */\nexport type ButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"tertiary\"\n | \"link\"\n | \"brand\"\n | \"destructive\"\n | \"white\"\n | \"tertiaryDestructive\"\n | \"text\";\n\n/** Button height in pixels. */\nexport type ButtonSize = \"48\" | \"40\" | \"32\" | \"24\";\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Visual style variant of the button. @default \"primary\" */\n variant?: ButtonVariant;\n /** Height of the button in pixels. @default \"40\" */\n size?: ButtonSize;\n /** Icon element displayed before the label. */\n leftIcon?: React.ReactNode;\n /** Icon element displayed after the label. */\n rightIcon?: React.ReactNode;\n /** When `true`, replaces the label with a spinner and disables interaction. @default false */\n loading?: boolean;\n /** Merge props onto a child element instead of rendering a `<button>`. @default false */\n asChild?: boolean;\n /** Old price shown with a strikethrough before the current price. */\n discount?: string;\n /** Current price shown inside the button after the label and icons. */\n price?: string;\n /** When `true`, the button will take the full width of its container. @default false */\n fullWidth?: boolean;\n}\n\nconst SIZE_CLASSES: Record<ButtonSize, string> = {\n \"48\": \"h-12 px-4 py-3 typography-semibold-body-lg\",\n \"40\": \"h-10 px-4 py-2 typography-semibold-body-lg\",\n \"32\": \"h-8 px-3 py-2 typography-semibold-body-md\",\n \"24\": \"h-6 px-2 py-1 typography-semibold-body-md\",\n};\n\nconst ICON_SIZE_CLASS: Record<ButtonSize, string> = {\n \"48\": \"size-5\",\n \"40\": \"size-5\",\n \"32\": \"size-4\",\n \"24\": \"size-3.5\",\n};\n\n/** Targets only direct SVG children so non-icon content (e.g. Pill) can size naturally. */\nconst ICON_WRAPPER_CLASS: Record<ButtonSize, string> = {\n \"48\": \"[&>svg]:size-5\",\n \"40\": \"[&>svg]:size-5\",\n \"32\": \"[&>svg]:size-4\",\n \"24\": \"[&>svg]:size-3.5\",\n};\n\nconst VARIANT_CLASSES: Record<ButtonVariant, string> = {\n primary:\n \"bg-neutral-solid text-foreground-inverse hover:bg-brand-accent-muted hover:text-foreground-default active:bg-brand-accent-muted active:text-foreground-default\",\n secondary:\n \"border-foreground-default border border-1 border-foreground-default bg-transparent text-foreground-default hover:bg-brand-accent-muted active:bg-brand-accent-muted\",\n tertiary:\n \"bg-transparent text-foreground-default hover:bg-brand-accent-muted active:bg-brand-accent-muted\",\n link: \"bg-transparent text-foreground-default underline decoration-solid hover:bg-brand-accent-muted active:bg-brand-accent-muted\",\n brand:\n \"bg-brand-accent-default text-foreground-onaccent hover:bg-brand-accent-muted hover:text-foreground-default active:bg-brand-accent-muted active:text-foreground-default\",\n destructive:\n \"bg-error-default text-foreground-onaccentinverse hover:bg-brand-accent-muted hover:text-foreground-default active:bg-brand-accent-muted active:text-foreground-default\",\n white:\n \"bg-foreground-onaccentinverse text-foreground-onaccent hover:bg-brand-accent-muted hover:text-foreground-default active:bg-brand-accent-muted active:text-foreground-default\",\n tertiaryDestructive:\n \"bg-transparent text-error-default hover:bg-error-background active:bg-error-background\",\n text: \"bg-transparent text-foreground-default hover:underline active:underline\",\n};\n\n/** Recursively extract text content from React nodes for accessible labels */\nfunction getTextContent(node: React.ReactNode): string | undefined {\n if (typeof node === \"string\") return node;\n if (typeof node === \"number\") return String(node);\n if (React.isValidElement(node)) {\n return getTextContent((node.props as { children?: React.ReactNode }).children);\n }\n if (Array.isArray(node)) {\n const text = node.map(getTextContent).filter(Boolean).join(\"\");\n return text || undefined;\n }\n return undefined;\n}\n\nconst LoadingSpinner = ({ size }: { size: ButtonSize }) => {\n return (\n <span className=\"animate-spin\" aria-hidden=\"true\">\n <SpinnerIcon className={ICON_SIZE_CLASS[size]}>\n <title>Loading</title>\n </SpinnerIcon>\n </span>\n );\n};\n\nfunction renderContent({\n loading,\n asChild,\n children,\n size,\n leftIcon,\n rightIcon,\n iconSizeClass,\n discount,\n price,\n}: {\n loading: boolean;\n asChild: boolean;\n children: React.ReactNode;\n size: ButtonSize;\n leftIcon: React.ReactNode;\n rightIcon: React.ReactNode;\n iconSizeClass: string;\n discount?: string;\n price?: string;\n fullWidth?: boolean;\n}) {\n if (loading) {\n // When asChild, clone the child element with spinner content instead of\n // wrapping in sr-only span (which would nest interactive elements)\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(\n children as React.ReactElement<{ children?: React.ReactNode }>,\n undefined,\n <LoadingSpinner size={size} />,\n );\n }\n return (\n <>\n <LoadingSpinner size={size} />\n <span className=\"sr-only\">{children}</span>\n </>\n );\n }\n\n if (asChild) return children;\n\n return (\n <>\n {leftIcon && (\n <span\n className={cn(\"flex shrink-0 items-center justify-center\", iconSizeClass)}\n aria-hidden=\"true\"\n >\n {leftIcon}\n </span>\n )}\n {React.Children.map(children, (child) =>\n typeof child === \"string\" || typeof child === \"number\" ? (\n <span className=\"min-w-0 truncate\">{child}</span>\n ) : (\n child\n ),\n )}\n {rightIcon && (\n <span\n className={cn(\"flex shrink-0 items-center justify-center\", iconSizeClass)}\n aria-hidden=\"true\"\n >\n {rightIcon}\n </span>\n )}\n {(price || discount) && (\n <div>\n {discount && (\n <span className=\"typography-regular-body-lg line-through\" aria-hidden=\"true\">\n {discount}\n </span>\n )}\n {price && (\n <span className=\"ml-2\" aria-hidden=\"true\">\n {price}\n </span>\n )}\n </div>\n )}\n </>\n );\n}\n\n/**\n * A versatile button component with multiple visual variants, sizes, icon\n * slots, loading state, and optional pricing display.\n *\n * @example\n * ```tsx\n * <Button variant=\"brand\" size=\"40\" leftIcon={<StarIcon />}>\n * Subscribe\n * </Button>\n * ```\n */\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n variant = \"primary\",\n size = \"40\",\n leftIcon,\n rightIcon,\n loading = false,\n asChild = false,\n disabled,\n children,\n discount,\n price,\n fullWidth = false,\n ...props\n },\n ref,\n ) => {\n const Comp = asChild ? Slot : \"button\";\n const isDisabled = disabled || loading;\n const iconSizeClass = ICON_WRAPPER_CLASS[size];\n\n const buttonSpecificProps = !asChild\n ? {\n type: \"button\" as const,\n \"data-testid\": \"button\",\n disabled: isDisabled,\n }\n : isDisabled\n ? { \"aria-disabled\": true }\n : {};\n\n // When asChild + loading, extract text from children for aria-label since we\n // can't wrap element children in an sr-only span (creates invalid nested markup)\n const loadingLabelProps = loading && asChild ? { \"aria-label\": getTextContent(children) } : {};\n\n const content = renderContent({\n loading,\n asChild,\n children,\n size,\n leftIcon,\n rightIcon,\n iconSizeClass,\n discount,\n price,\n });\n\n return (\n <Comp\n ref={ref}\n {...buttonSpecificProps}\n aria-busy={loading}\n {...loadingLabelProps}\n className={cn(\n // Base styles\n \"inline-flex min-w-0 cursor-pointer items-center gap-2 whitespace-nowrap rounded-full transition-colors\",\n // Focus ring\n \"focus-visible:shadow-focus-ring focus-visible:outline-none\",\n // Disabled state\n \"disabled:pointer-events-none disabled:opacity-50\",\n \"aria-disabled:pointer-events-none aria-disabled:opacity-50\",\n `${price ? \"justify-between\" : \"justify-center\"}`,\n fullWidth && \"w-full\",\n // Size styles\n SIZE_CLASSES[size],\n // Variant styles\n VARIANT_CLASSES[variant],\n // Manual CSS overrides\n className,\n )}\n {...props}\n >\n {content}\n </Comp>\n );\n },\n);\n\nButton.displayName = \"Button\";\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Button.mjs","sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { SpinnerIcon } from \"../Icons/SpinnerIcon\";\n\n/** Visual style variant of the button. */\nexport type ButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"tertiary\"\n | \"link\"\n | \"brand\"\n | \"destructive\"\n | \"white\"\n | \"tertiaryDestructive\"\n | \"text\";\n\n/** Button height in pixels. */\nexport type ButtonSize = \"48\" | \"40\" | \"32\" | \"24\";\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Visual style variant of the button. @default \"primary\" */\n variant?: ButtonVariant;\n /** Height of the button in pixels. @default \"40\" */\n size?: ButtonSize;\n /** Icon element displayed before the label. */\n leftIcon?: React.ReactNode;\n /** Icon element displayed after the label. */\n rightIcon?: React.ReactNode;\n /** When `true`, replaces the label with a spinner and disables interaction. @default false */\n loading?: boolean;\n /** Merge props onto a child element instead of rendering a `<button>`. @default false */\n asChild?: boolean;\n /** Old price shown with a strikethrough before the current price. */\n discount?: string;\n /** Current price shown inside the button after the label and icons. */\n price?: string;\n /** When `true`, the button will take the full width of its container. @default false */\n fullWidth?: boolean;\n}\n\nconst SIZE_CLASSES: Record<ButtonSize, string> = {\n \"48\": \"h-12 px-4 py-3 typography-semibold-body-lg\",\n \"40\": \"h-10 px-4 py-2 typography-semibold-body-lg\",\n \"32\": \"h-8 px-3 py-2 typography-semibold-body-md\",\n \"24\": \"h-6 px-2 py-1 typography-semibold-body-md\",\n};\n\nconst ICON_SIZE_CLASS: Record<ButtonSize, string> = {\n \"48\": \"size-5\",\n \"40\": \"size-5\",\n \"32\": \"size-4\",\n \"24\": \"size-3.5\",\n};\n\n/** Targets only direct SVG children so non-icon content (e.g. Pill) can size naturally. */\nconst ICON_WRAPPER_CLASS: Record<ButtonSize, string> = {\n \"48\": \"[&>svg]:size-5\",\n \"40\": \"[&>svg]:size-5\",\n \"32\": \"[&>svg]:size-4\",\n \"24\": \"[&>svg]:size-3.5\",\n};\n\nconst VARIANT_CLASSES: Record<ButtonVariant, string> = {\n primary:\n \"bg-buttons-primary text-content-primary-inverted hover:bg-buttons-primary-hover hover:text-content-primary-inverted active:bg-buttons-primary-hover active:text-content-primary-inverted\",\n secondary:\n \"border-content-primary border bg-transparent text-content-primary hover:bg-brand-primary-muted active:bg-brand-primary-muted\",\n tertiary:\n \"bg-transparent text-content-primary hover:bg-brand-primary-muted active:bg-brand-primary-muted\",\n link: \"bg-transparent text-content-primary underline decoration-solid hover:bg-brand-primary-muted active:bg-brand-primary-muted\",\n brand:\n \"bg-buttons-brand text-content-on-brand hover:bg-buttons-brand-hover hover:text-content-on-brand active:bg-buttons-brand-hover active:text-content-on-brand\",\n destructive:\n \"bg-error-content text-content-on-brand-inverted hover:bg-brand-primary-muted hover:text-content-primary active:bg-brand-primary-muted active:text-content-primary\",\n white:\n \"bg-content-on-brand-inverted text-content-on-brand hover:bg-brand-primary-muted hover:text-content-primary active:bg-brand-primary-muted active:text-content-primary\",\n tertiaryDestructive:\n \"bg-transparent text-error-content hover:bg-error-surface active:bg-error-surface\",\n text: \"bg-transparent text-content-primary hover:underline active:underline\",\n};\n\n/** Recursively extract text content from React nodes for accessible labels */\nfunction getTextContent(node: React.ReactNode): string | undefined {\n if (typeof node === \"string\") return node;\n if (typeof node === \"number\") return String(node);\n if (React.isValidElement(node)) {\n return getTextContent((node.props as { children?: React.ReactNode }).children);\n }\n if (Array.isArray(node)) {\n const text = node.map(getTextContent).filter(Boolean).join(\"\");\n return text || undefined;\n }\n return undefined;\n}\n\nconst LoadingSpinner = ({ size }: { size: ButtonSize }) => {\n return (\n <span className=\"animate-spin\" aria-hidden=\"true\">\n <SpinnerIcon className={ICON_SIZE_CLASS[size]}>\n <title>Loading</title>\n </SpinnerIcon>\n </span>\n );\n};\n\nfunction renderContent({\n loading,\n asChild,\n children,\n size,\n leftIcon,\n rightIcon,\n iconSizeClass,\n discount,\n price,\n}: {\n loading: boolean;\n asChild: boolean;\n children: React.ReactNode;\n size: ButtonSize;\n leftIcon: React.ReactNode;\n rightIcon: React.ReactNode;\n iconSizeClass: string;\n discount?: string;\n price?: string;\n fullWidth?: boolean;\n}) {\n if (loading) {\n // When asChild, clone the child element with spinner content instead of\n // wrapping in sr-only span (which would nest interactive elements)\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(\n children as React.ReactElement<{ children?: React.ReactNode }>,\n undefined,\n <LoadingSpinner size={size} />,\n );\n }\n return (\n <>\n <LoadingSpinner size={size} />\n <span className=\"sr-only\">{children}</span>\n </>\n );\n }\n\n if (asChild) return children;\n\n return (\n <>\n {leftIcon && (\n <span\n className={cn(\"flex shrink-0 items-center justify-center\", iconSizeClass)}\n aria-hidden=\"true\"\n >\n {leftIcon}\n </span>\n )}\n {React.Children.map(children, (child) =>\n typeof child === \"string\" ? (\n child.trim() ? (\n <span className=\"min-w-0 truncate\">{child}</span>\n ) : null\n ) : typeof child === \"number\" ? (\n <span className=\"min-w-0 truncate\">{child}</span>\n ) : (\n child\n ),\n )}\n {rightIcon && (\n <span\n className={cn(\"flex shrink-0 items-center justify-center\", iconSizeClass)}\n aria-hidden=\"true\"\n >\n {rightIcon}\n </span>\n )}\n {(price || discount) && (\n <div>\n {discount && (\n <span className=\"typography-regular-body-lg line-through\" aria-hidden=\"true\">\n {discount}\n </span>\n )}\n {price && (\n <span className=\"ml-2\" aria-hidden=\"true\">\n {price}\n </span>\n )}\n </div>\n )}\n </>\n );\n}\n\n/**\n * A versatile button component with multiple visual variants, sizes, icon\n * slots, loading state, and optional pricing display.\n *\n * @example\n * ```tsx\n * <Button variant=\"brand\" size=\"40\" leftIcon={<StarIcon />}>\n * Subscribe\n * </Button>\n * ```\n */\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n variant = \"primary\",\n size = \"40\",\n leftIcon,\n rightIcon,\n loading = false,\n asChild = false,\n disabled,\n children,\n discount,\n price,\n fullWidth = false,\n ...props\n },\n ref,\n ) => {\n const Comp = asChild ? Slot : \"button\";\n const isDisabled = disabled || loading;\n const iconSizeClass = ICON_WRAPPER_CLASS[size];\n\n const buttonSpecificProps = !asChild\n ? {\n type: \"button\" as const,\n \"data-testid\": \"button\",\n disabled: isDisabled,\n }\n : isDisabled\n ? { \"aria-disabled\": true }\n : {};\n\n // When asChild + loading, extract text from children for aria-label since we\n // can't wrap element children in an sr-only span (creates invalid nested markup)\n const loadingLabelProps = loading && asChild ? { \"aria-label\": getTextContent(children) } : {};\n\n const content = renderContent({\n loading,\n asChild,\n children,\n size,\n leftIcon,\n rightIcon,\n iconSizeClass,\n discount,\n price,\n });\n\n return (\n <Comp\n ref={ref}\n {...buttonSpecificProps}\n aria-busy={loading}\n {...loadingLabelProps}\n className={cn(\n // Base styles\n \"inline-flex min-w-0 cursor-pointer items-center gap-2 whitespace-nowrap rounded-full transition-colors\",\n // Focus ring\n \"focus-visible:shadow-focus-ring focus-visible:outline-none\",\n // Disabled state\n \"disabled:pointer-events-none disabled:opacity-50\",\n \"aria-disabled:pointer-events-none aria-disabled:opacity-50\",\n `${price ? \"justify-between\" : \"justify-center\"}`,\n fullWidth && \"w-full\",\n // Size styles\n SIZE_CLASSES[size],\n // Variant styles\n VARIANT_CLASSES[variant],\n // Manual CSS overrides\n className,\n )}\n {...props}\n >\n {content}\n </Comp>\n );\n },\n);\n\nButton.displayName = \"Button\";\n"],"names":[],"mappings":"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"}
@@ -3,9 +3,9 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { cn } from "../../utils/cn.mjs";
5
5
  const VARIANT_CLASSES = {
6
- outlined: "border border-neutral-200 bg-surface-container shadow-cardsubtle",
7
- elevated: "border border-neutral-200 bg-surface-container shadow-card",
8
- filled: "bg-neutral-500",
6
+ outlined: "border border-neutral-alphas-200 bg-surface-primary shadow-sm",
7
+ elevated: "border border-neutral-alphas-200 bg-surface-primary shadow-md",
8
+ filled: "bg-surface-secondary",
9
9
  ghost: "bg-transparent"
10
10
  };
11
11
  const Card = React.forwardRef(
@@ -15,7 +15,7 @@ const Card = React.forwardRef(
15
15
  {
16
16
  ref,
17
17
  className: cn(
18
- "flex flex-col overflow-hidden rounded-2xl",
18
+ "flex flex-col overflow-hidden rounded-md",
19
19
  !noPadding && "p-4",
20
20
  fullWidth && "w-full",
21
21
  VARIANT_CLASSES[variant],
@@ -43,7 +43,7 @@ const CardTitle = React.forwardRef(
43
43
  "h3",
44
44
  {
45
45
  ref,
46
- className: cn("typography-semibold-body-lg text-foreground-default", className),
46
+ className: cn("typography-semibold-body-lg text-content-primary", className),
47
47
  ...props,
48
48
  children
49
49
  }
@@ -57,7 +57,7 @@ const CardDescription = React.forwardRef(
57
57
  "p",
58
58
  {
59
59
  ref,
60
- className: cn("typography-regular-body-sm text-foreground-secondary", className),
60
+ className: cn("typography-regular-body-sm text-content-secondary", className),
61
61
  ...props,
62
62
  children
63
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Card.mjs","sources":["../../../src/components/Card/Card.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** Visual style variant of the card. */\nexport type CardVariant = \"outlined\" | \"elevated\" | \"filled\" | \"ghost\";\n\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Visual style variant of the card. @default \"outlined\" */\n variant?: CardVariant;\n /** When `true`, the card will take the full width of its container. @default true */\n fullWidth?: boolean;\n /** When `true`, removes all internal padding. @default false */\n noPadding?: boolean;\n}\n\nexport interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Icon element displayed at the trailing end of the header. */\n action?: React.ReactNode;\n}\n\nexport interface CardTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {}\n\nexport interface CardDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {}\n\nexport interface CardContentProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport interface CardFooterProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst VARIANT_CLASSES: Record<CardVariant, string> = {\n outlined: \"border border-neutral-200 bg-surface-container shadow-cardsubtle\",\n elevated: \"border border-neutral-200 bg-surface-container shadow-card\",\n filled: \"bg-neutral-500\",\n ghost: \"bg-transparent\",\n};\n\n/**\n * A composable card component with multiple visual variants. Use with\n * {@link CardHeader}, {@link CardTitle}, {@link CardDescription},\n * {@link CardContent}, and {@link CardFooter} for structured layouts.\n *\n * @example\n * ```tsx\n * <Card variant=\"outlined\">\n * <CardHeader action={<HomeIcon className=\"size-5\" />}>\n * <CardTitle>Card title</CardTitle>\n * <CardDescription>Card description text</CardDescription>\n * </CardHeader>\n * <CardContent>Content goes here</CardContent>\n * <CardFooter>\n * <Button variant=\"secondary\">Label</Button>\n * <Button variant=\"primary\">Label</Button>\n * </CardFooter>\n * </Card>\n * ```\n */\nexport const Card = React.forwardRef<HTMLDivElement, CardProps>(\n (\n { className, variant = \"outlined\", fullWidth = true, noPadding = false, children, ...props },\n ref,\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\n \"flex flex-col overflow-hidden rounded-2xl\",\n !noPadding && \"p-4\",\n fullWidth && \"w-full\",\n VARIANT_CLASSES[variant],\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n },\n);\nCard.displayName = \"Card\";\n\n/**\n * Header section of a {@link Card}. Renders a flex row with text content\n * on the left and an optional trailing action element (e.g. icon) on the right.\n */\nexport const CardHeader = React.forwardRef<HTMLDivElement, CardHeaderProps>(\n ({ className, action, children, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"flex items-start gap-3\", className)} {...props}>\n <div className=\"min-w-0 flex-1\">{children}</div>\n {action && <div className=\"shrink-0\">{action}</div>}\n </div>\n );\n },\n);\nCardHeader.displayName = \"CardHeader\";\n\n/** Title element rendered inside a {@link CardHeader}. */\nexport const CardTitle = React.forwardRef<HTMLHeadingElement, CardTitleProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <h3\n ref={ref}\n className={cn(\"typography-semibold-body-lg text-foreground-default\", className)}\n {...props}\n >\n {children}\n </h3>\n );\n },\n);\nCardTitle.displayName = \"CardTitle\";\n\n/** Description text rendered below the {@link CardTitle} inside a {@link CardHeader}. */\nexport const CardDescription = React.forwardRef<HTMLParagraphElement, CardDescriptionProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <p\n ref={ref}\n className={cn(\"typography-regular-body-sm text-foreground-secondary\", className)}\n {...props}\n >\n {children}\n </p>\n );\n },\n);\nCardDescription.displayName = \"CardDescription\";\n\n/** Flexible content area of a {@link Card}. Adds vertical padding between header and footer. */\nexport const CardContent = React.forwardRef<HTMLDivElement, CardContentProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"flex-1 py-4\", className)} {...props}>\n {children}\n </div>\n );\n },\n);\nCardContent.displayName = \"CardContent\";\n\n/** Footer section of a {@link Card}. Renders children in a horizontal row with a gap. */\nexport const CardFooter = React.forwardRef<HTMLDivElement, CardFooterProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"flex items-center gap-3\", className)} {...props}>\n {children}\n </div>\n );\n },\n);\nCardFooter.displayName = \"CardFooter\";\n"],"names":[],"mappings":";;;;AA4BA,MAAM,kBAA+C;AAAA,EACnD,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,OAAO;AACT;AAsBO,MAAM,OAAO,MAAM;AAAA,EACxB,CACE,EAAE,WAAW,UAAU,YAAY,YAAY,MAAM,YAAY,OAAO,UAAU,GAAG,MAAA,GACrF,QACG;AACH,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA,CAAC,aAAa;AAAA,UACd,aAAa;AAAA,UACb,gBAAgB,OAAO;AAAA,UACvB;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,QAEH;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AACA,KAAK,cAAc;AAMZ,MAAM,aAAa,MAAM;AAAA,EAC9B,CAAC,EAAE,WAAW,QAAQ,UAAU,GAAG,MAAA,GAAS,QAAQ;AAClD,WACE,qBAAC,SAAI,KAAU,WAAW,GAAG,0BAA0B,SAAS,GAAI,GAAG,OACrE,UAAA;AAAA,MAAA,oBAAC,OAAA,EAAI,WAAU,kBAAkB,SAAA,CAAS;AAAA,MACzC,UAAU,oBAAC,OAAA,EAAI,WAAU,YAAY,UAAA,OAAA,CAAO;AAAA,IAAA,GAC/C;AAAA,EAEJ;AACF;AACA,WAAW,cAAc;AAGlB,MAAM,YAAY,MAAM;AAAA,EAC7B,CAAC,EAAE,WAAW,UAAU,GAAG,MAAA,GAAS,QAAQ;AAC1C,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW,GAAG,uDAAuD,SAAS;AAAA,QAC7E,GAAG;AAAA,QAEH;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AACA,UAAU,cAAc;AAGjB,MAAM,kBAAkB,MAAM;AAAA,EACnC,CAAC,EAAE,WAAW,UAAU,GAAG,MAAA,GAAS,QAAQ;AAC1C,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW,GAAG,wDAAwD,SAAS;AAAA,QAC9E,GAAG;AAAA,QAEH;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AACA,gBAAgB,cAAc;AAGvB,MAAM,cAAc,MAAM;AAAA,EAC/B,CAAC,EAAE,WAAW,UAAU,GAAG,MAAA,GAAS,QAAQ;AAC1C,WACE,oBAAC,OAAA,EAAI,KAAU,WAAW,GAAG,eAAe,SAAS,GAAI,GAAG,OACzD,SAAA,CACH;AAAA,EAEJ;AACF;AACA,YAAY,cAAc;AAGnB,MAAM,aAAa,MAAM;AAAA,EAC9B,CAAC,EAAE,WAAW,UAAU,GAAG,MAAA,GAAS,QAAQ;AAC1C,WACE,oBAAC,OAAA,EAAI,KAAU,WAAW,GAAG,2BAA2B,SAAS,GAAI,GAAG,OACrE,SAAA,CACH;AAAA,EAEJ;AACF;AACA,WAAW,cAAc;"}
1
+ {"version":3,"file":"Card.mjs","sources":["../../../src/components/Card/Card.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** Visual style variant of the card. */\nexport type CardVariant = \"outlined\" | \"elevated\" | \"filled\" | \"ghost\";\n\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Visual style variant of the card. @default \"outlined\" */\n variant?: CardVariant;\n /** When `true`, the card will take the full width of its container. @default true */\n fullWidth?: boolean;\n /** When `true`, removes all internal padding. @default false */\n noPadding?: boolean;\n}\n\nexport interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Icon element displayed at the trailing end of the header. */\n action?: React.ReactNode;\n}\n\nexport interface CardTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {}\n\nexport interface CardDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {}\n\nexport interface CardContentProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport interface CardFooterProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst VARIANT_CLASSES: Record<CardVariant, string> = {\n outlined: \"border border-neutral-alphas-200 bg-surface-primary shadow-sm\",\n elevated: \"border border-neutral-alphas-200 bg-surface-primary shadow-md\",\n filled: \"bg-surface-secondary\",\n ghost: \"bg-transparent\",\n};\n\n/**\n * A composable card component with multiple visual variants. Use with\n * {@link CardHeader}, {@link CardTitle}, {@link CardDescription},\n * {@link CardContent}, and {@link CardFooter} for structured layouts.\n *\n * @example\n * ```tsx\n * <Card variant=\"outlined\">\n * <CardHeader action={<HomeIcon className=\"size-5\" />}>\n * <CardTitle>Card title</CardTitle>\n * <CardDescription>Card description text</CardDescription>\n * </CardHeader>\n * <CardContent>Content goes here</CardContent>\n * <CardFooter>\n * <Button variant=\"secondary\">Label</Button>\n * <Button variant=\"primary\">Label</Button>\n * </CardFooter>\n * </Card>\n * ```\n */\nexport const Card = React.forwardRef<HTMLDivElement, CardProps>(\n (\n { className, variant = \"outlined\", fullWidth = true, noPadding = false, children, ...props },\n ref,\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\n \"flex flex-col overflow-hidden rounded-md\",\n !noPadding && \"p-4\",\n fullWidth && \"w-full\",\n VARIANT_CLASSES[variant],\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n },\n);\nCard.displayName = \"Card\";\n\n/**\n * Header section of a {@link Card}. Renders a flex row with text content\n * on the left and an optional trailing action element (e.g. icon) on the right.\n */\nexport const CardHeader = React.forwardRef<HTMLDivElement, CardHeaderProps>(\n ({ className, action, children, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"flex items-start gap-3\", className)} {...props}>\n <div className=\"min-w-0 flex-1\">{children}</div>\n {action && <div className=\"shrink-0\">{action}</div>}\n </div>\n );\n },\n);\nCardHeader.displayName = \"CardHeader\";\n\n/** Title element rendered inside a {@link CardHeader}. */\nexport const CardTitle = React.forwardRef<HTMLHeadingElement, CardTitleProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <h3\n ref={ref}\n className={cn(\"typography-semibold-body-lg text-content-primary\", className)}\n {...props}\n >\n {children}\n </h3>\n );\n },\n);\nCardTitle.displayName = \"CardTitle\";\n\n/** Description text rendered below the {@link CardTitle} inside a {@link CardHeader}. */\nexport const CardDescription = React.forwardRef<HTMLParagraphElement, CardDescriptionProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <p\n ref={ref}\n className={cn(\"typography-regular-body-sm text-content-secondary\", className)}\n {...props}\n >\n {children}\n </p>\n );\n },\n);\nCardDescription.displayName = \"CardDescription\";\n\n/** Flexible content area of a {@link Card}. Adds vertical padding between header and footer. */\nexport const CardContent = React.forwardRef<HTMLDivElement, CardContentProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"flex-1 py-4\", className)} {...props}>\n {children}\n </div>\n );\n },\n);\nCardContent.displayName = \"CardContent\";\n\n/** Footer section of a {@link Card}. Renders children in a horizontal row with a gap. */\nexport const CardFooter = React.forwardRef<HTMLDivElement, CardFooterProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"flex items-center gap-3\", className)} {...props}>\n {children}\n </div>\n );\n },\n);\nCardFooter.displayName = \"CardFooter\";\n"],"names":[],"mappings":";;;;AA4BA,MAAM,kBAA+C;AAAA,EACnD,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,OAAO;AACT;AAsBO,MAAM,OAAO,MAAM;AAAA,EACxB,CACE,EAAE,WAAW,UAAU,YAAY,YAAY,MAAM,YAAY,OAAO,UAAU,GAAG,MAAA,GACrF,QACG;AACH,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA,CAAC,aAAa;AAAA,UACd,aAAa;AAAA,UACb,gBAAgB,OAAO;AAAA,UACvB;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,QAEH;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AACA,KAAK,cAAc;AAMZ,MAAM,aAAa,MAAM;AAAA,EAC9B,CAAC,EAAE,WAAW,QAAQ,UAAU,GAAG,MAAA,GAAS,QAAQ;AAClD,WACE,qBAAC,SAAI,KAAU,WAAW,GAAG,0BAA0B,SAAS,GAAI,GAAG,OACrE,UAAA;AAAA,MAAA,oBAAC,OAAA,EAAI,WAAU,kBAAkB,SAAA,CAAS;AAAA,MACzC,UAAU,oBAAC,OAAA,EAAI,WAAU,YAAY,UAAA,OAAA,CAAO;AAAA,IAAA,GAC/C;AAAA,EAEJ;AACF;AACA,WAAW,cAAc;AAGlB,MAAM,YAAY,MAAM;AAAA,EAC7B,CAAC,EAAE,WAAW,UAAU,GAAG,MAAA,GAAS,QAAQ;AAC1C,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW,GAAG,oDAAoD,SAAS;AAAA,QAC1E,GAAG;AAAA,QAEH;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AACA,UAAU,cAAc;AAGjB,MAAM,kBAAkB,MAAM;AAAA,EACnC,CAAC,EAAE,WAAW,UAAU,GAAG,MAAA,GAAS,QAAQ;AAC1C,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW,GAAG,qDAAqD,SAAS;AAAA,QAC3E,GAAG;AAAA,QAEH;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AACA,gBAAgB,cAAc;AAGvB,MAAM,cAAc,MAAM;AAAA,EAC/B,CAAC,EAAE,WAAW,UAAU,GAAG,MAAA,GAAS,QAAQ;AAC1C,WACE,oBAAC,OAAA,EAAI,KAAU,WAAW,GAAG,eAAe,SAAS,GAAI,GAAG,OACzD,SAAA,CACH;AAAA,EAEJ;AACF;AACA,YAAY,cAAc;AAGnB,MAAM,aAAa,MAAM;AAAA,EAC9B,CAAC,EAAE,WAAW,UAAU,GAAG,MAAA,GAAS,QAAQ;AAC1C,WACE,oBAAC,OAAA,EAAI,KAAU,WAAW,GAAG,2BAA2B,SAAS,GAAI,GAAG,OACrE,SAAA,CACH;AAAA,EAEJ;AACF;AACA,WAAW,cAAc;"}
@@ -8,8 +8,8 @@ import { InfoCircleIcon } from "../Icons/InfoCircleIcon.mjs";
8
8
  import { Skeleton } from "../Skeleton/Skeleton.mjs";
9
9
  import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/Tooltip.mjs";
10
10
  const TREND_CLASSES = {
11
- positive: "bg-success-background text-success-default",
12
- negative: "bg-error-background text-error-default"
11
+ positive: "bg-success-surface text-success-content",
12
+ negative: "bg-error-surface text-error-content"
13
13
  };
14
14
  const ChartCard = React.forwardRef(
15
15
  ({
@@ -31,7 +31,7 @@ const ChartCard = React.forwardRef(
31
31
  /* @__PURE__ */ jsx(Skeleton, { animation: "wave", variant: "rounded", className: "h-3 w-24" })
32
32
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
33
33
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
34
- /* @__PURE__ */ jsx("span", { className: "typography-semibold-body-md text-foreground-default", children: title }),
34
+ /* @__PURE__ */ jsx("span", { className: "typography-semibold-body-md text-content-primary", children: title }),
35
35
  tooltip && /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
36
36
  /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
37
37
  IconButton,
@@ -39,14 +39,14 @@ const ChartCard = React.forwardRef(
39
39
  variant: "tertiary",
40
40
  size: "24",
41
41
  "aria-label": tooltipAriaLabel,
42
- icon: /* @__PURE__ */ jsx(InfoCircleIcon, { className: "size-4 text-foreground-tertiary" })
42
+ icon: /* @__PURE__ */ jsx(InfoCircleIcon, { className: "size-4 text-content-tertiary" })
43
43
  }
44
44
  ) }),
45
45
  /* @__PURE__ */ jsx(TooltipContent, { children: tooltip })
46
46
  ] }) })
47
47
  ] }),
48
48
  subtitle && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
49
- /* @__PURE__ */ jsx("span", { className: "typography-bold-heading-sm text-foreground-default", children: subtitle }),
49
+ /* @__PURE__ */ jsx("span", { className: "typography-bold-heading-sm text-content-primary", children: subtitle }),
50
50
  trendChip && /* @__PURE__ */ jsx(
51
51
  "span",
52
52
  {
@@ -58,7 +58,7 @@ const ChartCard = React.forwardRef(
58
58
  }
59
59
  )
60
60
  ] }),
61
- dateInfo && /* @__PURE__ */ jsx("span", { className: "typography-regular-body-sm text-foreground-tertiary", children: dateInfo })
61
+ dateInfo && /* @__PURE__ */ jsx("span", { className: "typography-regular-body-sm text-content-tertiary", children: dateInfo })
62
62
  ] }),
63
63
  /* @__PURE__ */ jsx("div", { className: "mt-auto", children })
64
64
  ] }) });
@@ -1 +1 @@
1
- {"version":3,"file":"ChartCard.mjs","sources":["../../../src/components/Chart/ChartCard.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Card } from \"../Card/Card\";\nimport { IconButton } from \"../IconButton/IconButton\";\nimport { InfoCircleIcon } from \"../Icons/InfoCircleIcon\";\nimport { Skeleton } from \"../Skeleton/Skeleton\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../Tooltip/Tooltip\";\n\n/** Props for {@link ChartCard}. */\nexport interface ChartCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Card title text. Pass translated string for i18n. */\n title: React.ReactNode;\n /** Large subtitle value (e.g. formatted price or count). */\n subtitle?: React.ReactNode;\n /** Tooltip text shown next to the title. Pass translated string for i18n. */\n tooltip?: React.ReactNode;\n /** Accessible label for the info tooltip trigger. Override for i18n. @default \"More info\" */\n tooltipAriaLabel?: string;\n /** Date range or period label shown below the subtitle. */\n dateInfo?: React.ReactNode;\n /** Trend indicator chip config. */\n trendChip?: {\n /** Display label (e.g. \"12.5%\"). */\n label: React.ReactNode;\n /** Whether the trend is positive (green) or negative (red). */\n trend: \"positive\" | \"negative\";\n };\n /** Show loading skeleton instead of content. @default false */\n loading?: boolean;\n /** Chart content rendered below the header. */\n children?: React.ReactNode;\n}\n\nconst TREND_CLASSES: Record<\"positive\" | \"negative\", string> = {\n positive: \"bg-success-background text-success-default\",\n negative: \"bg-error-background text-error-default\",\n};\n\n/**\n * Wraps any chart with a structured header containing title, subtitle,\n * optional trend chip, date range label, info tooltip, and a loading\n * skeleton state.\n *\n * @example\n * ```tsx\n * <ChartCard\n * title=\"Revenue\"\n * subtitle=\"$4,523\"\n * trendChip={{ label: \"+12.5%\", trend: \"positive\" }}\n * dateInfo=\"Jan 1 – Mar 17\"\n * tooltip=\"Total revenue for the selected period.\"\n * >\n * <MyLineChart />\n * </ChartCard>\n * ```\n */\nexport const ChartCard = React.forwardRef<HTMLDivElement, ChartCardProps>(\n (\n {\n className,\n title,\n subtitle,\n tooltip,\n tooltipAriaLabel = \"More info\",\n dateInfo,\n trendChip,\n loading = false,\n children,\n ...props\n },\n ref,\n ) => {\n return (\n <Card ref={ref} variant=\"outlined\" noPadding className={className} {...props}>\n <div className=\"flex flex-col gap-2 p-4\">\n {loading ? (\n <>\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-4 w-32\" />\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-7 w-44\" />\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-3 w-24\" />\n </>\n ) : (\n <>\n <div className=\"flex items-center gap-1.5\">\n <span className=\"typography-semibold-body-md text-foreground-default\">{title}</span>\n {tooltip && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <IconButton\n variant=\"tertiary\"\n size=\"24\"\n aria-label={tooltipAriaLabel}\n icon={<InfoCircleIcon className=\"size-4 text-foreground-tertiary\" />}\n />\n </TooltipTrigger>\n <TooltipContent>{tooltip}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n {subtitle && (\n <div className=\"flex items-center gap-2\">\n <span className=\"typography-bold-heading-sm text-foreground-default\">\n {subtitle}\n </span>\n {trendChip && (\n <span\n className={cn(\n \"typography-semibold-body-sm rounded-full px-2 py-0.5\",\n TREND_CLASSES[trendChip.trend],\n )}\n >\n {trendChip.label}\n </span>\n )}\n </div>\n )}\n {dateInfo && (\n <span className=\"typography-regular-body-sm text-foreground-tertiary\">\n {dateInfo}\n </span>\n )}\n </>\n )}\n <div className=\"mt-auto\">{children}</div>\n </div>\n </Card>\n );\n },\n);\nChartCard.displayName = \"ChartCard\";\n"],"names":[],"mappings":";;;;;;;;;AAiCA,MAAM,gBAAyD;AAAA,EAC7D,UAAU;AAAA,EACV,UAAU;AACZ;AAoBO,MAAM,YAAY,MAAM;AAAA,EAC7B,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,IACnB;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,WACE,oBAAC,MAAA,EAAK,KAAU,SAAQ,YAAW,WAAS,MAAC,WAAuB,GAAG,OACrE,UAAA,qBAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,MAAA,UACC,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,oBAAC,YAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,YAAW;AAAA,4BACjE,UAAA,EAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,YAAW;AAAA,4BACjE,UAAA,EAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,WAAA,CAAW;AAAA,MAAA,EAAA,CACpE,IAEA,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,qBAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAK,WAAU,uDAAuD,UAAA,OAAM;AAAA,UAC5E,WACC,oBAAC,iBAAA,EACC,UAAA,qBAAC,SAAA,EACC,UAAA;AAAA,YAAA,oBAAC,gBAAA,EAAe,SAAO,MACrB,UAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,cAAY;AAAA,gBACZ,MAAM,oBAAC,gBAAA,EAAe,WAAU,kCAAA,CAAkC;AAAA,cAAA;AAAA,YAAA,GAEtE;AAAA,YACA,oBAAC,kBAAgB,UAAA,QAAA,CAAQ;AAAA,UAAA,EAAA,CAC3B,EAAA,CACF;AAAA,QAAA,GAEJ;AAAA,QACC,YACC,qBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAK,WAAU,sDACb,UAAA,UACH;AAAA,UACC,aACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,cAAc,UAAU,KAAK;AAAA,cAAA;AAAA,cAG9B,UAAA,UAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACb,GAEJ;AAAA,QAED,YACC,oBAAC,QAAA,EAAK,WAAU,uDACb,UAAA,SAAA,CACH;AAAA,MAAA,GAEJ;AAAA,MAEF,oBAAC,OAAA,EAAI,WAAU,WAAW,SAAA,CAAS;AAAA,IAAA,EAAA,CACrC,EAAA,CACF;AAAA,EAEJ;AACF;AACA,UAAU,cAAc;"}
1
+ {"version":3,"file":"ChartCard.mjs","sources":["../../../src/components/Chart/ChartCard.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Card } from \"../Card/Card\";\nimport { IconButton } from \"../IconButton/IconButton\";\nimport { InfoCircleIcon } from \"../Icons/InfoCircleIcon\";\nimport { Skeleton } from \"../Skeleton/Skeleton\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../Tooltip/Tooltip\";\n\n/** Props for {@link ChartCard}. */\nexport interface ChartCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Card title text. Pass translated string for i18n. */\n title: React.ReactNode;\n /** Large subtitle value (e.g. formatted price or count). */\n subtitle?: React.ReactNode;\n /** Tooltip text shown next to the title. Pass translated string for i18n. */\n tooltip?: React.ReactNode;\n /** Accessible label for the info tooltip trigger. Override for i18n. @default \"More info\" */\n tooltipAriaLabel?: string;\n /** Date range or period label shown below the subtitle. */\n dateInfo?: React.ReactNode;\n /** Trend indicator chip config. */\n trendChip?: {\n /** Display label (e.g. \"12.5%\"). */\n label: React.ReactNode;\n /** Whether the trend is positive (green) or negative (red). */\n trend: \"positive\" | \"negative\";\n };\n /** Show loading skeleton instead of content. @default false */\n loading?: boolean;\n /** Chart content rendered below the header. */\n children?: React.ReactNode;\n}\n\nconst TREND_CLASSES: Record<\"positive\" | \"negative\", string> = {\n positive: \"bg-success-surface text-success-content\",\n negative: \"bg-error-surface text-error-content\",\n};\n\n/**\n * Wraps any chart with a structured header containing title, subtitle,\n * optional trend chip, date range label, info tooltip, and a loading\n * skeleton state.\n *\n * @example\n * ```tsx\n * <ChartCard\n * title=\"Revenue\"\n * subtitle=\"$4,523\"\n * trendChip={{ label: \"+12.5%\", trend: \"positive\" }}\n * dateInfo=\"Jan 1 – Mar 17\"\n * tooltip=\"Total revenue for the selected period.\"\n * >\n * <MyLineChart />\n * </ChartCard>\n * ```\n */\nexport const ChartCard = React.forwardRef<HTMLDivElement, ChartCardProps>(\n (\n {\n className,\n title,\n subtitle,\n tooltip,\n tooltipAriaLabel = \"More info\",\n dateInfo,\n trendChip,\n loading = false,\n children,\n ...props\n },\n ref,\n ) => {\n return (\n <Card ref={ref} variant=\"outlined\" noPadding className={className} {...props}>\n <div className=\"flex flex-col gap-2 p-4\">\n {loading ? (\n <>\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-4 w-32\" />\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-7 w-44\" />\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-3 w-24\" />\n </>\n ) : (\n <>\n <div className=\"flex items-center gap-1.5\">\n <span className=\"typography-semibold-body-md text-content-primary\">{title}</span>\n {tooltip && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <IconButton\n variant=\"tertiary\"\n size=\"24\"\n aria-label={tooltipAriaLabel}\n icon={<InfoCircleIcon className=\"size-4 text-content-tertiary\" />}\n />\n </TooltipTrigger>\n <TooltipContent>{tooltip}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n {subtitle && (\n <div className=\"flex items-center gap-2\">\n <span className=\"typography-bold-heading-sm text-content-primary\">\n {subtitle}\n </span>\n {trendChip && (\n <span\n className={cn(\n \"typography-semibold-body-sm rounded-full px-2 py-0.5\",\n TREND_CLASSES[trendChip.trend],\n )}\n >\n {trendChip.label}\n </span>\n )}\n </div>\n )}\n {dateInfo && (\n <span className=\"typography-regular-body-sm text-content-tertiary\">{dateInfo}</span>\n )}\n </>\n )}\n <div className=\"mt-auto\">{children}</div>\n </div>\n </Card>\n );\n },\n);\nChartCard.displayName = \"ChartCard\";\n"],"names":[],"mappings":";;;;;;;;;AAiCA,MAAM,gBAAyD;AAAA,EAC7D,UAAU;AAAA,EACV,UAAU;AACZ;AAoBO,MAAM,YAAY,MAAM;AAAA,EAC7B,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,IACnB;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,WACE,oBAAC,MAAA,EAAK,KAAU,SAAQ,YAAW,WAAS,MAAC,WAAuB,GAAG,OACrE,UAAA,qBAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,MAAA,UACC,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,oBAAC,YAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,YAAW;AAAA,4BACjE,UAAA,EAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,YAAW;AAAA,4BACjE,UAAA,EAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,WAAA,CAAW;AAAA,MAAA,EAAA,CACpE,IAEA,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,qBAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAK,WAAU,oDAAoD,UAAA,OAAM;AAAA,UACzE,WACC,oBAAC,iBAAA,EACC,UAAA,qBAAC,SAAA,EACC,UAAA;AAAA,YAAA,oBAAC,gBAAA,EAAe,SAAO,MACrB,UAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,cAAY;AAAA,gBACZ,MAAM,oBAAC,gBAAA,EAAe,WAAU,+BAAA,CAA+B;AAAA,cAAA;AAAA,YAAA,GAEnE;AAAA,YACA,oBAAC,kBAAgB,UAAA,QAAA,CAAQ;AAAA,UAAA,EAAA,CAC3B,EAAA,CACF;AAAA,QAAA,GAEJ;AAAA,QACC,YACC,qBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAK,WAAU,mDACb,UAAA,UACH;AAAA,UACC,aACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,cAAc,UAAU,KAAK;AAAA,cAAA;AAAA,cAG9B,UAAA,UAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACb,GAEJ;AAAA,QAED,YACC,oBAAC,QAAA,EAAK,WAAU,oDAAoD,UAAA,SAAA,CAAS;AAAA,MAAA,GAEjF;AAAA,MAEF,oBAAC,OAAA,EAAI,WAAU,WAAW,SAAA,CAAS;AAAA,IAAA,EAAA,CACrC,EAAA,CACF;AAAA,EAEJ;AACF;AACA,UAAU,cAAc;"}
@@ -6,7 +6,7 @@ const ChartCenterLabel = React.forwardRef(
6
6
  viewBox,
7
7
  value,
8
8
  subtitle,
9
- valueClassName = "fill-foreground-default font-bold text-3xl",
9
+ valueClassName = "fill-content-primary font-bold text-3xl",
10
10
  ...props
11
11
  }, ref) => {
12
12
  if (!viewBox || !("cx" in viewBox) || !("cy" in viewBox)) return null;
@@ -21,7 +21,7 @@ const ChartCenterLabel = React.forwardRef(
21
21
  ...props,
22
22
  children: [
23
23
  /* @__PURE__ */ jsx("tspan", { x: viewBox.cx, y: viewBox.cy, className: valueClassName, children: value }),
24
- /* @__PURE__ */ jsx("tspan", { x: viewBox.cx, y: (viewBox.cy || 0) + 24, className: "fill-foreground-tertiary", children: subtitle })
24
+ /* @__PURE__ */ jsx("tspan", { x: viewBox.cx, y: (viewBox.cy || 0) + 24, className: "fill-content-tertiary", children: subtitle })
25
25
  ]
26
26
  }
27
27
  );
@@ -1 +1 @@
1
- {"version":3,"file":"ChartCenterLabel.mjs","sources":["../../../src/components/Chart/ChartCenterLabel.tsx"],"sourcesContent":["import * as React from \"react\";\n\n/** Props for {@link ChartCenterLabel}. */\nexport interface ChartCenterLabelProps\n extends Omit<React.SVGAttributes<SVGTextElement>, \"viewBox\"> {\n /** Recharts viewBox with center coordinates. */\n viewBox?: { cx?: number; cy?: number; [key: string]: unknown };\n /** Primary value displayed in the center. */\n value: React.ReactNode;\n /** Secondary text below the value. */\n subtitle: React.ReactNode;\n /** Custom className for the value tspan. @default \"fill-foreground-default font-bold text-3xl\" */\n valueClassName?: string;\n}\n\n/**\n * Centered label for radial/pie charts, rendered inside a Recharts `<Label>`.\n *\n * @example\n * ```tsx\n * <PolarRadiusAxis tick={false} tickLine={false} axisLine={false}>\n * <Label content={({ viewBox }) => (\n * <ChartCenterLabel viewBox={viewBox} value=\"78%\" subtitle=\"Complete\" />\n * )} />\n * </PolarRadiusAxis>\n * ```\n */\nexport const ChartCenterLabel = React.forwardRef<SVGTextElement, ChartCenterLabelProps>(\n (\n {\n viewBox,\n value,\n subtitle,\n valueClassName = \"fill-foreground-default font-bold text-3xl\",\n ...props\n },\n ref,\n ) => {\n if (!viewBox || !(\"cx\" in viewBox) || !(\"cy\" in viewBox)) return null;\n\n return (\n <text\n ref={ref}\n x={viewBox.cx}\n y={viewBox.cy}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n {...props}\n >\n <tspan x={viewBox.cx} y={viewBox.cy} className={valueClassName}>\n {value}\n </tspan>\n <tspan x={viewBox.cx} y={(viewBox.cy || 0) + 24} className=\"fill-foreground-tertiary\">\n {subtitle}\n </tspan>\n </text>\n );\n },\n);\n\nChartCenterLabel.displayName = \"ChartCenterLabel\";\n"],"names":[],"mappings":";;;AA2BO,MAAM,mBAAmB,MAAM;AAAA,EACpC,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB;AAAA,IACjB,GAAG;AAAA,EAAA,GAEL,QACG;AACH,QAAI,CAAC,WAAW,EAAE,QAAQ,YAAY,EAAE,QAAQ,SAAU,QAAO;AAEjE,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,GAAG,QAAQ;AAAA,QACX,GAAG,QAAQ;AAAA,QACX,YAAW;AAAA,QACX,kBAAiB;AAAA,QAChB,GAAG;AAAA,QAEJ,UAAA;AAAA,UAAA,oBAAC,SAAA,EAAM,GAAG,QAAQ,IAAI,GAAG,QAAQ,IAAI,WAAW,gBAC7C,UAAA,MAAA,CACH;AAAA,UACA,oBAAC,SAAA,EAAM,GAAG,QAAQ,IAAI,IAAI,QAAQ,MAAM,KAAK,IAAI,WAAU,4BACxD,UAAA,SAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,iBAAiB,cAAc;"}
1
+ {"version":3,"file":"ChartCenterLabel.mjs","sources":["../../../src/components/Chart/ChartCenterLabel.tsx"],"sourcesContent":["import * as React from \"react\";\n\n/** Props for {@link ChartCenterLabel}. */\nexport interface ChartCenterLabelProps\n extends Omit<React.SVGAttributes<SVGTextElement>, \"viewBox\"> {\n /** Recharts viewBox with center coordinates. */\n viewBox?: { cx?: number; cy?: number; [key: string]: unknown };\n /** Primary value displayed in the center. */\n value: React.ReactNode;\n /** Secondary text below the value. */\n subtitle: React.ReactNode;\n /** Custom className for the value tspan. @default \"fill-content-primary font-bold text-3xl\" */\n valueClassName?: string;\n}\n\n/**\n * Centered label for radial/pie charts, rendered inside a Recharts `<Label>`.\n *\n * @example\n * ```tsx\n * <PolarRadiusAxis tick={false} tickLine={false} axisLine={false}>\n * <Label content={({ viewBox }) => (\n * <ChartCenterLabel viewBox={viewBox} value=\"78%\" subtitle=\"Complete\" />\n * )} />\n * </PolarRadiusAxis>\n * ```\n */\nexport const ChartCenterLabel = React.forwardRef<SVGTextElement, ChartCenterLabelProps>(\n (\n {\n viewBox,\n value,\n subtitle,\n valueClassName = \"fill-content-primary font-bold text-3xl\",\n ...props\n },\n ref,\n ) => {\n if (!viewBox || !(\"cx\" in viewBox) || !(\"cy\" in viewBox)) return null;\n\n return (\n <text\n ref={ref}\n x={viewBox.cx}\n y={viewBox.cy}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n {...props}\n >\n <tspan x={viewBox.cx} y={viewBox.cy} className={valueClassName}>\n {value}\n </tspan>\n <tspan x={viewBox.cx} y={(viewBox.cy || 0) + 24} className=\"fill-content-tertiary\">\n {subtitle}\n </tspan>\n </text>\n );\n },\n);\n\nChartCenterLabel.displayName = \"ChartCenterLabel\";\n"],"names":[],"mappings":";;;AA2BO,MAAM,mBAAmB,MAAM;AAAA,EACpC,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB;AAAA,IACjB,GAAG;AAAA,EAAA,GAEL,QACG;AACH,QAAI,CAAC,WAAW,EAAE,QAAQ,YAAY,EAAE,QAAQ,SAAU,QAAO;AAEjE,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,GAAG,QAAQ;AAAA,QACX,GAAG,QAAQ;AAAA,QACX,YAAW;AAAA,QACX,kBAAiB;AAAA,QAChB,GAAG;AAAA,QAEJ,UAAA;AAAA,UAAA,oBAAC,SAAA,EAAM,GAAG,QAAQ,IAAI,GAAG,QAAQ,IAAI,WAAW,gBAC7C,UAAA,MAAA,CACH;AAAA,UACA,oBAAC,SAAA,EAAM,GAAG,QAAQ,IAAI,IAAI,QAAQ,MAAM,KAAK,IAAI,WAAU,yBACxD,UAAA,SAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,iBAAiB,cAAc;"}