@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.
- package/dist/components/accordion.d.ts +7 -0
- package/dist/components/alert-dialog.d.ts +14 -0
- package/dist/components/alert.d.ts +9 -0
- package/dist/components/aspect-ratio.d.ts +3 -0
- package/dist/components/avatar.d.ts +6 -0
- package/dist/components/badge.d.ts +9 -0
- package/dist/components/breadcrumb.d.ts +11 -0
- package/dist/components/button-group.d.ts +11 -0
- package/dist/components/button.d.ts +10 -0
- package/dist/components/calendar.d.ts +8 -0
- package/dist/components/card.d.ts +9 -0
- package/dist/components/carousel.d.ts +19 -0
- package/dist/components/chart.d.ts +40 -0
- package/dist/components/checkbox.d.ts +4 -0
- package/dist/components/collapsible.d.ts +5 -0
- package/dist/components/command.d.ts +18 -0
- package/dist/components/context-menu.d.ts +25 -0
- package/dist/components/dialog.d.ts +15 -0
- package/dist/components/drawer.d.ts +13 -0
- package/dist/components/dropdown-menu.d.ts +25 -0
- package/dist/components/empty.d.ts +11 -0
- package/dist/components/field.d.ts +24 -0
- package/dist/components/form.d.ts +24 -0
- package/dist/components/hover-card.d.ts +6 -0
- package/dist/components/input-group.d.ts +16 -0
- package/dist/components/input-otp.d.ts +11 -0
- package/dist/components/input.d.ts +3 -0
- package/dist/components/item.d.ts +23 -0
- package/dist/components/kbd.d.ts +3 -0
- package/dist/components/label.d.ts +4 -0
- package/dist/components/menubar.d.ts +26 -0
- package/dist/components/navigation-menu.d.ts +14 -0
- package/dist/components/pagination.d.ts +13 -0
- package/dist/components/popover.d.ts +7 -0
- package/dist/components/progress.d.ts +4 -0
- package/dist/components/radio-group.d.ts +5 -0
- package/dist/components/resizable.d.ts +8 -0
- package/dist/components/scroll-area.d.ts +5 -0
- package/dist/components/select.d.ts +15 -0
- package/dist/components/separator.d.ts +4 -0
- package/dist/components/sheet.d.ts +13 -0
- package/dist/components/sidebar.d.ts +69 -0
- package/dist/components/skeleton.d.ts +2 -0
- package/dist/components/slider.d.ts +4 -0
- package/dist/components/sonner.d.ts +3 -0
- package/dist/components/spinner.d.ts +2 -0
- package/dist/components/switch.d.ts +4 -0
- package/dist/components/table.d.ts +10 -0
- package/dist/components/tabs.d.ts +7 -0
- package/dist/components/textarea.d.ts +3 -0
- package/dist/components/toggle-group.d.ts +9 -0
- package/dist/components/toggle.d.ts +9 -0
- package/dist/components/tooltip.d.ts +7 -0
- package/dist/design-system.css +1 -0
- package/dist/design-system.es.js +30200 -0
- package/dist/design-system.umd.js +260 -0
- package/dist/foundations/ThemeProvider.d.ts +13 -0
- package/dist/hooks/use-mobile.d.ts +1 -0
- package/dist/index.d.ts +54 -0
- package/dist/lib/utils.d.ts +2 -0
- package/package.json +14 -1
- package/.husky/pre-push +0 -21
- package/.storybook/main.ts +0 -11
- package/.storybook/preview.tsx +0 -30
- package/.vscode/settings.json +0 -12
- package/.vscode/tailwind.json +0 -105
- package/bitbucket-pipelines.yml +0 -50
- package/components.json +0 -21
- package/eslint.config.js +0 -38
- package/src/components/accordion.stories.tsx +0 -258
- package/src/components/accordion.test.tsx +0 -390
- package/src/components/accordion.tsx +0 -64
- package/src/components/alert-dialog.stories.tsx +0 -213
- package/src/components/alert-dialog.test.tsx +0 -80
- package/src/components/alert-dialog.tsx +0 -155
- package/src/components/alert.stories.tsx +0 -84
- package/src/components/alert.test.tsx +0 -35
- package/src/components/alert.tsx +0 -66
- package/src/components/aspect-ratio.stories.tsx +0 -97
- package/src/components/aspect-ratio.test.tsx +0 -47
- package/src/components/aspect-ratio.tsx +0 -11
- package/src/components/avatar.stories.tsx +0 -76
- package/src/components/avatar.test.tsx +0 -50
- package/src/components/avatar.tsx +0 -51
- package/src/components/badge.stories.tsx +0 -64
- package/src/components/badge.test.tsx +0 -34
- package/src/components/badge.tsx +0 -46
- package/src/components/breadcrumb.stories.tsx +0 -86
- package/src/components/breadcrumb.test.tsx +0 -74
- package/src/components/breadcrumb.tsx +0 -109
- package/src/components/button-group.stories.tsx +0 -62
- package/src/components/button-group.tsx +0 -83
- package/src/components/button.stories.tsx +0 -118
- package/src/components/button.test.tsx +0 -64
- package/src/components/button.tsx +0 -62
- package/src/components/calendar.stories.tsx +0 -81
- package/src/components/calendar.tsx +0 -220
- package/src/components/card.stories.tsx +0 -110
- package/src/components/card.test.tsx +0 -56
- package/src/components/card.tsx +0 -92
- package/src/components/carousel.stories.tsx +0 -90
- package/src/components/carousel.tsx +0 -239
- package/src/components/chart.tsx +0 -357
- package/src/components/checkbox.stories.tsx +0 -108
- package/src/components/checkbox.test.tsx +0 -67
- package/src/components/checkbox.tsx +0 -32
- package/src/components/collapsible.stories.tsx +0 -106
- package/src/components/collapsible.test.tsx +0 -92
- package/src/components/collapsible.tsx +0 -31
- package/src/components/command.stories.tsx +0 -90
- package/src/components/command.tsx +0 -182
- package/src/components/context-menu.stories.tsx +0 -63
- package/src/components/context-menu.tsx +0 -252
- package/src/components/dialog.stories.tsx +0 -128
- package/src/components/dialog.tsx +0 -141
- package/src/components/drawer.stories.tsx +0 -104
- package/src/components/drawer.tsx +0 -135
- package/src/components/dropdown-menu.stories.tsx +0 -97
- package/src/components/dropdown-menu.tsx +0 -255
- package/src/components/empty.stories.tsx +0 -90
- package/src/components/empty.test.tsx +0 -55
- package/src/components/empty.tsx +0 -104
- package/src/components/field.tsx +0 -246
- package/src/components/form.tsx +0 -168
- package/src/components/hover-card.stories.tsx +0 -66
- package/src/components/hover-card.tsx +0 -44
- package/src/components/input-group.stories.tsx +0 -57
- package/src/components/input-group.test.tsx +0 -40
- package/src/components/input-group.tsx +0 -170
- package/src/components/input-otp.stories.tsx +0 -94
- package/src/components/input-otp.test.tsx +0 -60
- package/src/components/input-otp.tsx +0 -75
- package/src/components/input.stories.tsx +0 -94
- package/src/components/input.test.tsx +0 -53
- package/src/components/input.tsx +0 -21
- package/src/components/item.tsx +0 -193
- package/src/components/kbd.stories.tsx +0 -100
- package/src/components/kbd.test.tsx +0 -28
- package/src/components/kbd.tsx +0 -28
- package/src/components/label.stories.tsx +0 -48
- package/src/components/label.test.tsx +0 -28
- package/src/components/label.tsx +0 -24
- package/src/components/menubar.tsx +0 -274
- package/src/components/navigation-menu.tsx +0 -168
- package/src/components/pagination.stories.tsx +0 -107
- package/src/components/pagination.tsx +0 -127
- package/src/components/popover.stories.tsx +0 -102
- package/src/components/popover.tsx +0 -48
- package/src/components/progress.stories.tsx +0 -76
- package/src/components/progress.test.tsx +0 -36
- package/src/components/progress.tsx +0 -29
- package/src/components/radio-group.stories.tsx +0 -73
- package/src/components/radio-group.test.tsx +0 -74
- package/src/components/radio-group.tsx +0 -45
- package/src/components/resizable.stories.tsx +0 -120
- package/src/components/resizable.tsx +0 -54
- package/src/components/scroll-area.stories.tsx +0 -64
- package/src/components/scroll-area.test.tsx +0 -46
- package/src/components/scroll-area.tsx +0 -58
- package/src/components/select.stories.tsx +0 -111
- package/src/components/select.test.tsx +0 -90
- package/src/components/select.tsx +0 -188
- package/src/components/separator.stories.tsx +0 -76
- package/src/components/separator.test.tsx +0 -24
- package/src/components/separator.tsx +0 -28
- package/src/components/sheet.stories.tsx +0 -122
- package/src/components/sheet.tsx +0 -137
- package/src/components/sidebar.tsx +0 -726
- package/src/components/skeleton.stories.tsx +0 -53
- package/src/components/skeleton.test.tsx +0 -24
- package/src/components/skeleton.tsx +0 -13
- package/src/components/slider.stories.tsx +0 -97
- package/src/components/slider.test.tsx +0 -49
- package/src/components/slider.tsx +0 -63
- package/src/components/sonner.stories.tsx +0 -96
- package/src/components/sonner.tsx +0 -38
- package/src/components/spinner.stories.tsx +0 -54
- package/src/components/spinner.test.tsx +0 -30
- package/src/components/spinner.tsx +0 -16
- package/src/components/switch.stories.tsx +0 -108
- package/src/components/switch.test.tsx +0 -62
- package/src/components/switch.tsx +0 -31
- package/src/components/table.stories.tsx +0 -139
- package/src/components/table.test.tsx +0 -85
- package/src/components/table.tsx +0 -114
- package/src/components/tabs.stories.tsx +0 -99
- package/src/components/tabs.test.tsx +0 -64
- package/src/components/tabs.tsx +0 -66
- package/src/components/textarea.stories.tsx +0 -89
- package/src/components/textarea.test.tsx +0 -53
- package/src/components/textarea.tsx +0 -18
- package/src/components/toggle-group.stories.tsx +0 -108
- package/src/components/toggle-group.test.tsx +0 -66
- package/src/components/toggle-group.tsx +0 -81
- package/src/components/toggle.stories.tsx +0 -98
- package/src/components/toggle.test.tsx +0 -42
- package/src/components/toggle.tsx +0 -45
- package/src/components/tooltip.stories.tsx +0 -111
- package/src/components/tooltip.tsx +0 -61
- package/src/foundations/README.md +0 -141
- package/src/foundations/ThemeProvider.tsx +0 -77
- package/src/foundations/color.css +0 -232
- package/src/foundations/color.stories.tsx +0 -719
- package/src/foundations/palette.css +0 -249
- package/src/foundations/spacing.css +0 -8
- package/src/foundations/typography.css +0 -143
- package/src/foundations/typography.stories.tsx +0 -17
- package/src/hooks/use-mobile.ts +0 -19
- package/src/index.css +0 -176
- package/src/index.ts +0 -336
- package/src/lib/utils.ts +0 -6
- package/src/test/setup.ts +0 -8
- package/src/vite-env.d.ts +0 -1
- package/tsconfig.app.json +0 -33
- package/tsconfig.json +0 -13
- package/tsconfig.node.json +0 -25
- package/vite.config.ts +0 -30
- package/vitest.config.ts +0 -25
- /package/{public → dist}/vite.svg +0 -0
package/src/components/empty.tsx
DELETED
|
@@ -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
|
-
}
|
package/src/components/field.tsx
DELETED
|
@@ -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
|
-
};
|
package/src/components/form.tsx
DELETED
|
@@ -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
|
-
};
|