@codefast/ui 0.3.16-canary.1 → 0.3.16-canary.3

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 (223) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +1 -1
  3. package/dist/components/accordion.mjs +2 -2
  4. package/dist/components/alert-dialog.d.mts +1 -1
  5. package/dist/components/alert-dialog.mjs +4 -4
  6. package/dist/components/alert.d.mts +3 -13
  7. package/dist/components/alert.mjs +3 -23
  8. package/dist/components/badge.d.mts +3 -15
  9. package/dist/components/badge.mjs +2 -44
  10. package/dist/components/breadcrumb.mjs +1 -1
  11. package/dist/components/button-group.d.mts +3 -13
  12. package/dist/components/button-group.mjs +3 -24
  13. package/dist/components/button.d.mts +3 -25
  14. package/dist/components/button.mjs +2 -72
  15. package/dist/components/calendar.mjs +2 -1
  16. package/dist/components/carousel.d.mts +1 -2
  17. package/dist/components/chart.d.mts +2 -4
  18. package/dist/components/checkbox.mjs +2 -2
  19. package/dist/components/context-menu.mjs +2 -2
  20. package/dist/components/dialog.d.mts +1 -1
  21. package/dist/components/dialog.mjs +4 -4
  22. package/dist/components/drawer.d.mts +1 -1
  23. package/dist/components/drawer.mjs +2 -2
  24. package/dist/components/dropdown-menu.mjs +2 -2
  25. package/dist/components/empty.d.mts +3 -13
  26. package/dist/components/empty.mjs +3 -18
  27. package/dist/components/field.d.mts +3 -14
  28. package/dist/components/field.mjs +3 -32
  29. package/dist/components/form.d.mts +2 -4
  30. package/dist/components/hover-card.mjs +1 -1
  31. package/dist/components/input-group.d.mts +4 -31
  32. package/dist/components/input-group.mjs +3 -90
  33. package/dist/components/input-number.mjs +4 -4
  34. package/dist/components/input-otp.mjs +2 -2
  35. package/dist/components/input.mjs +1 -1
  36. package/dist/components/item.d.mts +4 -29
  37. package/dist/components/item.mjs +3 -56
  38. package/dist/components/menubar.mjs +2 -2
  39. package/dist/components/native-select.mjs +1 -1
  40. package/dist/components/navigation-menu.d.mts +1 -6
  41. package/dist/components/navigation-menu.mjs +8 -15
  42. package/dist/components/pagination.d.mts +1 -1
  43. package/dist/components/pagination.mjs +1 -1
  44. package/dist/components/popover.mjs +1 -1
  45. package/dist/components/progress-circle.d.mts +3 -47
  46. package/dist/components/progress-circle.mjs +2 -47
  47. package/dist/components/progress.mjs +1 -1
  48. package/dist/components/radio-group.mjs +1 -1
  49. package/dist/components/radio.mjs +1 -1
  50. package/dist/components/scroll-area.d.mts +3 -19
  51. package/dist/components/scroll-area.mjs +4 -61
  52. package/dist/components/select.d.mts +1 -1
  53. package/dist/components/select.mjs +3 -3
  54. package/dist/components/separator.d.mts +3 -18
  55. package/dist/components/separator.mjs +3 -23
  56. package/dist/components/sheet.d.mts +6 -18
  57. package/dist/components/sheet.mjs +6 -49
  58. package/dist/components/sidebar.d.mts +4 -19
  59. package/dist/components/sidebar.mjs +10 -46
  60. package/dist/components/skeleton.mjs +1 -1
  61. package/dist/components/slider.mjs +1 -1
  62. package/dist/components/spinner.mjs +1 -1
  63. package/dist/components/switch.mjs +2 -2
  64. package/dist/components/table.mjs +1 -1
  65. package/dist/components/tabs.mjs +1 -1
  66. package/dist/components/textarea.mjs +1 -1
  67. package/dist/components/toggle-group.d.mts +3 -2
  68. package/dist/components/toggle-group.mjs +1 -1
  69. package/dist/components/toggle.d.mts +2 -21
  70. package/dist/components/toggle.mjs +2 -39
  71. package/dist/components/tooltip.mjs +1 -1
  72. package/dist/index.d.mts +31 -16
  73. package/dist/index.mjs +30 -15
  74. package/dist/lib/utils.d.mts +1 -12
  75. package/dist/lib/utils.mjs +1 -9
  76. package/dist/primitives/checkbox-group.d.mts +1 -2
  77. package/dist/primitives/input-number.d.mts +1 -2
  78. package/dist/primitives/input.d.mts +1 -2
  79. package/dist/primitives/progress-circle.d.mts +1 -2
  80. package/dist/variants/alert.d.mts +18 -0
  81. package/dist/variants/alert.mjs +25 -0
  82. package/dist/variants/badge.d.mts +20 -0
  83. package/dist/variants/badge.mjs +46 -0
  84. package/dist/variants/button-group.d.mts +18 -0
  85. package/dist/variants/button-group.mjs +26 -0
  86. package/dist/variants/button.d.mts +30 -0
  87. package/dist/variants/button.mjs +76 -0
  88. package/dist/variants/empty.d.mts +18 -0
  89. package/dist/variants/empty.mjs +20 -0
  90. package/dist/variants/field.d.mts +19 -0
  91. package/dist/variants/field.mjs +34 -0
  92. package/dist/variants/input-group.d.mts +43 -0
  93. package/dist/variants/input-group.mjs +93 -0
  94. package/dist/variants/item.d.mts +37 -0
  95. package/dist/variants/item.mjs +60 -0
  96. package/dist/variants/navigation-menu.d.mts +13 -0
  97. package/dist/variants/navigation-menu.mjs +12 -0
  98. package/dist/variants/progress-circle.d.mts +52 -0
  99. package/dist/variants/progress-circle.mjs +49 -0
  100. package/dist/variants/scroll-area.d.mts +24 -0
  101. package/dist/variants/scroll-area.mjs +63 -0
  102. package/dist/variants/separator.d.mts +23 -0
  103. package/dist/variants/separator.mjs +25 -0
  104. package/dist/variants/sheet.d.mts +20 -0
  105. package/dist/variants/sheet.mjs +50 -0
  106. package/dist/variants/sidebar.d.mts +23 -0
  107. package/dist/variants/sidebar.mjs +42 -0
  108. package/dist/variants/toggle.d.mts +23 -0
  109. package/dist/variants/toggle.mjs +43 -0
  110. package/package.json +169 -21
  111. package/src/components/accordion.tsx +156 -0
  112. package/src/components/alert-dialog.tsx +314 -0
  113. package/src/components/alert.tsx +86 -0
  114. package/src/components/aspect-ratio.tsx +28 -0
  115. package/src/components/avatar.tsx +84 -0
  116. package/src/components/badge.tsx +38 -0
  117. package/src/components/breadcrumb.tsx +197 -0
  118. package/src/components/button-group.tsx +107 -0
  119. package/src/components/button.tsx +66 -0
  120. package/src/components/calendar.tsx +277 -0
  121. package/src/components/card.tsx +175 -0
  122. package/src/components/carousel.tsx +367 -0
  123. package/src/components/chart.tsx +587 -0
  124. package/src/components/checkbox-cards.tsx +92 -0
  125. package/src/components/checkbox-group.tsx +83 -0
  126. package/src/components/checkbox.tsx +65 -0
  127. package/src/components/collapsible.tsx +60 -0
  128. package/src/components/command.tsx +311 -0
  129. package/src/components/context-menu.tsx +489 -0
  130. package/src/components/dialog.tsx +295 -0
  131. package/src/components/drawer.tsx +271 -0
  132. package/src/components/dropdown-menu.tsx +498 -0
  133. package/src/components/empty.tsx +169 -0
  134. package/src/components/field.tsx +362 -0
  135. package/src/components/form.tsx +300 -0
  136. package/src/components/hover-card.tsx +116 -0
  137. package/src/components/input-group.tsx +224 -0
  138. package/src/components/input-number.tsx +161 -0
  139. package/src/components/input-otp.tsx +151 -0
  140. package/src/components/input-password.tsx +74 -0
  141. package/src/components/input-search.tsx +98 -0
  142. package/src/components/input.tsx +52 -0
  143. package/src/components/item.tsx +280 -0
  144. package/src/components/kbd.tsx +59 -0
  145. package/src/components/label.tsx +44 -0
  146. package/src/components/menubar.tsx +531 -0
  147. package/src/components/native-select.tsx +96 -0
  148. package/src/components/navigation-menu.tsx +295 -0
  149. package/src/components/pagination.tsx +204 -0
  150. package/src/components/popover.tsx +139 -0
  151. package/src/components/progress-circle.tsx +203 -0
  152. package/src/components/progress.tsx +54 -0
  153. package/src/components/radio-cards.tsx +85 -0
  154. package/src/components/radio-group.tsx +79 -0
  155. package/src/components/radio.tsx +61 -0
  156. package/src/components/resizable.tsx +99 -0
  157. package/src/components/scroll-area.tsx +115 -0
  158. package/src/components/select.tsx +319 -0
  159. package/src/components/separator.tsx +74 -0
  160. package/src/components/sheet.tsx +278 -0
  161. package/src/components/sidebar.tsx +1056 -0
  162. package/src/components/skeleton.tsx +37 -0
  163. package/src/components/slider.tsx +95 -0
  164. package/src/components/sonner.tsx +47 -0
  165. package/src/components/spinner.tsx +75 -0
  166. package/src/components/switch.tsx +66 -0
  167. package/src/components/table.tsx +200 -0
  168. package/src/components/tabs.tsx +128 -0
  169. package/src/components/textarea.tsx +49 -0
  170. package/src/components/toggle-group.tsx +141 -0
  171. package/src/components/toggle.tsx +39 -0
  172. package/src/components/tooltip.tsx +141 -0
  173. package/src/css/amber.css +59 -22
  174. package/src/css/blue.css +59 -22
  175. package/src/css/cyan.css +59 -22
  176. package/src/css/emerald.css +59 -22
  177. package/src/css/fuchsia.css +59 -22
  178. package/src/css/gray.css +59 -22
  179. package/src/css/green.css +59 -22
  180. package/src/css/indigo.css +59 -22
  181. package/src/css/lime.css +59 -22
  182. package/src/css/neutral.css +59 -22
  183. package/src/css/orange.css +59 -22
  184. package/src/css/pink.css +59 -22
  185. package/src/css/preset.css +32 -13
  186. package/src/css/purple.css +59 -22
  187. package/src/css/red.css +59 -22
  188. package/src/css/rose.css +59 -22
  189. package/src/css/sky.css +59 -22
  190. package/src/css/slate.css +59 -22
  191. package/src/css/stone.css +59 -22
  192. package/src/css/teal.css +59 -22
  193. package/src/css/violet.css +59 -22
  194. package/src/css/yellow.css +59 -22
  195. package/src/css/zinc.css +59 -22
  196. package/src/hooks/use-animated-value.ts +97 -0
  197. package/src/hooks/use-copy-to-clipboard.ts +63 -0
  198. package/src/hooks/use-is-mobile.ts +27 -0
  199. package/src/hooks/use-media-query.ts +71 -0
  200. package/src/hooks/use-mutation-observer.ts +54 -0
  201. package/src/hooks/use-pagination.ts +166 -0
  202. package/src/index.ts +720 -0
  203. package/src/lib/utils.ts +5 -0
  204. package/src/primitives/checkbox-group.tsx +360 -0
  205. package/src/primitives/input-number.tsx +1013 -0
  206. package/src/primitives/input.tsx +243 -0
  207. package/src/primitives/progress-circle.tsx +537 -0
  208. package/src/variants/alert.ts +45 -0
  209. package/src/variants/badge.ts +66 -0
  210. package/src/variants/button-group.ts +49 -0
  211. package/src/variants/button.ts +93 -0
  212. package/src/variants/empty.ts +43 -0
  213. package/src/variants/field.ts +50 -0
  214. package/src/variants/input-group.ts +132 -0
  215. package/src/variants/item.ts +90 -0
  216. package/src/variants/navigation-menu.ts +32 -0
  217. package/src/variants/progress-circle.ts +47 -0
  218. package/src/variants/scroll-area.ts +79 -0
  219. package/src/variants/separator.ts +41 -0
  220. package/src/variants/sheet.ts +70 -0
  221. package/src/variants/sidebar.ts +61 -0
  222. package/src/variants/toggle.ts +59 -0
  223. package/dist/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/clsx.d.mts +0 -6
@@ -0,0 +1,203 @@
1
+ "use client";
2
+
3
+ import type { ProgressCircleVariants } from "#/variants/progress-circle";
4
+ import type { ComponentProps, CSSProperties, JSX } from "react";
5
+
6
+ import { useCallback, useMemo } from "react";
7
+
8
+ import { progressCircleVariants } from "#/variants/progress-circle";
9
+
10
+ import { useAnimatedValue } from "#/hooks/use-animated-value";
11
+ import * as ProgressCirclePrimitive from "#/primitives/progress-circle";
12
+
13
+ /* -------------------------------------------------------------------------------------------------
14
+ * Component: ProgressCircle
15
+ * ----------------------------------------------------------------------------------------------- */
16
+
17
+ /**
18
+ * @since 0.3.16-canary.0
19
+ */
20
+ interface ProgressCircleProps
21
+ extends
22
+ Omit<ComponentProps<typeof ProgressCirclePrimitive.Provider>, "children" | "size">,
23
+ ProgressCircleVariants {
24
+ /**
25
+ * Enables animation effect when value changes
26
+ */
27
+ animate?: boolean;
28
+
29
+ /**
30
+ * Duration of the animation in milliseconds
31
+ */
32
+ animationDuration?: number;
33
+
34
+ /**
35
+ * CSS class to customize the entire component
36
+ */
37
+ className?: string;
38
+
39
+ /**
40
+ * CSS classes to customize specific parts of the component
41
+ */
42
+ classNames?: {
43
+ /**
44
+ * Class for the progress indicator
45
+ */
46
+ indicator?: string;
47
+
48
+ /**
49
+ * Class for the label in the center of the circle
50
+ */
51
+ label?: string;
52
+
53
+ /**
54
+ * Class for the root element of the component
55
+ */
56
+ root?: string;
57
+
58
+ /**
59
+ * Class for the SVG element
60
+ */
61
+ svg?: string;
62
+
63
+ /**
64
+ * Class for the circle track
65
+ */
66
+ track?: string;
67
+ };
68
+
69
+ /**
70
+ * Custom function to render content in the center of the circle
71
+ * @param value - Current value of the component
72
+ * @returns React element to display in the center of the circle
73
+ */
74
+ customLabel?: ({ value }: { value: number }) => JSX.Element;
75
+
76
+ /**
77
+ * Display the numeric value in the center of the circle
78
+ */
79
+ showValue?: boolean;
80
+
81
+ /**
82
+ * Custom size in pixels
83
+ * When provided, this value overrides the size variant option
84
+ */
85
+ sizeInPixels?: number;
86
+ }
87
+
88
+ /**
89
+ * @since 0.3.16-canary.0
90
+ */
91
+ function ProgressCircle({
92
+ animate = true,
93
+ animationDuration = 1000,
94
+ className,
95
+ classNames,
96
+ customLabel,
97
+ showValue = false,
98
+ size,
99
+ sizeInPixels,
100
+ strokeWidth,
101
+ thickness = "regular",
102
+ value = 0,
103
+ variant = "default",
104
+ ...props
105
+ }: ProgressCircleProps): JSX.Element {
106
+ const displayValue = useAnimatedValue(value, animationDuration, animate);
107
+
108
+ const actualSize = useMemo(() => sizeInPixels ?? getActualSize(size), [sizeInPixels, size]);
109
+
110
+ const actualThickness = useMemo(
111
+ () => strokeWidth ?? getStrokeWidth(thickness, actualSize),
112
+ [strokeWidth, thickness, actualSize],
113
+ );
114
+
115
+ const slots = useMemo(
116
+ () => progressCircleVariants({ size, thickness, variant }),
117
+ [variant, size, thickness],
118
+ );
119
+
120
+ const shouldShowLabel = showValue || Boolean(customLabel);
121
+
122
+ const renderLabel = useCallback(() => {
123
+ if (customLabel) {
124
+ return customLabel({ value: displayValue });
125
+ }
126
+
127
+ return `${displayValue.toString()}%`;
128
+ }, [customLabel, displayValue]);
129
+
130
+ return (
131
+ <ProgressCirclePrimitive.Provider
132
+ size={actualSize}
133
+ strokeWidth={actualThickness}
134
+ value={value}
135
+ {...props}
136
+ >
137
+ <ProgressCirclePrimitive.Root
138
+ className={slots.root({ className: [className, classNames?.root] })}
139
+ >
140
+ <ProgressCirclePrimitive.SVG className={slots.svg({ className: classNames?.svg })}>
141
+ <ProgressCirclePrimitive.Track
142
+ className={slots.track({ className: classNames?.track })}
143
+ />
144
+ <ProgressCirclePrimitive.Indicator
145
+ className={slots.indicator({ className: classNames?.indicator })}
146
+ style={
147
+ {
148
+ transitionDuration: `${animationDuration.toString()}ms`,
149
+ transitionProperty: "stroke-dashoffset",
150
+ } as CSSProperties
151
+ }
152
+ />
153
+ </ProgressCirclePrimitive.SVG>
154
+ {shouldShowLabel ? (
155
+ <ProgressCirclePrimitive.Value className={slots.label({ className: classNames?.label })}>
156
+ {renderLabel()}
157
+ </ProgressCirclePrimitive.Value>
158
+ ) : null}
159
+ </ProgressCirclePrimitive.Root>
160
+ </ProgressCirclePrimitive.Provider>
161
+ );
162
+ }
163
+
164
+ ProgressCircle.displayName = "ProgressCircle";
165
+
166
+ /* -----------------------------------------------------------------------------
167
+ * Helpers
168
+ * -------------------------------------------------------------------------- */
169
+
170
+ /**
171
+ * Maps size variants to actual pixel sizes
172
+ */
173
+ const getActualSize = (size?: ProgressCircleVariants["size"]): number => {
174
+ const sizeMap: Record<NonNullable<typeof size>, number> = {
175
+ "2xl": 128,
176
+ lg: 64,
177
+ md: 48,
178
+ sm: 32,
179
+ xl: 96,
180
+ };
181
+
182
+ return size ? sizeMap[size] : 48;
183
+ };
184
+
185
+ /**
186
+ * Calculates stroke width based on thickness variant and circle size
187
+ */
188
+ const getStrokeWidth = (thickness: ProgressCircleVariants["thickness"], size: number): number => {
189
+ const thicknessMap: Record<NonNullable<typeof thickness>, number> = {
190
+ regular: Math.max(3, size * 0.05),
191
+ thick: Math.max(4, size * 0.075),
192
+ thin: Math.max(2, size * 0.025),
193
+ };
194
+
195
+ return thickness ? thicknessMap[thickness] : Math.max(3, size * 0.05);
196
+ };
197
+
198
+ /* -----------------------------------------------------------------------------
199
+ * Exports
200
+ * -------------------------------------------------------------------------- */
201
+
202
+ export { ProgressCircle };
203
+ export type { ProgressCircleProps };
@@ -0,0 +1,54 @@
1
+ "use client";
2
+
3
+ import type { ComponentProps, JSX } from "react";
4
+
5
+ import { cn } from "#/lib/utils";
6
+ import * as ProgressPrimitive from "@radix-ui/react-progress";
7
+
8
+ /* -----------------------------------------------------------------------------
9
+ * Component: Progress
10
+ * -------------------------------------------------------------------------- */
11
+
12
+ /**
13
+ * @since 0.3.16-canary.0
14
+ */
15
+ type ProgressProps = ComponentProps<typeof ProgressPrimitive.Root>;
16
+
17
+ /**
18
+ * @since 0.3.16-canary.0
19
+ */
20
+ function Progress({ className, value, ...props }: ProgressProps): JSX.Element {
21
+ return (
22
+ <ProgressPrimitive.Root
23
+ className={cn(
24
+ "relative",
25
+ "h-2 w-full overflow-hidden",
26
+ "rounded-full",
27
+ "bg-primary/20",
28
+ className,
29
+ )}
30
+ data-slot="progress"
31
+ {...props}
32
+ >
33
+ <ProgressPrimitive.Indicator
34
+ className={cn(
35
+ "size-full flex-1",
36
+ "bg-primary",
37
+ "transition-[transform] duration-500 ease-gentle",
38
+ "motion-reduce:transition-none motion-reduce:duration-0",
39
+ )}
40
+ data-slot="progress-indicator"
41
+ style={{
42
+ transform: `translateX(-${(100 - (value ?? 0)).toString()}%)`,
43
+ }}
44
+ />
45
+ </ProgressPrimitive.Root>
46
+ );
47
+ }
48
+
49
+ /* -----------------------------------------------------------------------------
50
+ * Exports
51
+ * -------------------------------------------------------------------------- */
52
+
53
+ export { Progress };
54
+ export type { ProgressProps };
@@ -0,0 +1,85 @@
1
+ "use client";
2
+
3
+ import type { ComponentProps, JSX } from "react";
4
+
5
+ import { cn } from "#/lib/utils";
6
+ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
7
+
8
+ import { Label } from "#/components/label";
9
+
10
+ /* -----------------------------------------------------------------------------
11
+ * Component: RadioCards
12
+ * -------------------------------------------------------------------------- */
13
+
14
+ /**
15
+ * @since 0.3.16-canary.0
16
+ */
17
+ type RadioCardsProps = ComponentProps<typeof RadioGroupPrimitive.Root>;
18
+
19
+ /**
20
+ * @since 0.3.16-canary.0
21
+ */
22
+ function RadioCards(props: RadioCardsProps): JSX.Element {
23
+ return <RadioGroupPrimitive.Root data-slot="radio-cards" {...props} />;
24
+ }
25
+
26
+ /* -----------------------------------------------------------------------------
27
+ * Component: RadioCardsItem
28
+ * -------------------------------------------------------------------------- */
29
+
30
+ /**
31
+ * @since 0.3.16-canary.0
32
+ */
33
+ type RadioCardsItemProps = ComponentProps<typeof RadioGroupPrimitive.Item>;
34
+
35
+ /**
36
+ * @since 0.3.16-canary.0
37
+ */
38
+ function RadioCardsItem({ children, className, ...props }: RadioCardsItemProps): JSX.Element {
39
+ return (
40
+ <Label
41
+ className={cn(
42
+ "flex items-start gap-3",
43
+ "p-3",
44
+ "rounded-lg border border-input",
45
+ "transition",
46
+ "hover:not-has-disabled:not-has-aria-checked:bg-secondary",
47
+ "has-focus-visible:border-ring",
48
+ "has-disabled:opacity-50",
49
+ "has-aria-checked:border-primary has-aria-checked:bg-primary/10",
50
+ )}
51
+ data-slot="radio-card"
52
+ >
53
+ <RadioGroupPrimitive.Item
54
+ className={cn(
55
+ "peer flex size-4 shrink-0 items-center justify-center",
56
+ "rounded-full border border-input shadow-xs outline-hidden",
57
+ "text-primary-foreground",
58
+ "transition",
59
+ "focus-visible:ring-3 focus-visible:ring-ring/50",
60
+ "focus-visible:not-aria-checked:border-ring",
61
+ "aria-checked:border-primary aria-checked:bg-primary",
62
+ "focus-visible:aria-checked:ring-primary/20",
63
+ "dark:bg-input/30",
64
+ "dark:focus-visible:aria-checked:ring-primary/40",
65
+ className,
66
+ )}
67
+ data-slot="radio-card-item"
68
+ {...props}
69
+ >
70
+ <RadioGroupPrimitive.Indicator
71
+ className={cn("size-1", "rounded-full", "bg-background")}
72
+ data-slot="radio-card-indicator"
73
+ />
74
+ </RadioGroupPrimitive.Item>
75
+ {children}
76
+ </Label>
77
+ );
78
+ }
79
+
80
+ /* -----------------------------------------------------------------------------
81
+ * Exports
82
+ * -------------------------------------------------------------------------- */
83
+
84
+ export { RadioCards, RadioCardsItem };
85
+ export type { RadioCardsItemProps, RadioCardsProps };
@@ -0,0 +1,79 @@
1
+ "use client";
2
+
3
+ import type { ComponentProps, JSX } from "react";
4
+
5
+ import { cn } from "#/lib/utils";
6
+ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
7
+
8
+ /* -----------------------------------------------------------------------------
9
+ * Component: RadioGroup
10
+ * -------------------------------------------------------------------------- */
11
+
12
+ /**
13
+ * @since 0.3.16-canary.0
14
+ */
15
+ type RadioGroupProps = ComponentProps<typeof RadioGroupPrimitive.Root>;
16
+
17
+ /**
18
+ * @since 0.3.16-canary.0
19
+ */
20
+ function RadioGroup({ className, ...props }: RadioGroupProps): JSX.Element {
21
+ return (
22
+ <RadioGroupPrimitive.Root
23
+ className={cn("grid gap-2", className)}
24
+ data-slot="radio-group"
25
+ {...props}
26
+ />
27
+ );
28
+ }
29
+
30
+ /* -----------------------------------------------------------------------------
31
+ * Component: RadioGroupItem
32
+ * -------------------------------------------------------------------------- */
33
+
34
+ /**
35
+ * @since 0.3.16-canary.0
36
+ */
37
+ type RadioGroupItemProps = ComponentProps<typeof RadioGroupPrimitive.Item>;
38
+
39
+ /**
40
+ * @since 0.3.16-canary.0
41
+ */
42
+ function RadioGroupItem({ className, ...props }: RadioGroupItemProps): JSX.Element {
43
+ return (
44
+ <RadioGroupPrimitive.Item
45
+ className={cn(
46
+ "peer inline-flex size-4 shrink-0 items-center justify-center",
47
+ "rounded-full border border-input shadow-xs outline-hidden",
48
+ "transition-[border-color,background-color,box-shadow] duration-150 ease-spring",
49
+ "motion-reduce:transition-none motion-reduce:duration-0",
50
+ "hover:not-disabled:not-aria-checked:border-ring/60",
51
+ "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50",
52
+ "disabled:opacity-50",
53
+ "aria-checked:border-primary aria-checked:bg-primary",
54
+ "focus-visible:aria-checked:ring-primary/20",
55
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20",
56
+ "hover:not-disabled:not-aria-checked:aria-invalid:border-destructive/60",
57
+ "aria-checked:aria-invalid:bg-destructive",
58
+ "dark:bg-input/30",
59
+ "dark:focus-visible:aria-checked:ring-primary/40",
60
+ "dark:aria-invalid:ring-destructive/40",
61
+ className,
62
+ )}
63
+ data-slot="radio-group-item"
64
+ {...props}
65
+ >
66
+ <RadioGroupPrimitive.Indicator
67
+ className={cn("size-1", "rounded-full", "bg-background")}
68
+ data-slot="radio-group-indicator"
69
+ />
70
+ </RadioGroupPrimitive.Item>
71
+ );
72
+ }
73
+
74
+ /* -----------------------------------------------------------------------------
75
+ * Exports
76
+ * -------------------------------------------------------------------------- */
77
+
78
+ export { RadioGroup, RadioGroupItem };
79
+ export type { RadioGroupItemProps, RadioGroupProps };
@@ -0,0 +1,61 @@
1
+ "use client";
2
+
3
+ import type { ComponentProps, JSX } from "react";
4
+
5
+ import { cn } from "#/lib/utils";
6
+ import { composeEventHandlers } from "@radix-ui/primitive";
7
+
8
+ /* -----------------------------------------------------------------------------
9
+ * Component: Radio
10
+ * -------------------------------------------------------------------------- */
11
+
12
+ /**
13
+ * @since 0.3.16-canary.0
14
+ */
15
+ interface RadioProps extends Omit<ComponentProps<"input">, "type"> {
16
+ onValueChange?: (value: string) => void;
17
+ }
18
+
19
+ /**
20
+ * @since 0.3.16-canary.0
21
+ */
22
+ function Radio({ className, onChange, onValueChange, ...props }: RadioProps): JSX.Element {
23
+ return (
24
+ <input
25
+ className={cn(
26
+ "peer inline-flex size-4 shrink-0 items-center justify-center",
27
+ "rounded-full border border-input shadow-xs outline-hidden",
28
+ "appearance-none",
29
+ "after:size-full after:rounded-full after:bg-background after:transition-[width,height] after:duration-200 after:ease-spring",
30
+ "motion-reduce:after:transition-none motion-reduce:after:duration-0",
31
+ "checked:border-primary checked:bg-primary",
32
+ "checked:after:size-1",
33
+ "hover:not-disabled:not-checked:border-ring/60",
34
+ "focus-visible:ring-3 focus-visible:ring-ring/50",
35
+ "focus-visible:not-checked:border-ring",
36
+ "focus-visible:checked:ring-primary/20",
37
+ "disabled:opacity-50",
38
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20",
39
+ "checked:aria-invalid:bg-destructive",
40
+ "hover:not-disabled:not-checked:aria-invalid:border-destructive/60",
41
+ "dark:not-checked:after:bg-input/30",
42
+ "dark:focus-visible:checked:ring-primary/40",
43
+ "dark:aria-invalid:ring-destructive/40",
44
+ className,
45
+ )}
46
+ data-slot="radio"
47
+ type="radio"
48
+ onChange={composeEventHandlers(onChange, (event) =>
49
+ onValueChange?.(event.currentTarget.value),
50
+ )}
51
+ {...props}
52
+ />
53
+ );
54
+ }
55
+
56
+ /* -----------------------------------------------------------------------------
57
+ * Exports
58
+ * -------------------------------------------------------------------------- */
59
+
60
+ export { Radio };
61
+ export type { RadioProps };
@@ -0,0 +1,99 @@
1
+ "use client";
2
+
3
+ import type { ComponentProps, JSX } from "react";
4
+
5
+ import { cn } from "#/lib/utils";
6
+ import { GripVerticalIcon } from "lucide-react";
7
+ import * as ResizablePrimitive from "react-resizable-panels";
8
+
9
+ /* -----------------------------------------------------------------------------
10
+ * Component: ResizableGroup
11
+ * -------------------------------------------------------------------------- */
12
+
13
+ /**
14
+ * @since 0.3.16-canary.0
15
+ */
16
+ type ResizableGroupProps = ComponentProps<typeof ResizablePrimitive.Group>;
17
+
18
+ /**
19
+ * @since 0.3.16-canary.0
20
+ */
21
+ function ResizableGroup({ className, ...props }: ResizableGroupProps): JSX.Element {
22
+ return (
23
+ <ResizablePrimitive.Group
24
+ className={cn("flex size-full", className)}
25
+ data-slot="resizable-group"
26
+ {...props}
27
+ />
28
+ );
29
+ }
30
+
31
+ /* -----------------------------------------------------------------------------
32
+ * Component: ResizablePanel
33
+ * -------------------------------------------------------------------------- */
34
+
35
+ /**
36
+ * @since 0.3.16-canary.0
37
+ */
38
+ type ResizablePanelProps = ComponentProps<typeof ResizablePrimitive.Panel>;
39
+
40
+ /**
41
+ * @since 0.3.16-canary.0
42
+ */
43
+ function ResizablePanel({ ...props }: ResizablePanelProps): JSX.Element {
44
+ return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />;
45
+ }
46
+
47
+ /* -----------------------------------------------------------------------------
48
+ * Component: ResizableSeparator
49
+ * -------------------------------------------------------------------------- */
50
+
51
+ /**
52
+ * @since 0.3.16-canary.0
53
+ */
54
+ interface ResizableSeparatorProps extends ComponentProps<typeof ResizablePrimitive.Separator> {
55
+ withHandle?: boolean;
56
+ }
57
+
58
+ /**
59
+ * @since 0.3.16-canary.0
60
+ */
61
+ function ResizableSeparator({
62
+ className,
63
+ withHandle,
64
+ ...props
65
+ }: ResizableSeparatorProps): JSX.Element {
66
+ return (
67
+ <ResizablePrimitive.Separator
68
+ className={cn(
69
+ "flex items-center justify-center",
70
+ "bg-border outline-hidden",
71
+ "focus-visible:bg-ring focus-visible:ring-3 focus-visible:ring-ring/50",
72
+ "aria-[orientation=horizontal]:h-px",
73
+ "aria-[orientation=vertical]:w-px",
74
+ className,
75
+ )}
76
+ data-slot="resizable-separator"
77
+ {...props}
78
+ >
79
+ {withHandle ? (
80
+ <div
81
+ className={cn(
82
+ "z-10 flex h-4 w-3 items-center justify-center",
83
+ "rounded-sm border",
84
+ "bg-border",
85
+ )}
86
+ >
87
+ <GripVerticalIcon className="size-2.5" />
88
+ </div>
89
+ ) : null}
90
+ </ResizablePrimitive.Separator>
91
+ );
92
+ }
93
+
94
+ /* -----------------------------------------------------------------------------
95
+ * Exports
96
+ * -------------------------------------------------------------------------- */
97
+
98
+ export { ResizableGroup, ResizablePanel, ResizableSeparator };
99
+ export type { ResizableGroupProps, ResizablePanelProps, ResizableSeparatorProps };
@@ -0,0 +1,115 @@
1
+ "use client";
2
+
3
+ import type { ScrollAreaScrollbarVariants } from "#/variants/scroll-area";
4
+ import type { Scope } from "@radix-ui/react-context";
5
+ import type { ComponentProps, JSX } from "react";
6
+
7
+ import { cn } from "#/lib/utils";
8
+
9
+ import { scrollAreaScrollbarVariants } from "#/variants/scroll-area";
10
+ import { createContextScope } from "@radix-ui/react-context";
11
+ import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
12
+
13
+ /* -----------------------------------------------------------------------------
14
+ * Context: ScrollArea
15
+ * -------------------------------------------------------------------------- */
16
+
17
+ const SCROLL_AREA_NAME = "ScrollArea";
18
+
19
+ type ScopedProps<P> = P & { __scopeScrollArea?: Scope };
20
+
21
+ const [createScrollAreaContext] = createContextScope(SCROLL_AREA_NAME);
22
+
23
+ type ScrollAreaContextValue = Pick<ScrollAreaScrollbarVariants, "size">;
24
+
25
+ const [ScrollAreaContextProvider, useScrollAreaContext] =
26
+ createScrollAreaContext<ScrollAreaContextValue>(SCROLL_AREA_NAME);
27
+
28
+ /* -----------------------------------------------------------------------------
29
+ * Component: ScrollArea
30
+ * -------------------------------------------------------------------------- */
31
+
32
+ /**
33
+ * @since 0.3.16-canary.0
34
+ */
35
+ type ScrollAreaProps = ScopedProps<
36
+ ComponentProps<typeof ScrollAreaPrimitive.Root> & ScrollAreaContextValue
37
+ >;
38
+
39
+ /**
40
+ * @since 0.3.16-canary.0
41
+ */
42
+ function ScrollArea({
43
+ __scopeScrollArea,
44
+ children,
45
+ className,
46
+ size,
47
+ ...props
48
+ }: ScrollAreaProps): JSX.Element {
49
+ return (
50
+ <ScrollAreaContextProvider scope={__scopeScrollArea} size={size}>
51
+ <ScrollAreaPrimitive.Root
52
+ className={cn("relative", className)}
53
+ data-slot="scroll-area"
54
+ {...props}
55
+ >
56
+ <ScrollAreaPrimitive.Viewport
57
+ className={cn(
58
+ "size-full",
59
+ "rounded-[inherit] ring-ring/50 outline-ring",
60
+ "transition-[box-shadow] duration-150 ease-snappy",
61
+ "motion-reduce:transition-none motion-reduce:duration-0",
62
+ "focus-visible:ring-4 focus-visible:outline-1",
63
+ )}
64
+ data-slot="scroll-area-viewport"
65
+ >
66
+ {children}
67
+ </ScrollAreaPrimitive.Viewport>
68
+ <ScrollAreaScrollbar orientation="vertical" />
69
+ <ScrollAreaScrollbar orientation="horizontal" />
70
+ <ScrollAreaPrimitive.Corner />
71
+ </ScrollAreaPrimitive.Root>
72
+ </ScrollAreaContextProvider>
73
+ );
74
+ }
75
+
76
+ /* -----------------------------------------------------------------------------
77
+ * Component: ScrollAreaScrollbar
78
+ * -------------------------------------------------------------------------- */
79
+
80
+ /**
81
+ * @since 0.3.16-canary.0
82
+ */
83
+ type ScrollAreaScrollbarProps = ScopedProps<ComponentProps<typeof ScrollAreaPrimitive.Scrollbar>>;
84
+
85
+ /**
86
+ * @since 0.3.16-canary.0
87
+ */
88
+ function ScrollAreaScrollbar({
89
+ __scopeScrollArea,
90
+ className,
91
+ orientation,
92
+ ...props
93
+ }: ScrollAreaScrollbarProps): JSX.Element {
94
+ const { size } = useScrollAreaContext(SCROLL_AREA_NAME, __scopeScrollArea);
95
+
96
+ return (
97
+ <ScrollAreaPrimitive.Scrollbar
98
+ className={scrollAreaScrollbarVariants({ className, orientation, size })}
99
+ data-slot="scroll-area-scrollbar"
100
+ orientation={orientation}
101
+ {...props}
102
+ >
103
+ <ScrollAreaPrimitive.ScrollAreaThumb
104
+ className={cn("relative flex-1", "rounded-full", "bg-border")}
105
+ />
106
+ </ScrollAreaPrimitive.Scrollbar>
107
+ );
108
+ }
109
+
110
+ /* -----------------------------------------------------------------------------
111
+ * Exports
112
+ * -------------------------------------------------------------------------- */
113
+
114
+ export { ScrollArea, ScrollAreaScrollbar };
115
+ export type { ScrollAreaProps, ScrollAreaScrollbarProps };