generator-kodly-react-app 1.0.15 → 1.0.16
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/generators/app/index.js +4 -0
- package/generators/app/templates/I18N_MIGRATION.md +13 -13
- package/generators/app/templates/STRUCTURE.md +26 -26
- package/generators/app/templates/index.html +6 -14
- package/generators/app/templates/openapi-ts.config.ts +12 -12
- package/generators/app/templates/postcss.config.js +0 -1
- package/generators/app/templates/src/app.tsx +20 -20
- package/generators/app/templates/src/components/layout/language-switcher.tsx +20 -16
- package/generators/app/templates/src/components/layout/page-layout.tsx +31 -0
- package/generators/app/templates/src/components/layout/theme-switcher.tsx +15 -14
- package/generators/app/templates/src/components/theme/theme-provider.tsx +20 -13
- package/generators/app/templates/src/components/ui/button.tsx +15 -14
- package/generators/app/templates/src/components/ui/card.tsx +23 -16
- package/generators/app/templates/src/components/ui/field.tsx +35 -35
- package/generators/app/templates/src/components/ui/form.tsx +66 -30
- package/generators/app/templates/src/components/ui/input-group.tsx +24 -24
- package/generators/app/templates/src/components/ui/input.tsx +8 -8
- package/generators/app/templates/src/components/ui/label.tsx +9 -9
- package/generators/app/templates/src/components/ui/select.tsx +0 -1
- package/generators/app/templates/src/components/ui/separator.tsx +10 -10
- package/generators/app/templates/src/components/ui/textarea.tsx +7 -7
- package/generators/app/templates/src/index.css +12 -2
- package/generators/app/templates/src/lib/i18n.ts +16 -14
- package/generators/app/templates/src/lib/routes.ts +2 -3
- package/generators/app/templates/src/lib/utils/error-handler.ts +21 -14
- package/generators/app/templates/src/lib/utils.ts +3 -3
- package/generators/app/templates/src/locales/index.ts +12 -12
- package/generators/app/templates/src/locales/ja/theme.json +0 -1
- package/generators/app/templates/src/main.tsx +10 -12
- package/generators/app/templates/src/modules/app/layouts/app-layout.tsx +14 -25
- package/generators/app/templates/src/modules/app/locales/app-en.json +0 -1
- package/generators/app/templates/src/modules/app/locales/app-ja.json +0 -1
- package/generators/app/templates/src/modules/auth/components/auth-form.tsx +83 -0
- package/generators/app/templates/src/modules/auth/components/forgot-password-form.tsx +27 -52
- package/generators/app/templates/src/modules/auth/components/login-form.tsx +42 -72
- package/generators/app/templates/src/modules/auth/components/login-link.tsx +12 -0
- package/generators/app/templates/src/modules/auth/components/reset-password-form.tsx +46 -92
- package/generators/app/templates/src/modules/auth/components/signup-form.tsx +35 -71
- package/generators/app/templates/src/modules/auth/contexts/auth-context.tsx +10 -6
- package/generators/app/templates/src/modules/auth/hooks/use-auth-hook.ts +51 -36
- package/generators/app/templates/src/modules/auth/layouts/auth-layout.tsx +12 -15
- package/generators/app/templates/src/modules/auth/locales/auth-en.json +0 -1
- package/generators/app/templates/src/modules/auth/locales/auth-ja.json +0 -1
- package/generators/app/templates/src/modules/auth/schemas/form-schemas.ts +14 -10
- package/generators/app/templates/src/modules/landing/components/auth-hero.tsx +20 -18
- package/generators/app/templates/src/modules/landing/components/welcome-hero.tsx +13 -11
- package/generators/app/templates/src/modules/landing/landing-page-layout.tsx +1 -24
- package/generators/app/templates/src/modules/landing/landing-page.tsx +11 -6
- package/generators/app/templates/src/modules/landing/layouts/landing-page-layout.tsx +2 -21
- package/generators/app/templates/src/modules/landing/locales/landing-en.json +0 -1
- package/generators/app/templates/src/openapi-client-config.ts +1 -1
- package/generators/app/templates/src/routeTree.gen.ts +188 -188
- package/generators/app/templates/src/router.tsx +2 -2
- package/generators/app/templates/src/routes/$.tsx +0 -1
- package/generators/app/templates/src/routes/__root.tsx +2 -2
- package/generators/app/templates/src/routes/_landing/index.tsx +3 -3
- package/generators/app/templates/src/routes/_landing/route.tsx +3 -3
- package/generators/app/templates/src/routes/app/index.tsx +6 -6
- package/generators/app/templates/src/routes/app/route.tsx +4 -4
- package/generators/app/templates/src/routes/auth/forgot-password.tsx +1 -1
- package/generators/app/templates/src/routes/auth/login.tsx +3 -3
- package/generators/app/templates/src/routes/auth/reset-password.tsx +3 -3
- package/generators/app/templates/src/routes/auth/route.tsx +12 -7
- package/generators/app/templates/src/routes/auth/signup.tsx +1 -2
- package/generators/app/templates/src/sdk/@tanstack/react-query.gen.ts +157 -76
- package/generators/app/templates/src/sdk/client/client.gen.ts +35 -37
- package/generators/app/templates/src/sdk/client/index.ts +8 -8
- package/generators/app/templates/src/sdk/client/types.gen.ts +22 -19
- package/generators/app/templates/src/sdk/client/utils.gen.ts +53 -45
- package/generators/app/templates/src/sdk/client.gen.ts +18 -5
- package/generators/app/templates/src/sdk/core/auth.gen.ts +6 -6
- package/generators/app/templates/src/sdk/core/bodySerializer.gen.ts +25 -27
- package/generators/app/templates/src/sdk/core/params.gen.ts +12 -12
- package/generators/app/templates/src/sdk/core/pathSerializer.gen.ts +40 -41
- package/generators/app/templates/src/sdk/core/queryKeySerializer.gen.ts +12 -29
- package/generators/app/templates/src/sdk/core/serverSentEvents.gen.ts +26 -24
- package/generators/app/templates/src/sdk/core/types.gen.ts +17 -15
- package/generators/app/templates/src/sdk/core/utils.gen.ts +18 -18
- package/generators/app/templates/src/sdk/index.ts +40 -2
- package/generators/app/templates/src/sdk/schemas.gen.ts +108 -166
- package/generators/app/templates/src/sdk/sdk.gen.ts +145 -63
- package/generators/app/templates/src/sdk/types.gen.ts +90 -84
- package/generators/app/templates/src/sdk/zod.gen.ts +57 -74
- package/generators/app/templates/src/types/i18n.d.ts +0 -1
- package/generators/app/templates/tailwind.config.js +0 -1
- package/generators/app/templates/tsconfig.app.json +0 -1
- package/generators/app/templates/tsconfig.json +0 -1
- package/generators/app/templates/tsr.config.json +4 -0
- package/generators/app/templates/vite.config.js +12 -12
- package/package.json +2 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as React from "react"
|
|
1
|
+
import * as React from "react";
|
|
2
2
|
|
|
3
|
-
import { cn } from "@/lib/utils"
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
4
|
|
|
5
5
|
const Card = React.forwardRef<
|
|
6
6
|
HTMLDivElement,
|
|
@@ -10,12 +10,12 @@ const Card = React.forwardRef<
|
|
|
10
10
|
ref={ref}
|
|
11
11
|
className={cn(
|
|
12
12
|
"rounded-xl border bg-card text-card-foreground shadow",
|
|
13
|
-
className
|
|
13
|
+
className,
|
|
14
14
|
)}
|
|
15
15
|
{...props}
|
|
16
16
|
/>
|
|
17
|
-
))
|
|
18
|
-
Card.displayName = "Card"
|
|
17
|
+
));
|
|
18
|
+
Card.displayName = "Card";
|
|
19
19
|
|
|
20
20
|
const CardHeader = React.forwardRef<
|
|
21
21
|
HTMLDivElement,
|
|
@@ -26,8 +26,8 @@ const CardHeader = React.forwardRef<
|
|
|
26
26
|
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
|
27
27
|
{...props}
|
|
28
28
|
/>
|
|
29
|
-
))
|
|
30
|
-
CardHeader.displayName = "CardHeader"
|
|
29
|
+
));
|
|
30
|
+
CardHeader.displayName = "CardHeader";
|
|
31
31
|
|
|
32
32
|
const CardTitle = React.forwardRef<
|
|
33
33
|
HTMLDivElement,
|
|
@@ -38,8 +38,8 @@ const CardTitle = React.forwardRef<
|
|
|
38
38
|
className={cn("font-semibold leading-none tracking-tight", className)}
|
|
39
39
|
{...props}
|
|
40
40
|
/>
|
|
41
|
-
))
|
|
42
|
-
CardTitle.displayName = "CardTitle"
|
|
41
|
+
));
|
|
42
|
+
CardTitle.displayName = "CardTitle";
|
|
43
43
|
|
|
44
44
|
const CardDescription = React.forwardRef<
|
|
45
45
|
HTMLDivElement,
|
|
@@ -50,16 +50,16 @@ const CardDescription = React.forwardRef<
|
|
|
50
50
|
className={cn("text-sm text-muted-foreground", className)}
|
|
51
51
|
{...props}
|
|
52
52
|
/>
|
|
53
|
-
))
|
|
54
|
-
CardDescription.displayName = "CardDescription"
|
|
53
|
+
));
|
|
54
|
+
CardDescription.displayName = "CardDescription";
|
|
55
55
|
|
|
56
56
|
const CardContent = React.forwardRef<
|
|
57
57
|
HTMLDivElement,
|
|
58
58
|
React.HTMLAttributes<HTMLDivElement>
|
|
59
59
|
>(({ className, ...props }, ref) => (
|
|
60
60
|
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
|
61
|
-
))
|
|
62
|
-
CardContent.displayName = "CardContent"
|
|
61
|
+
));
|
|
62
|
+
CardContent.displayName = "CardContent";
|
|
63
63
|
|
|
64
64
|
const CardFooter = React.forwardRef<
|
|
65
65
|
HTMLDivElement,
|
|
@@ -70,7 +70,14 @@ const CardFooter = React.forwardRef<
|
|
|
70
70
|
className={cn("flex items-center p-6 pt-0", className)}
|
|
71
71
|
{...props}
|
|
72
72
|
/>
|
|
73
|
-
))
|
|
74
|
-
CardFooter.displayName = "CardFooter"
|
|
73
|
+
));
|
|
74
|
+
CardFooter.displayName = "CardFooter";
|
|
75
75
|
|
|
76
|
-
export {
|
|
76
|
+
export {
|
|
77
|
+
Card,
|
|
78
|
+
CardHeader,
|
|
79
|
+
CardFooter,
|
|
80
|
+
CardTitle,
|
|
81
|
+
CardDescription,
|
|
82
|
+
CardContent,
|
|
83
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { useMemo } from "react"
|
|
2
|
-
import { cva, type VariantProps } from "class-variance-authority"
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
3
|
|
|
4
|
-
import { cn } from "@/lib/utils"
|
|
5
|
-
import { Label } from "@/components/ui/label"
|
|
6
|
-
import { Separator } from "@/components/ui/separator"
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
import { Label } from "@/components/ui/label";
|
|
6
|
+
import { Separator } from "@/components/ui/separator";
|
|
7
7
|
|
|
8
8
|
function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
|
|
9
9
|
return (
|
|
@@ -12,11 +12,11 @@ function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
|
|
|
12
12
|
className={cn(
|
|
13
13
|
"flex flex-col gap-6",
|
|
14
14
|
"has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
|
|
15
|
-
className
|
|
15
|
+
className,
|
|
16
16
|
)}
|
|
17
17
|
{...props}
|
|
18
18
|
/>
|
|
19
|
-
)
|
|
19
|
+
);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function FieldLegend({
|
|
@@ -32,11 +32,11 @@ function FieldLegend({
|
|
|
32
32
|
"mb-3 font-medium",
|
|
33
33
|
"data-[variant=legend]:text-base",
|
|
34
34
|
"data-[variant=label]:text-sm",
|
|
35
|
-
className
|
|
35
|
+
className,
|
|
36
36
|
)}
|
|
37
37
|
{...props}
|
|
38
38
|
/>
|
|
39
|
-
)
|
|
39
|
+
);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
@@ -45,11 +45,11 @@ function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
45
45
|
data-slot="field-group"
|
|
46
46
|
className={cn(
|
|
47
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
|
|
48
|
+
className,
|
|
49
49
|
)}
|
|
50
50
|
{...props}
|
|
51
51
|
/>
|
|
52
|
-
)
|
|
52
|
+
);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
const fieldVariants = cva(
|
|
@@ -73,8 +73,8 @@ const fieldVariants = cva(
|
|
|
73
73
|
defaultVariants: {
|
|
74
74
|
orientation: "vertical",
|
|
75
75
|
},
|
|
76
|
-
}
|
|
77
|
-
)
|
|
76
|
+
},
|
|
77
|
+
);
|
|
78
78
|
|
|
79
79
|
function Field({
|
|
80
80
|
className,
|
|
@@ -89,7 +89,7 @@ function Field({
|
|
|
89
89
|
className={cn(fieldVariants({ orientation }), className)}
|
|
90
90
|
{...props}
|
|
91
91
|
/>
|
|
92
|
-
)
|
|
92
|
+
);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
@@ -98,11 +98,11 @@ function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
98
98
|
data-slot="field-content"
|
|
99
99
|
className={cn(
|
|
100
100
|
"group/field-content flex flex-1 flex-col gap-1.5 leading-snug",
|
|
101
|
-
className
|
|
101
|
+
className,
|
|
102
102
|
)}
|
|
103
103
|
{...props}
|
|
104
104
|
/>
|
|
105
|
-
)
|
|
105
|
+
);
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
function FieldLabel({
|
|
@@ -116,11 +116,11 @@ function FieldLabel({
|
|
|
116
116
|
"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
|
|
117
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
118
|
"has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10",
|
|
119
|
-
className
|
|
119
|
+
className,
|
|
120
120
|
)}
|
|
121
121
|
{...props}
|
|
122
122
|
/>
|
|
123
|
-
)
|
|
123
|
+
);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
|
|
@@ -129,11 +129,11 @@ function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
129
129
|
data-slot="field-label"
|
|
130
130
|
className={cn(
|
|
131
131
|
"flex w-fit items-center gap-2 text-sm font-medium leading-snug group-data-[disabled=true]/field:opacity-50",
|
|
132
|
-
className
|
|
132
|
+
className,
|
|
133
133
|
)}
|
|
134
134
|
{...props}
|
|
135
135
|
/>
|
|
136
|
-
)
|
|
136
|
+
);
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
@@ -144,11 +144,11 @@ function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
|
144
144
|
"text-muted-foreground text-sm font-normal leading-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
|
|
145
145
|
"nth-last-2:-mt-1 last:mt-0 [[data-variant=legend]+&]:-mt-1.5",
|
|
146
146
|
"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
|
|
147
|
-
className
|
|
147
|
+
className,
|
|
148
148
|
)}
|
|
149
149
|
{...props}
|
|
150
150
|
/>
|
|
151
|
-
)
|
|
151
|
+
);
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
function FieldSeparator({
|
|
@@ -156,7 +156,7 @@ function FieldSeparator({
|
|
|
156
156
|
className,
|
|
157
157
|
...props
|
|
158
158
|
}: React.ComponentProps<"div"> & {
|
|
159
|
-
children?: React.ReactNode
|
|
159
|
+
children?: React.ReactNode;
|
|
160
160
|
}) {
|
|
161
161
|
return (
|
|
162
162
|
<div
|
|
@@ -164,7 +164,7 @@ function FieldSeparator({
|
|
|
164
164
|
data-content={!!children}
|
|
165
165
|
className={cn(
|
|
166
166
|
"relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
|
|
167
|
-
className
|
|
167
|
+
className,
|
|
168
168
|
)}
|
|
169
169
|
{...props}
|
|
170
170
|
>
|
|
@@ -178,7 +178,7 @@ function FieldSeparator({
|
|
|
178
178
|
</span>
|
|
179
179
|
)}
|
|
180
180
|
</div>
|
|
181
|
-
)
|
|
181
|
+
);
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
function FieldError({
|
|
@@ -187,33 +187,33 @@ function FieldError({
|
|
|
187
187
|
errors,
|
|
188
188
|
...props
|
|
189
189
|
}: React.ComponentProps<"div"> & {
|
|
190
|
-
errors?: Array<{ message?: string } | undefined
|
|
190
|
+
errors?: Array<{ message?: string } | undefined>;
|
|
191
191
|
}) {
|
|
192
192
|
const content = useMemo(() => {
|
|
193
193
|
if (children) {
|
|
194
|
-
return children
|
|
194
|
+
return children;
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
if (!errors) {
|
|
198
|
-
return null
|
|
198
|
+
return null;
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
if (errors?.length === 1 && errors[0]?.message) {
|
|
202
|
-
return errors[0].message
|
|
202
|
+
return errors[0].message;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
return (
|
|
206
206
|
<ul className="ml-4 flex list-disc flex-col gap-1">
|
|
207
207
|
{errors.map(
|
|
208
208
|
(error, index) =>
|
|
209
|
-
error?.message && <li key={index}>{error.message}</li
|
|
209
|
+
error?.message && <li key={index}>{error.message}</li>,
|
|
210
210
|
)}
|
|
211
211
|
</ul>
|
|
212
|
-
)
|
|
213
|
-
}, [children, errors])
|
|
212
|
+
);
|
|
213
|
+
}, [children, errors]);
|
|
214
214
|
|
|
215
215
|
if (!content) {
|
|
216
|
-
return null
|
|
216
|
+
return null;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
return (
|
|
@@ -225,7 +225,7 @@ function FieldError({
|
|
|
225
225
|
>
|
|
226
226
|
{content}
|
|
227
227
|
</div>
|
|
228
|
-
)
|
|
228
|
+
);
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
export {
|
|
@@ -239,4 +239,4 @@ export {
|
|
|
239
239
|
FieldSet,
|
|
240
240
|
FieldContent,
|
|
241
241
|
FieldTitle,
|
|
242
|
-
}
|
|
242
|
+
};
|
|
@@ -1,20 +1,36 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import * as LabelPrimitive from
|
|
3
|
-
import { Slot } from
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
3
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
4
|
+
import {
|
|
5
|
+
Controller,
|
|
6
|
+
FormProvider,
|
|
7
|
+
useFormContext,
|
|
8
|
+
useFormState,
|
|
9
|
+
type ControllerProps,
|
|
10
|
+
type FieldPath,
|
|
11
|
+
type FieldValues,
|
|
12
|
+
} from "react-hook-form";
|
|
13
|
+
|
|
14
|
+
import { cn } from "@/lib/utils";
|
|
15
|
+
import { Label } from "@/components/ui/label";
|
|
8
16
|
|
|
9
17
|
const Form = FormProvider;
|
|
10
18
|
|
|
11
|
-
type FormFieldContextValue<
|
|
19
|
+
type FormFieldContextValue<
|
|
20
|
+
TFieldValues extends FieldValues = FieldValues,
|
|
21
|
+
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
|
|
22
|
+
> = {
|
|
12
23
|
name: TName;
|
|
13
24
|
};
|
|
14
25
|
|
|
15
|
-
const FormFieldContext = React.createContext<FormFieldContextValue>(
|
|
26
|
+
const FormFieldContext = React.createContext<FormFieldContextValue>(
|
|
27
|
+
{} as FormFieldContextValue,
|
|
28
|
+
);
|
|
16
29
|
|
|
17
|
-
const FormField = <
|
|
30
|
+
const FormField = <
|
|
31
|
+
TFieldValues extends FieldValues = FieldValues,
|
|
32
|
+
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
|
|
33
|
+
>({
|
|
18
34
|
...props
|
|
19
35
|
}: ControllerProps<TFieldValues, TName>) => {
|
|
20
36
|
return (
|
|
@@ -28,7 +44,9 @@ type FormItemContextValue = {
|
|
|
28
44
|
id: string;
|
|
29
45
|
};
|
|
30
46
|
|
|
31
|
-
const FormItemContext = React.createContext<FormItemContextValue>(
|
|
47
|
+
const FormItemContext = React.createContext<FormItemContextValue>(
|
|
48
|
+
{} as FormItemContextValue,
|
|
49
|
+
);
|
|
32
50
|
|
|
33
51
|
const useFormField = () => {
|
|
34
52
|
const fieldContext = React.useContext(FormFieldContext);
|
|
@@ -38,7 +56,7 @@ const useFormField = () => {
|
|
|
38
56
|
const fieldState = getFieldState(fieldContext.name, formState);
|
|
39
57
|
|
|
40
58
|
if (!fieldContext) {
|
|
41
|
-
throw new Error(
|
|
59
|
+
throw new Error("useFormField should be used within <FormField>");
|
|
42
60
|
}
|
|
43
61
|
|
|
44
62
|
const { id } = itemContext;
|
|
@@ -53,27 +71,30 @@ const useFormField = () => {
|
|
|
53
71
|
};
|
|
54
72
|
};
|
|
55
73
|
|
|
56
|
-
function FormItem({ className, ...props }: React.ComponentProps<
|
|
74
|
+
function FormItem({ className, ...props }: React.ComponentProps<"div">) {
|
|
57
75
|
const id = React.useId();
|
|
58
76
|
|
|
59
77
|
return (
|
|
60
78
|
<FormItemContext.Provider value={{ id }}>
|
|
61
79
|
<div
|
|
62
|
-
data-slot=
|
|
63
|
-
className={cn(
|
|
80
|
+
data-slot="form-item"
|
|
81
|
+
className={cn("flex flex-col gap-2", className)}
|
|
64
82
|
{...props}
|
|
65
83
|
/>
|
|
66
84
|
</FormItemContext.Provider>
|
|
67
85
|
);
|
|
68
86
|
}
|
|
69
87
|
|
|
70
|
-
function FormLabel({
|
|
88
|
+
function FormLabel({
|
|
89
|
+
className,
|
|
90
|
+
...props
|
|
91
|
+
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
|
|
71
92
|
const { error, formItemId } = useFormField();
|
|
72
93
|
|
|
73
94
|
return (
|
|
74
95
|
<Label
|
|
75
|
-
data-slot=
|
|
76
|
-
className={cn(error &&
|
|
96
|
+
data-slot="form-label"
|
|
97
|
+
className={cn(error && "text-destructive", className)}
|
|
77
98
|
htmlFor={formItemId}
|
|
78
99
|
{...props}
|
|
79
100
|
/>
|
|
@@ -81,35 +102,40 @@ function FormLabel({ className, ...props }: React.ComponentProps<typeof LabelPri
|
|
|
81
102
|
}
|
|
82
103
|
|
|
83
104
|
function FormControl({ ...props }: React.ComponentProps<typeof Slot>) {
|
|
84
|
-
const { error, formItemId, formDescriptionId, formMessageId } =
|
|
105
|
+
const { error, formItemId, formDescriptionId, formMessageId } =
|
|
106
|
+
useFormField();
|
|
85
107
|
|
|
86
108
|
return (
|
|
87
109
|
<Slot
|
|
88
|
-
data-slot=
|
|
110
|
+
data-slot="form-control"
|
|
89
111
|
id={formItemId}
|
|
90
|
-
aria-describedby={
|
|
112
|
+
aria-describedby={
|
|
113
|
+
!error
|
|
114
|
+
? `${formDescriptionId}`
|
|
115
|
+
: `${formDescriptionId} ${formMessageId}`
|
|
116
|
+
}
|
|
91
117
|
aria-invalid={!!error}
|
|
92
118
|
{...props}
|
|
93
119
|
/>
|
|
94
120
|
);
|
|
95
121
|
}
|
|
96
122
|
|
|
97
|
-
function FormDescription({ className, ...props }: React.ComponentProps<
|
|
123
|
+
function FormDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
98
124
|
const { formDescriptionId } = useFormField();
|
|
99
125
|
|
|
100
126
|
return (
|
|
101
127
|
<p
|
|
102
|
-
data-slot=
|
|
128
|
+
data-slot="form-description"
|
|
103
129
|
id={formDescriptionId}
|
|
104
|
-
className={cn(
|
|
130
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
105
131
|
{...props}
|
|
106
132
|
/>
|
|
107
133
|
);
|
|
108
134
|
}
|
|
109
135
|
|
|
110
|
-
function FormMessage({ className, ...props }: React.ComponentProps<
|
|
136
|
+
function FormMessage({ className, ...props }: React.ComponentProps<"p">) {
|
|
111
137
|
const { error, formMessageId } = useFormField();
|
|
112
|
-
const body = error ? String(error?.message ??
|
|
138
|
+
const body = error ? String(error?.message ?? "") : props.children;
|
|
113
139
|
|
|
114
140
|
if (!body) {
|
|
115
141
|
return null;
|
|
@@ -117,13 +143,23 @@ function FormMessage({ className, ...props }: React.ComponentProps<'p'>) {
|
|
|
117
143
|
|
|
118
144
|
return (
|
|
119
145
|
<p
|
|
120
|
-
data-slot=
|
|
146
|
+
data-slot="form-message"
|
|
121
147
|
id={formMessageId}
|
|
122
|
-
className={cn(
|
|
123
|
-
{...props}
|
|
148
|
+
className={cn("text-sm text-destructive", className)}
|
|
149
|
+
{...props}
|
|
150
|
+
>
|
|
124
151
|
{body}
|
|
125
152
|
</p>
|
|
126
153
|
);
|
|
127
154
|
}
|
|
128
155
|
|
|
129
|
-
export {
|
|
156
|
+
export {
|
|
157
|
+
useFormField,
|
|
158
|
+
Form,
|
|
159
|
+
FormItem,
|
|
160
|
+
FormLabel,
|
|
161
|
+
FormControl,
|
|
162
|
+
FormDescription,
|
|
163
|
+
FormMessage,
|
|
164
|
+
FormField,
|
|
165
|
+
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
"use client"
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
import { cva, type VariantProps } from "class-variance-authority"
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
5
5
|
|
|
6
|
-
import { cn } from "@/lib/utils"
|
|
7
|
-
import { Button } from "@/components/ui/button"
|
|
8
|
-
import { Input } from "@/components/ui/input"
|
|
9
|
-
import { Textarea } from "@/components/ui/textarea"
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
import { Button } from "@/components/ui/button";
|
|
8
|
+
import { Input } from "@/components/ui/input";
|
|
9
|
+
import { Textarea } from "@/components/ui/textarea";
|
|
10
10
|
|
|
11
11
|
function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
12
12
|
return (
|
|
@@ -29,11 +29,11 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
29
29
|
// Error state.
|
|
30
30
|
"has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
|
|
31
31
|
|
|
32
|
-
className
|
|
32
|
+
className,
|
|
33
33
|
)}
|
|
34
34
|
{...props}
|
|
35
35
|
/>
|
|
36
|
-
)
|
|
36
|
+
);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
const inputGroupAddonVariants = cva(
|
|
@@ -54,8 +54,8 @@ const inputGroupAddonVariants = cva(
|
|
|
54
54
|
defaultVariants: {
|
|
55
55
|
align: "inline-start",
|
|
56
56
|
},
|
|
57
|
-
}
|
|
58
|
-
)
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
59
|
|
|
60
60
|
function InputGroupAddon({
|
|
61
61
|
className,
|
|
@@ -70,13 +70,13 @@ function InputGroupAddon({
|
|
|
70
70
|
className={cn(inputGroupAddonVariants({ align }), className)}
|
|
71
71
|
onClick={(e) => {
|
|
72
72
|
if ((e.target as HTMLElement).closest("button")) {
|
|
73
|
-
return
|
|
73
|
+
return;
|
|
74
74
|
}
|
|
75
|
-
e.currentTarget.parentElement?.querySelector("input")?.focus()
|
|
75
|
+
e.currentTarget.parentElement?.querySelector("input")?.focus();
|
|
76
76
|
}}
|
|
77
77
|
{...props}
|
|
78
78
|
/>
|
|
79
|
-
)
|
|
79
|
+
);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
const inputGroupButtonVariants = cva(
|
|
@@ -94,8 +94,8 @@ const inputGroupButtonVariants = cva(
|
|
|
94
94
|
defaultVariants: {
|
|
95
95
|
size: "xs",
|
|
96
96
|
},
|
|
97
|
-
}
|
|
98
|
-
)
|
|
97
|
+
},
|
|
98
|
+
);
|
|
99
99
|
|
|
100
100
|
function InputGroupButton({
|
|
101
101
|
className,
|
|
@@ -113,7 +113,7 @@ function InputGroupButton({
|
|
|
113
113
|
className={cn(inputGroupButtonVariants({ size }), className)}
|
|
114
114
|
{...props}
|
|
115
115
|
/>
|
|
116
|
-
)
|
|
116
|
+
);
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
|
|
@@ -121,11 +121,11 @@ function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
|
|
|
121
121
|
<span
|
|
122
122
|
className={cn(
|
|
123
123
|
"text-muted-foreground flex items-center gap-2 text-sm [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none",
|
|
124
|
-
className
|
|
124
|
+
className,
|
|
125
125
|
)}
|
|
126
126
|
{...props}
|
|
127
127
|
/>
|
|
128
|
-
)
|
|
128
|
+
);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
function InputGroupInput({
|
|
@@ -137,11 +137,11 @@ function InputGroupInput({
|
|
|
137
137
|
data-slot="input-group-control"
|
|
138
138
|
className={cn(
|
|
139
139
|
"flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent",
|
|
140
|
-
className
|
|
140
|
+
className,
|
|
141
141
|
)}
|
|
142
142
|
{...props}
|
|
143
143
|
/>
|
|
144
|
-
)
|
|
144
|
+
);
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
function InputGroupTextarea({
|
|
@@ -153,11 +153,11 @@ function InputGroupTextarea({
|
|
|
153
153
|
data-slot="input-group-control"
|
|
154
154
|
className={cn(
|
|
155
155
|
"flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent",
|
|
156
|
-
className
|
|
156
|
+
className,
|
|
157
157
|
)}
|
|
158
158
|
{...props}
|
|
159
159
|
/>
|
|
160
|
-
)
|
|
160
|
+
);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
export {
|
|
@@ -167,4 +167,4 @@ export {
|
|
|
167
167
|
InputGroupText,
|
|
168
168
|
InputGroupInput,
|
|
169
169
|
InputGroupTextarea,
|
|
170
|
-
}
|
|
170
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as React from "react"
|
|
1
|
+
import * as React from "react";
|
|
2
2
|
|
|
3
|
-
import { cn } from "@/lib/utils"
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
4
|
|
|
5
5
|
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
|
|
6
6
|
({ className, type, ...props }, ref) => {
|
|
@@ -9,14 +9,14 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
|
|
|
9
9
|
type={type}
|
|
10
10
|
className={cn(
|
|
11
11
|
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
12
|
-
className
|
|
12
|
+
className,
|
|
13
13
|
)}
|
|
14
14
|
ref={ref}
|
|
15
15
|
{...props}
|
|
16
16
|
/>
|
|
17
|
-
)
|
|
18
|
-
}
|
|
19
|
-
)
|
|
20
|
-
Input.displayName = "Input"
|
|
17
|
+
);
|
|
18
|
+
},
|
|
19
|
+
);
|
|
20
|
+
Input.displayName = "Input";
|
|
21
21
|
|
|
22
|
-
export { Input }
|
|
22
|
+
export { Input };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import * as LabelPrimitive from "@radix-ui/react-label"
|
|
3
|
-
import { cva, type VariantProps } from "class-variance-authority"
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
4
4
|
|
|
5
|
-
import { cn } from "@/lib/utils"
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
6
|
|
|
7
7
|
const labelVariants = cva(
|
|
8
|
-
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
9
|
-
)
|
|
8
|
+
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
9
|
+
);
|
|
10
10
|
|
|
11
11
|
const Label = React.forwardRef<
|
|
12
12
|
React.ElementRef<typeof LabelPrimitive.Root>,
|
|
@@ -18,7 +18,7 @@ const Label = React.forwardRef<
|
|
|
18
18
|
className={cn(labelVariants(), className)}
|
|
19
19
|
{...props}
|
|
20
20
|
/>
|
|
21
|
-
))
|
|
22
|
-
Label.displayName = LabelPrimitive.Root.displayName
|
|
21
|
+
));
|
|
22
|
+
Label.displayName = LabelPrimitive.Root.displayName;
|
|
23
23
|
|
|
24
|
-
export { Label }
|
|
24
|
+
export { Label };
|