@dinachi/cli 0.5.1 → 0.6.1
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/index.js +390 -13
- package/package.json +12 -5
- package/templates/accordion/accordion.tsx +8 -3
- package/templates/alert-dialog/alert-dialog.tsx +24 -25
- package/templates/alert-dialog/index.ts +1 -1
- package/templates/autocomplete/autocomplete.tsx +0 -1
- package/templates/avatar/avatar.tsx +1 -3
- package/templates/badge/badge.tsx +167 -0
- package/templates/badge/index.ts +2 -0
- package/templates/button/button.tsx +6 -6
- package/templates/button/index.ts +2 -2
- package/templates/card/card.tsx +78 -0
- package/templates/card/index.ts +1 -0
- package/templates/checkbox/checkbox.tsx +2 -3
- package/templates/checkbox-group/checkbox-group.tsx +1 -3
- package/templates/collapsible/collapsible.tsx +1 -2
- package/templates/combobox/combobox.tsx +0 -1
- package/templates/context-menu/context-menu.tsx +0 -1
- package/templates/dialog/dialog.tsx +1 -1
- package/templates/drawer/drawer.tsx +0 -1
- package/templates/field/field.tsx +69 -85
- package/templates/fieldset/fieldset.tsx +0 -1
- package/templates/form/form.tsx +36 -28
- package/templates/input/index.ts +1 -2
- package/templates/input/input.tsx +0 -1
- package/templates/menu/menu.tsx +0 -1
- package/templates/menubar/menubar.tsx +21 -22
- package/templates/meter/meter.tsx +0 -1
- package/templates/navigation-menu/index.ts +1 -13
- package/templates/navigation-menu/navigation-menu.tsx +1 -3
- package/templates/number-field/number-field.tsx +0 -1
- package/templates/popover/popover.tsx +0 -1
- package/templates/preview-card/preview-card.tsx +0 -1
- package/templates/progress/progress.tsx +0 -1
- package/templates/radio/radio.tsx +0 -1
- package/templates/scroll-area/scroll-area.tsx +0 -1
- package/templates/select/select.tsx +1 -4
- package/templates/separator/separator.tsx +0 -1
- package/templates/slider/index.ts +10 -0
- package/templates/slider/slider.tsx +1 -3
- package/templates/switch/switch.tsx +0 -1
- package/templates/tabs/index.ts +8 -0
- package/templates/tabs/tabs.tsx +8 -3
- package/templates/textarea/index.ts +2 -0
- package/templates/textarea/textarea.tsx +23 -0
- package/templates/toast/toast.tsx +3 -2
- package/templates/toggle/toggle.tsx +0 -1
- package/templates/toggle-group/toggle-group.tsx +0 -1
- package/templates/toolbar/toolbar.tsx +0 -1
- package/templates/tooltip/tooltip.tsx +0 -1
- package/templates/tsconfig.json +20 -0
- package/templates/utils/utils.ts +0 -1
- package/templates/utils/variants.ts +0 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
5
|
+
import { useRender } from '@base-ui/react/use-render'
|
|
6
|
+
import { cn } from "@/lib/utils"
|
|
7
|
+
|
|
8
|
+
const badgeVariants = cva(
|
|
9
|
+
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
default:
|
|
14
|
+
"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
|
|
15
|
+
secondary:
|
|
16
|
+
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
17
|
+
destructive:
|
|
18
|
+
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
19
|
+
outline: "text-foreground",
|
|
20
|
+
success:
|
|
21
|
+
"border-transparent bg-green-500 text-white hover:bg-green-600",
|
|
22
|
+
warning:
|
|
23
|
+
"border-transparent bg-yellow-500 text-yellow-900 hover:bg-yellow-600",
|
|
24
|
+
info:
|
|
25
|
+
"border-transparent bg-blue-500 text-white hover:bg-blue-600",
|
|
26
|
+
},
|
|
27
|
+
size: {
|
|
28
|
+
sm: "px-2 py-0.5 text-xs",
|
|
29
|
+
default: "px-2.5 py-0.5 text-xs",
|
|
30
|
+
lg: "px-3 py-1 text-sm",
|
|
31
|
+
},
|
|
32
|
+
rounded: {
|
|
33
|
+
default: "rounded-full",
|
|
34
|
+
sm: "rounded-sm",
|
|
35
|
+
md: "rounded-md",
|
|
36
|
+
lg: "rounded-lg",
|
|
37
|
+
none: "rounded-none",
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
defaultVariants: {
|
|
41
|
+
variant: "default",
|
|
42
|
+
size: "default",
|
|
43
|
+
rounded: "default",
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
type BadgeElement = React.ComponentRef<"div">
|
|
49
|
+
|
|
50
|
+
export interface BadgeProps
|
|
51
|
+
extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'>,
|
|
52
|
+
VariantProps<typeof badgeVariants> {
|
|
53
|
+
/**
|
|
54
|
+
* The content of the badge
|
|
55
|
+
*/
|
|
56
|
+
children?: React.ReactNode
|
|
57
|
+
/**
|
|
58
|
+
* Custom render prop for composition
|
|
59
|
+
*/
|
|
60
|
+
render?: React.ReactElement
|
|
61
|
+
/**
|
|
62
|
+
* Whether the badge should be interactive (clickable)
|
|
63
|
+
*/
|
|
64
|
+
interactive?: boolean
|
|
65
|
+
/**
|
|
66
|
+
* Icon to display before the content
|
|
67
|
+
*/
|
|
68
|
+
icon?: React.ReactNode
|
|
69
|
+
/**
|
|
70
|
+
* Whether to show a close button
|
|
71
|
+
*/
|
|
72
|
+
dismissible?: boolean
|
|
73
|
+
/**
|
|
74
|
+
* Callback when close button is clicked
|
|
75
|
+
*/
|
|
76
|
+
onDismiss?: () => void
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const Badge = React.forwardRef<BadgeElement, BadgeProps>(
|
|
80
|
+
({
|
|
81
|
+
className,
|
|
82
|
+
variant,
|
|
83
|
+
size,
|
|
84
|
+
rounded,
|
|
85
|
+
children,
|
|
86
|
+
render = <div />,
|
|
87
|
+
interactive = false,
|
|
88
|
+
icon,
|
|
89
|
+
dismissible = false,
|
|
90
|
+
onDismiss,
|
|
91
|
+
onClick,
|
|
92
|
+
...props
|
|
93
|
+
}, ref) => {
|
|
94
|
+
// Handle keyboard interaction for dismissible badges
|
|
95
|
+
const handleKeyDown = React.useCallback((event: React.KeyboardEvent) => {
|
|
96
|
+
if (dismissible && onDismiss && (event.key === 'Delete' || event.key === 'Backspace')) {
|
|
97
|
+
event.preventDefault()
|
|
98
|
+
onDismiss()
|
|
99
|
+
}
|
|
100
|
+
}, [dismissible, onDismiss])
|
|
101
|
+
|
|
102
|
+
// Handle click for interactive badges
|
|
103
|
+
const handleClick = React.useCallback((event: React.MouseEvent<HTMLDivElement>) => {
|
|
104
|
+
if (interactive && onClick) {
|
|
105
|
+
onClick(event)
|
|
106
|
+
}
|
|
107
|
+
}, [interactive, onClick])
|
|
108
|
+
|
|
109
|
+
// Compute classes once
|
|
110
|
+
const badgeClasses = React.useMemo(() =>
|
|
111
|
+
cn(
|
|
112
|
+
badgeVariants({ variant, size, rounded }),
|
|
113
|
+
{
|
|
114
|
+
'cursor-pointer hover:opacity-80': interactive,
|
|
115
|
+
'focus:ring-2 focus:ring-offset-2': interactive || dismissible,
|
|
116
|
+
},
|
|
117
|
+
className
|
|
118
|
+
),
|
|
119
|
+
[variant, size, rounded, interactive, dismissible, className]
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
const content = (
|
|
123
|
+
<>
|
|
124
|
+
{icon && <span className="mr-1 shrink-0">{icon}</span>}
|
|
125
|
+
{children}
|
|
126
|
+
{dismissible && (
|
|
127
|
+
<button
|
|
128
|
+
type="button"
|
|
129
|
+
onClick={onDismiss}
|
|
130
|
+
className="ml-1 shrink-0 rounded-full p-0.5 hover:bg-black/10 focus:outline-none focus:ring-1 focus:ring-black/20"
|
|
131
|
+
aria-label="Remove badge"
|
|
132
|
+
>
|
|
133
|
+
<svg
|
|
134
|
+
className="h-3 w-3"
|
|
135
|
+
fill="none"
|
|
136
|
+
stroke="currentColor"
|
|
137
|
+
viewBox="0 0 24 24"
|
|
138
|
+
aria-hidden="true"
|
|
139
|
+
>
|
|
140
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
|
141
|
+
</svg>
|
|
142
|
+
</button>
|
|
143
|
+
)}
|
|
144
|
+
</>
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
return useRender({
|
|
148
|
+
render: React.cloneElement(render, {
|
|
149
|
+
ref,
|
|
150
|
+
className: badgeClasses,
|
|
151
|
+
onClick: handleClick,
|
|
152
|
+
onKeyDown: handleKeyDown,
|
|
153
|
+
tabIndex: interactive || dismissible ? 0 : undefined,
|
|
154
|
+
role: interactive ? 'button' : dismissible ? 'button' : undefined,
|
|
155
|
+
'aria-label': interactive ? 'Interactive badge' : dismissible ? 'Dismissible badge' : undefined,
|
|
156
|
+
...props,
|
|
157
|
+
}),
|
|
158
|
+
props: {
|
|
159
|
+
children: content,
|
|
160
|
+
},
|
|
161
|
+
})
|
|
162
|
+
}
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
Badge.displayName = "Badge"
|
|
166
|
+
|
|
167
|
+
export { Badge, badgeVariants }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import * as React from "react"
|
|
2
|
+
import { Button as BaseButton } from "@base-ui/react/button"
|
|
3
3
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
4
4
|
import { cn } from "@/lib/utils"
|
|
5
5
|
|
|
@@ -33,15 +33,15 @@ const buttonVariants = cva(
|
|
|
33
33
|
)
|
|
34
34
|
|
|
35
35
|
export interface ButtonProps
|
|
36
|
-
extends React.
|
|
36
|
+
extends Omit<React.ComponentPropsWithoutRef<typeof BaseButton>, 'className'>,
|
|
37
37
|
VariantProps<typeof buttonVariants> {
|
|
38
|
-
|
|
38
|
+
className?: string
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
const Button = React.forwardRef<
|
|
42
|
-
({ className, variant, size,
|
|
41
|
+
const Button = React.forwardRef<HTMLElement, ButtonProps>(
|
|
42
|
+
({ className, variant, size, ...props }, ref) => {
|
|
43
43
|
return (
|
|
44
|
-
<
|
|
44
|
+
<BaseButton
|
|
45
45
|
className={cn(buttonVariants({ variant, size, className }))}
|
|
46
46
|
ref={ref}
|
|
47
47
|
{...props}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { Button, buttonVariants } from
|
|
2
|
-
export type { ButtonProps } from
|
|
1
|
+
export { Button, buttonVariants } from './button'
|
|
2
|
+
export type { ButtonProps } from './button'
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cn } from "@/lib/utils"
|
|
3
|
+
|
|
4
|
+
const Card = React.forwardRef<
|
|
5
|
+
HTMLDivElement,
|
|
6
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
7
|
+
>(({ className, ...props }, ref) => (
|
|
8
|
+
<div
|
|
9
|
+
ref={ref}
|
|
10
|
+
className={cn(
|
|
11
|
+
"rounded-lg border bg-card text-card-foreground shadow-sm",
|
|
12
|
+
className
|
|
13
|
+
)}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
))
|
|
17
|
+
Card.displayName = "Card"
|
|
18
|
+
|
|
19
|
+
const CardHeader = React.forwardRef<
|
|
20
|
+
HTMLDivElement,
|
|
21
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
22
|
+
>(({ className, ...props }, ref) => (
|
|
23
|
+
<div
|
|
24
|
+
ref={ref}
|
|
25
|
+
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
|
26
|
+
{...props}
|
|
27
|
+
/>
|
|
28
|
+
))
|
|
29
|
+
CardHeader.displayName = "CardHeader"
|
|
30
|
+
|
|
31
|
+
const CardTitle = React.forwardRef<
|
|
32
|
+
HTMLParagraphElement,
|
|
33
|
+
React.HTMLAttributes<HTMLHeadingElement>
|
|
34
|
+
>(({ className, ...props }, ref) => (
|
|
35
|
+
<h3
|
|
36
|
+
ref={ref}
|
|
37
|
+
className={cn(
|
|
38
|
+
"text-2xl font-semibold leading-none tracking-tight",
|
|
39
|
+
className
|
|
40
|
+
)}
|
|
41
|
+
{...props}
|
|
42
|
+
/>
|
|
43
|
+
))
|
|
44
|
+
CardTitle.displayName = "CardTitle"
|
|
45
|
+
|
|
46
|
+
const CardDescription = React.forwardRef<
|
|
47
|
+
HTMLParagraphElement,
|
|
48
|
+
React.HTMLAttributes<HTMLParagraphElement>
|
|
49
|
+
>(({ className, ...props }, ref) => (
|
|
50
|
+
<p
|
|
51
|
+
ref={ref}
|
|
52
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
))
|
|
56
|
+
CardDescription.displayName = "CardDescription"
|
|
57
|
+
|
|
58
|
+
const CardContent = React.forwardRef<
|
|
59
|
+
HTMLDivElement,
|
|
60
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
61
|
+
>(({ className, ...props }, ref) => (
|
|
62
|
+
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
|
63
|
+
))
|
|
64
|
+
CardContent.displayName = "CardContent"
|
|
65
|
+
|
|
66
|
+
const CardFooter = React.forwardRef<
|
|
67
|
+
HTMLDivElement,
|
|
68
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
69
|
+
>(({ className, ...props }, ref) => (
|
|
70
|
+
<div
|
|
71
|
+
ref={ref}
|
|
72
|
+
className={cn("flex items-center p-6 pt-0", className)}
|
|
73
|
+
{...props}
|
|
74
|
+
/>
|
|
75
|
+
))
|
|
76
|
+
CardFooter.displayName = "CardFooter"
|
|
77
|
+
|
|
78
|
+
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } from './card'
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import * as React from "react";
|
|
3
|
-
import { Checkbox as BaseCheckbox } from
|
|
4
|
-
import { cn } from "@/lib/utils"
|
|
2
|
+
import { Checkbox as BaseCheckbox } from '@base-ui/react/checkbox';
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
5
4
|
import { Check } from "lucide-react";
|
|
6
5
|
|
|
7
6
|
const Checkbox = React.forwardRef<
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import * as React from "react";
|
|
3
2
|
import { CheckboxGroup as BaseCheckboxGroup } from "@base-ui/react/checkbox-group";
|
|
4
|
-
import { cn } from "@/lib/utils"
|
|
5
|
-
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
6
4
|
|
|
7
5
|
const CheckboxGroup = React.forwardRef<
|
|
8
6
|
React.ComponentRef<typeof BaseCheckboxGroup>,
|
|
@@ -1,112 +1,96 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import * as React from "react";
|
|
3
2
|
import { Field as BaseField } from "@base-ui/react/field";
|
|
4
|
-
import { cn } from "@/lib/utils"
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
5
4
|
|
|
6
5
|
const Field = React.forwardRef<
|
|
7
6
|
HTMLDivElement,
|
|
8
7
|
React.ComponentProps<typeof BaseField.Root>
|
|
9
|
-
>(({ className, ...props }, ref) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
className={cn("space-y-2", className)}
|
|
14
|
-
{...props}
|
|
15
|
-
/>
|
|
16
|
-
);
|
|
17
|
-
});
|
|
8
|
+
>(({ className, ...props }, ref) => (
|
|
9
|
+
<BaseField.Root ref={ref} className={cn("space-y-2", className)} {...props} />
|
|
10
|
+
));
|
|
11
|
+
Field.displayName = "Field";
|
|
18
12
|
|
|
19
13
|
const FieldLabel = React.forwardRef<
|
|
20
14
|
HTMLLabelElement,
|
|
21
15
|
React.ComponentProps<typeof BaseField.Label>
|
|
22
|
-
>(({ className, ...props }, ref) =>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
});
|
|
16
|
+
>(({ className, ...props }, ref) => (
|
|
17
|
+
<BaseField.Label
|
|
18
|
+
ref={ref}
|
|
19
|
+
className={cn(
|
|
20
|
+
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
21
|
+
"data-[invalid]:text-destructive",
|
|
22
|
+
className
|
|
23
|
+
)}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
));
|
|
27
|
+
FieldLabel.displayName = "FieldLabel";
|
|
35
28
|
|
|
36
29
|
const FieldControl = React.forwardRef<
|
|
37
30
|
HTMLInputElement,
|
|
38
31
|
React.ComponentProps<typeof BaseField.Control>
|
|
39
|
-
>(({ className, ...props }, ref) =>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
});
|
|
32
|
+
>(({ className, ...props }, ref) => (
|
|
33
|
+
<BaseField.Control
|
|
34
|
+
ref={ref}
|
|
35
|
+
className={cn(
|
|
36
|
+
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background",
|
|
37
|
+
"file:border-0 file:bg-transparent file:text-sm file:font-medium",
|
|
38
|
+
"placeholder:text-muted-foreground",
|
|
39
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
40
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
41
|
+
"data-[invalid]:border-destructive data-[invalid]:ring-destructive",
|
|
42
|
+
className
|
|
43
|
+
)}
|
|
44
|
+
{...props}
|
|
45
|
+
/>
|
|
46
|
+
));
|
|
47
|
+
FieldControl.displayName = "FieldControl";
|
|
56
48
|
|
|
57
49
|
const FieldDescription = React.forwardRef<
|
|
58
50
|
HTMLParagraphElement,
|
|
59
51
|
React.ComponentProps<typeof BaseField.Description>
|
|
60
|
-
>(({ className, ...props }, ref) =>
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
});
|
|
52
|
+
>(({ className, ...props }, ref) => (
|
|
53
|
+
<BaseField.Description
|
|
54
|
+
ref={ref}
|
|
55
|
+
className={cn(
|
|
56
|
+
"text-sm text-muted-foreground",
|
|
57
|
+
"data-[disabled]:opacity-50",
|
|
58
|
+
className
|
|
59
|
+
)}
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
));
|
|
63
|
+
FieldDescription.displayName = "FieldDescription";
|
|
73
64
|
|
|
74
65
|
const FieldError = React.forwardRef<
|
|
75
|
-
|
|
66
|
+
HTMLDivElement,
|
|
76
67
|
React.ComponentProps<typeof BaseField.Error>
|
|
77
|
-
>(({ className, ...props }, ref) =>
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
});
|
|
68
|
+
>(({ className, ...props }, ref) => (
|
|
69
|
+
<BaseField.Error
|
|
70
|
+
ref={ref}
|
|
71
|
+
className={cn(
|
|
72
|
+
"text-sm font-medium text-destructive",
|
|
73
|
+
"data-[disabled]:opacity-50",
|
|
74
|
+
className
|
|
75
|
+
)}
|
|
76
|
+
{...props}
|
|
77
|
+
/>
|
|
78
|
+
));
|
|
79
|
+
FieldError.displayName = "FieldError";
|
|
90
80
|
|
|
91
81
|
const FieldValidity = React.forwardRef<
|
|
92
82
|
HTMLDivElement,
|
|
93
|
-
React.ComponentProps<typeof BaseField.Validity> & {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
</
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
Field.displayName = "Field";
|
|
106
|
-
FieldLabel.displayName = "FieldLabel";
|
|
107
|
-
FieldControl.displayName = "FieldControl";
|
|
108
|
-
FieldDescription.displayName = "FieldDescription";
|
|
109
|
-
FieldError.displayName = "FieldError";
|
|
83
|
+
React.ComponentProps<typeof BaseField.Validity> & {
|
|
84
|
+
className?: string;
|
|
85
|
+
}
|
|
86
|
+
>(({ className, children, ...props }, ref) => (
|
|
87
|
+
<div
|
|
88
|
+
ref={ref}
|
|
89
|
+
className={cn("text-sm", "data-[disabled]:opacity-50", className)}
|
|
90
|
+
>
|
|
91
|
+
<BaseField.Validity {...props}>{children}</BaseField.Validity>
|
|
92
|
+
</div>
|
|
93
|
+
));
|
|
110
94
|
FieldValidity.displayName = "FieldValidity";
|
|
111
95
|
|
|
112
96
|
export {
|
package/templates/form/form.tsx
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
"use client"
|
|
3
2
|
|
|
4
3
|
import * as React from "react"
|
|
@@ -18,13 +17,10 @@ export interface FormState extends Record<string, unknown> {
|
|
|
18
17
|
// Form component props interface using useRender types
|
|
19
18
|
export interface FormProps extends useRender.ComponentProps<'form', FormState> {
|
|
20
19
|
/**
|
|
21
|
-
* Object containing field errors where keys are field names and values are error messages
|
|
20
|
+
* Object containing field errors where keys are field names and values are error messages.
|
|
21
|
+
* Errors are automatically cleared when the value changes (Base UI 1.0.0+).
|
|
22
22
|
*/
|
|
23
23
|
errors?: Errors
|
|
24
|
-
/**
|
|
25
|
-
* Callback function called when errors should be cleared
|
|
26
|
-
*/
|
|
27
|
-
onClearErrors?: (errors: Errors) => void
|
|
28
24
|
/**
|
|
29
25
|
* Form submission handler
|
|
30
26
|
*/
|
|
@@ -34,36 +30,48 @@ export interface FormProps extends useRender.ComponentProps<'form', FormState> {
|
|
|
34
30
|
const Form = React.forwardRef<
|
|
35
31
|
HTMLFormElement,
|
|
36
32
|
FormProps
|
|
37
|
-
>(({ className, errors = {},
|
|
33
|
+
>(({ className, errors = {}, render, children, onSubmit, ...props }, ref) => {
|
|
38
34
|
// Create form state object
|
|
39
35
|
const formState: FormState = React.useMemo(() => ({
|
|
40
36
|
errors
|
|
41
37
|
}), [errors])
|
|
42
38
|
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
39
|
+
// If using render prop, handle it with useRender
|
|
40
|
+
if (render && typeof render === 'function') {
|
|
41
|
+
// Function render prop
|
|
42
|
+
const defaultProps = {
|
|
43
|
+
className: cn("space-y-4", className),
|
|
44
|
+
onSubmit
|
|
45
|
+
}
|
|
46
|
+
const formProps = mergeProps<'form'>(defaultProps, props)
|
|
47
|
+
|
|
48
|
+
const element = useRender({
|
|
49
|
+
render,
|
|
50
|
+
props: formProps,
|
|
51
|
+
state: formState,
|
|
52
|
+
ref
|
|
53
|
+
})
|
|
54
|
+
return element
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
render
|
|
61
|
-
|
|
62
|
-
state: formState,
|
|
63
|
-
ref
|
|
64
|
-
})
|
|
57
|
+
if (render && React.isValidElement(render) && render.type !== 'form') {
|
|
58
|
+
// Element render prop - return the element directly (but not if it's the default <form />)
|
|
59
|
+
return render
|
|
60
|
+
}
|
|
65
61
|
|
|
66
|
-
|
|
62
|
+
// Default rendering using BaseForm
|
|
63
|
+
return (
|
|
64
|
+
<BaseForm
|
|
65
|
+
ref={ref}
|
|
66
|
+
className={cn("space-y-4", className)}
|
|
67
|
+
errors={errors}
|
|
68
|
+
onSubmit={onSubmit}
|
|
69
|
+
role="form"
|
|
70
|
+
{...props}
|
|
71
|
+
>
|
|
72
|
+
{children}
|
|
73
|
+
</BaseForm>
|
|
74
|
+
)
|
|
67
75
|
})
|
|
68
76
|
|
|
69
77
|
Form.displayName = "Form"
|
package/templates/input/index.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export { Input
|
|
2
|
-
export type { InputProps } from "./input"
|
|
1
|
+
export { Input } from "./input"
|
package/templates/menu/menu.tsx
CHANGED