Combobox
Autocomplete input and command palette with a list of suggestions.
import { Button } from "@/components/ui/button";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command";
import { Label } from "@/components/ui/label";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { ChevronUpDown } from "@mynaui/icons-react";
export default function Basic() {
return (
<div className="w-full space-y-1 md:w-72">
<Label htmlFor="tag">Tag</Label>
<Popover>
<PopoverTrigger asChild>
<Button variant="outline" className="w-full justify-between">
Select Tag
<ChevronUpDown
className="size-4 shrink-0 text-muted-foreground"
stroke={2}
/>
</Button>
</PopoverTrigger>
<PopoverContent align="start" className="w-full p-0">
<Command>
<CommandInput placeholder="Search tags..." autoFocus />
<CommandList>
<CommandEmpty>No tags found.</CommandEmpty>
<CommandGroup>
<CommandItem>Work</CommandItem>
<CommandItem>Personal</CommandItem>
<CommandItem>Travel</CommandItem>
<CommandItem>Shopping</CommandItem>
<CommandItem>Recipes</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</div>
);
}
import { Button } from "@/components/ui/button";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command";
import { Label } from "@/components/ui/label";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { ChevronUpDown, Mobile, Tablet, Tv } from "@mynaui/icons-react";
export default function WithIcons() {
return (
<div className="w-full space-y-1 md:w-72">
<Label htmlFor="device">Device</Label>
<Popover>
<PopoverTrigger asChild>
<Button variant="outline" className="w-full justify-between">
Select Device
<ChevronUpDown
className="size-4 shrink-0 text-muted-foreground"
stroke={2}
/>
</Button>
</PopoverTrigger>
<PopoverContent className="w-full p-0">
<Command>
<CommandEmpty>No device options found.</CommandEmpty>
<CommandList>
<CommandInput placeholder="Search devices..." autoFocus />
<CommandGroup>
<CommandItem>
<Tv
className="mr-2 size-4 text-muted-foreground"
stroke={2}
/>
Desktop
</CommandItem>
<CommandItem>
<Mobile
className="mr-2 size-4 text-muted-foreground"
stroke={2}
/>
Mobile
</CommandItem>
<CommandItem>
<Tablet
className="mr-2 size-4 text-muted-foreground"
stroke={2}
/>
Tablet
</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</div>
);
}
import { Button } from "@/components/ui/button";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { Bookmark, ChevronUpDown } from "@mynaui/icons-react";
export default function Simple() {
return (
<Popover>
<PopoverTrigger asChild>
<Button
variant="outline"
role="combobox"
className="w-full justify-between md:w-72"
>
<div className="flex items-center gap-2 truncate">
<Bookmark className="size-4" stroke={2} />
<span className="truncate">Select a bookmark</span>
</div>
<ChevronUpDown
className="size-4 shrink-0 text-muted-foreground"
stroke={2}
/>
</Button>
</PopoverTrigger>
<PopoverContent className="w-full p-0 md:w-72">
<Command>
<CommandInput placeholder="Search bookmarks..." />
<CommandEmpty>No bookmarks found.</CommandEmpty>
<CommandList>
<CommandGroup className="max-h-[300px] overflow-auto">
<CommandItem>
<Bookmark className="mr-2 size-4" stroke={2} />
<span className="truncate">Personal Blog</span>
</CommandItem>
<CommandItem>
<Bookmark className="mr-2 size-4" stroke={2} />
<span className="truncate">Work Project Dashboard</span>
</CommandItem>
<CommandItem>
<Bookmark className="mr-2 size-4" stroke={2} />
<span className="truncate">Favorite Recipes</span>
</CommandItem>
<CommandItem>
<Bookmark className="mr-2 size-4" stroke={2} />
<span className="truncate">Travel Inspiration</span>
</CommandItem>
<CommandItem>
<Bookmark className="mr-2 size-4" stroke={2} />
<span className="truncate">Coding Resources</span>
</CommandItem>
<CommandItem>
<Bookmark className="mr-2 size-4" stroke={2} />
<span className="truncate">Design Inspiration</span>
</CommandItem>
<CommandItem>
<Bookmark className="mr-2 size-4" stroke={2} />
<span className="truncate">Financial Trackers</span>
</CommandItem>
<CommandItem>
<Bookmark className="mr-2 size-4" stroke={2} />
<span className="truncate">Fitness Routines</span>
</CommandItem>
<CommandItem>
<Bookmark className="mr-2 size-4" stroke={2} />
<span className="truncate">Productivity Tools</span>
</CommandItem>
<CommandItem>
<Bookmark className="mr-2 size-4" stroke={2} />
<span className="truncate">Educational Resources</span>
</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
}
"use client";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command";
import { Label } from "@/components/ui/label";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { ChevronUpDown, Atom, CodeCircle, CodeHexagon, CodeDiamond, CodeSquare } from "@mynaui/icons-react";
const frameworks = [
{ label: "React", value: "react", icon: Atom },
{ label: "Vue", value: "vue", icon: CodeHexagon },
{ label: "Angular", value: "angular", icon: CodeDiamond },
{ label: "Svelte", value: "svelte", icon: CodeSquare },
{ label: "Solid", value: "solid", icon: CodeCircle },
];
export default function MultiSelect() {
const [selected, setSelected] = useState<string[]>([]);
const [open, setOpen] = useState(false);
const toggleSelect = (value: string) => {
setSelected((current) =>
current.includes(value)
? current.filter((v) => v !== value)
: [...current, value]
);
};
return (
<div className="w-full space-y-1 text-sm md:w-72">
<Label htmlFor="framework">Framework</Label>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
id="framework"
variant="outline"
className="w-full justify-between"
role="combobox"
aria-expanded={open}
>
<span className="truncate">
{selected.length ? selected.join(", ") : "Select frameworks"}
</span>
<ChevronUpDown className="size-4 shrink-0 text-muted-foreground" stroke={2} />
</Button>
</PopoverTrigger>
<PopoverContent align="start" className="w-full p-0">
<Command>
<CommandInput placeholder="Search frameworks..." autoFocus />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup>
{frameworks.map((fw) => (
<CommandItem
key={fw.value}
onSelect={() => toggleSelect(fw.value)}
aria-selected={selected.includes(fw.value)}
>
<fw.icon className="mr-2 size-4 text-muted-foreground" stroke={2} />
<Checkbox
checked={selected.includes(fw.value)}
aria-label={fw.label}
tabIndex={-1}
className=" data-[state=checked]:[&_svg]:!text-background"
/>
{fw.label}
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</div>
);
}
"use client";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command";
import { Label } from "@/components/ui/label";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import {
ChevronUpDown,
Cake,
Coffee,
Cupcake,
Pizza,
Wine,
} from "@mynaui/icons-react";
const desserts = [
{ label: "Cake", value: "cake", icon: Cake },
{ label: "Cupcake", value: "cupcake", icon: Cupcake },
{ label: "Pizza", value: "pizza", icon: Pizza },
];
const drinks = [
{ label: "Coffee", value: "coffee", icon: Coffee },
{ label: "Wine", value: "wine", icon: Wine },
];
const foods = [...desserts, ...drinks];
export default function Grouped() {
const [value, setValue] = useState("");
const [open, setOpen] = useState(false);
const selectedLabel = foods.find((f) => f.value === value)?.label;
return (
<div className="w-full space-y-1 text-sm md:w-72">
<Label htmlFor="food">Food</Label>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
id="food"
variant="outline"
className="w-full justify-between"
role="combobox"
aria-expanded={open}
>
<span className="truncate">{selectedLabel || "Select Food"}</span>
<ChevronUpDown className="size-4 shrink-0 text-muted-foreground" stroke={2} />
</Button>
</PopoverTrigger>
<PopoverContent align="start" className="w-full p-0">
<Command>
<CommandInput placeholder="Search food..." autoFocus />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Desserts">
{desserts.map((item) => (
<CommandItem
key={item.value}
value={item.value}
onSelect={(val) => {
setValue(val);
setOpen(false);
}}
>
<item.icon className="size-4 text-muted-foreground" stroke={2} />
{item.label}
</CommandItem>
))}
</CommandGroup>
<CommandGroup heading="Drinks">
{drinks.map((item) => (
<CommandItem
key={item.value}
value={item.value}
onSelect={(val) => {
setValue(val);
setOpen(false);
}}
>
<item.icon className="size-4 text-muted-foreground" stroke={2} />
{item.label}
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</div>
);
}
"use client";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command";
import { Label } from "@/components/ui/label";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { ChevronUpDown, Desktop, Moon, Sun } from "@mynaui/icons-react";
const themes = [
{ label: "Light", value: "light", icon: Sun },
{ label: "Dark", value: "dark", icon: Moon },
{ label: "System", value: "system", icon: Desktop },
];
export default function ThemeSelector() {
const [value, setValue] = useState<string>("");
const [open, setOpen] = useState(false);
const selectedLabel = themes.find((t) => t.value === value)?.label;
const SelectedIcon = themes.find((t) => t.value === value)?.icon;
return (
<div className="w-full space-y-1 text-sm md:w-72">
<Label htmlFor="theme">Theme</Label>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
id="theme"
variant="outline"
className="w-full justify-between"
role="combobox"
aria-expanded={open}
>
{value ? (
<span className="flex items-center gap-2 truncate">
{SelectedIcon && <SelectedIcon className="size-4" stroke={2} />}
{selectedLabel}
</span>
) : (
"Select Theme"
)}
<ChevronUpDown className="size-4 shrink-0 text-muted-foreground" stroke={2} />
</Button>
</PopoverTrigger>
<PopoverContent align="start" className="w-full p-0">
<Command>
<CommandInput placeholder="Search theme..." autoFocus />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup>
{themes.map((theme) => (
<CommandItem
key={theme.value}
value={theme.value}
onSelect={(val) => setValue(val)}
>
<theme.icon className="size-4 text-muted-foreground" stroke={2} />
{theme.label}
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</div>
);
}