Primitives
Tag input
Enter, comma or paste a list; Backspace marks then removes; validate, max, suggestions.
DHA-GA 12-3456DHA-KHA 45-10202/5
Enter or comma adds one; paste a list to add many.
Karim Ahmed
Suggestions from your team.
24 hoursEV chargingCovered
tag-input.tsx
"use client";
import { FormField, TagInput } from "@waveinno/ui";
import * as React from "react";
export default function TagDemo() {
const [plates, setPlates] = React.useState(["DHA-GA 12-3456", "DHA-KHA 45-1020"]);
return (
<div className="grid gap-6 md:grid-cols-2">
<FormField label="Plates on this pass" hint="Enter or comma adds one; paste a list to add many.">
<TagInput value={plates} onValueChange={setPlates} max={5} transform={(t) => t.trim().toUpperCase()} validate={(t) => (/^[A-Z]+-[A-Z]+ \d{2}-\d{4}$/.test(t) ? null : "Plates look like DHA-GA 12-3456")} />
</FormField>
<FormField label="Notify" hint="Suggestions from your team.">
<TagInput variant="outline" placeholder="Add a person…" suggestions={["Karim Ahmed", "Nusrat Jahan", "Rafiq Islam", "Farhana Akter", "Tanvir Hasan"]} defaultValue={["Karim Ahmed"]} />
</FormField>
<FormField label="Site labels">
<TagInput variant="solid" defaultValue={["24 hours", "EV charging", "Covered"]} />
</FormField>
</div>
);
}Import#
Everything comes from the package root. The example above uses:
your-component.tsx
import { FormField, TagInput } from "@waveinno/ui";Props#
Read from the source of this version, so they match the code exactly.
<TagInput>
src/components/ui/tag-input.tsx| Prop | Type | Default | Description |
|---|---|---|---|
value | string[] | — | |
defaultValue | string[] | [] | |
onValueChange | (tags: string[]) => void | — | |
placeholder | string | "Add…" | |
suggestions | string[] | — | |
max | number | — | |
validate | (tag: string) => string | void | undefined | null | — | Return a reason to refuse a tag, or nothing to accept it. |
transform | (tag: string) => string | (t) => t.trim() | Change a tag before it is added: trim, upper-case a plate. |
variant | "soft" | "outline" | "solid" | "soft" | |
state | InputState | "default" | |
disabled | boolean | — | |
aria-label | string | — | |
className | string | — |
<FormField>
src/components/ui/form-field.tsx| Prop | Type | Default | Description |
|---|---|---|---|
label | React.ReactNode | — | |
htmlFor | string | — | The control's id, so clicking the label focuses it. |
required | boolean | — | |
hint | React.ReactNode | — | |
error | React.ReactNode | — | |
warning | React.ReactNode | — | |
success | React.ReactNode | — | |
count | { value: number; max: number } | — | Character counter, e.g. { value: note.length, max: 240 }. |
className | string | — | |
childrenrequired | React.ReactNode | — |
Install#
If the project does not have the package yet, add it, then follow the setup for Next.js or Vite once.
$ npm install @waveinno/ui