Dropdown
A button that opens a list of options to choose from, like a native select. Use it for one or more choices from a known list; add search when the list is long.
Code
import {Dropdown, Stack} from '@earendil-works/elanor-react';
const projects = ['Website redesign', 'Design system', 'Release notes'];
export default function DropdownDemo() {
return (
<Dropdown.Root>
<Stack gap="small">
<Dropdown.Label>Project</Dropdown.Label>
<Dropdown.Trigger>
<Dropdown.Value placeholder="Select a project" />
<Dropdown.Icon />
</Dropdown.Trigger>
</Stack>
<Dropdown.Portal>
<Dropdown.Positioner>
<Dropdown.Popup>
<Dropdown.List>
{projects.map((project) => (
<Dropdown.Item key={project} value={project}>
{project}
</Dropdown.Item>
))}
</Dropdown.List>
</Dropdown.Popup>
</Dropdown.Positioner>
</Dropdown.Portal>
</Dropdown.Root>
);
} Usage
import {Dropdown} from '@earendil-works/elanor-react';
<Dropdown.Root>
<Dropdown.Label />
<Dropdown.Trigger>
<Dropdown.Value />
<Dropdown.Icon />
</Dropdown.Trigger>
<Dropdown.Portal>
<Dropdown.Positioner>
<Dropdown.Popup>
<Dropdown.List>
<Dropdown.Item />
</Dropdown.List>
</Dropdown.Popup>
</Dropdown.Positioner>
</Dropdown.Portal>
</Dropdown.Root>;
Value shows the selected value. When values differ from their labels, pass items to Root, such as items={[{value: 'alpha', label: 'Alpha'}]}.
The trigger stays on one line and truncates long values. Wrap its text in Value or an element, such as a span; bare text doesn’t truncate and hides the icon.
Name the dropdown with Label, or with Prefix inside the trigger. Without either, set aria-label on the trigger and include the value.
The popup opens below the trigger, aligned to its start edge, and repositions when space is limited. Set alignItemWithTrigger on Positioner to overlap the trigger with the selected item instead.
Density
Use compact on the trigger in dense layouts, such as a filter beside a heading. The touch target keeps the default height, and on touch screens extends half the medium gap above and below. SearchableDropdown.Trigger takes the same density.
Code
import {Dropdown, Stack} from '@earendil-works/elanor-react';
const ranges = [
{value: 'week', label: 'Last 7 days'},
{value: 'month', label: 'Last 30 days'},
{value: 'quarter', label: 'Last 90 days'},
];
export default function DropdownDensity() {
return (
<Stack direction="row" gap="large" align="end" wrap="wrap">
{(['default', 'compact'] as const).map((density) => (
<Dropdown.Root key={density} items={ranges} defaultValue="month">
<Stack gap="small">
<Dropdown.Label>{density === 'default' ? 'Default' : 'Compact'}</Dropdown.Label>
<Dropdown.Trigger density={density}>
<Dropdown.Value />
<Dropdown.Icon />
</Dropdown.Trigger>
</Stack>
<Dropdown.Portal>
<Dropdown.Positioner>
<Dropdown.Popup>
<Dropdown.List>
{ranges.map((range) => (
<Dropdown.Item key={range.value} value={range.value}>
<Dropdown.ItemIndicator />
<Dropdown.ItemText>{range.label}</Dropdown.ItemText>
</Dropdown.Item>
))}
</Dropdown.List>
</Dropdown.Popup>
</Dropdown.Positioner>
</Dropdown.Portal>
</Dropdown.Root>
))}
</Stack>
);
} Prefix
Prefix labels the dropdown inside the trigger, such as “Date range: Last 30 days”. Use it when there’s no room for Label, and keep it to a word or two. Prefix adds the colon, so leave it out of the text. Only the value truncates.
Use Prefix instead of Label, or instead of Field.Label inside a Field. It overrides aria-label on the trigger.
Code
import {Dropdown} from '@earendil-works/elanor-react';
const ranges = [
{value: 'week', label: 'Last 7 days'},
{value: 'month', label: 'Last 30 days'},
{value: 'quarter', label: 'Last 90 days'},
];
export default function DropdownPrefix() {
return (
<Dropdown.Root items={ranges} defaultValue="month">
<Dropdown.Trigger density="compact">
<Dropdown.Prefix>Date range</Dropdown.Prefix>
<Dropdown.Value />
<Dropdown.Icon />
</Dropdown.Trigger>
<Dropdown.Portal>
<Dropdown.Positioner>
<Dropdown.Popup>
<Dropdown.List>
{ranges.map((range) => (
<Dropdown.Item key={range.value} value={range.value}>
<Dropdown.ItemIndicator />
<Dropdown.ItemText>{range.label}</Dropdown.ItemText>
</Dropdown.Item>
))}
</Dropdown.List>
</Dropdown.Popup>
</Dropdown.Positioner>
</Dropdown.Portal>
</Dropdown.Root>
);
} Clear
Clear is a button after the trigger that clears the value and moves focus back to the trigger. It renders only while there’s something to clear. Put the trigger and Clear in Control, which joins them in one fill; Clear is the next tab stop after the trigger.
Use Clear on filters, where no value means no filter, not on view controls that always have a value, such as a date range or a sort order.
Name Clear with aria-label, such as “Clear Status filter”, and show the empty value with Value’s placeholder, such as “All”. Clear calls onValueChange with null, or [] with multiple, and the reason clear-press. A disabled or read-only Root, or a disabled Field or Fieldset, disables it. Its touch target matches the trigger’s.
When you control Root, pass null for no value, or [] with multiple, such as value={search.status ?? null}. undefined makes Root uncontrolled.
Code
import {Dropdown, Grid} from '@earendil-works/elanor-react';
const statuses = [
{value: 'active', label: 'Active'},
{value: 'invited', label: 'Invited'},
{value: 'suspended', label: 'Suspended'},
];
export default function DropdownClear() {
return (
<Grid.Root>
<Grid.Item span={{base: 'full', xSmall: 4}}>
<Dropdown.Root items={statuses} defaultValue="invited">
<Dropdown.Control>
<Dropdown.Trigger density="compact">
<Dropdown.Prefix>Status</Dropdown.Prefix>
<Dropdown.Value placeholder="All" />
<Dropdown.Icon />
</Dropdown.Trigger>
<Dropdown.Clear aria-label="Clear Status filter" />
</Dropdown.Control>
<Dropdown.Portal>
<Dropdown.Positioner>
<Dropdown.Popup>
<Dropdown.List>
{statuses.map((status) => (
<Dropdown.Item key={status.value} value={status.value}>
<Dropdown.ItemIndicator />
<Dropdown.ItemText>{status.label}</Dropdown.ItemText>
</Dropdown.Item>
))}
</Dropdown.List>
</Dropdown.Popup>
</Dropdown.Positioner>
</Dropdown.Portal>
</Dropdown.Root>
</Grid.Item>
</Grid.Root>
);
} With multiple, Clear empties the array.
Code
import {Dropdown, Grid} from '@earendil-works/elanor-react';
const groups = ['developers', 'design', 'operations', 'support'];
export default function DropdownClearMultiple() {
return (
<Grid.Root>
<Grid.Item span={{base: 'full', xSmall: 4}}>
<Dropdown.Root multiple defaultValue={['developers', 'design', 'support']}>
<Dropdown.Control>
<Dropdown.Trigger density="compact">
<Dropdown.Prefix>Groups</Dropdown.Prefix>
<Dropdown.Value placeholder="All" />
<Dropdown.Icon />
</Dropdown.Trigger>
<Dropdown.Clear aria-label="Clear Groups filter" />
</Dropdown.Control>
<Dropdown.Portal>
<Dropdown.Positioner>
<Dropdown.Popup>
<Dropdown.List>
{groups.map((group) => (
<Dropdown.Item key={group} value={group}>
<Dropdown.ItemIndicator />
<Dropdown.ItemText>{group}</Dropdown.ItemText>
</Dropdown.Item>
))}
</Dropdown.List>
</Dropdown.Popup>
</Dropdown.Positioner>
</Dropdown.Portal>
</Dropdown.Root>
</Grid.Item>
</Grid.Root>
);
} Clear to a default
For a filter that starts at a value, such as API keys that show only active ones, pass the default to Root as clearValue. Clear then shows while the value differs from it, including when nothing is selected, and sets it back. Name it for what it does, such as “Reset Status filter to Active”.
Code
import {Dropdown, Grid} from '@earendil-works/elanor-react';
import {useState} from 'react';
const statuses = [
{value: 'active', label: 'Active'},
{value: 'expired', label: 'Expired'},
{value: 'revoked', label: 'Revoked'},
];
const defaultStatus = ['active'];
export default function DropdownClearDefault() {
// Unchecking every status shows all keys; Clear goes back to the default.
const [status, setStatus] = useState(defaultStatus);
return (
<Grid.Root>
<Grid.Item span={{base: 'full', xSmall: 4}}>
<Dropdown.Root
multiple
items={statuses}
value={status}
clearValue={defaultStatus}
onValueChange={setStatus}
>
<Dropdown.Control>
<Dropdown.Trigger density="compact">
<Dropdown.Prefix>Status</Dropdown.Prefix>
<Dropdown.Value placeholder="All" />
<Dropdown.Icon />
</Dropdown.Trigger>
<Dropdown.Clear aria-label="Reset Status filter to Active" />
</Dropdown.Control>
<Dropdown.Portal>
<Dropdown.Positioner>
<Dropdown.Popup>
<Dropdown.List>
{statuses.map((option) => (
<Dropdown.Item key={option.value} value={option.value}>
<Dropdown.ItemIndicator />
<Dropdown.ItemText>{option.label}</Dropdown.ItemText>
</Dropdown.Item>
))}
</Dropdown.List>
</Dropdown.Popup>
</Dropdown.Positioner>
</Dropdown.Portal>
</Dropdown.Root>
</Grid.Item>
</Grid.Root>
);
} Value count
ValueCount shows how many more values are selected, such as “Groups: developers +2”. Render the first selected value with Value’s children and put ValueCount after it. It counts from Root unless you pass count, and stays whole while the value truncates. Screen readers read “developers and 2 more”; pass label to translate it.
Code
import {Dropdown, Grid} from '@earendil-works/elanor-react';
const groups = ['developers', 'design', 'operations', 'support'];
export default function DropdownValueCount() {
return (
<Grid.Root>
<Grid.Item span={{base: 'full', xSmall: 4}}>
<Dropdown.Root multiple defaultValue={['developers', 'design', 'support']}>
<Dropdown.Trigger density="compact">
<Dropdown.Prefix>Groups</Dropdown.Prefix>
<Dropdown.Value>{(values: string[]) => values[0] ?? 'All'}</Dropdown.Value>
<Dropdown.ValueCount />
<Dropdown.Icon />
</Dropdown.Trigger>
<Dropdown.Portal>
<Dropdown.Positioner>
<Dropdown.Popup>
<Dropdown.List>
{groups.map((group) => (
<Dropdown.Item key={group} value={group}>
<Dropdown.ItemIndicator />
<Dropdown.ItemText>{group}</Dropdown.ItemText>
</Dropdown.Item>
))}
</Dropdown.List>
</Dropdown.Popup>
</Dropdown.Positioner>
</Dropdown.Portal>
</Dropdown.Root>
</Grid.Item>
</Grid.Root>
);
} Item indicator
ItemIndicator marks the selected item. Put the label next to it in ItemText.
Code
import {Dropdown, Stack} from '@earendil-works/elanor-react';
const projects = ['Website redesign', 'Design system', 'Release notes'];
export default function DropdownItemIndicator() {
return (
<Dropdown.Root defaultValue="Design system">
<Stack gap="small">
<Dropdown.Label>Project</Dropdown.Label>
<Dropdown.Trigger>
<Dropdown.Value />
<Dropdown.Icon />
</Dropdown.Trigger>
</Stack>
<Dropdown.Portal>
<Dropdown.Positioner>
<Dropdown.Popup>
<Dropdown.List>
{projects.map((project) => (
<Dropdown.Item key={project} value={project}>
<Dropdown.ItemIndicator />
<Dropdown.ItemText>{project}</Dropdown.ItemText>
</Dropdown.Item>
))}
</Dropdown.List>
</Dropdown.Popup>
</Dropdown.Positioner>
</Dropdown.Portal>
</Dropdown.Root>
);
} Multiple selection
With multiple, the value is an array and ItemIndicator shows a checkbox.
Code
import {Dropdown, Stack} from '@earendil-works/elanor-react';
const projects = ['Website redesign', 'Design system', 'Release notes'];
export default function DropdownMultiple() {
return (
<Dropdown.Root multiple defaultValue={['Design system']}>
<Stack gap="small">
<Dropdown.Label>Projects</Dropdown.Label>
<Dropdown.Trigger>
<Dropdown.Value placeholder="Select projects" />
<Dropdown.Icon />
</Dropdown.Trigger>
</Stack>
<Dropdown.Portal>
<Dropdown.Positioner>
<Dropdown.Popup>
<Dropdown.List>
{projects.map((project) => (
<Dropdown.Item key={project} value={project}>
<Dropdown.ItemIndicator />
<Dropdown.ItemText>{project}</Dropdown.ItemText>
</Dropdown.Item>
))}
</Dropdown.List>
</Dropdown.Popup>
</Dropdown.Positioner>
</Dropdown.Portal>
</Dropdown.Root>
);
} Groups
Group, GroupLabel, and Separator divide long lists.
Code
import {Dropdown, Stack} from '@earendil-works/elanor-react';
const regions = {
Europe: ['Frankfurt', 'London'],
'North America': ['Toronto', 'Virginia'],
};
export default function DropdownGroups() {
return (
<Dropdown.Root defaultValue="Frankfurt">
<Stack gap="small">
<Dropdown.Label>Region</Dropdown.Label>
<Dropdown.Trigger>
<Dropdown.Value />
<Dropdown.Icon />
</Dropdown.Trigger>
</Stack>
<Dropdown.Portal>
<Dropdown.Positioner>
<Dropdown.Popup>
<Dropdown.List>
{Object.entries(regions).map(([continent, cities], index) => (
<Dropdown.Group key={continent}>
{index > 0 ? <Dropdown.Separator /> : null}
<Dropdown.GroupLabel>{continent}</Dropdown.GroupLabel>
{cities.map((city) => (
<Dropdown.Item key={city} value={city}>
{city}
</Dropdown.Item>
))}
</Dropdown.Group>
))}
</Dropdown.List>
</Dropdown.Popup>
</Dropdown.Positioner>
</Dropdown.Portal>
</Dropdown.Root>
);
} Searchable
SearchableDropdown adds a filter input to the popup, aligned like Dropdown’s. Keep Status outside the popup so screen readers announce the selection after it closes. For a list that is always visible, see Searchable list.
Code
import {SearchableDropdown, Stack} from '@earendil-works/elanor-react';
import {useState} from 'react';
const projects = ['Website redesign', 'Design system', 'Release notes', 'Help center'];
export default function DropdownSearchable() {
const [project, setProject] = useState<string | null>(null);
return (
<SearchableDropdown.Root items={projects} value={project} onValueChange={setProject}>
<Stack gap="small">
<SearchableDropdown.Label>Project</SearchableDropdown.Label>
<SearchableDropdown.Trigger>
<SearchableDropdown.Value placeholder="Select a project" />
<SearchableDropdown.Icon />
</SearchableDropdown.Trigger>
</Stack>
<SearchableDropdown.Portal>
<SearchableDropdown.Positioner>
<SearchableDropdown.Popup aria-label="Choose a project">
<SearchableDropdown.InputGroup>
<SearchableDropdown.Input
aria-label="Filter projects"
placeholder="Filter projects"
/>
</SearchableDropdown.InputGroup>
<SearchableDropdown.Empty>No projects found.</SearchableDropdown.Empty>
<SearchableDropdown.List>
{(item: string) => (
<SearchableDropdown.Item key={item} value={item}>
<SearchableDropdown.ItemIndicator />
{item}
</SearchableDropdown.Item>
)}
</SearchableDropdown.List>
</SearchableDropdown.Popup>
</SearchableDropdown.Positioner>
</SearchableDropdown.Portal>
<SearchableDropdown.Status>
{project === null ? null : `Selected ${project}.`}
</SearchableDropdown.Status>
</SearchableDropdown.Root>
);
} SearchableDropdown has the same Prefix, ValueCount, Control and Clear. Its Value renders no element, so wrap it in a span to truncate it.
Code
import {Grid, SearchableDropdown} from '@earendil-works/elanor-react';
import {useState} from 'react';
const groups = ['developers', 'design', 'operations', 'support', 'marketing', 'finance'];
export default function DropdownSearchableFilter() {
const [selected, setSelected] = useState(['developers', 'operations']);
return (
<Grid.Root>
<Grid.Item span={{base: 'full', xSmall: 4}}>
<SearchableDropdown.Root
items={groups}
multiple
value={selected}
onValueChange={setSelected}
>
<SearchableDropdown.Control>
<SearchableDropdown.Trigger density="compact">
<SearchableDropdown.Prefix>Groups</SearchableDropdown.Prefix>
<span>
<SearchableDropdown.Value>
{(values: string[]) => values[0] ?? 'All'}
</SearchableDropdown.Value>
</span>
<SearchableDropdown.ValueCount />
<SearchableDropdown.Icon />
</SearchableDropdown.Trigger>
<SearchableDropdown.Clear aria-label="Clear Groups filter" />
</SearchableDropdown.Control>
<SearchableDropdown.Portal>
<SearchableDropdown.Positioner>
<SearchableDropdown.Popup aria-label="Choose groups">
<SearchableDropdown.InputGroup>
<SearchableDropdown.Input
aria-label="Search groups"
placeholder="Search groups"
/>
</SearchableDropdown.InputGroup>
<SearchableDropdown.Empty>No matching groups.</SearchableDropdown.Empty>
<SearchableDropdown.List>
{(group: string) => (
<SearchableDropdown.Item key={group} value={group}>
<SearchableDropdown.ItemIndicator />
{group}
</SearchableDropdown.Item>
)}
</SearchableDropdown.List>
</SearchableDropdown.Popup>
</SearchableDropdown.Positioner>
</SearchableDropdown.Portal>
</SearchableDropdown.Root>
</Grid.Item>
</Grid.Root>
);
} API
Dropdown.Root
| Prop | Type | Default | Description |
|---|---|---|---|
onValueChange | | (( value: DropdownRootChangedValue<Value, Multiple>, eventDetails: DropdownRootChangeEventDetails, ) => void) | - | Called when the value changes. When Clear clears it, the value is clearValue and the reason is clear-press. |
clearValue | DropdownRootChangedValue<Value, Multiple> | null, or [] with `multiple` | The value Clear sets, such as a filter's default. Clear shows while the value differs from it. Compared as Base UI compares items, with isItemEqualToValue. |
Also accepts Base UI Select.Root props.
Dropdown.Label
Accepts Base UI Select.Label props.
Dropdown.Trigger
| Prop | Type | Default | Description |
|---|---|---|---|
density | 'compact' | 'default' | 'default' | compact removes block padding but keeps the touch target height. |
Also accepts Base UI Select.Trigger props.
Dropdown.Value
Accepts Base UI Select.Value props.
Dropdown.Icon
Accepts Base UI Select.Icon props.
Dropdown.Portal
Accepts Base UI Select.Portal props.
Dropdown.Positioner
| Prop | Type | Default | Description |
|---|---|---|---|
alignItemWithTrigger | boolean | false | Whether the positioner overlaps the trigger so the selected item's text is aligned with the trigger's value text. |
align | Align | 'start' | How to align the popup relative to the specified side. |
Also accepts Base UI Select.Positioner props.
Dropdown.Popup
Accepts Base UI Select.Popup props.
Dropdown.List
Accepts Base UI Select.List props.
Dropdown.Item
Accepts Base UI Select.Item props.
Dropdown.Prefix
A label inside the trigger, before the value. Use it instead of Label.
| Prop | Type | Default | Description |
|---|---|---|---|
onPointerDown | PointerEventHandler<HTMLSpanElement> | - | A plain React handler; it replaces Base UI's label handler. |
Also accepts Base UI Select props.
Dropdown.ItemIndicator
Accepts Base UI Select.ItemIndicator props.
Dropdown.GroupLabel
Accepts Base UI Select.GroupLabel props.
Dropdown.Separator
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | 'horizontal' | - | Only horizontal is supported. |
Also accepts Base UI Select.Separator props.
Dropdown.Control
Joins the trigger and Clear in one fill. data-has-value is set while a value is selected.
Renders <div>. Accepts its HTML attributes and ref.
Dropdown.Clear
Clears the value, to none or Root's clearValue, and focuses the trigger. Renders only while there's something to clear. Put it after the trigger, inside Control.
| Prop | Type | Default | Description |
|---|---|---|---|
aria-labelrequired | string | - | Names the button, such as “Clear Status filter”. |
type | 'submit' | 'reset' | 'button' | 'button' |
Also accepts Base UI Button props.
Dropdown.ValueCount
A muted count of the selected values after the first, such as “+2”.
| Prop | Type | Default | Description |
|---|---|---|---|
count | number | the selected values after the first | How many values to count, shown as “+2”. Nothing renders below 1. |
label | ((count: number) => string) | (count) => `and ${count} more` | What screen readers read instead of “+2”, such as “and 2 more”. |
Renders <span>. Also accepts its HTML attributes and ref.
Dropdown.ItemText
Accepts Base UI Select.ItemText props.
Dropdown.Group
Accepts Base UI Select.Group props.
SearchableDropdown.Root
| Prop | Type | Default | Description |
|---|---|---|---|
grid | false | - | Only list navigation is supported; grid layouts are not. |
clearValue | SearchableDropdownRootChangedValue<Value, Multiple> | null, or [] with `multiple` | The value Clear sets, such as a filter's default. Clear shows while the value differs from it. Compared as Base UI compares items, with isItemEqualToValue. |
Also accepts Base UI Combobox.Root props.
SearchableDropdown.Label
Accepts Base UI Combobox.Label props.
SearchableDropdown.Prefix
A label inside the trigger, before the value. Use it instead of Label.
| Prop | Type | Default | Description |
|---|---|---|---|
onPointerDown | PointerEventHandler<HTMLSpanElement> | - | A plain React handler; it replaces Base UI's label handler. |
Also accepts Base UI Combobox props.
SearchableDropdown.Trigger
| Prop | Type | Default | Description |
|---|---|---|---|
density | 'compact' | 'default' | 'default' | compact removes block padding but keeps the touch target height. |
Also accepts Base UI Combobox.Trigger props.
SearchableDropdown.Icon
Accepts Base UI Combobox.Icon props.
SearchableDropdown.Positioner
Places the popup below the trigger, aligned to its start edge, as Dropdown's.
| Prop | Type | Default | Description |
|---|---|---|---|
align | Align | 'start' | How to align the popup relative to the specified side. |
Also accepts Base UI Combobox.Positioner props.
SearchableDropdown.Popup
Accepts Base UI Combobox.Popup props.
SearchableDropdown.InputGroup
Accepts Base UI Combobox.InputGroup props.
SearchableDropdown.Input
| Prop | Type | Default | Description |
|---|---|---|---|
type | 'search' | 'text' | 'text' |
Also accepts Base UI Combobox.Input props.
SearchableDropdown.List
Accepts Base UI Combobox.List props.
SearchableDropdown.Item
Accepts Base UI Combobox.Item props.
SearchableDropdown.ItemIndicator
Accepts Base UI Combobox.ItemIndicator props.
SearchableDropdown.GroupLabel
Accepts Base UI Combobox.GroupLabel props.
SearchableDropdown.Separator
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | 'horizontal' | - | Only horizontal is supported. |
Also accepts Base UI Combobox.Separator props.
SearchableDropdown.Empty
Accepts Base UI Combobox.Empty props.
SearchableDropdown.Status
Accepts Base UI Combobox.Status props.
SearchableDropdown.Control
Joins the trigger and Clear in one fill. data-has-value is set while a value is selected.
Renders <div>. Accepts its HTML attributes and ref.
SearchableDropdown.Clear
Clears the value, to none or Root's clearValue, and focuses the trigger. Renders only while there's something to clear. Put it after the trigger, inside Control.
| Prop | Type | Default | Description |
|---|---|---|---|
aria-labelrequired | string | - | Names the button, such as “Clear Status filter”. |
type | 'submit' | 'reset' | 'button' | 'button' |
Also accepts Base UI Button props.
SearchableDropdown.ValueCount
A muted count of the selected values after the first, such as “+2”.
| Prop | Type | Default | Description |
|---|---|---|---|
count | number | the selected values after the first | How many values to count, shown as “+2”. Nothing renders below 1. |
label | ((count: number) => string) | (count) => `and ${count} more` | What screen readers read instead of “+2”, such as “and 2 more”. |
Renders <span>. Also accepts its HTML attributes and ref.
SearchableDropdown.Value
Accepts Base UI Combobox.Value props.
SearchableDropdown.Portal
Accepts Base UI Combobox.Portal props.
SearchableDropdown.Group
Accepts Base UI Combobox.Group props.
SearchableDropdown.Collection
Accepts Base UI Combobox.Collection props.