Dropdown

Animated single and multi select dropdown with search, select all / deselect all, removable chips, per-option icons, color dots, descriptions, disabled options, grouping, and checkbox / radio / check indicators. Fully keyboard accessible.

UniqueUI CLI

npx uniqueui add dropdown

shadcn CLI

npx shadcn@latest add https://uniqueui-platform.vercel.app/r/dropdown.json -y

shadcn path expects @/lib/utils (run shadcn init first). Same source file is installed to components/ui/.

Single select + icons

Variant 1 of 4
"use client";
import { Dropdown } from "@/components/ui/dropdown";
import { Shield, Settings, User, Globe } from "lucide-react";

export default function Example() {
  return (
    <div className="flex h-[440px] w-full justify-center px-6 pt-10">
      <Dropdown
        theme="dark"
        placeholder="Select a role"
        clearable
        options={[
          { value: "admin", label: "Administrator", icon: <Shield className="h-4 w-4 text-purple-400" />, description: "Full access to everything" },
          { value: "editor", label: "Editor", icon: <Settings className="h-4 w-4 text-blue-400" />, description: "Can create and edit content" },
          { value: "viewer", label: "Viewer", icon: <User className="h-4 w-4 text-green-400" />, description: "Read-only access" },
          { value: "guest", label: "Guest", icon: <Globe className="h-4 w-4 text-neutral-400" />, disabled: true },
        ]}
      />
    </div>
  );
}

Multi-select + search

Variant 2 of 4
"use client";
import { Dropdown } from "@/components/ui/dropdown";

export default function Example() {
  return (
    <div className="flex h-[440px] w-full justify-center px-6 pt-10">
      <Dropdown
        theme="dark"
        multiple
        searchable
        clearable
        showSelectAll
        chips
        defaultValue={["react", "ts"]}
        placeholder="Pick technologies"
        searchPlaceholder="Search technologies…"
        options={[
          { value: "react", label: "React", color: "#61dafb" },
          { value: "vue", label: "Vue", color: "#42b883" },
          { value: "svelte", label: "Svelte", color: "#ff3e00" },
          { value: "angular", label: "Angular", color: "#dd0031" },
          { value: "solid", label: "Solid", color: "#2c4f7c" },
          { value: "ts", label: "TypeScript", color: "#3178c6" },
          { value: "tailwind", label: "Tailwind", color: "#38bdf8" },
        ]}
      />
    </div>
  );
}

Grouped + radio

Variant 3 of 4
"use client";
import { Dropdown } from "@/components/ui/dropdown";

export default function Example() {
  return (
    <div className="flex h-[440px] w-full justify-center px-6 pt-10">
      <Dropdown
        theme="dark"
        selectionIndicator="radio"
        placeholder="Choose a plan"
        defaultValue="pro"
        options={[
          { value: "free", label: "Free", description: "$0 / month", group: "Personal" },
          { value: "plus", label: "Plus", description: "$8 / month", group: "Personal" },
          { value: "pro", label: "Pro", description: "$20 / month", group: "Teams" },
          { value: "enterprise", label: "Enterprise", description: "Contact us", group: "Teams" },
        ]}
      />
    </div>
  );
}

Count display + clear

Variant 4 of 4
"use client";
import { Dropdown } from "@/components/ui/dropdown";

export default function Example() {
  return (
    <div className="flex h-[440px] w-full justify-center px-6 pt-10">
      <Dropdown
        theme="dark"
        multiple
        searchable
        clearable
        showSelectAll
        defaultValue={["read", "write"]}
        placeholder="Select permissions"
        searchPlaceholder="Search permissions…"
        options={[
          { value: "read", label: "Read", color: "#22c55e" },
          { value: "write", label: "Write", color: "#eab308" },
          { value: "delete", label: "Delete", color: "#ef4444" },
          { value: "admin", label: "Admin", color: "#a855f7" },
          { value: "billing", label: "Billing", color: "#3b82f6" },
          { value: "audit", label: "Audit log", color: "#06b6d4" },
        ]}
      />
    </div>
  );
}

Props

PropTypeDescription
optionsDropdownOption[]Items: { value, label, icon?, color?, description?, group?, disabled? }. Consecutive options sharing a group render as a labelled section.
valuestring | string[]Controlled value — string[] in multiple mode, string in single mode. Omit for uncontrolled.
defaultValuestring | string[]Initial value when uncontrolled.
onChange(value: string | string[]) => voidFires on selection change. Receives string[] when multiple, otherwise the selected string ("" when cleared).
multiplebooleanEnable multi-select (checkbox indicators, chips/count, select all).
searchablebooleanShow an in-panel search box that filters options by label.
clearablebooleanShow a clear (×) button in the trigger when there is a selection.
showSelectAllbooleanMultiple mode: show a Select all / Deselect all row with an indeterminate state.
selectionIndicator"checkbox" | "radio" | "check" | "none"Per-option marker. Defaults to checkbox in multiple mode, check in single mode.
chipsbooleanMultiple mode: render selected items as removable chips in the trigger instead of a count.
maxVisibleChipsnumberNumber of chips shown before collapsing the remainder into "+N".
placeholderstringTrigger text when nothing is selected; also the listbox accessible name.
searchPlaceholderstringPlaceholder for the search input.
emptyMessagestringShown when search yields no matches.
selectAllLabelstringLabel for the select-all row (switches to "Deselect all" when all are selected).
disabledbooleanDisable the whole control.
theme"light" | "dark"Theme for default trigger and panel colors.
classNamestringAdditional classes merged onto the root wrapper.