---
title: "Radio Dropdown"
description: "Dropdown for single-choice filtering with counts"
source: "Equality"
---
import { RadioDropdownDemo } from "@demo/components/demo/radio-dropdown";

## Overview

Radio Dropdown is a compact control for picking a single option from a list — typically a filter such as a status or category. It renders as a [Button](button) showing the current selection, opening a [Dropdown Menu](dropdown-menu) of radio options. Each option can carry an optional `count`, shown as a [Badge](badge) on the trigger and inline in the menu, which is handy for surfacing how many items match each filter.

It is a controlled component: you provide the `options` and the `selectedValue`, and it calls `onSelect` when the user chooses a different one. Options with an empty `value` or `label` are filtered out automatically. For longer lists, `searchable` adds in-menu search.

## Usage

Import the component:

```tsx
import { RadioDropdown } from "@eqtylab/equality";
```

Hold the selected value in state and update it from `onSelect`:

```tsx
const [status, setStatus] = useState("active");

<RadioDropdown
  label="Status"
  options={[
    { value: "active", label: "Active", count: 5 },
    { value: "archived", label: "Archived", count: 2 },
  ]}
  selectedValue={status}
  onSelect={setStatus}
/>;
```

The `label` is shown on the trigger before anything is selected, and as the heading inside the menu. Once an option is selected, its label replaces the trigger text.

## Default

<RadioDropdownDemo client:only="react" />

## Search

Pass `searchable` to add the [Dropdown Menu](dropdown-menu)'s in-place search. It is off by default. Reach for it once the list is long enough.

The search box is hidden until the user starts typing with the menu open — the first keystroke reveals it and seeds the query. Options that don't match hide themselves, matching against each option's `label`.

<RadioDropdownDemo client:only="react" variant="searchable" />

Use `searchPlaceholder` to describe what is being searched, and `emptyPlaceholder` for the message shown when a query matches nothing. Both are ignored unless `searchable` is set:

```tsx
<RadioDropdown
  label="Status"
  options={statuses}
  selectedValue={status}
  onSelect={setStatus}
  searchable
  searchPlaceholder="Search categories..."
  emptyPlaceholder="No categories match"
/>
```

The empty message only appears while a query is active — an empty `options` array renders an empty menu rather than this message.

## Props

| Name                | Description                                                                  | Type                                                 | Default             | Required |
| ------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------- | ------------------- | -------- |
| `label`             | Trigger text before selection, and the menu heading.                         | `string`                                             | —                   | ✅       |
| `options`           | The selectable options. Each is `{ value, label, count? }`.                  | `{ value: string; label: string; count?: number }[]` | —                   | ✅       |
| `selectedValue`     | The `value` of the currently selected option.                                | `string`                                             | —                   | ✅       |
| `onSelect`          | Called with the chosen option's `value` when the selection changes.          | `(value: string) => void`                            | —                   | ✅       |
| `className`         | Additional CSS classes applied to the trigger button.                        | `string`                                             | —                   | ❌       |
| `searchable`        | Adds in-menu search, revealed on the first keystroke.                        | `boolean`                                            | `false`             | ❌       |
| `searchPlaceholder` | Placeholder text for the in-menu search input. Requires `searchable`.        | `string`                                             | `Search options...` | ❌       |
| `emptyPlaceholder`  | Message shown when a search query matches no options. Requires `searchable`. | `string`                                             | `No options found`  | ❌       |