@mzc-fe/design-system 0.0.1 → 0.0.2

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 (219) hide show
  1. package/dist/components/accordion.d.ts +7 -0
  2. package/dist/components/alert-dialog.d.ts +14 -0
  3. package/dist/components/alert.d.ts +9 -0
  4. package/dist/components/aspect-ratio.d.ts +3 -0
  5. package/dist/components/avatar.d.ts +6 -0
  6. package/dist/components/badge.d.ts +9 -0
  7. package/dist/components/breadcrumb.d.ts +11 -0
  8. package/dist/components/button-group.d.ts +11 -0
  9. package/dist/components/button.d.ts +10 -0
  10. package/dist/components/calendar.d.ts +8 -0
  11. package/dist/components/card.d.ts +9 -0
  12. package/dist/components/carousel.d.ts +19 -0
  13. package/dist/components/chart.d.ts +40 -0
  14. package/dist/components/checkbox.d.ts +4 -0
  15. package/dist/components/collapsible.d.ts +5 -0
  16. package/dist/components/command.d.ts +18 -0
  17. package/dist/components/context-menu.d.ts +25 -0
  18. package/dist/components/dialog.d.ts +15 -0
  19. package/dist/components/drawer.d.ts +13 -0
  20. package/dist/components/dropdown-menu.d.ts +25 -0
  21. package/dist/components/empty.d.ts +11 -0
  22. package/dist/components/field.d.ts +24 -0
  23. package/dist/components/form.d.ts +24 -0
  24. package/dist/components/hover-card.d.ts +6 -0
  25. package/dist/components/input-group.d.ts +16 -0
  26. package/dist/components/input-otp.d.ts +11 -0
  27. package/dist/components/input.d.ts +3 -0
  28. package/dist/components/item.d.ts +23 -0
  29. package/dist/components/kbd.d.ts +3 -0
  30. package/dist/components/label.d.ts +4 -0
  31. package/dist/components/menubar.d.ts +26 -0
  32. package/dist/components/navigation-menu.d.ts +14 -0
  33. package/dist/components/pagination.d.ts +13 -0
  34. package/dist/components/popover.d.ts +7 -0
  35. package/dist/components/progress.d.ts +4 -0
  36. package/dist/components/radio-group.d.ts +5 -0
  37. package/dist/components/resizable.d.ts +8 -0
  38. package/dist/components/scroll-area.d.ts +5 -0
  39. package/dist/components/select.d.ts +15 -0
  40. package/dist/components/separator.d.ts +4 -0
  41. package/dist/components/sheet.d.ts +13 -0
  42. package/dist/components/sidebar.d.ts +69 -0
  43. package/dist/components/skeleton.d.ts +2 -0
  44. package/dist/components/slider.d.ts +4 -0
  45. package/dist/components/sonner.d.ts +3 -0
  46. package/dist/components/spinner.d.ts +2 -0
  47. package/dist/components/switch.d.ts +4 -0
  48. package/dist/components/table.d.ts +10 -0
  49. package/dist/components/tabs.d.ts +7 -0
  50. package/dist/components/textarea.d.ts +3 -0
  51. package/dist/components/toggle-group.d.ts +9 -0
  52. package/dist/components/toggle.d.ts +9 -0
  53. package/dist/components/tooltip.d.ts +7 -0
  54. package/dist/design-system.css +1 -0
  55. package/dist/design-system.es.js +30200 -0
  56. package/dist/design-system.umd.js +260 -0
  57. package/dist/foundations/ThemeProvider.d.ts +13 -0
  58. package/dist/hooks/use-mobile.d.ts +1 -0
  59. package/dist/index.d.ts +54 -0
  60. package/dist/lib/utils.d.ts +2 -0
  61. package/package.json +14 -1
  62. package/.husky/pre-push +0 -21
  63. package/.storybook/main.ts +0 -11
  64. package/.storybook/preview.tsx +0 -30
  65. package/.vscode/settings.json +0 -12
  66. package/.vscode/tailwind.json +0 -105
  67. package/bitbucket-pipelines.yml +0 -50
  68. package/components.json +0 -21
  69. package/eslint.config.js +0 -38
  70. package/src/components/accordion.stories.tsx +0 -258
  71. package/src/components/accordion.test.tsx +0 -390
  72. package/src/components/accordion.tsx +0 -64
  73. package/src/components/alert-dialog.stories.tsx +0 -213
  74. package/src/components/alert-dialog.test.tsx +0 -80
  75. package/src/components/alert-dialog.tsx +0 -155
  76. package/src/components/alert.stories.tsx +0 -84
  77. package/src/components/alert.test.tsx +0 -35
  78. package/src/components/alert.tsx +0 -66
  79. package/src/components/aspect-ratio.stories.tsx +0 -97
  80. package/src/components/aspect-ratio.test.tsx +0 -47
  81. package/src/components/aspect-ratio.tsx +0 -11
  82. package/src/components/avatar.stories.tsx +0 -76
  83. package/src/components/avatar.test.tsx +0 -50
  84. package/src/components/avatar.tsx +0 -51
  85. package/src/components/badge.stories.tsx +0 -64
  86. package/src/components/badge.test.tsx +0 -34
  87. package/src/components/badge.tsx +0 -46
  88. package/src/components/breadcrumb.stories.tsx +0 -86
  89. package/src/components/breadcrumb.test.tsx +0 -74
  90. package/src/components/breadcrumb.tsx +0 -109
  91. package/src/components/button-group.stories.tsx +0 -62
  92. package/src/components/button-group.tsx +0 -83
  93. package/src/components/button.stories.tsx +0 -118
  94. package/src/components/button.test.tsx +0 -64
  95. package/src/components/button.tsx +0 -62
  96. package/src/components/calendar.stories.tsx +0 -81
  97. package/src/components/calendar.tsx +0 -220
  98. package/src/components/card.stories.tsx +0 -110
  99. package/src/components/card.test.tsx +0 -56
  100. package/src/components/card.tsx +0 -92
  101. package/src/components/carousel.stories.tsx +0 -90
  102. package/src/components/carousel.tsx +0 -239
  103. package/src/components/chart.tsx +0 -357
  104. package/src/components/checkbox.stories.tsx +0 -108
  105. package/src/components/checkbox.test.tsx +0 -67
  106. package/src/components/checkbox.tsx +0 -32
  107. package/src/components/collapsible.stories.tsx +0 -106
  108. package/src/components/collapsible.test.tsx +0 -92
  109. package/src/components/collapsible.tsx +0 -31
  110. package/src/components/command.stories.tsx +0 -90
  111. package/src/components/command.tsx +0 -182
  112. package/src/components/context-menu.stories.tsx +0 -63
  113. package/src/components/context-menu.tsx +0 -252
  114. package/src/components/dialog.stories.tsx +0 -128
  115. package/src/components/dialog.tsx +0 -141
  116. package/src/components/drawer.stories.tsx +0 -104
  117. package/src/components/drawer.tsx +0 -135
  118. package/src/components/dropdown-menu.stories.tsx +0 -97
  119. package/src/components/dropdown-menu.tsx +0 -255
  120. package/src/components/empty.stories.tsx +0 -90
  121. package/src/components/empty.test.tsx +0 -55
  122. package/src/components/empty.tsx +0 -104
  123. package/src/components/field.tsx +0 -246
  124. package/src/components/form.tsx +0 -168
  125. package/src/components/hover-card.stories.tsx +0 -66
  126. package/src/components/hover-card.tsx +0 -44
  127. package/src/components/input-group.stories.tsx +0 -57
  128. package/src/components/input-group.test.tsx +0 -40
  129. package/src/components/input-group.tsx +0 -170
  130. package/src/components/input-otp.stories.tsx +0 -94
  131. package/src/components/input-otp.test.tsx +0 -60
  132. package/src/components/input-otp.tsx +0 -75
  133. package/src/components/input.stories.tsx +0 -94
  134. package/src/components/input.test.tsx +0 -53
  135. package/src/components/input.tsx +0 -21
  136. package/src/components/item.tsx +0 -193
  137. package/src/components/kbd.stories.tsx +0 -100
  138. package/src/components/kbd.test.tsx +0 -28
  139. package/src/components/kbd.tsx +0 -28
  140. package/src/components/label.stories.tsx +0 -48
  141. package/src/components/label.test.tsx +0 -28
  142. package/src/components/label.tsx +0 -24
  143. package/src/components/menubar.tsx +0 -274
  144. package/src/components/navigation-menu.tsx +0 -168
  145. package/src/components/pagination.stories.tsx +0 -107
  146. package/src/components/pagination.tsx +0 -127
  147. package/src/components/popover.stories.tsx +0 -102
  148. package/src/components/popover.tsx +0 -48
  149. package/src/components/progress.stories.tsx +0 -76
  150. package/src/components/progress.test.tsx +0 -36
  151. package/src/components/progress.tsx +0 -29
  152. package/src/components/radio-group.stories.tsx +0 -73
  153. package/src/components/radio-group.test.tsx +0 -74
  154. package/src/components/radio-group.tsx +0 -45
  155. package/src/components/resizable.stories.tsx +0 -120
  156. package/src/components/resizable.tsx +0 -54
  157. package/src/components/scroll-area.stories.tsx +0 -64
  158. package/src/components/scroll-area.test.tsx +0 -46
  159. package/src/components/scroll-area.tsx +0 -58
  160. package/src/components/select.stories.tsx +0 -111
  161. package/src/components/select.test.tsx +0 -90
  162. package/src/components/select.tsx +0 -188
  163. package/src/components/separator.stories.tsx +0 -76
  164. package/src/components/separator.test.tsx +0 -24
  165. package/src/components/separator.tsx +0 -28
  166. package/src/components/sheet.stories.tsx +0 -122
  167. package/src/components/sheet.tsx +0 -137
  168. package/src/components/sidebar.tsx +0 -726
  169. package/src/components/skeleton.stories.tsx +0 -53
  170. package/src/components/skeleton.test.tsx +0 -24
  171. package/src/components/skeleton.tsx +0 -13
  172. package/src/components/slider.stories.tsx +0 -97
  173. package/src/components/slider.test.tsx +0 -49
  174. package/src/components/slider.tsx +0 -63
  175. package/src/components/sonner.stories.tsx +0 -96
  176. package/src/components/sonner.tsx +0 -38
  177. package/src/components/spinner.stories.tsx +0 -54
  178. package/src/components/spinner.test.tsx +0 -30
  179. package/src/components/spinner.tsx +0 -16
  180. package/src/components/switch.stories.tsx +0 -108
  181. package/src/components/switch.test.tsx +0 -62
  182. package/src/components/switch.tsx +0 -31
  183. package/src/components/table.stories.tsx +0 -139
  184. package/src/components/table.test.tsx +0 -85
  185. package/src/components/table.tsx +0 -114
  186. package/src/components/tabs.stories.tsx +0 -99
  187. package/src/components/tabs.test.tsx +0 -64
  188. package/src/components/tabs.tsx +0 -66
  189. package/src/components/textarea.stories.tsx +0 -89
  190. package/src/components/textarea.test.tsx +0 -53
  191. package/src/components/textarea.tsx +0 -18
  192. package/src/components/toggle-group.stories.tsx +0 -108
  193. package/src/components/toggle-group.test.tsx +0 -66
  194. package/src/components/toggle-group.tsx +0 -81
  195. package/src/components/toggle.stories.tsx +0 -98
  196. package/src/components/toggle.test.tsx +0 -42
  197. package/src/components/toggle.tsx +0 -45
  198. package/src/components/tooltip.stories.tsx +0 -111
  199. package/src/components/tooltip.tsx +0 -61
  200. package/src/foundations/README.md +0 -141
  201. package/src/foundations/ThemeProvider.tsx +0 -77
  202. package/src/foundations/color.css +0 -232
  203. package/src/foundations/color.stories.tsx +0 -719
  204. package/src/foundations/palette.css +0 -249
  205. package/src/foundations/spacing.css +0 -8
  206. package/src/foundations/typography.css +0 -143
  207. package/src/foundations/typography.stories.tsx +0 -17
  208. package/src/hooks/use-mobile.ts +0 -19
  209. package/src/index.css +0 -176
  210. package/src/index.ts +0 -336
  211. package/src/lib/utils.ts +0 -6
  212. package/src/test/setup.ts +0 -8
  213. package/src/vite-env.d.ts +0 -1
  214. package/tsconfig.app.json +0 -33
  215. package/tsconfig.json +0 -13
  216. package/tsconfig.node.json +0 -25
  217. package/vite.config.ts +0 -30
  218. package/vitest.config.ts +0 -25
  219. /package/{public → dist}/vite.svg +0 -0
@@ -1,104 +0,0 @@
1
- import { cva, type VariantProps } from "class-variance-authority"
2
-
3
- import { cn } from "@/lib/utils"
4
-
5
- function Empty({ className, ...props }: React.ComponentProps<"div">) {
6
- return (
7
- <div
8
- data-slot="empty"
9
- className={cn(
10
- "flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12",
11
- className
12
- )}
13
- {...props}
14
- />
15
- )
16
- }
17
-
18
- function EmptyHeader({ className, ...props }: React.ComponentProps<"div">) {
19
- return (
20
- <div
21
- data-slot="empty-header"
22
- className={cn(
23
- "flex max-w-sm flex-col items-center gap-2 text-center",
24
- className
25
- )}
26
- {...props}
27
- />
28
- )
29
- }
30
-
31
- const emptyMediaVariants = cva(
32
- "flex shrink-0 items-center justify-center mb-2 [&_svg]:pointer-events-none [&_svg]:shrink-0",
33
- {
34
- variants: {
35
- variant: {
36
- default: "bg-transparent",
37
- icon: "bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6",
38
- },
39
- },
40
- defaultVariants: {
41
- variant: "default",
42
- },
43
- }
44
- )
45
-
46
- function EmptyMedia({
47
- className,
48
- variant = "default",
49
- ...props
50
- }: React.ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>) {
51
- return (
52
- <div
53
- data-slot="empty-icon"
54
- data-variant={variant}
55
- className={cn(emptyMediaVariants({ variant, className }))}
56
- {...props}
57
- />
58
- )
59
- }
60
-
61
- function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
62
- return (
63
- <div
64
- data-slot="empty-title"
65
- className={cn("text-lg font-medium tracking-tight", className)}
66
- {...props}
67
- />
68
- )
69
- }
70
-
71
- function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
72
- return (
73
- <div
74
- data-slot="empty-description"
75
- className={cn(
76
- "text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4",
77
- className
78
- )}
79
- {...props}
80
- />
81
- )
82
- }
83
-
84
- function EmptyContent({ className, ...props }: React.ComponentProps<"div">) {
85
- return (
86
- <div
87
- data-slot="empty-content"
88
- className={cn(
89
- "flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance",
90
- className
91
- )}
92
- {...props}
93
- />
94
- )
95
- }
96
-
97
- export {
98
- Empty,
99
- EmptyHeader,
100
- EmptyTitle,
101
- EmptyDescription,
102
- EmptyContent,
103
- EmptyMedia,
104
- }
@@ -1,246 +0,0 @@
1
- import { useMemo } from "react";
2
- import { cva, type VariantProps } from "class-variance-authority";
3
-
4
- import { cn } from "@/lib/utils";
5
- import { Label } from "@/components/label";
6
- import { Separator } from "@/components/separator";
7
-
8
- function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
9
- return (
10
- <fieldset
11
- data-slot="field-set"
12
- className={cn(
13
- "flex flex-col gap-6",
14
- "has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
15
- className
16
- )}
17
- {...props}
18
- />
19
- );
20
- }
21
-
22
- function FieldLegend({
23
- className,
24
- variant = "legend",
25
- ...props
26
- }: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) {
27
- return (
28
- <legend
29
- data-slot="field-legend"
30
- data-variant={variant}
31
- className={cn(
32
- "mb-3 font-medium",
33
- "data-[variant=legend]:text-base",
34
- "data-[variant=label]:text-sm",
35
- className
36
- )}
37
- {...props}
38
- />
39
- );
40
- }
41
-
42
- function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
43
- return (
44
- <div
45
- data-slot="field-group"
46
- className={cn(
47
- "group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4",
48
- className
49
- )}
50
- {...props}
51
- />
52
- );
53
- }
54
-
55
- const fieldVariants = cva(
56
- "group/field flex w-full gap-3 data-[invalid=true]:text-destructive",
57
- {
58
- variants: {
59
- orientation: {
60
- vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
61
- horizontal: [
62
- "flex-row items-center",
63
- "[&>[data-slot=field-label]]:flex-auto",
64
- "has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
65
- ],
66
- responsive: [
67
- "flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto",
68
- "@md/field-group:[&>[data-slot=field-label]]:flex-auto",
69
- "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
70
- ],
71
- },
72
- },
73
- defaultVariants: {
74
- orientation: "vertical",
75
- },
76
- }
77
- );
78
-
79
- function Field({
80
- className,
81
- orientation = "vertical",
82
- ...props
83
- }: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) {
84
- return (
85
- <div
86
- role="group"
87
- data-slot="field"
88
- data-orientation={orientation}
89
- className={cn(fieldVariants({ orientation }), className)}
90
- {...props}
91
- />
92
- );
93
- }
94
-
95
- function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
96
- return (
97
- <div
98
- data-slot="field-content"
99
- className={cn(
100
- "group/field-content flex flex-1 flex-col gap-1.5 leading-snug",
101
- className
102
- )}
103
- {...props}
104
- />
105
- );
106
- }
107
-
108
- function FieldLabel({
109
- className,
110
- ...props
111
- }: React.ComponentProps<typeof Label>) {
112
- return (
113
- <Label
114
- data-slot="field-label"
115
- className={cn(
116
- "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
117
- "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4",
118
- "has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10",
119
- className
120
- )}
121
- {...props}
122
- />
123
- );
124
- }
125
-
126
- function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
127
- return (
128
- <div
129
- data-slot="field-label"
130
- className={cn(
131
- "flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50",
132
- className
133
- )}
134
- {...props}
135
- />
136
- );
137
- }
138
-
139
- function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
140
- return (
141
- <p
142
- data-slot="field-description"
143
- className={cn(
144
- "text-muted-foreground text-sm leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
145
- "last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5",
146
- "[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
147
- className
148
- )}
149
- {...props}
150
- />
151
- );
152
- }
153
-
154
- function FieldSeparator({
155
- children,
156
- className,
157
- ...props
158
- }: React.ComponentProps<"div"> & {
159
- children?: React.ReactNode;
160
- }) {
161
- return (
162
- <div
163
- data-slot="field-separator"
164
- data-content={!!children}
165
- className={cn(
166
- "relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
167
- className
168
- )}
169
- {...props}
170
- >
171
- <Separator className="absolute inset-0 top-1/2" />
172
- {children && (
173
- <span
174
- className="bg-background text-muted-foreground relative mx-auto block w-fit px-2"
175
- data-slot="field-separator-content"
176
- >
177
- {children}
178
- </span>
179
- )}
180
- </div>
181
- );
182
- }
183
-
184
- function FieldError({
185
- className,
186
- children,
187
- errors,
188
- ...props
189
- }: React.ComponentProps<"div"> & {
190
- errors?: Array<{ message?: string } | undefined>;
191
- }) {
192
- const content = useMemo(() => {
193
- if (children) {
194
- return children;
195
- }
196
-
197
- if (!errors?.length) {
198
- return null;
199
- }
200
-
201
- const uniqueErrors = [
202
- ...new Map(errors.map((error) => [error?.message, error])).values(),
203
- ];
204
-
205
- if (uniqueErrors?.length == 1) {
206
- return uniqueErrors[0]?.message;
207
- }
208
-
209
- return (
210
- <ul className="ml-4 flex list-disc flex-col gap-1">
211
- {uniqueErrors.map(
212
- (error, index) =>
213
- error?.message && <li key={index}>{error.message}</li>
214
- )}
215
- </ul>
216
- );
217
- }, [children, errors]);
218
-
219
- if (!content) {
220
- return null;
221
- }
222
-
223
- return (
224
- <div
225
- role="alert"
226
- data-slot="field-error"
227
- className={cn("text-destructive text-sm font-normal", className)}
228
- {...props}
229
- >
230
- {content}
231
- </div>
232
- );
233
- }
234
-
235
- export {
236
- Field,
237
- FieldLabel,
238
- FieldDescription,
239
- FieldError,
240
- FieldGroup,
241
- FieldLegend,
242
- FieldSeparator,
243
- FieldSet,
244
- FieldContent,
245
- FieldTitle,
246
- };
@@ -1,168 +0,0 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import type * as LabelPrimitive from "@radix-ui/react-label";
5
- import { Slot } from "@radix-ui/react-slot";
6
- import {
7
- Controller,
8
- FormProvider,
9
- useFormContext,
10
- useFormState,
11
- type ControllerProps,
12
- type FieldPath,
13
- type FieldValues,
14
- } from "react-hook-form";
15
-
16
- import { cn } from "@/lib/utils";
17
- import { Label } from "@/components/label";
18
-
19
- const Form = FormProvider;
20
-
21
- type FormFieldContextValue<
22
- TFieldValues extends FieldValues = FieldValues,
23
- TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
24
- > = {
25
- name: TName;
26
- };
27
-
28
- const FormFieldContext = React.createContext<FormFieldContextValue>(
29
- {} as FormFieldContextValue
30
- );
31
-
32
- const FormField = <
33
- TFieldValues extends FieldValues = FieldValues,
34
- TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
35
- >({
36
- ...props
37
- }: ControllerProps<TFieldValues, TName>) => {
38
- return (
39
- <FormFieldContext.Provider value={{ name: props.name }}>
40
- <Controller {...props} />
41
- </FormFieldContext.Provider>
42
- );
43
- };
44
-
45
- const useFormField = () => {
46
- const fieldContext = React.useContext(FormFieldContext);
47
- const itemContext = React.useContext(FormItemContext);
48
- const { getFieldState } = useFormContext();
49
- const formState = useFormState({ name: fieldContext.name });
50
- const fieldState = getFieldState(fieldContext.name, formState);
51
-
52
- if (!fieldContext) {
53
- throw new Error("useFormField should be used within <FormField>");
54
- }
55
-
56
- const { id } = itemContext;
57
-
58
- return {
59
- id,
60
- name: fieldContext.name,
61
- formItemId: `${id}-form-item`,
62
- formDescriptionId: `${id}-form-item-description`,
63
- formMessageId: `${id}-form-item-message`,
64
- ...fieldState,
65
- };
66
- };
67
-
68
- type FormItemContextValue = {
69
- id: string;
70
- };
71
-
72
- const FormItemContext = React.createContext<FormItemContextValue>(
73
- {} as FormItemContextValue
74
- );
75
-
76
- function FormItem({ className, ...props }: React.ComponentProps<"div">) {
77
- const id = React.useId();
78
-
79
- return (
80
- <FormItemContext.Provider value={{ id }}>
81
- <div
82
- data-slot="form-item"
83
- className={cn("grid gap-2", className)}
84
- {...props}
85
- />
86
- </FormItemContext.Provider>
87
- );
88
- }
89
-
90
- function FormLabel({
91
- className,
92
- ...props
93
- }: React.ComponentProps<typeof LabelPrimitive.Root>) {
94
- const { error, formItemId } = useFormField();
95
-
96
- return (
97
- <Label
98
- data-slot="form-label"
99
- data-error={!!error}
100
- className={cn("data-[error=true]:text-destructive", className)}
101
- htmlFor={formItemId}
102
- {...props}
103
- />
104
- );
105
- }
106
-
107
- function FormControl({ ...props }: React.ComponentProps<typeof Slot>) {
108
- const { error, formItemId, formDescriptionId, formMessageId } =
109
- useFormField();
110
-
111
- return (
112
- <Slot
113
- data-slot="form-control"
114
- id={formItemId}
115
- aria-describedby={
116
- !error
117
- ? `${formDescriptionId}`
118
- : `${formDescriptionId} ${formMessageId}`
119
- }
120
- aria-invalid={!!error}
121
- {...props}
122
- />
123
- );
124
- }
125
-
126
- function FormDescription({ className, ...props }: React.ComponentProps<"p">) {
127
- const { formDescriptionId } = useFormField();
128
-
129
- return (
130
- <p
131
- data-slot="form-description"
132
- id={formDescriptionId}
133
- className={cn("text-muted-foreground text-sm", className)}
134
- {...props}
135
- />
136
- );
137
- }
138
-
139
- function FormMessage({ className, ...props }: React.ComponentProps<"p">) {
140
- const { error, formMessageId } = useFormField();
141
- const body = error ? String(error?.message ?? "") : props.children;
142
-
143
- if (!body) {
144
- return null;
145
- }
146
-
147
- return (
148
- <p
149
- data-slot="form-message"
150
- id={formMessageId}
151
- className={cn("text-destructive text-sm", className)}
152
- {...props}
153
- >
154
- {body}
155
- </p>
156
- );
157
- }
158
-
159
- export {
160
- useFormField,
161
- Form,
162
- FormItem,
163
- FormLabel,
164
- FormControl,
165
- FormDescription,
166
- FormMessage,
167
- FormField,
168
- };
@@ -1,66 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react-vite";
2
- import { HoverCard, HoverCardContent, HoverCardTrigger } from "./hover-card";
3
- import { Button } from "./button";
4
-
5
- const meta = {
6
- title: "Components/HoverCard",
7
- component: HoverCard,
8
- parameters: {
9
- layout: "padded",
10
- },
11
- tags: ["autodocs"],
12
- } satisfies Meta<typeof HoverCard>;
13
-
14
- export default meta;
15
- type Story = StoryObj<typeof meta>;
16
-
17
- export const Default: Story = {
18
- render: () => (
19
- <HoverCard>
20
- <HoverCardTrigger asChild>
21
- <Button variant="link">@nextjs</Button>
22
- </HoverCardTrigger>
23
- <HoverCardContent>
24
- <div className="flex justify-between space-x-4">
25
- <div className="space-y-1">
26
- <h4 className="text-sm font-semibold">@nextjs</h4>
27
- <p className="text-sm">
28
- The React Framework – created and maintained by @vercel.
29
- </p>
30
- <div className="flex items-center pt-2">
31
- <span className="text-xs text-muted-foreground">
32
- Joined December 2021
33
- </span>
34
- </div>
35
- </div>
36
- </div>
37
- </HoverCardContent>
38
- </HoverCard>
39
- ),
40
- };
41
-
42
- export const WithImage: Story = {
43
- render: () => (
44
- <HoverCard>
45
- <HoverCardTrigger asChild>
46
- <Button variant="link">Hover me</Button>
47
- </HoverCardTrigger>
48
- <HoverCardContent className="w-80">
49
- <div className="flex justify-between space-x-4">
50
- <div className="space-y-1">
51
- <h4 className="text-sm font-semibold">John Doe</h4>
52
- <p className="text-sm text-muted-foreground">
53
- Software Engineer at Acme Inc.
54
- </p>
55
- <div className="flex items-center pt-2">
56
- <span className="text-xs text-muted-foreground">
57
- Followed by 1,234 people
58
- </span>
59
- </div>
60
- </div>
61
- </div>
62
- </HoverCardContent>
63
- </HoverCard>
64
- ),
65
- };
66
-
@@ -1,44 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import * as HoverCardPrimitive from "@radix-ui/react-hover-card"
5
-
6
- import { cn } from "@/lib/utils"
7
-
8
- function HoverCard({
9
- ...props
10
- }: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
11
- return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />
12
- }
13
-
14
- function HoverCardTrigger({
15
- ...props
16
- }: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
17
- return (
18
- <HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
19
- )
20
- }
21
-
22
- function HoverCardContent({
23
- className,
24
- align = "center",
25
- sideOffset = 4,
26
- ...props
27
- }: React.ComponentProps<typeof HoverCardPrimitive.Content>) {
28
- return (
29
- <HoverCardPrimitive.Portal data-slot="hover-card-portal">
30
- <HoverCardPrimitive.Content
31
- data-slot="hover-card-content"
32
- align={align}
33
- sideOffset={sideOffset}
34
- className={cn(
35
- "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
36
- className
37
- )}
38
- {...props}
39
- />
40
- </HoverCardPrimitive.Portal>
41
- )
42
- }
43
-
44
- export { HoverCard, HoverCardTrigger, HoverCardContent }
@@ -1,57 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react-vite";
2
- import { InputGroup, InputGroupAddon, InputGroupInput } from "./input-group";
3
- import { Button } from "./button";
4
- import { Kbd } from "./kbd";
5
-
6
- const meta = {
7
- title: "Components/InputGroup",
8
- component: InputGroup,
9
- parameters: {
10
- layout: "padded",
11
- },
12
- tags: ["autodocs"],
13
- } satisfies Meta<typeof InputGroup>;
14
-
15
- export default meta;
16
- type Story = StoryObj<typeof meta>;
17
-
18
- export const Default: Story = {
19
- render: () => (
20
- <InputGroup>
21
- <InputGroupAddon align="inline-start">$</InputGroupAddon>
22
- <InputGroupInput placeholder="0.00" />
23
- </InputGroup>
24
- ),
25
- };
26
-
27
- export const WithButton: Story = {
28
- render: () => (
29
- <InputGroup>
30
- <InputGroupInput placeholder="Search..." />
31
- <InputGroupAddon align="inline-end">
32
- <Button>Search</Button>
33
- </InputGroupAddon>
34
- </InputGroup>
35
- ),
36
- };
37
-
38
- export const WithKbd: Story = {
39
- render: () => (
40
- <InputGroup>
41
- <InputGroupInput placeholder="Search..." />
42
- <InputGroupAddon align="inline-end">
43
- <Kbd>⌘</Kbd>
44
- <Kbd>K</Kbd>
45
- </InputGroupAddon>
46
- </InputGroup>
47
- ),
48
- };
49
-
50
- export const WithLabel: Story = {
51
- render: () => (
52
- <InputGroup>
53
- <InputGroupAddon align="block-start">Email</InputGroupAddon>
54
- <InputGroupInput type="email" placeholder="name@example.com" />
55
- </InputGroup>
56
- ),
57
- };