- Published on
Creating a Shadcn/UI TextArea with Chips in React
- Authors
- Name
- Ripal & Zalak
Creating a TextArea with chips functionality is a great way to enhance user input, especially when dealing with lists like names or tags. In this guide, we'll use Shadcn/UI, React-Hook-Form, and Zod to implement this feature in a clean and reusable way.
Problem Statement
We want a TextArea where users can:
- Enter multiple names separated by commas.
- See each name converted into a chip once a comma is entered.
- Delete chips individually.
- Submit the form with all names as a comma-separated string.
Full Implementation
Here is the implementation for creating a Shadcn/UI TextArea with chips:
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} method="post" className="space-y-8">
<FormField
control={form.control}
name="names"
render={({ field: { value, onChange } }) => (
<FormItem>
<FormLabel>Names</FormLabel>
<div className="border-input rounded-md border p-2">
<div className="flex gap-2 empty:hidden">
{!!value.trim().length &&
value?.split(',').map((name, index) => (
<div
key={index}
className="inline-flex items-center rounded-md bg-zinc-100 py-1 pl-2.5 pr-1 text-xs"
>
{name}
<button
type="button"
onClick={() =>
onChange(
value
.split(',')
.filter((_) => _ != name)
.join(',')
)
}
>
<svg
width="12"
height="12"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="ml-2"
>
<path
d="M12.8536 2.85355C13.0488 2.65829 13.0488 2.34171 12.8536 2.14645C12.6583 1.95118 12.3417 1.95118 12.1464 2.14645L7.5 6.79289L2.85355 2.14645C2.65829 1.95118 2.34171 1.95118 2.14645 2.14645C1.95118 2.34171 1.95118 2.65829 2.14645 2.85355L6.79289 7.5L2.14645 12.1464C1.95118 12.3417 1.95118 12.6583 2.14645 12.8536C2.34171 13.0488 2.65829 13.0488 2.85355 12.8536L7.5 8.20711L12.1464 12.8536C12.3417 13.0488 12.6583 13.0488 12.8536 12.8536C13.0488 12.6583 13.0488 12.3417 12.8536 12.1464L8.20711 7.5L12.8536 2.85355Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
></path>
</svg>
</button>
</div>
))}
</div>
<FormControl>
<Textarea
placeholder="Enter names"
className="min-h-40 border-0 focus-visible:ring-0"
onKeyDown={(e) => {
if (e.key == ',') {
if (!value) {
onChange(e.target.value.replace(',', ''))
e.target.value = ''
} else {
onChange(value.concat(',', e.target.value.replace(',', '')))
e.target.value = ''
}
e.preventDefault() // Prevent comma from entering the TextArea
}
}}
/>
</FormControl>
</div>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
Key Features Explained
Dynamic Chip Creation:
- Chips are created when the user types a comma.
- Each chip is rendered with a delete button.
Deleting Chips:
- Chips can be removed individually by clicking the delete button.
- This updates the internal state to remove the corresponding name.
Submission Format:
- When submitted, the form outputs names as a comma-separated string, ready for backend processing.
Styling Notes
- Use Tailwind CSS classes like
p-2
,border
, androunded-md
to style the container and chips. - Adjust
Textarea
styles to fit your design requirements.
FAQs
1. How does the chip logic work?
The onKeyDown
event checks for the comma key, adds the input to the value, and clears the TextArea.
2. Can this handle duplicate names?
Yes, but you can modify the logic to prevent duplicates by adding a check before updating the value.
3. Can I use this for tags or other inputs?
Absolutely! The same logic applies to tags or other list-based inputs.
Conclusion
This implementation provides a user-friendly way to handle multiple inputs dynamically. With Shadcn/UI and React-Hook-Form, you can create robust and visually appealing forms that enhance the user experience.
For more information, refer to the official Shadcn/UI documentation and React-Hook-Form resources.