Dropdown panel
The open list of a dropdown, with search, checkboxes or radios, and a Reset, Cancel and Apply footer.
import { DropdownPanel } from "@/ui";DropdownPanel matches the Figma Dropdown and Dropdown Element components: a 260px list with optional search and an Apply footer. Use it for filters, where people pick several things and apply them together. For a short menu of actions or a single choice that applies at once, use the product Dropdown menu.
It is the panel only. Open it under a trigger the way the Date picker does.
This replaces the DropdownMenu that @/ui used to export. That was an unfinished static version of the same Figma panel, and nothing used it. The name clashed with the product's Dropdown menu, so it is gone.
Actions
With the default type, a click calls onSelect with the item's value. Items can have a 16px icon on the left and a caret on the right when they open a submenu.
<DropdownPanel
items={[
{ value: "rename", label: "Rename", icon: PencilSimple },
{ value: "move", label: "Move to folder", icon: FolderSimple, submenu: true },
]}
onSelect={run}
/>Several choices, with Apply
type="checkbox" puts a checkbox on each item. With footer, ticks are a draft until Apply. Cancel goes back to what was applied, and Reset clears every tick. Search to filter the list, and try a word that matches nothing.
<DropdownPanel type="checkbox" items={channels} value={applied} searchable footer onApply={setApplied} />One choice
type="radio" puts a radio on each item. Without a footer, onChange runs on every click.
<DropdownPanel type="radio" items={periods} value={period} onChange={setPeriod} />Format hints and logos
hint shows a format on the right, in italic on a grey pill with an info icon. Use it for fields where people type a value later, like dates. logo shows a 16px integration logo in place of an icon.
{ value: "close", label: "Close date", hint: "yyyy/mm/dd", hintInfo: "Dates use the workspace format" }
{ value: "salesforce", label: "Salesforce", logo: "/logos/integrations/salesforce.png" }Search
| Figma state | What shows |
|---|---|
| Search Bar=No | The list, five items tall, then the footer |
| Search Bar=Yes | A search field (Grey 200 border) above a list four items tall |
| Searching | Blue border, a clear button, and "Search results for “term”" |
| Search Empty | "No results for “term”" and a Clear search button |
Anatomy
| Part | Spec |
|---|---|
| Panel | 260px, white, 8px radius, shadow 0 8px 12px at 10% |
| Item | 12px by 16px padding (46px tall), 14px text, Primary 50 on hover |
| Item extras | 16px checkbox, radio, icon or logo on the left with a 12px gap; 16px caret on the right |
| Search | 12px 12px 6px around a 32px field, 12px text and icons |
| Status line | 12px secondary text, the term in medium primary text |
| Footer | 42px, 0.5px Grey 100 line above. Reset is a ghost Button; Cancel secondary and Apply primary, all sm |
Figma's footer and Clear search buttons use 10px text. Code uses sm Buttons, which are 12px, because 12px is the smallest text in the product.
Props
| Prop | Type | Default | Notes |
|---|---|---|---|
type | "default" | "checkbox" | "radio" | "default" | |
items | { value, label, icon?, logo?, hint?, hintInfo?, submenu?, disabled? }[] | [] | |
value | string | string[] | null | A string for radio, an array for checkbox. | |
onSelect | function | Default type only. | |
onChange | function | Every change without a footer; on Apply with one. | |
searchable | boolean | false | |
searchPlaceholder | string | "Search Item" | |
footer | boolean | false | |
onApply, onCancel, onReset | function | ||
className | string | "" | For layout only. |
Accessibility
- Items are buttons with
menuitem,menuitemcheckboxormenuitemradioroles andaria-checked. - Down from the search field moves into the list. Up and Down move between items, and Up from the first item goes back to search.
- The search status line is a live region, so screen readers hear whether anything matched.