generator-kodly-react-app 1.0.15 → 1.0.17
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 +15 -1
- package/generators/app/templates/.env.sandbox +4 -3
- package/generators/app/templates/.node-version +1 -0
- package/generators/app/templates/.pnpmfile.cjs +14 -0
- package/generators/app/templates/.prettierignore +13 -0
- package/generators/app/templates/AGENTS.md +14 -0
- package/generators/app/templates/I18N_MIGRATION.md +13 -13
- package/generators/app/templates/STRUCTURE.md +26 -26
- package/generators/app/templates/TESTING.md +30 -0
- package/generators/app/templates/index.html +6 -14
- package/generators/app/templates/openapi-ts.config.ts +16 -12
- package/generators/app/templates/oxlint.config.ts +72 -0
- package/generators/app/templates/package.json +66 -52
- package/generators/app/templates/pnpm-workspace.yaml +19 -0
- package/generators/app/templates/scripts/check-duplicates.mjs +28 -0
- package/generators/app/templates/scripts/generated-files.mjs +21 -0
- 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 +16 -15
- 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 +22 -28
- 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 +78 -68
- package/generators/app/templates/src/lib/i18n.ts +40 -31
- 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 +86 -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 +54 -39
- 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 +4 -4
- package/generators/app/templates/src/routes/$.tsx +0 -1
- package/generators/app/templates/src/routes/__root.tsx +3 -3
- 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 +16 -8
- 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 +14 -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/stylelint.config.js +55 -0
- package/generators/app/templates/tailwind.config.js +0 -1
- package/generators/app/templates/tests/form-controls.test.tsx +39 -0
- package/generators/app/templates/tests/sdk.test.ts +49 -0
- package/generators/app/templates/tests/setup.ts +5 -0
- package/generators/app/templates/tsconfig.app.json +0 -2
- package/generators/app/templates/tsconfig.json +2 -2
- package/generators/app/templates/tsr.config.json +4 -0
- package/generators/app/templates/vite.config.js +14 -16
- package/generators/app/templates/vitest.config.ts +14 -0
- package/package.json +9 -10
- package/generators/app/templates/postcss.config.js +0 -6
|
@@ -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,
|
|
@@ -68,15 +68,9 @@ function InputGroupAddon({
|
|
|
68
68
|
data-slot="input-group-addon"
|
|
69
69
|
data-align={align}
|
|
70
70
|
className={cn(inputGroupAddonVariants({ align }), className)}
|
|
71
|
-
onClick={(e) => {
|
|
72
|
-
if ((e.target as HTMLElement).closest("button")) {
|
|
73
|
-
return
|
|
74
|
-
}
|
|
75
|
-
e.currentTarget.parentElement?.querySelector("input")?.focus()
|
|
76
|
-
}}
|
|
77
71
|
{...props}
|
|
78
72
|
/>
|
|
79
|
-
)
|
|
73
|
+
);
|
|
80
74
|
}
|
|
81
75
|
|
|
82
76
|
const inputGroupButtonVariants = cva(
|
|
@@ -94,8 +88,8 @@ const inputGroupButtonVariants = cva(
|
|
|
94
88
|
defaultVariants: {
|
|
95
89
|
size: "xs",
|
|
96
90
|
},
|
|
97
|
-
}
|
|
98
|
-
)
|
|
91
|
+
},
|
|
92
|
+
);
|
|
99
93
|
|
|
100
94
|
function InputGroupButton({
|
|
101
95
|
className,
|
|
@@ -113,7 +107,7 @@ function InputGroupButton({
|
|
|
113
107
|
className={cn(inputGroupButtonVariants({ size }), className)}
|
|
114
108
|
{...props}
|
|
115
109
|
/>
|
|
116
|
-
)
|
|
110
|
+
);
|
|
117
111
|
}
|
|
118
112
|
|
|
119
113
|
function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
|
|
@@ -121,11 +115,11 @@ function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
|
|
|
121
115
|
<span
|
|
122
116
|
className={cn(
|
|
123
117
|
"text-muted-foreground flex items-center gap-2 text-sm [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none",
|
|
124
|
-
className
|
|
118
|
+
className,
|
|
125
119
|
)}
|
|
126
120
|
{...props}
|
|
127
121
|
/>
|
|
128
|
-
)
|
|
122
|
+
);
|
|
129
123
|
}
|
|
130
124
|
|
|
131
125
|
function InputGroupInput({
|
|
@@ -137,11 +131,11 @@ function InputGroupInput({
|
|
|
137
131
|
data-slot="input-group-control"
|
|
138
132
|
className={cn(
|
|
139
133
|
"flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent",
|
|
140
|
-
className
|
|
134
|
+
className,
|
|
141
135
|
)}
|
|
142
136
|
{...props}
|
|
143
137
|
/>
|
|
144
|
-
)
|
|
138
|
+
);
|
|
145
139
|
}
|
|
146
140
|
|
|
147
141
|
function InputGroupTextarea({
|
|
@@ -153,11 +147,11 @@ function InputGroupTextarea({
|
|
|
153
147
|
data-slot="input-group-control"
|
|
154
148
|
className={cn(
|
|
155
149
|
"flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent",
|
|
156
|
-
className
|
|
150
|
+
className,
|
|
157
151
|
)}
|
|
158
152
|
{...props}
|
|
159
153
|
/>
|
|
160
|
-
)
|
|
154
|
+
);
|
|
161
155
|
}
|
|
162
156
|
|
|
163
157
|
export {
|
|
@@ -167,4 +161,4 @@ export {
|
|
|
167
161
|
InputGroupText,
|
|
168
162
|
InputGroupInput,
|
|
169
163
|
InputGroupTextarea,
|
|
170
|
-
}
|
|
164
|
+
};
|
|
@@ -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 };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use client"
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
import * as SeparatorPrimitive from "@radix-ui/react-separator"
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
|
5
5
|
|
|
6
|
-
import { cn } from "@/lib/utils"
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
7
|
|
|
8
8
|
const Separator = React.forwardRef<
|
|
9
9
|
React.ElementRef<typeof SeparatorPrimitive.Root>,
|
|
@@ -11,7 +11,7 @@ const Separator = React.forwardRef<
|
|
|
11
11
|
>(
|
|
12
12
|
(
|
|
13
13
|
{ className, orientation = "horizontal", decorative = true, ...props },
|
|
14
|
-
ref
|
|
14
|
+
ref,
|
|
15
15
|
) => (
|
|
16
16
|
<SeparatorPrimitive.Root
|
|
17
17
|
ref={ref}
|
|
@@ -20,12 +20,12 @@ const Separator = React.forwardRef<
|
|
|
20
20
|
className={cn(
|
|
21
21
|
"shrink-0 bg-border",
|
|
22
22
|
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
|
|
23
|
-
className
|
|
23
|
+
className,
|
|
24
24
|
)}
|
|
25
25
|
{...props}
|
|
26
26
|
/>
|
|
27
|
-
)
|
|
28
|
-
)
|
|
29
|
-
Separator.displayName = SeparatorPrimitive.Root.displayName
|
|
27
|
+
),
|
|
28
|
+
);
|
|
29
|
+
Separator.displayName = SeparatorPrimitive.Root.displayName;
|
|
30
30
|
|
|
31
|
-
export { Separator }
|
|
31
|
+
export { Separator };
|
|
@@ -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 Textarea = React.forwardRef<
|
|
6
6
|
HTMLTextAreaElement,
|
|
@@ -10,13 +10,13 @@ const Textarea = React.forwardRef<
|
|
|
10
10
|
<textarea
|
|
11
11
|
className={cn(
|
|
12
12
|
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm 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",
|
|
13
|
-
className
|
|
13
|
+
className,
|
|
14
14
|
)}
|
|
15
15
|
ref={ref}
|
|
16
16
|
{...props}
|
|
17
17
|
/>
|
|
18
|
-
)
|
|
19
|
-
})
|
|
20
|
-
Textarea.displayName = "Textarea"
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
Textarea.displayName = "Textarea";
|
|
21
21
|
|
|
22
|
-
export { Textarea }
|
|
22
|
+
export { Textarea };
|