Docs
Combobox

Combobox

An input component that combines a text field with a dropdown list, allowing users to either type a value directly or select one from a predefined, searchable list of options. Ideal for autocomplete scenarios or command palettes.

Loading...

Component Installation and Dependencies

The Combobox component is not a standalone primitive but rather a sophisticated composition leveraging two other core components:

  1. <Popover />: Used to display the dropdown list of suggestions.

  2. <Command />: Provides the searching/filtering capabilities within the popover list.

Therefore, to use the Combobox, you must first ensure that both the Popover and the Command components are installed and available in your project. Follow the installation instructions provided on their respective documentation pages.

Implementing the Combobox

"use client"; // Directive for Next.js App Router, indicating client-side interactivity
  Command, // Core command component for search functionality
  CommandEmpty, // Displayed when no results are found
  CommandGroup, // Groups command items
  CommandInput, // The search input field
  CommandItem, // Represents a single selectable item
  CommandList, // Container for command items, handles scrolling
} from "@/components/ui/command";
import {
  Popover, // Container for the dropdown content
  PopoverContent, // The actual dropdown panel
  PopoverTrigger, // The element that opens the popover (our button)
} from "@/components/ui/popover";

// Sample data structure for the combobox options
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" },
];

export function ComboboxDemo() {
  // State to manage the popover's open/closed status
  const [open, setOpen] = React.useState(false);
  // State to store the selected value
  const [value, setValue] = React.useState("");

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox" // ARIA role for accessibility
          aria-expanded={open} // ARIA state indicating if dropdown is open
          className="w-[200px] justify-between" // Styling
        >
          {value
            ? frameworks.find((framework) => framework.value === value)?.label
            : "Select framework..."}
          <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-[200px] p-0">
        <Command>
          <CommandInput placeholder="Search framework..." />
          <CommandList>
            <CommandEmpty>No framework found.</CommandEmpty>
            <CommandGroup>
              {frameworks.map((framework) => (
                <CommandItem
                  key={framework.value}
                  value={framework.value} // Value used for matching and selection
                  // Handler for when an item is selected
                  onSelect={(currentValue) => {
                    setValue(currentValue === value ? "" : currentValue);

                    setOpen(false);
                  }}
                >
                  <Check
                    className={cn(
                      "mr-2 h-4 w-4",

                      value === framework.value ? "opacity-100" : "opacity-0",
                    )}
                  />

                  {framework.label}
                </CommandItem>
              ))}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}

The core idea is to use a <Button> wrapped in a <PopoverTrigger> to open a <PopoverContent>. Inside the content, a <Command> component handles the list rendering, searching (<CommandInput>), and item selection (<CommandItem>). State (open, value) is managed using React.useState to control the popover visibility and track the selected item.

Combobox Variations and Examples

Standard Combobox Implementation

Loading...

Alternative Trigger: Popover Integration

Loading...

Integration within a Dropdown Menu

Loading...

Responsive Design Adaptation

Achieve a responsive user experience by conditionally rendering the dropdown. Use the standard <Popover /> for wider screens (desktop) and switch to a <Drawer /> component for narrower screens (mobile), providing a more touch-friendly interface on smaller devices.

Loading...

Usage within Forms

Loading...