Form components with shadcn

When I look at the shadcn components examples for forms, they all have the primitives put inline in the form as below:
<FormField
control={form.control}
name='email'
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder='Select a verified email to display' />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value='[email protected]'>[email protected]</SelectItem>
<SelectItem value='[email protected]'>[email protected]</SelectItem>
<SelectItem value='[email protected]'>[email protected]</SelectItem>
</SelectContent>
</Select>
<FormDescription>
You can manage verified email addresses in your <Link href='/examples/forms'>email settings</Link>.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='email'
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder='Select a verified email to display' />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value='[email protected]'>[email protected]</SelectItem>
<SelectItem value='[email protected]'>[email protected]</SelectItem>
<SelectItem value='[email protected]'>[email protected]</SelectItem>
</SelectContent>
</Select>
<FormDescription>
You can manage verified email addresses in your <Link href='/examples/forms'>email settings</Link>.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
The pros of this to my mind is you can directly style the labels and fields with tailwind without having to do some wierd propdrilling. It is verbose however, and I've recently started on a code base that has build higher level componets on top of the shadcn form primitives and uses this when it makes a form:
<FormSelect
name='email'
label='Email'
items={[
{ value: '[email protected]', label: '[email protected]' },
{ value: '[email protected]', label: '[email protected]' },
{ value: '[email protected]', label: '[email protected]' },
]}
/>
<FormSelect
name='email'
label='Email'
items={[
{ value: '[email protected]', label: '[email protected]' },
{ value: '[email protected]', label: '[email protected]' },
{ value: '[email protected]', label: '[email protected]' },
]}
/>
While simpler to use, you can't add extra tailwind classes to say the label and are stuck with whatever styles are used inside FormSelect The context is we have these components used inside a frontend app for the team I recently joined, but I would not say there's exactly a defined design language yet? (We have like three Button components, and a split of forms using either shadcn + react-hook-form or formik for some reason). I'm not sure having the intermediate molecular components help as much in this situation as every form is slighly different, but the existing frontend engineer appreciates not having to copy and paste the same code over and over again. I'm wondering if there's much in the way of opinions as to how to use shadcn's stuff, just copy and paste the patterns like the examples or abstract into higher level components. Not found much answers anywhere else at the moment.
1 Reply
lanc3
lanc312mo ago
had some similar issues when it came to building forms, most of the time it's too verbose, but I still need control over some components, so I ended up building https://github.com/lanc33llis/ozef for my personal usage which is kinda an intermediate. Not for production, but you might be interested in some of the ideas in the project. In general though at my work, I see higher-level components built for forms
GitHub
GitHub - lanc33llis/ozef: Opinionated Zod-empowered forms
Opinionated Zod-empowered forms. Contribute to lanc33llis/ozef development by creating an account on GitHub.
Want results from more Discord servers?
Add your server