@autono/create-open-pages 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/package.json +1 -1
- package/template/.agents/skills/create-page/SKILL.md +1 -1
- package/template/.agents/skills/page-authoring/SKILL.md +2 -2
- package/template/.agents/skills/page-authoring/references/interactivity.md +14 -22
- package/template/components.json +19 -3
- package/template/package.json +12 -12
- package/template/styles/globals.css +83 -66
- package/template/ui/accordion.tsx +22 -7
- package/template/ui/alert-dialog.tsx +22 -21
- package/template/ui/alert.tsx +15 -5
- package/template/ui/avatar.tsx +7 -4
- package/template/ui/badge.tsx +8 -7
- package/template/ui/breadcrumb.tsx +21 -8
- package/template/ui/button-group.tsx +5 -5
- package/template/ui/button.tsx +18 -15
- package/template/ui/calendar.tsx +28 -24
- package/template/ui/card.tsx +17 -6
- package/template/ui/carousel.tsx +10 -11
- package/template/ui/chart.tsx +1 -2
- package/template/ui/checkbox.tsx +5 -6
- package/template/ui/collapsible.tsx +2 -0
- package/template/ui/combobox.tsx +9 -20
- package/template/ui/command.tsx +39 -26
- package/template/ui/context-menu.tsx +69 -60
- package/template/ui/dialog.tsx +26 -14
- package/template/ui/drawer.tsx +8 -9
- package/template/ui/dropdown-menu.tsx +34 -22
- package/template/ui/empty.tsx +8 -8
- package/template/ui/field.tsx +15 -25
- package/template/ui/hover-card.tsx +1 -1
- package/template/ui/input-group.tsx +10 -24
- package/template/ui/input-otp.tsx +16 -6
- package/template/ui/input.tsx +1 -3
- package/template/ui/item.tsx +17 -14
- package/template/ui/kbd.tsx +1 -3
- package/template/ui/menubar.tsx +28 -24
- package/template/ui/message-scroller.tsx +5 -4
- package/template/ui/native-select.tsx +13 -14
- package/template/ui/navigation-menu.tsx +8 -12
- package/template/ui/pagination.tsx +35 -33
- package/template/ui/popover.tsx +5 -5
- package/template/ui/progress.tsx +2 -2
- package/template/ui/radio-group.tsx +4 -5
- package/template/ui/resizable.tsx +2 -5
- package/template/ui/scroll-area.tsx +2 -5
- package/template/ui/select.tsx +26 -24
- package/template/ui/separator.tsx +1 -1
- package/template/ui/sheet.tsx +20 -16
- package/template/ui/sidebar.tsx +39 -63
- package/template/ui/skeleton.tsx +1 -1
- package/template/ui/slider.tsx +6 -8
- package/template/ui/sonner.tsx +21 -14
- package/template/ui/spinner.tsx +2 -8
- package/template/ui/switch.tsx +4 -4
- package/template/ui/table.tsx +2 -4
- package/template/ui/tabs.tsx +9 -8
- package/template/ui/textarea.tsx +1 -1
- package/template/ui/toggle-group.tsx +14 -8
- package/template/ui/toggle.tsx +8 -10
- package/template/ui/tooltip.tsx +4 -2
- package/template/ui/form.tsx +0 -167
package/template/ui/table.tsx
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
1
|
import * as React from "react"
|
|
4
2
|
|
|
5
3
|
import { cn } from "@/lib/utils"
|
|
@@ -70,7 +68,7 @@ function TableHead({ className, ...props }: React.ComponentProps<"th">) {
|
|
|
70
68
|
<th
|
|
71
69
|
data-slot="table-head"
|
|
72
70
|
className={cn(
|
|
73
|
-
"h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0
|
|
71
|
+
"h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
|
|
74
72
|
className
|
|
75
73
|
)}
|
|
76
74
|
{...props}
|
|
@@ -83,7 +81,7 @@ function TableCell({ className, ...props }: React.ComponentProps<"td">) {
|
|
|
83
81
|
<td
|
|
84
82
|
data-slot="table-cell"
|
|
85
83
|
className={cn(
|
|
86
|
-
"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0
|
|
84
|
+
"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
|
|
87
85
|
className
|
|
88
86
|
)}
|
|
89
87
|
{...props}
|
package/template/ui/tabs.tsx
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
1
3
|
import * as React from "react"
|
|
2
4
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
3
5
|
import { Tabs as TabsPrimitive } from "radix-ui"
|
|
@@ -13,9 +15,8 @@ function Tabs({
|
|
|
13
15
|
<TabsPrimitive.Root
|
|
14
16
|
data-slot="tabs"
|
|
15
17
|
data-orientation={orientation}
|
|
16
|
-
orientation={orientation}
|
|
17
18
|
className={cn(
|
|
18
|
-
"group/tabs flex gap-2 data-
|
|
19
|
+
"group/tabs flex gap-2 data-horizontal:flex-col",
|
|
19
20
|
className
|
|
20
21
|
)}
|
|
21
22
|
{...props}
|
|
@@ -24,7 +25,7 @@ function Tabs({
|
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
const tabsListVariants = cva(
|
|
27
|
-
"group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-
|
|
28
|
+
"group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none",
|
|
28
29
|
{
|
|
29
30
|
variants: {
|
|
30
31
|
variant: {
|
|
@@ -62,10 +63,10 @@ function TabsTrigger({
|
|
|
62
63
|
<TabsPrimitive.Trigger
|
|
63
64
|
data-slot="tabs-trigger"
|
|
64
65
|
className={cn(
|
|
65
|
-
"relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-
|
|
66
|
-
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-
|
|
67
|
-
"data-
|
|
68
|
-
"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-
|
|
66
|
+
"relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
67
|
+
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent",
|
|
68
|
+
"data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground",
|
|
69
|
+
"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
|
|
69
70
|
className
|
|
70
71
|
)}
|
|
71
72
|
{...props}
|
|
@@ -80,7 +81,7 @@ function TabsContent({
|
|
|
80
81
|
return (
|
|
81
82
|
<TabsPrimitive.Content
|
|
82
83
|
data-slot="tabs-content"
|
|
83
|
-
className={cn("flex-1 outline-none", className)}
|
|
84
|
+
className={cn("flex-1 text-sm outline-none", className)}
|
|
84
85
|
{...props}
|
|
85
86
|
/>
|
|
86
87
|
)
|
package/template/ui/textarea.tsx
CHANGED
|
@@ -7,7 +7,7 @@ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
|
|
|
7
7
|
<textarea
|
|
8
8
|
data-slot="textarea"
|
|
9
9
|
className={cn(
|
|
10
|
-
"flex field-sizing-content min-h-16 w-full rounded-
|
|
10
|
+
"flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
|
11
11
|
className
|
|
12
12
|
)}
|
|
13
13
|
{...props}
|
|
@@ -8,23 +8,27 @@ import { toggleVariants } from "@/ui/toggle"
|
|
|
8
8
|
const ToggleGroupContext = React.createContext<
|
|
9
9
|
VariantProps<typeof toggleVariants> & {
|
|
10
10
|
spacing?: number
|
|
11
|
+
orientation?: "horizontal" | "vertical"
|
|
11
12
|
}
|
|
12
13
|
>({
|
|
13
14
|
size: "default",
|
|
14
15
|
variant: "default",
|
|
15
|
-
spacing:
|
|
16
|
+
spacing: 2,
|
|
17
|
+
orientation: "horizontal",
|
|
16
18
|
})
|
|
17
19
|
|
|
18
20
|
function ToggleGroup({
|
|
19
21
|
className,
|
|
20
22
|
variant,
|
|
21
23
|
size,
|
|
22
|
-
spacing =
|
|
24
|
+
spacing = 2,
|
|
25
|
+
orientation = "horizontal",
|
|
23
26
|
children,
|
|
24
27
|
...props
|
|
25
28
|
}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
|
|
26
29
|
VariantProps<typeof toggleVariants> & {
|
|
27
30
|
spacing?: number
|
|
31
|
+
orientation?: "horizontal" | "vertical"
|
|
28
32
|
}) {
|
|
29
33
|
return (
|
|
30
34
|
<ToggleGroupPrimitive.Root
|
|
@@ -32,14 +36,17 @@ function ToggleGroup({
|
|
|
32
36
|
data-variant={variant}
|
|
33
37
|
data-size={size}
|
|
34
38
|
data-spacing={spacing}
|
|
39
|
+
data-orientation={orientation}
|
|
35
40
|
style={{ "--gap": spacing } as React.CSSProperties}
|
|
36
41
|
className={cn(
|
|
37
|
-
"group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-
|
|
42
|
+
"group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-vertical:flex-col data-vertical:items-stretch",
|
|
38
43
|
className
|
|
39
44
|
)}
|
|
40
45
|
{...props}
|
|
41
46
|
>
|
|
42
|
-
<ToggleGroupContext.Provider
|
|
47
|
+
<ToggleGroupContext.Provider
|
|
48
|
+
value={{ variant, size, spacing, orientation }}
|
|
49
|
+
>
|
|
43
50
|
{children}
|
|
44
51
|
</ToggleGroupContext.Provider>
|
|
45
52
|
</ToggleGroupPrimitive.Root>
|
|
@@ -49,8 +56,8 @@ function ToggleGroup({
|
|
|
49
56
|
function ToggleGroupItem({
|
|
50
57
|
className,
|
|
51
58
|
children,
|
|
52
|
-
variant,
|
|
53
|
-
size,
|
|
59
|
+
variant = "default",
|
|
60
|
+
size = "default",
|
|
54
61
|
...props
|
|
55
62
|
}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
|
|
56
63
|
VariantProps<typeof toggleVariants>) {
|
|
@@ -63,12 +70,11 @@ function ToggleGroupItem({
|
|
|
63
70
|
data-size={context.size || size}
|
|
64
71
|
data-spacing={context.spacing}
|
|
65
72
|
className={cn(
|
|
73
|
+
"shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t",
|
|
66
74
|
toggleVariants({
|
|
67
75
|
variant: context.variant || variant,
|
|
68
76
|
size: context.size || size,
|
|
69
77
|
}),
|
|
70
|
-
"w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10",
|
|
71
|
-
"data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l",
|
|
72
78
|
className
|
|
73
79
|
)}
|
|
74
80
|
{...props}
|
package/template/ui/toggle.tsx
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
1
|
import * as React from "react"
|
|
4
2
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
5
3
|
import { Toggle as TogglePrimitive } from "radix-ui"
|
|
@@ -7,18 +5,18 @@ import { Toggle as TogglePrimitive } from "radix-ui"
|
|
|
7
5
|
import { cn } from "@/lib/utils"
|
|
8
6
|
|
|
9
7
|
const toggleVariants = cva(
|
|
10
|
-
"inline-flex items-center justify-center gap-
|
|
8
|
+
"group/toggle inline-flex items-center justify-center gap-1 rounded-lg text-sm font-medium whitespace-nowrap transition-all outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted data-[state=on]:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
11
9
|
{
|
|
12
10
|
variants: {
|
|
13
11
|
variant: {
|
|
14
12
|
default: "bg-transparent",
|
|
15
|
-
outline:
|
|
16
|
-
"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
|
|
13
|
+
outline: "border border-input bg-transparent hover:bg-muted",
|
|
17
14
|
},
|
|
18
15
|
size: {
|
|
19
|
-
default:
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
default:
|
|
17
|
+
"h-8 min-w-8 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
18
|
+
sm: "h-7 min-w-7 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
|
19
|
+
lg: "h-9 min-w-9 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
22
20
|
},
|
|
23
21
|
},
|
|
24
22
|
defaultVariants: {
|
|
@@ -30,8 +28,8 @@ const toggleVariants = cva(
|
|
|
30
28
|
|
|
31
29
|
function Toggle({
|
|
32
30
|
className,
|
|
33
|
-
variant,
|
|
34
|
-
size,
|
|
31
|
+
variant = "default",
|
|
32
|
+
size = "default",
|
|
35
33
|
...props
|
|
36
34
|
}: React.ComponentProps<typeof TogglePrimitive.Root> &
|
|
37
35
|
VariantProps<typeof toggleVariants>) {
|
package/template/ui/tooltip.tsx
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
1
3
|
import * as React from "react"
|
|
2
4
|
import { Tooltip as TooltipPrimitive } from "radix-ui"
|
|
3
5
|
|
|
@@ -40,7 +42,7 @@ function TooltipContent({
|
|
|
40
42
|
data-slot="tooltip-content"
|
|
41
43
|
sideOffset={sideOffset}
|
|
42
44
|
className={cn(
|
|
43
|
-
"z-50 w-fit origin-(--radix-tooltip-content-transform-origin)
|
|
45
|
+
"z-50 inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 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 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
44
46
|
className
|
|
45
47
|
)}
|
|
46
48
|
{...props}
|
|
@@ -52,4 +54,4 @@ function TooltipContent({
|
|
|
52
54
|
)
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
export { Tooltip,
|
|
57
|
+
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }
|
package/template/ui/form.tsx
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
import type { Label as LabelPrimitive } from "radix-ui"
|
|
5
|
-
import { Slot } from "radix-ui"
|
|
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 "@/ui/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.Root>) {
|
|
108
|
-
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
|
|
109
|
-
|
|
110
|
-
return (
|
|
111
|
-
<Slot.Root
|
|
112
|
-
data-slot="form-control"
|
|
113
|
-
id={formItemId}
|
|
114
|
-
aria-describedby={
|
|
115
|
-
!error
|
|
116
|
-
? `${formDescriptionId}`
|
|
117
|
-
: `${formDescriptionId} ${formMessageId}`
|
|
118
|
-
}
|
|
119
|
-
aria-invalid={!!error}
|
|
120
|
-
{...props}
|
|
121
|
-
/>
|
|
122
|
-
)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function FormDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
126
|
-
const { formDescriptionId } = useFormField()
|
|
127
|
-
|
|
128
|
-
return (
|
|
129
|
-
<p
|
|
130
|
-
data-slot="form-description"
|
|
131
|
-
id={formDescriptionId}
|
|
132
|
-
className={cn("text-sm text-muted-foreground", className)}
|
|
133
|
-
{...props}
|
|
134
|
-
/>
|
|
135
|
-
)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function FormMessage({ className, ...props }: React.ComponentProps<"p">) {
|
|
139
|
-
const { error, formMessageId } = useFormField()
|
|
140
|
-
const body = error ? String(error?.message ?? "") : props.children
|
|
141
|
-
|
|
142
|
-
if (!body) {
|
|
143
|
-
return null
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return (
|
|
147
|
-
<p
|
|
148
|
-
data-slot="form-message"
|
|
149
|
-
id={formMessageId}
|
|
150
|
-
className={cn("text-sm text-destructive", className)}
|
|
151
|
-
{...props}
|
|
152
|
-
>
|
|
153
|
-
{body}
|
|
154
|
-
</p>
|
|
155
|
-
)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export {
|
|
159
|
-
useFormField,
|
|
160
|
-
Form,
|
|
161
|
-
FormItem,
|
|
162
|
-
FormLabel,
|
|
163
|
-
FormControl,
|
|
164
|
-
FormDescription,
|
|
165
|
-
FormMessage,
|
|
166
|
-
FormField,
|
|
167
|
-
}
|