@codefast/ui 0.3.16-canary.2 → 0.4.0-canary.4

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 (289) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README.md +28 -17
  3. package/dist/components/accordion.d.mts +7 -22
  4. package/dist/components/accordion.mjs +26 -29
  5. package/dist/components/alert-dialog.d.mts +27 -26
  6. package/dist/components/alert-dialog.mjs +53 -45
  7. package/dist/components/alert.d.mts +14 -14
  8. package/dist/components/alert.mjs +17 -28
  9. package/dist/components/aspect-ratio.d.mts +2 -2
  10. package/dist/components/aspect-ratio.mjs +2 -3
  11. package/dist/components/avatar.d.mts +41 -5
  12. package/dist/components/avatar.mjs +40 -10
  13. package/dist/components/badge.d.mts +3 -15
  14. package/dist/components/badge.mjs +6 -48
  15. package/dist/components/breadcrumb.d.mts +1 -0
  16. package/dist/components/breadcrumb.mjs +11 -10
  17. package/dist/components/button-group.d.mts +3 -13
  18. package/dist/components/button-group.mjs +9 -31
  19. package/dist/components/button.d.mts +3 -26
  20. package/dist/components/button.mjs +9 -79
  21. package/dist/components/calendar.d.mts +6 -2
  22. package/dist/components/calendar.mjs +41 -44
  23. package/dist/components/card.d.mts +4 -2
  24. package/dist/components/card.mjs +9 -9
  25. package/dist/components/carousel.d.mts +16 -5
  26. package/dist/components/carousel.mjs +24 -11
  27. package/dist/components/chart.d.mts +9 -6
  28. package/dist/components/chart.mjs +21 -15
  29. package/dist/components/checkbox-cards.mjs +4 -4
  30. package/dist/components/checkbox-group.mjs +3 -4
  31. package/dist/components/checkbox.d.mts +2 -2
  32. package/dist/components/checkbox.mjs +6 -7
  33. package/dist/components/collapsible.d.mts +4 -4
  34. package/dist/components/collapsible.mjs +4 -5
  35. package/dist/components/command.d.mts +11 -1
  36. package/dist/components/command.mjs +35 -32
  37. package/dist/components/context-menu.d.mts +22 -15
  38. package/dist/components/context-menu.mjs +44 -39
  39. package/dist/components/dialog.d.mts +19 -23
  40. package/dist/components/dialog.mjs +48 -47
  41. package/dist/components/direction.d.mts +24 -0
  42. package/dist/components/direction.mjs +18 -0
  43. package/dist/components/drawer.d.mts +3 -21
  44. package/dist/components/drawer.mjs +19 -27
  45. package/dist/components/dropdown-menu.d.mts +22 -15
  46. package/dist/components/dropdown-menu.mjs +41 -37
  47. package/dist/components/empty.d.mts +3 -13
  48. package/dist/components/empty.mjs +8 -23
  49. package/dist/components/field.d.mts +3 -14
  50. package/dist/components/field.mjs +14 -44
  51. package/dist/components/form.d.mts +7 -10
  52. package/dist/components/form.mjs +6 -7
  53. package/dist/components/hover-card.d.mts +5 -5
  54. package/dist/components/hover-card.mjs +14 -12
  55. package/dist/components/input-group.d.mts +4 -31
  56. package/dist/components/input-group.mjs +14 -96
  57. package/dist/components/input-number.d.mts +3 -1
  58. package/dist/components/input-number.mjs +50 -28
  59. package/dist/components/input-otp.mjs +9 -7
  60. package/dist/components/input-password.mjs +1 -4
  61. package/dist/components/input-search.mjs +3 -5
  62. package/dist/components/input.mjs +1 -2
  63. package/dist/components/item.d.mts +4 -29
  64. package/dist/components/item.mjs +12 -65
  65. package/dist/components/kbd.mjs +1 -1
  66. package/dist/components/label.d.mts +2 -2
  67. package/dist/components/label.mjs +3 -4
  68. package/dist/components/menubar.d.mts +22 -16
  69. package/dist/components/menubar.mjs +54 -47
  70. package/dist/components/native-select.d.mts +5 -1
  71. package/dist/components/native-select.mjs +9 -6
  72. package/dist/components/navigation-menu.d.mts +30 -13
  73. package/dist/components/navigation-menu.mjs +35 -32
  74. package/dist/components/pagination.d.mts +7 -1
  75. package/dist/components/pagination.mjs +27 -12
  76. package/dist/components/popover.d.mts +40 -7
  77. package/dist/components/popover.mjs +46 -14
  78. package/dist/components/progress-circle.d.mts +3 -47
  79. package/dist/components/progress-circle.mjs +2 -48
  80. package/dist/components/progress.d.mts +2 -2
  81. package/dist/components/progress.mjs +5 -6
  82. package/dist/components/radio-cards.d.mts +3 -3
  83. package/dist/components/radio-cards.mjs +11 -11
  84. package/dist/components/radio-group.d.mts +3 -3
  85. package/dist/components/radio-group.mjs +9 -9
  86. package/dist/components/radio.mjs +2 -3
  87. package/dist/components/resizable.mjs +3 -8
  88. package/dist/components/scroll-area.d.mts +8 -24
  89. package/dist/components/scroll-area.mjs +16 -70
  90. package/dist/components/select.d.mts +14 -14
  91. package/dist/components/select.mjs +47 -47
  92. package/dist/components/separator.d.mts +4 -19
  93. package/dist/components/separator.mjs +6 -27
  94. package/dist/components/sheet.d.mts +18 -31
  95. package/dist/components/sheet.mjs +46 -87
  96. package/dist/components/sidebar.d.mts +3 -19
  97. package/dist/components/sidebar.mjs +48 -84
  98. package/dist/components/skeleton.mjs +1 -1
  99. package/dist/components/slider.d.mts +2 -2
  100. package/dist/components/slider.mjs +9 -11
  101. package/dist/components/sonner.mjs +11 -3
  102. package/dist/components/spinner.mjs +6 -7
  103. package/dist/components/switch.d.mts +5 -2
  104. package/dist/components/switch.mjs +7 -7
  105. package/dist/components/table.mjs +10 -10
  106. package/dist/components/tabs.d.mts +8 -5
  107. package/dist/components/tabs.mjs +18 -12
  108. package/dist/components/textarea.mjs +1 -1
  109. package/dist/components/toggle-group.d.mts +11 -7
  110. package/dist/components/toggle-group.mjs +20 -21
  111. package/dist/components/toggle.d.mts +4 -24
  112. package/dist/components/toggle.mjs +6 -45
  113. package/dist/components/tooltip.d.mts +7 -6
  114. package/dist/components/tooltip.mjs +19 -17
  115. package/dist/hooks/use-animated-value.mjs +0 -1
  116. package/dist/hooks/use-copy-to-clipboard.mjs +0 -1
  117. package/dist/hooks/use-is-mobile.mjs +0 -1
  118. package/dist/hooks/use-media-query.mjs +0 -1
  119. package/dist/hooks/use-mutation-observer.mjs +0 -1
  120. package/dist/hooks/use-pagination.mjs +0 -1
  121. package/dist/index.d.mts +38 -21
  122. package/dist/index.mjs +40 -23
  123. package/dist/lib/utils.d.mts +1 -12
  124. package/dist/lib/utils.mjs +1 -9
  125. package/dist/primitives/checkbox-group.d.mts +9 -11
  126. package/dist/primitives/checkbox-group.mjs +14 -19
  127. package/dist/primitives/input-number.d.mts +3 -4
  128. package/dist/primitives/input-number.mjs +3 -5
  129. package/dist/primitives/input.d.mts +4 -5
  130. package/dist/primitives/input.mjs +2 -3
  131. package/dist/primitives/progress-circle.d.mts +3 -4
  132. package/dist/primitives/progress-circle.mjs +2 -3
  133. package/dist/variants/alert.d.mts +18 -0
  134. package/dist/variants/alert.mjs +15 -0
  135. package/dist/variants/badge.d.mts +22 -0
  136. package/dist/variants/badge.mjs +19 -0
  137. package/dist/variants/button-group.d.mts +18 -0
  138. package/dist/variants/button-group.mjs +15 -0
  139. package/dist/variants/button.d.mts +32 -0
  140. package/dist/variants/button.mjs +34 -0
  141. package/dist/variants/empty.d.mts +18 -0
  142. package/dist/variants/empty.mjs +15 -0
  143. package/dist/variants/field.d.mts +19 -0
  144. package/dist/variants/field.mjs +16 -0
  145. package/dist/variants/input-group.d.mts +43 -0
  146. package/dist/variants/input-group.mjs +34 -0
  147. package/dist/variants/input-number.d.mts +45 -0
  148. package/dist/variants/input-number.mjs +40 -0
  149. package/dist/variants/item.d.mts +38 -0
  150. package/dist/variants/item.mjs +38 -0
  151. package/dist/variants/navigation-menu.d.mts +13 -0
  152. package/dist/variants/navigation-menu.mjs +8 -0
  153. package/dist/variants/progress-circle.d.mts +52 -0
  154. package/dist/variants/progress-circle.mjs +45 -0
  155. package/dist/variants/scroll-area.d.mts +24 -0
  156. package/dist/variants/scroll-area.mjs +58 -0
  157. package/dist/variants/separator.d.mts +23 -0
  158. package/dist/variants/separator.mjs +25 -0
  159. package/dist/variants/sheet.d.mts +20 -0
  160. package/dist/variants/sheet.mjs +17 -0
  161. package/dist/variants/sidebar.d.mts +23 -0
  162. package/dist/variants/sidebar.mjs +25 -0
  163. package/dist/variants/tabs.d.mts +18 -0
  164. package/dist/variants/tabs.mjs +15 -0
  165. package/dist/variants/toggle.d.mts +23 -0
  166. package/dist/variants/toggle.mjs +25 -0
  167. package/package.json +186 -55
  168. package/src/components/accordion.tsx +114 -0
  169. package/src/components/alert-dialog.tsx +298 -0
  170. package/src/components/alert.tsx +94 -0
  171. package/src/components/aspect-ratio.tsx +25 -0
  172. package/src/components/avatar.tsx +171 -0
  173. package/src/components/badge.tsx +35 -0
  174. package/src/components/breadcrumb.tsx +191 -0
  175. package/src/components/button-group.tsx +97 -0
  176. package/src/components/button.tsx +55 -0
  177. package/src/components/calendar.tsx +222 -0
  178. package/src/components/card.tsx +169 -0
  179. package/src/components/carousel.tsx +349 -0
  180. package/src/components/chart.tsx +536 -0
  181. package/src/components/checkbox-cards.tsx +72 -0
  182. package/src/components/checkbox-group.tsx +60 -0
  183. package/src/components/checkbox.tsx +44 -0
  184. package/src/components/collapsible.tsx +57 -0
  185. package/src/components/command.tsx +298 -0
  186. package/src/components/context-menu.tsx +410 -0
  187. package/src/components/dialog.tsx +243 -0
  188. package/src/components/direction.tsx +32 -0
  189. package/src/components/drawer.tsx +209 -0
  190. package/src/components/dropdown-menu.tsx +419 -0
  191. package/src/components/empty.tsx +155 -0
  192. package/src/components/field.tsx +329 -0
  193. package/src/components/form.tsx +258 -0
  194. package/src/components/hover-card.tsx +93 -0
  195. package/src/components/input-group.tsx +185 -0
  196. package/src/components/input-number.tsx +141 -0
  197. package/src/components/input-otp.tsx +132 -0
  198. package/src/components/input-password.tsx +50 -0
  199. package/src/components/input-search.tsx +81 -0
  200. package/src/components/input.tsx +36 -0
  201. package/src/components/item.tsx +266 -0
  202. package/src/components/kbd.tsx +47 -0
  203. package/src/components/label.tsx +36 -0
  204. package/src/components/menubar.tsx +440 -0
  205. package/src/components/native-select.tsx +87 -0
  206. package/src/components/navigation-menu.tsx +235 -0
  207. package/src/components/pagination.tsx +198 -0
  208. package/src/components/popover.tsx +170 -0
  209. package/src/components/progress-circle.tsx +185 -0
  210. package/src/components/progress.tsx +41 -0
  211. package/src/components/radio-cards.tsx +66 -0
  212. package/src/components/radio-group.tsx +59 -0
  213. package/src/components/radio.tsx +40 -0
  214. package/src/components/resizable.tsx +78 -0
  215. package/src/components/scroll-area.tsx +95 -0
  216. package/src/components/select.tsx +296 -0
  217. package/src/components/separator.tsx +60 -0
  218. package/src/components/sheet.tsx +241 -0
  219. package/src/components/sidebar.tsx +926 -0
  220. package/src/components/skeleton.tsx +35 -0
  221. package/src/components/slider.tsx +66 -0
  222. package/src/components/sonner.tsx +57 -0
  223. package/src/components/spinner.tsx +66 -0
  224. package/src/components/switch.tsx +44 -0
  225. package/src/components/table.tsx +183 -0
  226. package/src/components/tabs.tsx +110 -0
  227. package/src/components/textarea.tsx +35 -0
  228. package/src/components/toggle-group.tsx +137 -0
  229. package/src/components/toggle.tsx +30 -0
  230. package/src/components/tooltip.tsx +115 -0
  231. package/src/css/foundation/base.css +50 -0
  232. package/src/css/foundation/motion.css +36 -0
  233. package/src/css/foundation/source.css +3 -0
  234. package/src/css/foundation/tokens.css +71 -0
  235. package/src/css/foundation/variants.css +113 -0
  236. package/src/css/preset.css +5 -195
  237. package/src/css/style.css +1 -1
  238. package/src/css/{amber.css → themes/amber.css} +59 -22
  239. package/src/css/{blue.css → themes/blue.css} +59 -22
  240. package/src/css/{cyan.css → themes/cyan.css} +59 -22
  241. package/src/css/{emerald.css → themes/emerald.css} +59 -22
  242. package/src/css/{fuchsia.css → themes/fuchsia.css} +59 -22
  243. package/src/css/{gray.css → themes/gray.css} +59 -22
  244. package/src/css/{green.css → themes/green.css} +59 -22
  245. package/src/css/{indigo.css → themes/indigo.css} +59 -22
  246. package/src/css/{lime.css → themes/lime.css} +59 -22
  247. package/src/css/{neutral.css → themes/neutral.css} +59 -22
  248. package/src/css/{orange.css → themes/orange.css} +59 -22
  249. package/src/css/{pink.css → themes/pink.css} +59 -22
  250. package/src/css/{purple.css → themes/purple.css} +59 -22
  251. package/src/css/{red.css → themes/red.css} +59 -22
  252. package/src/css/{rose.css → themes/rose.css} +59 -22
  253. package/src/css/{sky.css → themes/sky.css} +59 -22
  254. package/src/css/{slate.css → themes/slate.css} +59 -22
  255. package/src/css/{stone.css → themes/stone.css} +59 -22
  256. package/src/css/{teal.css → themes/teal.css} +59 -22
  257. package/src/css/{violet.css → themes/violet.css} +59 -22
  258. package/src/css/{yellow.css → themes/yellow.css} +59 -22
  259. package/src/css/{zinc.css → themes/zinc.css} +59 -22
  260. package/src/hooks/use-animated-value.ts +91 -0
  261. package/src/hooks/use-copy-to-clipboard.ts +58 -0
  262. package/src/hooks/use-is-mobile.ts +25 -0
  263. package/src/hooks/use-media-query.ts +69 -0
  264. package/src/hooks/use-mutation-observer.ts +51 -0
  265. package/src/hooks/use-pagination.ts +164 -0
  266. package/src/index.ts +679 -0
  267. package/src/lib/utils.ts +5 -0
  268. package/src/primitives/checkbox-group.tsx +346 -0
  269. package/src/primitives/input-number.tsx +967 -0
  270. package/src/primitives/input.tsx +227 -0
  271. package/src/primitives/progress-circle.tsx +507 -0
  272. package/src/variants/alert.ts +34 -0
  273. package/src/variants/badge.ts +39 -0
  274. package/src/variants/button-group.ts +36 -0
  275. package/src/variants/button.ts +56 -0
  276. package/src/variants/empty.ts +34 -0
  277. package/src/variants/field.ts +37 -0
  278. package/src/variants/input-group.ts +80 -0
  279. package/src/variants/input-number.ts +65 -0
  280. package/src/variants/item.ts +68 -0
  281. package/src/variants/navigation-menu.ts +25 -0
  282. package/src/variants/progress-circle.ts +46 -0
  283. package/src/variants/scroll-area.ts +73 -0
  284. package/src/variants/separator.ts +40 -0
  285. package/src/variants/sheet.ts +37 -0
  286. package/src/variants/sidebar.ts +41 -0
  287. package/src/variants/tabs.ts +34 -0
  288. package/src/variants/toggle.ts +40 -0
  289. package/dist/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/clsx.d.mts +0 -6
@@ -0,0 +1,35 @@
1
+ import type { ComponentProps, JSX } from "react";
2
+
3
+ import { cn } from "#/lib/utils";
4
+
5
+ /* -----------------------------------------------------------------------------
6
+ * Component: Skeleton
7
+ * -------------------------------------------------------------------------- */
8
+
9
+ /**
10
+ * @since 0.3.16-canary.0
11
+ */
12
+ type SkeletonProps = ComponentProps<"div">;
13
+
14
+ /**
15
+ * @since 0.3.16-canary.0
16
+ */
17
+ function Skeleton({ className, ...props }: SkeletonProps): JSX.Element {
18
+ return (
19
+ <div
20
+ className={cn(
21
+ "animate-shimmer rounded-md bg-linear-to-r from-muted via-white/15 to-muted bg-size-[400%_100%]",
22
+ className,
23
+ )}
24
+ data-slot="skeleton"
25
+ {...props}
26
+ />
27
+ );
28
+ }
29
+
30
+ /* -----------------------------------------------------------------------------
31
+ * Exports
32
+ * -------------------------------------------------------------------------- */
33
+
34
+ export { Skeleton };
35
+ export type { SkeletonProps };
@@ -0,0 +1,66 @@
1
+ import { Slider as SliderPrimitive } from "radix-ui";
2
+ import type { ComponentProps, JSX } from "react";
3
+ import { useMemo } from "react";
4
+
5
+ import { cn } from "#/lib/utils";
6
+
7
+ /* -----------------------------------------------------------------------------
8
+ * Component: Slider
9
+ * -------------------------------------------------------------------------- */
10
+
11
+ /**
12
+ * @since 0.3.16-canary.0
13
+ */
14
+ type SliderProps = ComponentProps<typeof SliderPrimitive.Root>;
15
+
16
+ /**
17
+ * @since 0.3.16-canary.0
18
+ */
19
+ function Slider({ className, defaultValue, max = 100, min = 0, value, ...props }: SliderProps): JSX.Element {
20
+ const _values = useMemo(() => {
21
+ if (Array.isArray(value)) {
22
+ return value;
23
+ }
24
+
25
+ return Array.isArray(defaultValue) ? defaultValue : [min, max];
26
+ }, [value, defaultValue, min, max]);
27
+
28
+ return (
29
+ <SliderPrimitive.Root
30
+ className={cn(
31
+ "relative flex w-full touch-none items-center select-none data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col data-disabled:opacity-50",
32
+ className,
33
+ )}
34
+ data-slot="slider"
35
+ defaultValue={defaultValue}
36
+ max={max}
37
+ min={min}
38
+ value={value}
39
+ {...props}
40
+ >
41
+ <SliderPrimitive.Track
42
+ className="relative grow overflow-hidden rounded-full bg-muted data-horizontal:h-1.5 data-horizontal:w-full data-vertical:h-full data-vertical:w-1.5"
43
+ data-slot="slider-track"
44
+ >
45
+ <SliderPrimitive.Range
46
+ className="absolute bg-primary select-none data-horizontal:h-full data-vertical:w-full"
47
+ data-slot="slider-range"
48
+ />
49
+ </SliderPrimitive.Track>
50
+ {Array.from({ length: _values.length }, (_, index) => (
51
+ <SliderPrimitive.Thumb
52
+ key={index}
53
+ className="block size-4 shrink-0 rounded-full border border-primary bg-white shadow-sm ring-ring/50 transition-[color,box-shadow] select-none hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50"
54
+ data-slot="slider-thumb"
55
+ />
56
+ ))}
57
+ </SliderPrimitive.Root>
58
+ );
59
+ }
60
+
61
+ /* -----------------------------------------------------------------------------
62
+ * Exports
63
+ * -------------------------------------------------------------------------- */
64
+
65
+ export { Slider };
66
+ export type { SliderProps };
@@ -0,0 +1,57 @@
1
+ import { CircleCheckIcon, InfoIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon } from "lucide-react";
2
+ import { useTheme } from "next-themes";
3
+ import type { CSSProperties, JSX } from "react";
4
+ import type { ToasterProps as SonnerToasterProps } from "sonner";
5
+ import { Toaster as Sonner } from "sonner";
6
+
7
+ /* -----------------------------------------------------------------------------
8
+ * Component: Sonner
9
+ * -------------------------------------------------------------------------- */
10
+
11
+ /**
12
+ * @since 0.3.16-canary.0
13
+ */
14
+ type ToasterProps = SonnerToasterProps;
15
+
16
+ /**
17
+ * @since 0.3.16-canary.0
18
+ */
19
+ function Toaster({ ...props }: ToasterProps): JSX.Element {
20
+ const { theme = "system" } = useTheme();
21
+
22
+ return (
23
+ <Sonner
24
+ className="toaster group"
25
+ icons={{
26
+ error: <OctagonXIcon className="size-4" />,
27
+ info: <InfoIcon className="size-4" />,
28
+ loading: <Loader2Icon className="size-4 animate-spin" />,
29
+ success: <CircleCheckIcon className="size-4" />,
30
+ warning: <TriangleAlertIcon className="size-4" />,
31
+ }}
32
+ style={
33
+ {
34
+ "--border-radius": "var(--radius)",
35
+ "--normal-bg": "var(--popover)",
36
+ "--normal-border": "var(--border)",
37
+ "--normal-text": "var(--popover-foreground)",
38
+ } as CSSProperties
39
+ }
40
+ theme={theme as ToasterProps["theme"]}
41
+ toastOptions={{
42
+ classNames: {
43
+ toast: "rounded-2xl",
44
+ },
45
+ }}
46
+ {...props}
47
+ />
48
+ );
49
+ }
50
+
51
+ /* -----------------------------------------------------------------------------
52
+ * Exports
53
+ * -------------------------------------------------------------------------- */
54
+
55
+ export { toast, useSonner } from "sonner";
56
+ export { Toaster };
57
+ export type { ToasterProps };
@@ -0,0 +1,66 @@
1
+ import { VisuallyHidden } from "radix-ui";
2
+ import type { ComponentProps, CSSProperties, ReactNode } from "react";
3
+
4
+ import { cn } from "#/lib/utils";
5
+
6
+ /* -----------------------------------------------------------------------------
7
+ * Component: Spinner
8
+ * -------------------------------------------------------------------------- */
9
+
10
+ const SPINNER_COUNT = 8;
11
+
12
+ /**
13
+ * @since 0.3.16-canary.0
14
+ */
15
+ interface SpinnerProps extends ComponentProps<"span"> {
16
+ loading?: boolean;
17
+ }
18
+
19
+ /**
20
+ * @since 0.3.16-canary.0
21
+ */
22
+ function Spinner({ children, className, loading = true, ...props }: SpinnerProps): ReactNode {
23
+ if (!loading) {
24
+ return children;
25
+ }
26
+
27
+ const spinner = (
28
+ <span className={cn("relative flex size-4 items-center justify-center opacity-60", className)} {...props}>
29
+ {Array.from({ length: SPINNER_COUNT }, (_, index) => (
30
+ <span
31
+ key={index}
32
+ className="absolute h-full rotate-(--spinner-rotate) before:block before:h-1/3 before:w-full before:animate-out before:rounded-full before:bg-current before:delay-(--spinner-delay) before:animation-duration-(--spinner-duration) before:fade-out-25 before:repeat-infinite motion-reduce:before:animate-none"
33
+ style={
34
+ {
35
+ "--spinner-delay": `-${((SPINNER_COUNT - index) * 100).toString()}ms`,
36
+ "--spinner-duration": `${(SPINNER_COUNT * 100).toString()}ms`,
37
+ "--spinner-rotate": `${((360 / SPINNER_COUNT) * index).toString()}deg`,
38
+ width: `${(100 / SPINNER_COUNT).toString()}%`,
39
+ } as CSSProperties
40
+ }
41
+ />
42
+ ))}
43
+ </span>
44
+ );
45
+
46
+ if (children === undefined) {
47
+ return spinner;
48
+ }
49
+
50
+ return (
51
+ <span className="relative">
52
+ <span aria-hidden className="invisible contents">
53
+ {children}
54
+ </span>
55
+ <VisuallyHidden.Root>{children}</VisuallyHidden.Root>
56
+ <span className="absolute inset-0 flex items-center justify-center">{spinner}</span>
57
+ </span>
58
+ );
59
+ }
60
+
61
+ /* -----------------------------------------------------------------------------
62
+ * Exports
63
+ * -------------------------------------------------------------------------- */
64
+
65
+ export { Spinner };
66
+ export type { SpinnerProps };
@@ -0,0 +1,44 @@
1
+ import { Switch as SwitchPrimitives } from "radix-ui";
2
+ import type { ComponentProps, JSX } from "react";
3
+
4
+ import { cn } from "#/lib/utils";
5
+
6
+ /* -----------------------------------------------------------------------------
7
+ * Component: Switch
8
+ * -------------------------------------------------------------------------- */
9
+
10
+ /**
11
+ * @since 0.3.16-canary.0
12
+ */
13
+ type SwitchProps = ComponentProps<typeof SwitchPrimitives.Root> & {
14
+ size?: "default" | "sm";
15
+ };
16
+
17
+ /**
18
+ * @since 0.3.16-canary.0
19
+ */
20
+ function Switch({ className, size = "default", ...props }: SwitchProps): JSX.Element {
21
+ return (
22
+ <SwitchPrimitives.Root
23
+ className={cn(
24
+ "peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50",
25
+ className,
26
+ )}
27
+ data-size={size}
28
+ data-slot="switch"
29
+ {...props}
30
+ >
31
+ <SwitchPrimitives.Thumb
32
+ className="pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground"
33
+ data-slot="switch-thumb"
34
+ />
35
+ </SwitchPrimitives.Root>
36
+ );
37
+ }
38
+
39
+ /* -----------------------------------------------------------------------------
40
+ * Exports
41
+ * -------------------------------------------------------------------------- */
42
+
43
+ export { Switch };
44
+ export type { SwitchProps };
@@ -0,0 +1,183 @@
1
+ import type { ComponentProps, JSX } from "react";
2
+
3
+ import { cn } from "#/lib/utils";
4
+
5
+ /* -----------------------------------------------------------------------------
6
+ * Component: Table
7
+ * -------------------------------------------------------------------------- */
8
+
9
+ /**
10
+ * @since 0.3.16-canary.0
11
+ */
12
+ type TableProps = ComponentProps<"table">;
13
+
14
+ /**
15
+ * @since 0.3.16-canary.0
16
+ */
17
+ function Table({ className, ...props }: TableProps): JSX.Element {
18
+ return (
19
+ <div className="relative w-full overflow-x-auto" data-slot="table-container">
20
+ <table className={cn("w-full caption-bottom text-sm", className)} data-slot="table" {...props} />
21
+ </div>
22
+ );
23
+ }
24
+
25
+ /* -----------------------------------------------------------------------------
26
+ * Component: TableHeader
27
+ * -------------------------------------------------------------------------- */
28
+
29
+ /**
30
+ * @since 0.3.16-canary.0
31
+ */
32
+ type TableHeaderProps = ComponentProps<"thead">;
33
+
34
+ /**
35
+ * @since 0.3.16-canary.0
36
+ */
37
+ function TableHeader({ className, ...props }: TableHeaderProps): JSX.Element {
38
+ return <thead className={cn("[&_tr]:border-b", className)} data-slot="table-header" {...props} />;
39
+ }
40
+
41
+ /* -----------------------------------------------------------------------------
42
+ * Component: TableBody
43
+ * -------------------------------------------------------------------------- */
44
+
45
+ /**
46
+ * @since 0.3.16-canary.0
47
+ */
48
+ type TableBodyProps = ComponentProps<"tbody">;
49
+
50
+ /**
51
+ * @since 0.3.16-canary.0
52
+ */
53
+ function TableBody({ className, ...props }: TableBodyProps): JSX.Element {
54
+ return <tbody className={cn("[&_tr:last-child]:border-0", className)} data-slot="table-body" {...props} />;
55
+ }
56
+
57
+ /* -----------------------------------------------------------------------------
58
+ * Component: TableFooter
59
+ * -------------------------------------------------------------------------- */
60
+
61
+ /**
62
+ * @since 0.3.16-canary.0
63
+ */
64
+ type TableFooterProps = ComponentProps<"tfoot">;
65
+
66
+ /**
67
+ * @since 0.3.16-canary.0
68
+ */
69
+ function TableFooter({ className, ...props }: TableFooterProps): JSX.Element {
70
+ return (
71
+ <tfoot
72
+ className={cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className)}
73
+ data-slot="table-footer"
74
+ {...props}
75
+ />
76
+ );
77
+ }
78
+
79
+ /* -----------------------------------------------------------------------------
80
+ * Component: TableRow
81
+ * -------------------------------------------------------------------------- */
82
+
83
+ /**
84
+ * @since 0.3.16-canary.0
85
+ */
86
+ type TableRowProps = ComponentProps<"tr">;
87
+
88
+ /**
89
+ * @since 0.3.16-canary.0
90
+ */
91
+ function TableRow({ className, ...props }: TableRowProps): JSX.Element {
92
+ return (
93
+ <tr
94
+ className={cn(
95
+ "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-selected:bg-muted",
96
+ className,
97
+ )}
98
+ data-slot="table-row"
99
+ {...props}
100
+ />
101
+ );
102
+ }
103
+
104
+ /* -----------------------------------------------------------------------------
105
+ * Component: TableHead
106
+ * -------------------------------------------------------------------------- */
107
+
108
+ /**
109
+ * @since 0.3.16-canary.0
110
+ */
111
+ type TableHeadProps = ComponentProps<"th">;
112
+
113
+ /**
114
+ * @since 0.3.16-canary.0
115
+ */
116
+ function TableHead({ className, ...props }: TableHeadProps): JSX.Element {
117
+ return (
118
+ <th
119
+ className={cn(
120
+ "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
121
+ className,
122
+ )}
123
+ data-slot="table-head"
124
+ {...props}
125
+ />
126
+ );
127
+ }
128
+
129
+ /* -----------------------------------------------------------------------------
130
+ * Component: TableCell
131
+ * -------------------------------------------------------------------------- */
132
+
133
+ /**
134
+ * @since 0.3.16-canary.0
135
+ */
136
+ type TableCellProps = ComponentProps<"td">;
137
+
138
+ /**
139
+ * @since 0.3.16-canary.0
140
+ */
141
+ function TableCell({ className, ...props }: TableCellProps): JSX.Element {
142
+ return (
143
+ <td
144
+ className={cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className)}
145
+ data-slot="table-cell"
146
+ {...props}
147
+ />
148
+ );
149
+ }
150
+
151
+ /* -----------------------------------------------------------------------------
152
+ * Component: TableCaption
153
+ * -------------------------------------------------------------------------- */
154
+
155
+ /**
156
+ * @since 0.3.16-canary.0
157
+ */
158
+ type TableCaptionProps = ComponentProps<"caption">;
159
+
160
+ /**
161
+ * @since 0.3.16-canary.0
162
+ */
163
+ function TableCaption({ className, ...props }: TableCaptionProps): JSX.Element {
164
+ return (
165
+ <caption className={cn("mt-4 text-sm text-muted-foreground", className)} data-slot="table-caption" {...props} />
166
+ );
167
+ }
168
+
169
+ /* -----------------------------------------------------------------------------
170
+ * Exports
171
+ * -------------------------------------------------------------------------- */
172
+
173
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
174
+ export type {
175
+ TableBodyProps,
176
+ TableCaptionProps,
177
+ TableCellProps,
178
+ TableFooterProps,
179
+ TableHeaderProps,
180
+ TableHeadProps,
181
+ TableProps,
182
+ TableRowProps,
183
+ };
@@ -0,0 +1,110 @@
1
+ import { Tabs as TabsPrimitive } from "radix-ui";
2
+ import type { ComponentProps, JSX } from "react";
3
+
4
+ import { cn } from "#/lib/utils";
5
+ import type { TabsListVariants } from "#/variants/tabs";
6
+ import { tabsListVariants } from "#/variants/tabs";
7
+
8
+ /* -----------------------------------------------------------------------------
9
+ * Component: Tabs
10
+ * -------------------------------------------------------------------------- */
11
+
12
+ /**
13
+ * @since 0.3.16-canary.0
14
+ */
15
+ type TabsProps = ComponentProps<typeof TabsPrimitive.Root>;
16
+
17
+ /**
18
+ * @since 0.3.16-canary.0
19
+ */
20
+ function Tabs({ className, orientation = "horizontal", ...props }: TabsProps): JSX.Element {
21
+ return (
22
+ <TabsPrimitive.Root
23
+ className={cn("group/tabs flex gap-2 data-horizontal:flex-col", className)}
24
+ data-orientation={orientation}
25
+ data-slot="tabs"
26
+ orientation={orientation}
27
+ {...props}
28
+ />
29
+ );
30
+ }
31
+
32
+ /* -----------------------------------------------------------------------------
33
+ * Component: TabsList
34
+ * -------------------------------------------------------------------------- */
35
+
36
+ /**
37
+ * @since 0.3.16-canary.0
38
+ */
39
+ type TabsListProps = ComponentProps<typeof TabsPrimitive.List> & TabsListVariants;
40
+
41
+ /**
42
+ * @since 0.3.16-canary.0
43
+ */
44
+ function TabsList({ className, variant = "default", ...props }: TabsListProps): JSX.Element {
45
+ return (
46
+ <TabsPrimitive.List
47
+ className={tabsListVariants({ className, variant })}
48
+ data-slot="tabs-list"
49
+ data-variant={variant}
50
+ {...props}
51
+ />
52
+ );
53
+ }
54
+
55
+ /* -----------------------------------------------------------------------------
56
+ * Component: TabsTrigger
57
+ * -------------------------------------------------------------------------- */
58
+
59
+ /**
60
+ * @since 0.3.16-canary.0
61
+ */
62
+ type TabsTriggerProps = ComponentProps<typeof TabsPrimitive.Trigger>;
63
+
64
+ /**
65
+ * @since 0.3.16-canary.0
66
+ */
67
+ function TabsTrigger({ className, ...props }: TabsTriggerProps): JSX.Element {
68
+ return (
69
+ <TabsPrimitive.Trigger
70
+ className={cn(
71
+ "relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
72
+ "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent",
73
+ "data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground",
74
+ "after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:-bottom-1.25 group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
75
+ className,
76
+ )}
77
+ data-slot="tabs-trigger"
78
+ {...props}
79
+ />
80
+ );
81
+ }
82
+
83
+ /* -----------------------------------------------------------------------------
84
+ * Component: TabsContent
85
+ * -------------------------------------------------------------------------- */
86
+
87
+ /**
88
+ * @since 0.3.16-canary.0
89
+ */
90
+ type TabsContentProps = ComponentProps<typeof TabsPrimitive.Content>;
91
+
92
+ /**
93
+ * @since 0.3.16-canary.0
94
+ */
95
+ function TabsContent({ className, ...props }: TabsContentProps): JSX.Element {
96
+ return (
97
+ <TabsPrimitive.Content
98
+ className={cn("flex-1 text-sm outline-none", className)}
99
+ data-slot="tabs-content"
100
+ {...props}
101
+ />
102
+ );
103
+ }
104
+
105
+ /* -----------------------------------------------------------------------------
106
+ * Exports
107
+ * -------------------------------------------------------------------------- */
108
+
109
+ export { Tabs, TabsContent, TabsList, TabsTrigger };
110
+ export type { TabsContentProps, TabsListProps, TabsProps, TabsTriggerProps };
@@ -0,0 +1,35 @@
1
+ import type { ComponentProps, JSX } from "react";
2
+
3
+ import { cn } from "#/lib/utils";
4
+
5
+ /* -----------------------------------------------------------------------------
6
+ * Component: Textarea
7
+ * -------------------------------------------------------------------------- */
8
+
9
+ /**
10
+ * @since 0.3.16-canary.0
11
+ */
12
+ type TextareaProps = ComponentProps<"textarea">;
13
+
14
+ /**
15
+ * @since 0.3.16-canary.0
16
+ */
17
+ function Textarea({ className, ...props }: TextareaProps): JSX.Element {
18
+ return (
19
+ <textarea
20
+ className={cn(
21
+ "flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-2.5 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
22
+ className,
23
+ )}
24
+ data-slot="textarea"
25
+ {...props}
26
+ />
27
+ );
28
+ }
29
+
30
+ /* -----------------------------------------------------------------------------
31
+ * Exports
32
+ * -------------------------------------------------------------------------- */
33
+
34
+ export { Textarea };
35
+ export type { TextareaProps };