Skip to content

Commit 69abf0d

Browse files
authored
feat: add forms related components
1 parent 3d6c107 commit 69abf0d

File tree

6 files changed

+316
-22
lines changed

6 files changed

+316
-22
lines changed

components.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
"aliases": {
1414
"components": "@/components",
1515
"utils": "@/lib/utils",
16-
"lib": "@/lib"
16+
"lib": "@/lib",
17+
"ui": "@/components",
18+
"hooks": "@/hooks"
1719
},
1820
"iconLibrary": "lucide"
1921
}

package-lock.json

+57-18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,14 @@
6363
"vitest": "^3.0.4"
6464
},
6565
"dependencies": {
66-
"@radix-ui/react-label": "^2.1.1",
67-
"@radix-ui/react-slot": "^1.1.1",
66+
"@hookform/resolvers": "^4.1.0",
67+
"@radix-ui/react-label": "^2.1.2",
68+
"@radix-ui/react-slot": "^1.1.2",
6869
"class-variance-authority": "^0.7.1",
6970
"clsx": "^2.1.1",
7071
"lucide-react": "^0.474.0",
71-
"tailwind-merge": "^2.6.0"
72+
"react-hook-form": "^7.54.2",
73+
"tailwind-merge": "^2.6.0",
74+
"zod": "^3.24.2"
7275
}
7376
}

src/components/form.stories.tsx

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import { fn } from "@storybook/test";
3+
4+
import { zodResolver } from "@hookform/resolvers/zod";
5+
import { useForm } from "react-hook-form";
6+
import { z } from "zod";
7+
import { Button } from "./button";
8+
import {
9+
Form,
10+
FormControl,
11+
FormDescription,
12+
FormField,
13+
FormItem,
14+
FormLabel,
15+
FormMessage,
16+
} from "./form";
17+
import { Input } from "./input";
18+
19+
const meta = {
20+
title: "Form",
21+
parameters: {
22+
layout: "centered",
23+
},
24+
} satisfies Meta<typeof Form>;
25+
26+
export default meta;
27+
type Story = StoryObj<typeof meta>;
28+
29+
const formSchema = z.object({
30+
username: z.string().min(2, {
31+
message: "Username must be at least 2 characters.",
32+
}),
33+
});
34+
35+
export const Example: Story = {
36+
render() {
37+
const form = useForm({
38+
resolver: zodResolver(formSchema),
39+
defaultValues: {
40+
username: "",
41+
},
42+
});
43+
44+
const onSubmit = fn();
45+
46+
return (
47+
<Form {...form}>
48+
<form className="space-y-8" onSubmit={form.handleSubmit(onSubmit)}>
49+
<FormField
50+
control={form.control}
51+
name="username"
52+
render={({ field }) => (
53+
<FormItem>
54+
<FormLabel>Username</FormLabel>
55+
<FormControl>
56+
<Input placeholder="Enter username" {...field} />
57+
</FormControl>
58+
<FormDescription>
59+
This is your public display name.
60+
</FormDescription>
61+
<FormMessage />
62+
</FormItem>
63+
)}
64+
/>
65+
<Button type="submit">Submit</Button>
66+
</form>
67+
</Form>
68+
);
69+
},
70+
};

0 commit comments

Comments
 (0)