Primitives
Combobox (searchable select)
For lists past ~8 items. Searches label, hint and keywords in either script: try “dha”, “ঢাকা” or “div”.
combobox.tsx
"use client";
import { Combobox, Label } from "@waveinno/ui";
import { Building2, Car, MapPin } from "lucide-react";
import * as React from "react";
const CITIES = [
["Dhaka", "ঢাকা", "Dhaka division"],
["Chattogram", "চট্টগ্রাম", "Chattogram division"],
["Sylhet", "সিলেট", "Sylhet division"],
["Khulna", "খুলনা", "Khulna division"],
["Rajshahi", "রাজশাহী", "Rajshahi division"],
["Barishal", "বরিশাল", "Barishal division"],
["Rangpur", "রংপুর", "Rangpur division"],
["Mymensingh", "ময়মনসিংহ", "Mymensingh division"],
["Cox's Bazar", "কক্সবাজার", "Chattogram division"],
["Gazipur", "গাজীপুর", "Dhaka division"],
["Narayanganj", "নারায়ণগঞ্জ", "Dhaka division"],
["Cumilla", "কুমিল্লা", "Chattogram division"],
].map(([label, bn, hint]) => ({ value: label!.toLowerCase(), label: label!, hint, keywords: [bn!], icon: <MapPin className="size-4" /> }));
const SITES = [
{ value: "gulshan", label: "Gulshan Car Park", hint: "120 cars · 60 bikes", group: "Dhaka", icon: <Building2 className="size-4" /> },
{ value: "banani", label: "Banani Trade Centre", hint: "80 cars", group: "Dhaka", icon: <Building2 className="size-4" /> },
{ value: "dhanmondi", label: "Dhanmondi 27", hint: "Street, 40 cars", group: "Dhaka", icon: <Car className="size-4" /> },
{ value: "gec", label: "GEC Circle", hint: "60 cars", group: "Chattogram", icon: <Building2 className="size-4" /> },
{ value: "zindabazar", label: "Zindabazar", hint: "Closed for works", group: "Sylhet", icon: <Car className="size-4" />, disabled: true },
];
export default function ComboboxDemo() {
const [city, setCity] = React.useState<string | null>("dhaka");
const [site, setSite] = React.useState<string | null>(null);
return (
<div className="grid max-w-xl gap-4 sm:grid-cols-2">
<div className="space-y-1.5">
<Label>City</Label>
<Combobox value={city} onChange={setCity} options={CITIES} clearable />
</div>
<div className="space-y-1.5">
<Label>Car park</Label>
<Combobox value={site} onChange={setSite} options={SITES} placeholder="Choose a car park" hintInValue />
</div>
</div>
);
}Import#
Everything comes from the package root. The example above uses:
your-component.tsx
import { Combobox, Label } from "@waveinno/ui";Props#
Read from the source of this version, so they match the code exactly.
<Combobox>
src/components/ui/combobox.tsx| Prop | Type | Default | Description |
|---|---|---|---|
id | string | — | |
valuerequired | string | null | — | |
onChangerequired | (value: string | null) => void | — | |
optionsrequired | ComboOption[] | — | |
placeholder | string | — | |
searchPlaceholder | string | — | |
clearable | boolean | false | |
disabled | boolean | — | |
className | string | — | |
contentClassName | string | — | |
hintInValue | boolean | ((o: ComboOption) => string) | false | Show the selected option's hint in the closed box too (e.g. a zone's offset). |
labels | Partial<ComboboxLabels> | — | |
aria-invalid | boolean | — |
<Label>
src/components/ui/label.tsx| Prop | Type | Default | Description |
|---|---|---|---|
required | boolean | — |
Also takes ComponentPropsWithoutRef<typeof LabelPrimitive.Root>.
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