@ponti-studios/ui 2.0.1 → 3.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 (319) hide show
  1. package/README.md +36 -3
  2. package/dist/auth/index.d.ts +3 -0
  3. package/dist/auth/index.js +3 -0
  4. package/dist/components/data-display/accordion.d.ts +10 -0
  5. package/dist/components/data-display/accordion.js +53 -0
  6. package/{src/components/data-display/index.ts → dist/components/data-display/index.d.ts} +1 -10
  7. package/dist/components/data-display/index.js +8 -0
  8. package/dist/components/data-display/metric-card.d.ts +9 -0
  9. package/dist/components/data-display/metric-card.js +25 -0
  10. package/dist/components/data-display/sort-controls.d.ts +13 -0
  11. package/dist/components/data-display/sort-controls.js +57 -0
  12. package/dist/components/data-display/sort-row.d.ts +10 -0
  13. package/dist/components/data-display/sort-row.js +52 -0
  14. package/dist/components/data-display/table.d.ts +10 -0
  15. package/dist/components/data-display/table.js +57 -0
  16. package/dist/components/feedback/alert.d.ts +9 -0
  17. package/dist/components/feedback/alert.js +38 -0
  18. package/dist/components/feedback/empty-state.d.ts +18 -0
  19. package/dist/components/feedback/empty-state.js +36 -0
  20. package/{src/components/feedback/index.ts → dist/components/feedback/index.d.ts} +2 -0
  21. package/dist/components/feedback/index.js +7 -0
  22. package/dist/components/feedback/progress.d.ts +6 -0
  23. package/dist/components/feedback/progress.js +25 -0
  24. package/dist/components/feedback/skeleton.d.ts +2 -0
  25. package/dist/components/feedback/skeleton.js +11 -0
  26. package/dist/components/feedback/spinner.d.ts +14 -0
  27. package/dist/components/feedback/spinner.js +27 -0
  28. package/dist/components/feedback/update-guard.d.ts +13 -0
  29. package/dist/components/feedback/update-guard.js +38 -0
  30. package/dist/components/filters/active-filters-bar.d.ts +14 -0
  31. package/dist/components/filters/active-filters-bar.js +44 -0
  32. package/dist/components/filters/filter-chip.d.ts +11 -0
  33. package/dist/components/filters/filter-chip.js +33 -0
  34. package/dist/components/filters/filter-select.d.ts +17 -0
  35. package/dist/components/filters/filter-select.js +46 -0
  36. package/dist/components/filters/index.js +4 -0
  37. package/dist/components/forms/checkbox.d.ts +4 -0
  38. package/dist/components/forms/checkbox.js +24 -0
  39. package/dist/components/forms/date-month-select.d.ts +11 -0
  40. package/dist/components/forms/date-month-select.js +47 -0
  41. package/dist/components/forms/date-picker.d.ts +60 -0
  42. package/dist/components/forms/date-picker.js +193 -0
  43. package/dist/components/forms/date-utils.d.ts +14 -0
  44. package/dist/components/forms/date-utils.js +18 -0
  45. package/dist/components/forms/drop-zone.d.ts +42 -0
  46. package/dist/components/forms/drop-zone.js +184 -0
  47. package/{src/components/forms/index.ts → dist/components/forms/index.d.ts} +3 -9
  48. package/dist/components/forms/index.js +17 -0
  49. package/dist/components/forms/input.d.ts +3 -0
  50. package/dist/components/forms/input.js +15 -0
  51. package/dist/components/forms/label.d.ts +3 -0
  52. package/dist/components/forms/label.js +14 -0
  53. package/dist/components/forms/passkey-management.d.ts +14 -0
  54. package/dist/components/forms/passkey-management.js +132 -0
  55. package/dist/components/forms/radio-group.d.ts +6 -0
  56. package/dist/components/forms/radio-group.js +28 -0
  57. package/dist/components/forms/select.d.ts +18 -0
  58. package/dist/components/forms/select.js +103 -0
  59. package/dist/components/forms/slider.d.ts +9 -0
  60. package/dist/components/forms/slider.js +25 -0
  61. package/dist/components/forms/stepper.d.ts +15 -0
  62. package/dist/components/forms/stepper.js +41 -0
  63. package/dist/components/forms/switch.d.ts +6 -0
  64. package/dist/components/forms/switch.js +21 -0
  65. package/dist/components/forms/text-field.d.ts +15 -0
  66. package/dist/components/forms/text-field.js +46 -0
  67. package/dist/components/forms/text-field.types.d.ts +8 -0
  68. package/dist/components/forms/textarea.d.ts +3 -0
  69. package/dist/components/forms/textarea.js +14 -0
  70. package/dist/components/layout/index.js +5 -0
  71. package/dist/components/layout/particle-background.d.ts +19 -0
  72. package/dist/components/layout/particle-background.js +171 -0
  73. package/dist/components/layout/scroll-area.d.ts +9 -0
  74. package/dist/components/layout/scroll-area.js +35 -0
  75. package/dist/components/layout/section-intro.d.ts +12 -0
  76. package/dist/components/layout/section-intro.js +28 -0
  77. package/dist/components/layout/surface-panel.d.ts +7 -0
  78. package/dist/components/layout/surface-panel.js +11 -0
  79. package/dist/components/navigation/app-navigation.d.ts +67 -0
  80. package/dist/components/navigation/app-navigation.js +106 -0
  81. package/{src/components/navigation/index.ts → dist/components/navigation/index.d.ts} +1 -7
  82. package/dist/components/navigation/index.js +4 -0
  83. package/dist/components/navigation/pagination-controls.d.ts +7 -0
  84. package/dist/components/navigation/pagination-controls.js +50 -0
  85. package/dist/components/navigation/tabs.d.ts +7 -0
  86. package/dist/components/navigation/tabs.js +35 -0
  87. package/dist/components/overlays/bottom-sheet.d.ts +20 -0
  88. package/dist/components/overlays/bottom-sheet.js +101 -0
  89. package/dist/components/overlays/command.d.ts +29 -0
  90. package/dist/components/overlays/command.js +123 -0
  91. package/dist/components/overlays/dialog.d.ts +30 -0
  92. package/dist/components/overlays/dialog.js +105 -0
  93. package/dist/components/overlays/dropdown-menu.d.ts +29 -0
  94. package/dist/components/overlays/dropdown-menu.js +128 -0
  95. package/dist/components/overlays/index.d.ts +7 -0
  96. package/dist/components/overlays/index.js +8 -0
  97. package/dist/components/overlays/popover.d.ts +14 -0
  98. package/dist/components/overlays/popover.js +56 -0
  99. package/dist/components/overlays/sheet.d.ts +27 -0
  100. package/dist/components/overlays/sheet.js +81 -0
  101. package/dist/components/overlays/tooltip.d.ts +10 -0
  102. package/dist/components/overlays/tooltip.js +23 -0
  103. package/dist/components/primitives/avatar.d.ts +14 -0
  104. package/dist/components/primitives/avatar.js +72 -0
  105. package/dist/components/primitives/badge.d.ts +7 -0
  106. package/dist/components/primitives/badge.js +27 -0
  107. package/dist/components/primitives/button.d.ts +13 -0
  108. package/dist/components/primitives/button.js +113 -0
  109. package/{src/components/primitives/button.types.ts → dist/components/primitives/button.types.d.ts} +4 -6
  110. package/dist/components/primitives/card.d.ts +9 -0
  111. package/dist/components/primitives/card.js +56 -0
  112. package/{src/components/primitives/index.ts → dist/components/primitives/index.d.ts} +1 -9
  113. package/dist/components/primitives/index.js +7 -0
  114. package/dist/components/primitives/segmented-control.d.ts +20 -0
  115. package/dist/components/primitives/segmented-control.js +27 -0
  116. package/dist/components/primitives/separator.d.ts +4 -0
  117. package/dist/components/primitives/separator.js +16 -0
  118. package/dist/constants/chart-colors.d.ts +33 -0
  119. package/dist/constants/chart-colors.js +31 -0
  120. package/dist/hooks/index.js +9 -0
  121. package/{src/hooks/sort.types.ts → dist/hooks/sort.types.d.ts} +2 -4
  122. package/dist/hooks/use-api-client.d.ts +30 -0
  123. package/dist/hooks/use-api-client.js +106 -0
  124. package/dist/hooks/use-debounced-value.d.ts +1 -0
  125. package/dist/hooks/use-debounced-value.js +12 -0
  126. package/dist/hooks/use-derived-filter-state.d.ts +20 -0
  127. package/dist/hooks/use-derived-filter-state.js +39 -0
  128. package/dist/hooks/use-filter-state.d.ts +12 -0
  129. package/dist/hooks/use-filter-state.js +37 -0
  130. package/dist/hooks/use-media-query.d.ts +6 -0
  131. package/dist/hooks/use-media-query.js +27 -0
  132. package/dist/hooks/use-mobile.d.ts +1 -0
  133. package/dist/hooks/use-mobile.js +14 -0
  134. package/dist/hooks/use-sort.d.ts +11 -0
  135. package/dist/hooks/use-sort.js +14 -0
  136. package/{src/index.ts → dist/index.d.ts} +4 -32
  137. package/dist/index.js +15 -0
  138. package/dist/integrations/service-worker.d.ts +2 -0
  139. package/dist/integrations/service-worker.js +2 -0
  140. package/dist/lib/auth.d.ts +2 -0
  141. package/dist/lib/auth.js +7 -0
  142. package/dist/lib/clipboard.d.ts +1 -0
  143. package/dist/lib/clipboard.js +10 -0
  144. package/dist/lib/index.js +4 -0
  145. package/{src/lib/slot.tsx → dist/lib/slot.d.ts} +2 -15
  146. package/dist/lib/slot.js +14 -0
  147. package/dist/lib/utils.d.ts +2 -0
  148. package/dist/lib/utils.js +8 -0
  149. package/dist/native/components.d.ts +41 -0
  150. package/dist/native/components.js +135 -0
  151. package/dist/native/index.js +3 -0
  152. package/dist/native/theme.d.ts +19 -0
  153. package/dist/native/theme.js +58 -0
  154. package/dist/styles/tokens/css-vars.d.ts +7 -0
  155. package/dist/styles/tokens/css-vars.js +5 -0
  156. package/dist/styles/tokens/generated/dark.colors.generated.d.ts +40 -0
  157. package/dist/styles/tokens/generated/dark.colors.generated.js +39 -0
  158. package/dist/styles/tokens/generated/foundations.generated.d.ts +323 -0
  159. package/dist/styles/tokens/generated/foundations.generated.js +453 -0
  160. package/dist/styles/tokens/generated/light.colors.generated.d.ts +40 -0
  161. package/dist/styles/tokens/generated/light.colors.generated.js +39 -0
  162. package/dist/styles/tokens/index.d.ts +317 -0
  163. package/dist/styles/tokens/index.js +14 -0
  164. package/dist/styles.css +1 -1
  165. package/dist/translations/en.d.ts +34 -0
  166. package/dist/translations/index.d.ts +39 -0
  167. package/dist/translations/ui-provider.d.ts +9 -0
  168. package/dist/translations/ui-provider.js +16 -0
  169. package/dist/types/upload.d.ts +36 -0
  170. package/package.json +50 -33
  171. package/src/components/data-display/accordion.stories.tsx +0 -57
  172. package/src/components/data-display/accordion.tsx +0 -86
  173. package/src/components/data-display/metric-card.stories.tsx +0 -48
  174. package/src/components/data-display/metric-card.tsx +0 -20
  175. package/src/components/data-display/sort-controls.stories.tsx +0 -45
  176. package/src/components/data-display/sort-controls.tsx +0 -96
  177. package/src/components/data-display/sort-row.tsx +0 -88
  178. package/src/components/data-display/table.stories.tsx +0 -75
  179. package/src/components/data-display/table.tsx +0 -80
  180. package/src/components/feedback/alert.stories.tsx +0 -51
  181. package/src/components/feedback/alert.tsx +0 -64
  182. package/src/components/feedback/empty-state.tsx +0 -76
  183. package/src/components/feedback/progress.stories.tsx +0 -54
  184. package/src/components/feedback/progress.tsx +0 -41
  185. package/src/components/feedback/skeleton.stories.tsx +0 -36
  186. package/src/components/feedback/skeleton.tsx +0 -7
  187. package/src/components/feedback/spinner.stories.tsx +0 -52
  188. package/src/components/feedback/spinner.tsx +0 -47
  189. package/src/components/feedback/update-guard.stories.tsx +0 -28
  190. package/src/components/feedback/update-guard.tsx +0 -57
  191. package/src/components/filters/active-filters-bar.stories.tsx +0 -114
  192. package/src/components/filters/active-filters-bar.tsx +0 -61
  193. package/src/components/filters/filter-chip.tsx +0 -57
  194. package/src/components/filters/filter-select.stories.tsx +0 -71
  195. package/src/components/filters/filter-select.tsx +0 -68
  196. package/src/components/forms/checkbox.stories.tsx +0 -35
  197. package/src/components/forms/checkbox.tsx +0 -38
  198. package/src/components/forms/date-month-select.stories.tsx +0 -26
  199. package/src/components/forms/date-month-select.tsx +0 -79
  200. package/src/components/forms/date-picker.stories.tsx +0 -188
  201. package/src/components/forms/date-picker.tsx +0 -303
  202. package/src/components/forms/date-utils.ts +0 -37
  203. package/src/components/forms/drop-zone.stories.tsx +0 -140
  204. package/src/components/forms/drop-zone.tsx +0 -298
  205. package/src/components/forms/input.stories.tsx +0 -47
  206. package/src/components/forms/input.tsx +0 -24
  207. package/src/components/forms/label.stories.tsx +0 -16
  208. package/src/components/forms/label.tsx +0 -25
  209. package/src/components/forms/passkey-management.stories.tsx +0 -85
  210. package/src/components/forms/passkey-management.tsx +0 -168
  211. package/src/components/forms/radio-group.stories.tsx +0 -46
  212. package/src/components/forms/radio-group.tsx +0 -44
  213. package/src/components/forms/select.stories.tsx +0 -207
  214. package/src/components/forms/select.tsx +0 -182
  215. package/src/components/forms/slider.stories.tsx +0 -70
  216. package/src/components/forms/slider.tsx +0 -50
  217. package/src/components/forms/stepper.stories.tsx +0 -111
  218. package/src/components/forms/stepper.tsx +0 -66
  219. package/src/components/forms/switch.stories.tsx +0 -144
  220. package/src/components/forms/switch.tsx +0 -39
  221. package/src/components/forms/text-field.stories.tsx +0 -87
  222. package/src/components/forms/text-field.tsx +0 -75
  223. package/src/components/forms/text-field.types.ts +0 -9
  224. package/src/components/forms/textarea.stories.tsx +0 -150
  225. package/src/components/forms/textarea.tsx +0 -22
  226. package/src/components/layout/particle-background.stories.tsx +0 -38
  227. package/src/components/layout/particle-background.tsx +0 -378
  228. package/src/components/layout/scroll-area.stories.tsx +0 -91
  229. package/src/components/layout/scroll-area.tsx +0 -79
  230. package/src/components/layout/section-intro.stories.tsx +0 -29
  231. package/src/components/layout/section-intro.tsx +0 -31
  232. package/src/components/layout/surface-panel.stories.tsx +0 -32
  233. package/src/components/layout/surface-panel.tsx +0 -23
  234. package/src/components/navigation/app-navigation.stories.tsx +0 -217
  235. package/src/components/navigation/app-navigation.tsx +0 -234
  236. package/src/components/navigation/pagination-controls.stories.tsx +0 -41
  237. package/src/components/navigation/pagination-controls.tsx +0 -46
  238. package/src/components/navigation/tabs.stories.tsx +0 -48
  239. package/src/components/navigation/tabs.tsx +0 -52
  240. package/src/components/overlays/bottom-sheet.stories.tsx +0 -52
  241. package/src/components/overlays/bottom-sheet.tsx +0 -179
  242. package/src/components/overlays/command.stories.tsx +0 -65
  243. package/src/components/overlays/command.tsx +0 -227
  244. package/src/components/overlays/dialog.stories.tsx +0 -148
  245. package/src/components/overlays/dialog.tsx +0 -203
  246. package/src/components/overlays/dropdown-menu.stories.tsx +0 -74
  247. package/src/components/overlays/dropdown-menu.tsx +0 -236
  248. package/src/components/overlays/index.ts +0 -56
  249. package/src/components/overlays/popover.stories.tsx +0 -51
  250. package/src/components/overlays/popover.tsx +0 -78
  251. package/src/components/overlays/sheet.stories.tsx +0 -68
  252. package/src/components/overlays/sheet.tsx +0 -155
  253. package/src/components/overlays/tooltip.stories.tsx +0 -29
  254. package/src/components/overlays/tooltip.tsx +0 -41
  255. package/src/components/primitives/avatar-placeholder.svg +0 -13
  256. package/src/components/primitives/avatar.stories.tsx +0 -72
  257. package/src/components/primitives/avatar.tsx +0 -136
  258. package/src/components/primitives/badge.stories.tsx +0 -43
  259. package/src/components/primitives/badge.tsx +0 -43
  260. package/src/components/primitives/button.stories.tsx +0 -113
  261. package/src/components/primitives/button.tsx +0 -131
  262. package/src/components/primitives/card.stories.tsx +0 -59
  263. package/src/components/primitives/card.tsx +0 -66
  264. package/src/components/primitives/segmented-control.stories.tsx +0 -54
  265. package/src/components/primitives/segmented-control.tsx +0 -73
  266. package/src/components/primitives/separator.stories.tsx +0 -34
  267. package/src/components/primitives/separator.tsx +0 -27
  268. package/src/constants/chart-colors.ts +0 -39
  269. package/src/env.d.ts +0 -9
  270. package/src/hooks/use-api-client.ts +0 -122
  271. package/src/hooks/use-debounced-value.ts +0 -12
  272. package/src/hooks/use-derived-filter-state.ts +0 -70
  273. package/src/hooks/use-filter-state.ts +0 -66
  274. package/src/hooks/use-media-query.ts +0 -69
  275. package/src/hooks/use-mobile.tsx +0 -19
  276. package/src/hooks/use-sort.ts +0 -20
  277. package/src/lib/auth.ts +0 -5
  278. package/src/lib/clipboard.ts +0 -8
  279. package/src/lib/utils.ts +0 -6
  280. package/src/native/components.tsx +0 -198
  281. package/src/native/theme.tsx +0 -69
  282. package/src/storybook/controls.ts +0 -117
  283. package/src/storybook/options.ts +0 -52
  284. package/src/styles/build.ts +0 -1
  285. package/src/styles/index.css +0 -423
  286. package/src/styles/nokia.css +0 -36
  287. package/src/styles/package.css +0 -3
  288. package/src/styles/tokens/chart-colors.stories.tsx +0 -189
  289. package/src/styles/tokens/color-systems.stories.tsx +0 -190
  290. package/src/styles/tokens/css-vars.ts +0 -15
  291. package/src/styles/tokens/generated/dark-class.css +0 -39
  292. package/src/styles/tokens/generated/dark.colors.generated.ts +0 -39
  293. package/src/styles/tokens/generated/dark.css +0 -39
  294. package/src/styles/tokens/generated/foundations.css +0 -149
  295. package/src/styles/tokens/generated/foundations.generated.ts +0 -454
  296. package/src/styles/tokens/generated/light.colors.generated.ts +0 -39
  297. package/src/styles/tokens/generated/light.css +0 -39
  298. package/src/styles/tokens/index.ts +0 -70
  299. package/src/styles/tokens/layout.stories.tsx +0 -50
  300. package/src/styles/tokens/scripts/check-foundations.mjs +0 -126
  301. package/src/styles/tokens/scripts/check-source.mjs +0 -53
  302. package/src/styles/tokens/source/dark.tokens.json +0 -138
  303. package/src/styles/tokens/source/foundations.tokens.json +0 -344
  304. package/src/styles/tokens/source/light.tokens.json +0 -138
  305. package/src/styles/tokens/style-dictionary.dark-class.json +0 -16
  306. package/src/styles/tokens/style-dictionary.dark-storybook.json +0 -16
  307. package/src/styles/tokens/style-dictionary.dark.json +0 -21
  308. package/src/styles/tokens/style-dictionary.foundations.json +0 -21
  309. package/src/styles/tokens/style-dictionary.light-storybook.json +0 -16
  310. package/src/styles/tokens/style-dictionary.light.json +0 -21
  311. package/src/styles/tokens/typography.stories.tsx +0 -157
  312. package/src/translations/en.ts +0 -34
  313. package/src/translations/index.ts +0 -32
  314. package/src/types/upload.ts +0 -42
  315. /package/{src/components/filters/index.ts → dist/components/filters/index.d.ts} +0 -0
  316. /package/{src/components/layout/index.ts → dist/components/layout/index.d.ts} +0 -0
  317. /package/{src/hooks/index.ts → dist/hooks/index.d.ts} +0 -0
  318. /package/{src/lib/index.ts → dist/lib/index.d.ts} +0 -0
  319. /package/{src/native/index.ts → dist/native/index.d.ts} +0 -0
@@ -1,46 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react-vite";
2
-
3
- import { RadioGroup, RadioGroupItem } from "./radio-group";
4
-
5
- const meta: Meta<typeof RadioGroup> = {
6
- title: "Forms/RadioGroup",
7
- component: RadioGroup,
8
- tags: ["autodocs"],
9
- };
10
-
11
- export default meta;
12
- type Story = StoryObj<typeof meta>;
13
-
14
- const options = [
15
- { value: "default", label: "Default" },
16
- { value: "comfortable", label: "Comfortable" },
17
- { value: "compact", label: "Compact" },
18
- ];
19
-
20
- export const Default: Story = {
21
- render: () => (
22
- <RadioGroup defaultValue="default" className="gap-3">
23
- {options.map(({ value, label }) => (
24
- <div key={value} className="flex items-center gap-3">
25
- <RadioGroupItem value={value} id={`opt-${value}`} />
26
- <label htmlFor={`opt-${value}`} className="cursor-pointer">
27
- {label}
28
- </label>
29
- </div>
30
- ))}
31
- </RadioGroup>
32
- ),
33
- };
34
-
35
- export const Disabled: Story = {
36
- render: () => (
37
- <RadioGroup defaultValue="default" disabled className="gap-3">
38
- {options.map(({ value, label }) => (
39
- <div key={value} className="flex items-center gap-3">
40
- <RadioGroupItem value={value} id={`dis-${value}`} />
41
- <label htmlFor={`dis-${value}`}>{label}</label>
42
- </div>
43
- ))}
44
- </RadioGroup>
45
- ),
46
- };
@@ -1,44 +0,0 @@
1
- "use client";
2
-
3
- import { Radio as RadioPrimitive } from "@base-ui/react/radio";
4
- import { RadioGroup as RadioGroupPrimitive } from "@base-ui/react/radio-group";
5
- import { Circle } from "lucide-react";
6
- import * as React from "react";
7
-
8
- import { cn } from "../../lib/utils";
9
-
10
- const RadioGroup = React.forwardRef<
11
- React.ComponentRef<typeof RadioGroupPrimitive>,
12
- React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive>
13
- >(({ className, ...props }, ref) => {
14
- return <RadioGroupPrimitive className={cn("grid gap-2", className)} {...props} ref={ref} />;
15
- });
16
- RadioGroup.displayName = "RadioGroup";
17
-
18
- const RadioGroupItem = React.forwardRef<
19
- React.ComponentRef<typeof RadioPrimitive.Root>,
20
- React.ComponentPropsWithoutRef<typeof RadioPrimitive.Root>
21
- >(({ className, ...props }, ref) => {
22
- return (
23
- <RadioPrimitive.Root
24
- ref={ref}
25
- className={cn(
26
- "border-ring bg-background flex aspect-square size-6 items-center justify-center rounded-full border",
27
- "focus-visible:border-ring focus-visible:bg-muted/25 focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none",
28
- "disabled:cursor-not-allowed disabled:opacity-50",
29
- className,
30
- )}
31
- {...props}
32
- >
33
- <RadioPrimitive.Indicator
34
- keepMounted
35
- className="data-unchecked:opacity-0 data-checked:opacity-100 data-starting-style:animate-fade-in data-ending-style:animate-fade-out"
36
- >
37
- <Circle className="fill-ring size-5" />
38
- </RadioPrimitive.Indicator>
39
- </RadioPrimitive.Root>
40
- );
41
- });
42
- RadioGroupItem.displayName = "Radio";
43
-
44
- export { RadioGroup, RadioGroupItem };
@@ -1,207 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react-vite";
2
- import * as React from "react";
3
- import { expect, userEvent, within } from "storybook/test";
4
-
5
- import {
6
- Select,
7
- SelectContent,
8
- SelectGroup,
9
- SelectItem,
10
- SelectLabel,
11
- SelectTrigger,
12
- SelectValue,
13
- } from "./select";
14
-
15
- const meta = {
16
- title: "Forms/Select",
17
- component: Select,
18
- tags: ["autodocs"],
19
- } satisfies Meta<typeof Select>;
20
-
21
- export default meta;
22
- type Story = StoryObj<typeof meta>;
23
-
24
- export const Default: Story = {
25
- render: () => (
26
- <Select>
27
- <SelectTrigger className="w-[180px]" aria-label="Select a fruit">
28
- <SelectValue placeholder="Select a fruit" />
29
- </SelectTrigger>
30
- <SelectContent>
31
- <SelectItem value="apple">Apple</SelectItem>
32
- <SelectItem value="banana">Banana</SelectItem>
33
- <SelectItem value="blueberry">Blueberry</SelectItem>
34
- <SelectItem value="grapes">Grapes</SelectItem>
35
- <SelectItem value="pineapple">Pineapple</SelectItem>
36
- </SelectContent>
37
- </Select>
38
- ),
39
- };
40
-
41
- export const SelectedValue: Story = {
42
- render: () => (
43
- <Select defaultValue="banana">
44
- <SelectTrigger className="w-[180px]" aria-label="Selected fruit">
45
- <SelectValue placeholder="Select a fruit" />
46
- </SelectTrigger>
47
- <SelectContent>
48
- <SelectItem value="apple">Apple</SelectItem>
49
- <SelectItem value="banana">Banana</SelectItem>
50
- </SelectContent>
51
- </Select>
52
- ),
53
- play: async ({ canvasElement }) => {
54
- await expect(
55
- within(canvasElement).getByRole("combobox", { name: "Selected fruit" }),
56
- ).toHaveTextContent("Banana");
57
- },
58
- };
59
-
60
- export const ExplicitItems: Story = {
61
- render: () => (
62
- <Select
63
- defaultValue="us"
64
- items={[
65
- { value: "us", label: "United States" },
66
- { value: "ca", label: "Canada" },
67
- ]}
68
- >
69
- <SelectTrigger aria-label="Country">
70
- <SelectValue placeholder="Select a country" />
71
- </SelectTrigger>
72
- <SelectContent>
73
- <SelectItem value="us">US</SelectItem>
74
- <SelectItem value="ca">CA</SelectItem>
75
- </SelectContent>
76
- </Select>
77
- ),
78
- play: async ({ canvasElement }) => {
79
- await expect(
80
- within(canvasElement).getByRole("combobox", { name: "Country" }),
81
- ).toHaveTextContent("United States");
82
- },
83
- };
84
-
85
- export const NullItem: Story = {
86
- render: () => (
87
- <Select defaultValue={null} items={[{ value: null, label: "All options" }]}>
88
- <SelectTrigger aria-label="Filter">
89
- <SelectValue placeholder="Choose a filter" />
90
- </SelectTrigger>
91
- <SelectContent>
92
- <SelectItem>All options</SelectItem>
93
- <SelectItem value="active">Active</SelectItem>
94
- </SelectContent>
95
- </Select>
96
- ),
97
- play: async ({ canvasElement }) => {
98
- await expect(within(canvasElement).getByRole("combobox", { name: "Filter" })).toHaveTextContent(
99
- "All options",
100
- );
101
- },
102
- };
103
-
104
- function ControlledNullSelection() {
105
- const [value, setValue] = React.useState<string | null>("active");
106
- const [lastChange, setLastChange] = React.useState<string | null>("active");
107
-
108
- return (
109
- <div>
110
- <Select
111
- value={value}
112
- onValueChange={(nextValue) => {
113
- setValue(nextValue);
114
- setLastChange(nextValue);
115
- }}
116
- items={[
117
- { value: null, label: "All options" },
118
- { value: "active", label: "Active" },
119
- ]}
120
- >
121
- <SelectTrigger aria-label="Controlled filter">
122
- <SelectValue placeholder="Choose a filter" />
123
- </SelectTrigger>
124
- <SelectContent>
125
- <SelectItem>All options</SelectItem>
126
- <SelectItem value="active">Active</SelectItem>
127
- </SelectContent>
128
- </Select>
129
- <output aria-label="Last selected value">{lastChange ?? "null"}</output>
130
- </div>
131
- );
132
- }
133
-
134
- export const ControlledNullChange: Story = {
135
- render: () => <ControlledNullSelection />,
136
- parameters: { a11y: { test: "off" } },
137
- play: async ({ canvasElement }) => {
138
- const canvas = within(canvasElement);
139
- const trigger = canvas.getByRole("combobox", { name: "Controlled filter" });
140
-
141
- await userEvent.click(trigger);
142
- await userEvent.click(
143
- await within(document.body).findByRole("option", { name: "All options" }),
144
- );
145
- await expect(trigger).toHaveTextContent("All options");
146
- await expect(canvas.getByRole("status", { name: "Last selected value" })).toHaveTextContent(
147
- "null",
148
- );
149
- await userEvent.keyboard("{Escape}");
150
- },
151
- };
152
-
153
- export const WithGroups: Story = {
154
- render: () => (
155
- <Select>
156
- <SelectTrigger className="w-[200px]" aria-label="Select timezone">
157
- <SelectValue placeholder="Select timezone" />
158
- </SelectTrigger>
159
- <SelectContent>
160
- <SelectGroup>
161
- <SelectLabel>North America</SelectLabel>
162
- <SelectItem value="est">Eastern Standard Time (EST)</SelectItem>
163
- <SelectItem value="cst">Central Standard Time (CST)</SelectItem>
164
- <SelectItem value="pst">Pacific Standard Time (PST)</SelectItem>
165
- </SelectGroup>
166
- <SelectGroup>
167
- <SelectLabel>Europe</SelectLabel>
168
- <SelectItem value="gmt">Greenwich Mean Time (GMT)</SelectItem>
169
- <SelectItem value="cet">Central European Time (CET)</SelectItem>
170
- </SelectGroup>
171
- </SelectContent>
172
- </Select>
173
- ),
174
- };
175
-
176
- export const Disabled: Story = {
177
- render: () => (
178
- <Select disabled>
179
- <SelectTrigger className="w-[180px]" aria-label="Select a fruit">
180
- <SelectValue placeholder="Select a fruit" />
181
- </SelectTrigger>
182
- <SelectContent>
183
- <SelectItem value="apple">Apple</SelectItem>
184
- </SelectContent>
185
- </Select>
186
- ),
187
- play: async ({ canvasElement }) => {
188
- await expect(
189
- within(canvasElement).getByRole("combobox", { name: "Select a fruit" }),
190
- ).toBeDisabled();
191
- },
192
- };
193
-
194
- export const Small: Story = {
195
- render: () => (
196
- <Select>
197
- <SelectTrigger size="sm" className="w-[160px]" aria-label="Select an option">
198
- <SelectValue placeholder="Select" />
199
- </SelectTrigger>
200
- <SelectContent>
201
- <SelectItem value="1">Option 1</SelectItem>
202
- <SelectItem value="2">Option 2</SelectItem>
203
- <SelectItem value="3">Option 3</SelectItem>
204
- </SelectContent>
205
- </Select>
206
- ),
207
- };
@@ -1,182 +0,0 @@
1
- import { Select as SelectPrimitive } from "@base-ui/react/select";
2
- import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
3
- import * as React from "react";
4
-
5
- import { cn } from "../../lib/utils";
6
-
7
- type SelectProps = Omit<
8
- React.ComponentProps<typeof SelectPrimitive.Root<string>>,
9
- "value" | "defaultValue"
10
- > & {
11
- value?: string | null;
12
- defaultValue?: string | null;
13
- };
14
-
15
- function Select({ children, items, ...props }: SelectProps) {
16
- const resolvedItems = items ?? getItemsFromChildren(children);
17
-
18
- return (
19
- <SelectPrimitive.Root data-slot="select" items={resolvedItems} {...props}>
20
- {children}
21
- </SelectPrimitive.Root>
22
- );
23
- }
24
-
25
- function SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {
26
- return <SelectPrimitive.Group data-slot="select-group" {...props} />;
27
- }
28
-
29
- function SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {
30
- return <SelectPrimitive.Value data-slot="select-value" {...props} />;
31
- }
32
-
33
- function SelectTrigger({
34
- className,
35
- size = "default",
36
- children,
37
- ...props
38
- }: React.ComponentProps<typeof SelectPrimitive.Trigger> & { size?: "sm" | "default" }) {
39
- return (
40
- <SelectPrimitive.Trigger
41
- data-slot="select-trigger"
42
- data-size={size}
43
- className={cn(
44
- "border-input flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap transition-[color,box-shadow] outline-none",
45
- "data-placeholder:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground",
46
- "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] focus-visible:ring-inset",
47
- "aria-invalid:ring-destructive/20 aria-invalid:border-destructive",
48
- "disabled:cursor-not-allowed disabled:opacity-50",
49
- "data-[size=default]:h-9 data-[size=sm]:h-8",
50
- "*:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2",
51
- "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
52
- className,
53
- )}
54
- {...props}
55
- >
56
- {children}
57
- <SelectPrimitive.Icon>
58
- <ChevronDownIcon className="size-4 opacity-50" />
59
- </SelectPrimitive.Icon>
60
- </SelectPrimitive.Trigger>
61
- );
62
- }
63
-
64
- function SelectContent({
65
- className,
66
- children,
67
- position: _position = "popper",
68
- ...props
69
- }: React.ComponentProps<typeof SelectPrimitive.Popup> & {
70
- position?: "item-aligned" | "popper";
71
- }) {
72
- return (
73
- <SelectPrimitive.Portal>
74
- <SelectPrimitive.Backdrop className="ui-mobile-sheet-backdrop" />
75
- <SelectPrimitive.Positioner
76
- className="ui-mobile-sheet-positioner"
77
- alignItemWithTrigger={_position === "item-aligned"}
78
- sideOffset={4}
79
- >
80
- <SelectPrimitive.Popup
81
- data-slot="select-content"
82
- className={cn(
83
- "bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:zoom-out-95 data-open:zoom-in-95 relative z-50 max-h-(--available-height) min-w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 outline-none ui-mobile-sheet-popup",
84
- className,
85
- )}
86
- {...props}
87
- >
88
- <SelectScrollUpButton />
89
- <SelectPrimitive.List>{children}</SelectPrimitive.List>
90
- <SelectScrollDownButton />
91
- </SelectPrimitive.Popup>
92
- </SelectPrimitive.Positioner>
93
- </SelectPrimitive.Portal>
94
- );
95
- }
96
-
97
- function SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {
98
- return (
99
- <SelectPrimitive.Label
100
- data-slot="select-label"
101
- className={cn("text-muted-foreground px-2 py-1.5 text-xs", className)}
102
- {...props}
103
- />
104
- );
105
- }
106
-
107
- function SelectItem({
108
- className,
109
- children,
110
- ...props
111
- }: React.ComponentProps<typeof SelectPrimitive.Item>) {
112
- return (
113
- <SelectPrimitive.Item
114
- data-slot="select-item"
115
- className={cn(
116
- "data-highlighted:bg-muted data-highlighted:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-md py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50",
117
- className,
118
- )}
119
- {...props}
120
- >
121
- <span className="absolute right-2 flex size-3.5 items-center justify-center">
122
- <SelectPrimitive.ItemIndicator>
123
- <CheckIcon className="size-4" />
124
- </SelectPrimitive.ItemIndicator>
125
- </span>
126
- <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
127
- </SelectPrimitive.Item>
128
- );
129
- }
130
-
131
- function getItemsFromChildren(children: React.ReactNode): Record<string, React.ReactNode> {
132
- const items: Record<string, React.ReactNode> = {};
133
-
134
- React.Children.forEach(children, (child) => {
135
- if (!React.isValidElement(child)) return;
136
-
137
- const element = child as React.ReactElement<{
138
- children?: React.ReactNode;
139
- value?: unknown;
140
- }>;
141
-
142
- if (element.type === SelectItem) {
143
- const value = element.props.value;
144
- if (typeof value === "string") {
145
- items[value] = element.props.children;
146
- }
147
- return;
148
- }
149
-
150
- if (element.props.children) {
151
- Object.assign(items, getItemsFromChildren(element.props.children));
152
- }
153
- });
154
-
155
- return items;
156
- }
157
-
158
- function SelectScrollUpButton({ className, ...props }: React.ComponentProps<"div">) {
159
- return (
160
- <SelectPrimitive.ScrollUpArrow
161
- data-slot="select-scroll-up-button"
162
- className={cn("flex cursor-default items-center justify-center py-1", className)}
163
- {...props}
164
- >
165
- <ChevronUpIcon className="size-4" />
166
- </SelectPrimitive.ScrollUpArrow>
167
- );
168
- }
169
-
170
- function SelectScrollDownButton({ className, ...props }: React.ComponentProps<"div">) {
171
- return (
172
- <SelectPrimitive.ScrollDownArrow
173
- data-slot="select-scroll-down-button"
174
- className={cn("flex cursor-default items-center justify-center py-1", className)}
175
- {...props}
176
- >
177
- <ChevronDownIcon className="size-4" />
178
- </SelectPrimitive.ScrollDownArrow>
179
- );
180
- }
181
-
182
- export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue };
@@ -1,70 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react-vite";
2
- import * as React from "react";
3
-
4
- import { Slider } from "./slider";
5
-
6
- const meta: Meta<typeof Slider> = {
7
- title: "Forms/Slider",
8
- component: Slider,
9
- tags: ["autodocs"],
10
- decorators: [
11
- (Story) => (
12
- <div className="w-80 px-1">
13
- <Story />
14
- </div>
15
- ),
16
- ],
17
- argTypes: {
18
- disabled: { control: "boolean" },
19
- min: { control: "number" },
20
- max: { control: "number" },
21
- step: { control: "number" },
22
- },
23
- };
24
-
25
- export default meta;
26
- type Story = StoryObj<typeof meta>;
27
-
28
- export const Default: Story = {
29
- args: {
30
- defaultValue: [50],
31
- min: 0,
32
- max: 100,
33
- "aria-label": "Volume",
34
- },
35
- };
36
-
37
- export const WithStep: Story = {
38
- args: {
39
- defaultValue: [0],
40
- min: 0,
41
- max: 100,
42
- step: 10,
43
- "aria-label": "Volume",
44
- },
45
- };
46
-
47
- export const Controlled: Story = {
48
- render: () => {
49
- const [value, setValue] = React.useState([33]);
50
- return (
51
- <div className="w-80 space-y-4 px-1">
52
- <Slider aria-label="Volume" value={value} onValueChange={setValue} min={0} max={100} />
53
- <div className="flex justify-between text-sm">
54
- <span className="text-muted-foreground">Volume</span>
55
- <span className="font-medium tabular-nums">{value[0]}%</span>
56
- </div>
57
- </div>
58
- );
59
- },
60
- };
61
-
62
- export const Disabled: Story = {
63
- args: {
64
- value: [40],
65
- disabled: true,
66
- min: 0,
67
- max: 100,
68
- "aria-label": "Volume",
69
- },
70
- };
@@ -1,50 +0,0 @@
1
- "use client";
2
-
3
- import { Slider as SliderPrimitive } from "@base-ui/react/slider";
4
- import * as React from "react";
5
-
6
- import { cn } from "../../lib/utils";
7
-
8
- type SliderProps = Omit<
9
- React.ComponentProps<typeof SliderPrimitive.Root>,
10
- "onValueChange" | "value" | "defaultValue"
11
- > & {
12
- value?: number[];
13
- defaultValue?: number[];
14
- onValueChange?: (value: number[]) => void;
15
- };
16
-
17
- const Slider = React.forwardRef<HTMLDivElement, SliderProps>(
18
- (
19
- {
20
- className,
21
- onValueChange,
22
- "aria-label": ariaLabel,
23
- "aria-labelledby": ariaLabelledby,
24
- ...props
25
- },
26
- ref,
27
- ) => (
28
- <SliderPrimitive.Root
29
- ref={ref}
30
- {...props}
31
- onValueChange={(value) => onValueChange?.(Array.isArray(value) ? [...value] : [value])}
32
- >
33
- <SliderPrimitive.Control
34
- className={cn("relative flex w-full touch-none items-center py-2 select-none", className)}
35
- >
36
- <SliderPrimitive.Track className="bg-muted relative h-2 w-full grow rounded-full">
37
- <SliderPrimitive.Indicator className="bg-primary absolute h-full rounded-full" />
38
- <SliderPrimitive.Thumb
39
- aria-label={ariaLabel ?? "Slider"}
40
- aria-labelledby={ariaLabelledby}
41
- className="border-border focus-visible:border-ring focus-visible:bg-primary focus-visible:ring-ring bg-background z-10 block h-6 w-6 rounded-full border shadow-sm ring-1 ring-border/5 transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50"
42
- />
43
- </SliderPrimitive.Track>
44
- </SliderPrimitive.Control>
45
- </SliderPrimitive.Root>
46
- ),
47
- );
48
- Slider.displayName = "Slider";
49
-
50
- export { Slider };