RadCN
Inputsreadycomponentready

Combobox

A searchable listbox primitive for command-style selection, native form values, and composed popover, menu, and drawer examples.

Importimport { Combobox, ComboboxContent, ComboboxInput, ComboboxItem, ComboboxList, ComboboxTrigger } from 'radcn/combobox'
Preview

Live package example

Render the four upstream Combobox examples through RadCN primitives and app-owned composition.

Example Parity

Render the four upstream Combobox examples through RadCN primitives and app-owned composition.

Preview

Selected label: Remix

featureCreate a new project

Status
import { Button } from 'radcn/button'
import {
  Combobox,
  ComboboxContent,
  ComboboxEmpty,
  ComboboxGroup,
  ComboboxInput,
  ComboboxItem,
  ComboboxList,
  ComboboxPortal,
  ComboboxTrigger,
} from 'radcn/combobox'
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from 'radcn/command'
import { Drawer, DrawerContent, DrawerPortal, DrawerTrigger } from 'radcn/drawer'
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from 'radcn/dropdown-menu'
import { Popover, PopoverContent, PopoverPortal, PopoverTrigger } from 'radcn/popover'

export function ComboboxPreview() {
  return (
    <div class="combobox-examples">
      <div data-radcn-docs-combobox-family="combobox-demo">
        <Combobox defaultValue="remix" name="framework">
          <div class="radcn-combobox-control">
            <ComboboxInput ariaLabel="Framework" placeholder="Search framework..." />
            <ComboboxTrigger>v</ComboboxTrigger>
          </div>
          <ComboboxPortal>
            <ComboboxContent>
              <ComboboxList>
                <ComboboxGroup>
                  <ComboboxItem value="next.js">Next.js</ComboboxItem>
                  <ComboboxItem value="sveltekit">SvelteKit</ComboboxItem>
                  <ComboboxItem value="nuxt.js">Nuxt.js</ComboboxItem>
                  <ComboboxItem value="remix">Remix</ComboboxItem>
                  <ComboboxItem value="astro">Astro</ComboboxItem>
                </ComboboxGroup>
                <ComboboxEmpty>No framework found.</ComboboxEmpty>
              </ComboboxList>
            </ComboboxContent>
          </ComboboxPortal>
        </Combobox>
      </div>

      <div data-radcn-docs-combobox-family="combobox-dropdown-menu">
        <span data-radcn-docs-combobox-label>feature</span>
        <span>Create a new project</span>
        <DropdownMenu defaultOpen>
          <DropdownMenuTrigger ariaLabel="Project actions">...</DropdownMenuTrigger>
          <DropdownMenuPortal>
            <DropdownMenuContent align="end">
              <DropdownMenuItem>Assign to...</DropdownMenuItem>
              <DropdownMenuSub>
                <DropdownMenuSubTrigger>Apply label</DropdownMenuSubTrigger>
                <DropdownMenuSubContent>
                  <Command>
                    <CommandInput placeholder="Filter label..." />
                    <CommandList>
                      <CommandEmpty>No label found.</CommandEmpty>
                      <CommandGroup>
                        <CommandItem value="feature">feature</CommandItem>
                        <CommandItem value="bug">bug</CommandItem>
                        <CommandItem value="design">design</CommandItem>
                      </CommandGroup>
                    </CommandList>
                  </Command>
                </DropdownMenuSubContent>
              </DropdownMenuSub>
            </DropdownMenuContent>
          </DropdownMenuPortal>
        </DropdownMenu>
      </div>

      <div data-radcn-docs-combobox-family="combobox-popover">
        <span>Status</span>
        <Popover defaultOpen>
          <PopoverTrigger class="radcn-button radcn-button--outline">+ Set status</PopoverTrigger>
          <PopoverPortal>
            <PopoverContent align="start" side="right">
              <Command>
                <CommandInput placeholder="Change status..." />
                <CommandList>
                  <CommandEmpty>No results found.</CommandEmpty>
                  <CommandGroup>
                    <CommandItem value="backlog">Backlog</CommandItem>
                    <CommandItem value="todo">Todo</CommandItem>
                    <CommandItem value="done">Done</CommandItem>
                  </CommandGroup>
                </CommandList>
              </Command>
            </PopoverContent>
          </PopoverPortal>
        </Popover>
      </div>

      <div data-radcn-docs-combobox-family="combobox-responsive">
        <div class="combobox-responsive-desktop">
          <Popover defaultOpen>
            <PopoverTrigger class="radcn-button radcn-button--outline">Desktop status</PopoverTrigger>
            <PopoverPortal><PopoverContent><Command><CommandInput placeholder="Filter status..." /></Command></PopoverContent></PopoverPortal>
          </Popover>
        </div>
        <div class="combobox-responsive-mobile">
          <Drawer defaultOpen>
            <DrawerTrigger>Mobile status</DrawerTrigger>
            <DrawerPortal><DrawerContent><Command><CommandInput placeholder="Filter status..." /></Command></DrawerContent></DrawerPortal>
          </Drawer>
        </div>
      </div>
    </div>
  )
}

Installation

Intended future install command. RadCN is private and not published to npm yet, so this snippet documents the target user-facing API rather than something external consumers can run today.

pnpm add radcn # intended future package
import { Combobox, ComboboxContent, ComboboxInput, ComboboxItem, ComboboxList, ComboboxTrigger } from 'radcn/combobox'

Theming

RadCN tokens read the resolved theme from the document. Store the user's preference separately, then resolve system preferences to a concrete light or dark theme before setting package tokens.

<html data-radcn-theme-mode="system" data-radcn-theme="dark">
  ...
</html>

Accessibility

  • ComboboxInput receives role="combobox", aria-expanded, aria-controls, aria-autocomplete, and aria-activedescendant during enhancement.
  • ComboboxList renders role="listbox" and ComboboxItem renders role="option" with aria-selected and aria-disabled state.
  • Keyboard navigation covers Arrow keys, Home, End, Enter, Escape, Tab, and disabled option skipping.
  • Native hidden inputs preserve selected values for server actions and form submissions when name is supplied.

Customization

  • Combobox exposes public data-radcn-combobox hooks for root, input, trigger, portal, content, list, group, label, item, empty state, clear button, and chips.
  • Popover, DropdownMenu, Drawer, Command, and Button remain separate primitives that can be composed around Combobox examples.
  • Selected labels, row badges, responsive branch selection, and icon choices are app-owned presentation and state.
  • Tailwind width, padding, flex, and responsive utilities map to RadCN classes, class, style, CSS variables, CSS breakpoints, or small dependency-free browser enhancement.

Remix 3 Notes

  • shadcn React useState and onSelect map to RadCN package-owned selection behavior for Combobox and app-owned browser/server state for composed labels.
  • Button asChild maps to explicit ComboboxTrigger, PopoverTrigger, DropdownMenuTrigger, and DrawerTrigger components.
  • Upstream Command, Popover, DropdownMenu, and Drawer examples map to RadCN package imports without making them Combobox package dependencies.
  • useMediaQuery maps to CSS breakpoints or dependency-free enhancement; lucide-react icons remain app-owned presentation.
  • className maps to class, data-slot maps to data-radcn-* hooks, and vendor source remains read-only evidence.
  • combobox-form is adjacent Form/Combobox evidence because its React Hook Form, Zod, Sonner, and validation mechanics belong to form composition.