Collaboration
Project Management
Finance
Combobox
Autocomplete input and command palette with a list of suggestions.
Installation
npx love-ui@latest add comboboxUsage
import { Combobox, ComboboxTrigger, ComboboxContent, ComboboxInput, ComboboxList, ComboboxEmpty, ComboboxGroup, ComboboxItem } from "@/components/combobox"<Combobox>
<ComboboxTrigger>Select option...</ComboboxTrigger>
<ComboboxContent>
<ComboboxInput placeholder="Search..." />
<ComboboxList>
<ComboboxEmpty>No results found.</ComboboxEmpty>
<ComboboxGroup>
<ComboboxItem value="option1">Option 1</ComboboxItem>
<ComboboxItem value="option2">Option 2</ComboboxItem>
<ComboboxItem value="option3">Option 3</ComboboxItem>
</ComboboxGroup>
</ComboboxList>
</ComboboxContent>
</Combobox>Features
- Autocomplete input with dropdown list of suggestions
- Controlled and uncontrolled modes
- Customizable trigger button
- Search functionality
- Empty state handling
- Responsive width that matches the trigger
- Keyboard navigation support
- Grouping of items
- Context-based type labeling
- Native "create new" functionality
Examples
Controlled version
"use client";
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxGroup,
ComboboxInput,
ComboboxItem,
ComboboxList,
ComboboxTrigger,
} from "../../../../../packages/combobox";
import { useState } from "react";
const plants = [
{
value: "monstera-deliciosa",
label: "Monstera Deliciosa (Swiss Cheese Plant)",
},
{
value: "ficus-lyrata",
label: "Ficus Lyrata (Fiddle Leaf Fig)",
},
{
value: "sansevieria-trifasciata",
label: "Sansevieria Trifasciata (Snake Plant)",
},
{
value: "spathiphyllum-wallisii",
label: "Spathiphyllum Wallisii (Peace Lily)",
},
{
value: "epipremnum-aureum",
label: "Epipremnum Aureum (Golden Pothos)",
},
{
value: "calathea-orbifolia",
label: "Calathea Orbifolia (Prayer Plant)",
},
];
const Example = () => {
const [open, setOpen] = useState(false);
const [value, setValue] = useState(plants[0].value);
return (
<Combobox
data={plants}
onOpenChange={setOpen}
onValueChange={setValue}
open={open}
type="plant"
value={value}
>
<ComboboxTrigger />
<ComboboxContent>
<ComboboxInput />
<ComboboxEmpty />
<ComboboxList>
<ComboboxGroup>
{plants.map((plant) => (
<ComboboxItem key={plant.value} value={plant.value}>
{plant.label}
</ComboboxItem>
))}
</ComboboxGroup>
</ComboboxList>
</ComboboxContent>
</Combobox>
);
};
export default Example;
Fixed width
"use client";
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxGroup,
ComboboxInput,
ComboboxItem,
ComboboxList,
ComboboxTrigger,
} from "../../../../../packages/combobox";
const frameworks = [
{
value: "next.js",
label: "Next.js",
},
{
value: "sveltekit",
label: "SvelteKit",
},
{
value: "nuxt.js",
label: "Nuxt.js",
},
{
value: "remix",
label: "Remix",
},
{
value: "astro",
label: "Astro",
},
{
value: "vite",
label: "Vite",
},
];
const Example = () => (
<Combobox
data={frameworks}
onOpenChange={(open) => console.log("Combobox is open?", open)}
onValueChange={(newValue) => console.log("Combobox value:", newValue)}
type="framework"
>
<ComboboxTrigger className="w-[70%]" />
<ComboboxContent>
<ComboboxInput />
<ComboboxEmpty />
<ComboboxList>
<ComboboxGroup>
{frameworks.map((framework) => (
<ComboboxItem key={framework.value} value={framework.value}>
{framework.label}
</ComboboxItem>
))}
</ComboboxGroup>
</ComboboxList>
</ComboboxContent>
</Combobox>
);
export default Example;
Create new items
"use client";
import {
Combobox,
ComboboxContent,
ComboboxCreateNew,
ComboboxEmpty,
ComboboxGroup,
ComboboxInput,
ComboboxItem,
ComboboxList,
ComboboxTrigger,
} from "../../../../../packages/combobox";
import { useState } from "react";
const initialFrameworks = [
{
value: "next.js",
label: "Next.js",
},
{
value: "sveltekit",
label: "SvelteKit",
},
{
value: "nuxt.js",
label: "Nuxt.js",
},
{
value: "remix",
label: "Remix",
},
{
value: "astro",
label: "Astro",
},
{
value: "vite",
label: "Vite",
},
];
const Example = () => {
const [frameworks, setFrameworks] = useState(initialFrameworks);
const [value, setValue] = useState("");
const handleCreateNew = (newValue: string) => {
console.log("Creating new framework:", newValue);
// Add the new framework to the list
const newFramework = {
value: newValue.toLowerCase().replace(/\s+/g, "-"),
label: newValue,
};
setFrameworks((prev) => [...prev, newFramework]);
setValue(newFramework.value);
};
return (
<Combobox
data={frameworks}
onValueChange={setValue}
type="framework"
value={value}
>
<ComboboxTrigger className="w-[300px]" />
<ComboboxContent>
<ComboboxInput />
<ComboboxEmpty>
<ComboboxCreateNew onCreateNew={handleCreateNew} />
</ComboboxEmpty>
<ComboboxList>
<ComboboxGroup>
{frameworks.map((framework) => (
<ComboboxItem key={framework.value} value={framework.value}>
{framework.label}
</ComboboxItem>
))}
</ComboboxGroup>
</ComboboxList>
</ComboboxContent>
</Combobox>
);
};
export default Example;