# @carlos3g/element-dropdown — full documentation
> Single-file dump of every documentation page on https://carlos3g.github.io/element-dropdown, in stable order.
> Generated at build time. For the manifest version see https://carlos3g.github.io/element-dropdown/llms.txt.
---
# Accessibility
Source: https://carlos3g.github.io/element-dropdown/docs/accessibility
# Accessibility
`@carlos3g/element-dropdown` ships sensible a11y defaults: every
touchable surface is exposed to screen readers, items announce
their selection state, the modal traps VoiceOver focus, and the
component honours the user's reduce-motion preference. Nothing
on this page requires any code change to benefit from — it's all
on by default.
## Trigger
Both `Dropdown` and `MultiSelect` triggers expose:
- `accessibilityRole="combobox"` — screen readers announce it as a
dropdown.
- `accessibilityState.expanded` — `true` when the list is open.
- `accessibilityState.disabled` — `true` when the `disable` prop
is set.
Set `accessibilityLabel` on the component to give the trigger a
descriptive label, and `accessibilityHint` for an action
description:
```tsx
```
The label is also propagated to the search input
(as `{label} input`) and the list (as `{label} flatlist`), so
tests and assistive tech can address each surface.
## List items
Every list row exposes:
- `accessibilityRole="button"` — TalkBack / VoiceOver announces
rows as actionable.
- `accessibilityState.selected` — `true` when this item matches
the current value.
- `accessibilityState.disabled` — `true` when `disabledField` is
set and the item's value at that field is truthy.
By default, the row's `accessibilityLabel` is `item[labelField]`.
To use a different field, set `itemAccessibilityLabelField`:
```tsx
setValue(item.id)}
/>
```
Items are accessible regardless of whether you pass a
component-level `accessibilityLabel`. (Earlier upstream versions
silently set `accessible={false}` when the component label was
missing — that gate has been removed.)
## Section headers
When you use the `sections` prop, the default section header
carries `accessibilityRole="header"` so VoiceOver / TalkBack's
"next heading" gesture surfaces group titles:
```tsx
```
If you supply your own `renderSectionHeader`, set the role
yourself.
## MultiSelect chips
Each chip in the selection row exposes:
- `accessibilityRole="button"`
- `accessibilityHint="Double tap to remove from selection"`
The decorative `ⓧ` glyph is hidden from the accessibility tree
(`accessibilityElementsHidden` + `importantForAccessibility="no-hide-descendants"`)
so screen readers don't read out "circled x" after the label.
The chip-row container is an
`accessibilityLiveRegion="polite"` region — toggling a row
announces the new chip without forcing the user to navigate back
to the row.
## Modal isolation
The dropdown opens inside a React Native `` whose root
view sets `accessibilityViewIsModal`. On iOS, this scopes
VoiceOver focus to the modal contents; users can't accidentally
swipe back into the screen behind the open list.
## Reduce motion
Both components subscribe to the OS-level "Reduce Motion"
preference via `AccessibilityInfo`. When enabled, the modal
opens / closes with `animationType="none"` instead of the
default platform animation. The change happens live — toggling
the OS setting while a dropdown is open propagates without a
remount.
## Tap target size
Use [`hitSlop`](./guides/hit-slop) to expand the trigger's tap
area without changing its visual layout. WCAG 2.5.5 recommends
at least 44 × 44 pt; if your trigger sits in tight UI, set
`hitSlop` to widen the touch target.
## Font scaling
Labels and the search input respect the system font-scale setting
by default. Use [`allowFontScaling`](./guides/font-scaling) to
override per-component when you need to lock a fixed size for
layout reasons.
## Search input
The built-in search input inherits an accessibility label
derived from the component's `accessibilityLabel` (`{label}
input`). To set a more user-friendly label, override via
`searchInputProps`:
```tsx
```
`searchInputProps` is also where to set `selectionColor`,
`returnKeyType`, `autoCapitalize`, `autoFocus`, etc. for
keyboard / cursor a11y. See
[Search input passthrough](./guides/search-input-props).
## Known gaps
- **Hardware keyboard navigation** (arrow keys, Home/End, Escape,
typeahead) is not yet implemented. The component relies on
touch. Tracking upstream `#228` as a follow-up; needs an
active-descendant focus model that doesn't exist yet in the
codebase.
- **Programmatic focus management** — opening the dropdown does
not auto-focus the search input, and closing does not return
focus to the trigger. Adding this without device-level testing
would risk regressions on Android, so it's deferred until we
have a Fabric / web harness.
If you hit an accessibility bug or gap not listed here, open an
issue at
[`carlos3g/element-dropdown`](https://github.com/carlos3g/element-dropdown/issues).
---
# Introduction
Source: https://carlos3g.github.io/element-dropdown/docs/intro
# `react-native-element-dropdown`, maintained.
`@carlos3g/element-dropdown` is a drop-in fork of
[`react-native-element-dropdown`](https://github.com/hoaphantn7604/react-native-element-dropdown).
Bugs get fixed, the toolchain stays current, and every release is
signed. Same API, same three components (`Dropdown`,
`MultiSelect`, `SelectCountry`), same props — change two lines and
keep shipping.
```sh
npm install @carlos3g/element-dropdown
```
```diff
- import { Dropdown } from 'react-native-element-dropdown';
+ import { Dropdown } from '@carlos3g/element-dropdown';
```
## Why this fork exists
The original package is unmaintained. A large open-issue backlog,
plus clean community pull requests sitting untouched for years. If
you're already on `react-native-element-dropdown`, you've likely
hit one of these:
- `Invariant Violation: scrollToIndex out of range` when searching
long lists
- The list flashes at the wrong position for a frame when you
reopen it
- `IDropdownRef` / `IMultiSelectRef` aren't importable when you
build for web or Expo
- Every item has a non-overridable `padding: 17` —
`itemContainerStyle` can't shrink it
- `MultiSelect` trigger uses `placeholderStyle` even after you've
selected something
All fixed in this fork — along with plenty more. The
[release notes](https://github.com/carlos3g/element-dropdown/releases)
have the per-version detail.
## Where to go next
- **[Installation](./installation)** — add the package to your
project.
- **[Quick start](./quick-start)** — render your first `Dropdown`
and `MultiSelect`.
- **[Migration from upstream](./migration-from-upstream)** — what
changes (and what doesn't) when moving from
`react-native-element-dropdown`.
- **Components** — full prop reference for
[`Dropdown`](./components/dropdown),
[`MultiSelect`](./components/multi-select), and
[`SelectCountry`](./components/select-country).
- **Guides** — copy-paste recipes for common patterns.
- **[Why this fork](./why-this-fork)** — the longer version.
---
# Installation
Source: https://carlos3g.github.io/element-dropdown/docs/installation
# Installation
## Install the package
```sh
npm install @carlos3g/element-dropdown
```
```sh
yarn add @carlos3g/element-dropdown
```
## Peer dependencies
`@carlos3g/element-dropdown` declares `react` and `react-native` as
`peerDependencies: "*"` — the package does not pin them. Use the
`react` and `react-native` versions your app is already on. The
library itself runs on everything from `react-native@0.71`+ and any
matching React version.
There are no native modules, no pods to link, no Gradle files to
touch. Expo Managed and bare React Native both work as-is.
## Supported platforms
- iOS
- Android
- React Native Web (via `react-native-web`)
## TypeScript
TypeScript support is first-class — the package ships both the
type definitions and the TypeScript source. Consumer types are
re-exported from the package root:
```tsx
import type {
DropdownProps,
IDropdownRef,
MultiSelectProps,
IMultiSelectRef,
SelectCountryProps,
ISelectCountryRef,
} from '@carlos3g/element-dropdown';
```
## Verifying the install
The fastest smoke test is rendering a minimal `Dropdown` — head to
[Quick start](./quick-start).
---
# Why this fork
Source: https://carlos3g.github.io/element-dropdown/docs/why-this-fork
# Why this fork
`react-native-element-dropdown` has been a good library. At the
time of writing this fork was created, the upstream had **1.3k
GitHub stars, 210 forks, and roughly 1.2 million weekly npm
downloads**. People rely on it.
It's also effectively unmaintained. The last meaningful upstream
activity was mid-2024. The issue tracker has a large backlog, and
the PR queue has clean, small community fixes that have been
waiting years to merge.
Rather than re-architect a new dropdown library, this fork keeps
what worked and fixes what didn't.
## What this fork commits to
- **Same public API.** Migration is two lines: the install name
and the import path. See
[Migration from upstream](./migration-from-upstream).
- **Bugs get fixed.** Upstream issues get triaged and landed
release by release. See the
[release notes](https://github.com/carlos3g/element-dropdown/releases)
for what's in each version, and
[`docs/upstream-triage.md`](https://github.com/carlos3g/element-dropdown/blob/master/docs/upstream-triage.md)
for the roadmap.
- **The toolchain stays current.** TypeScript, React Native,
ESLint, Prettier, Jest — they get upgraded so this library can
keep up with its consumers rather than hold them back.
- **Releases are signed.** Every version is published via npm
Trusted Publishing (OIDC) with provenance attestation. Anyone
can verify a given tarball came from this repository's CI.
## What this fork does not try to be
- A rewrite. The public API is intentionally unchanged; do not
expect breaking redesigns.
- A new dependency-free implementation. The same FlatList +
Modal approach the upstream used is still used here.
- An enterprise-supported product. This is a maintained
open-source fork — no SLA, no commercial tier, no email
support. Issues and pull requests are the interface.
## Open questions and follow-ups
Some upstream issues are deferred because they need device-level
reproduction:
- Keyboard-avoidance math on iOS and Android 0.76+ (upstream
`#180`, `#357`, `#339`, `#288`, `#328`).
- Android 14+ `dropdownPosition="top"` behavior (`#355`).
- Realme OEM positioning quirks (`#350`).
These are tracked in
[`docs/upstream-triage.md`](https://github.com/carlos3g/element-dropdown/blob/master/docs/upstream-triage.md).
Pull requests with repro projects are welcome.
## How to help
- File issues with minimal repros.
- Send pull requests — ideally with a test.
- Port clean upstream PRs (see the upstream-triage doc for the
prioritized list).
- Star the repo; it makes the fork easier to find for people who
are currently on the abandoned upstream.
---
# Quick start
Source: https://carlos3g.github.io/element-dropdown/docs/quick-start
# Quick start
## A single-select `Dropdown`
```tsx
import { useState } from 'react';
import { Dropdown } from '@carlos3g/element-dropdown';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Cherry', value: 'cherry' },
];
export function FruitPicker() {
const [value, setValue] = useState(null);
return (
setValue(item.value)}
/>
);
}
```
What you get out of the box:
- A styled trigger that displays the placeholder or the selected
label.
- A modal-backed list that opens on tap and closes on outside press.
- Automatic positioning above or below the trigger (set
[`dropdownPosition`](./components/dropdown#behavior) to lock it).
## A `MultiSelect`
```tsx
import { useState } from 'react';
import { MultiSelect } from '@carlos3g/element-dropdown';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Cherry', value: 'cherry' },
];
export function FruitBasket() {
const [value, setValue] = useState([]);
return (
);
}
```
`MultiSelect` is controlled by `value`. Tapping an item toggles it
on or off; `onChange` fires with the new array.
## With a search input
Set `search={true}` and the component renders a `TextInput` above
the list. By default the search matches against the label field.
```tsx
setValue(item.value)}
/>
```
See the [custom search](./guides/custom-search-field) and
[custom matcher](./guides/custom-search-matcher) guides for more
control.
## Next steps
- **[Components](./components/dropdown)** — the full prop reference.
- **Guides** — recipes for programmatic open/close, disabled items,
nesting inside a Modal, and more.
---
# Migration from upstream
Source: https://carlos3g.github.io/element-dropdown/docs/migration-from-upstream
import Head from '@docusaurus/Head';
# Migration from `react-native-element-dropdown`
The fork is designed for drop-in migration from
`react-native-element-dropdown@2.12.x`. The public API is
unchanged — only the package name and import paths differ.
## The two-line change
```sh
# 1. Remove the upstream and install the fork
npm uninstall react-native-element-dropdown
npm install @carlos3g/element-dropdown
```
```diff
// 2. Update your imports
- import { Dropdown, MultiSelect, SelectCountry } from 'react-native-element-dropdown';
+ import { Dropdown, MultiSelect, SelectCountry } from '@carlos3g/element-dropdown';
```
That's it. No config file changes, no `metro.config.js` tweaks, no
native rebuild.
## Is the API compatible?
Yes. Every prop and every component signature from `2.12.x` works
unchanged. Peer dependencies are still `react: *` and
`react-native: *`. Platforms supported: iOS, Android, and React
Native Web.
## Do I need to rebuild native code?
No. The library has no native modules, no pods to link, no Gradle
files to touch. Expo Managed and bare React Native both work
as-is.
## What improves automatically after migration?
Behavior changes you get for free, with no code changes:
- **TypeScript types are exported as types.** Importing
`IDropdownRef` or `IMultiSelectRef` no longer trips bundlers on
web or Expo.
- **The `scrollToIndex out of range` crash is gone.** The common
crash when auto-scrolling to a selected item while searching a
long list no longer fires.
- **Open-time flicker is gone.** The list no longer paints for a
frame at the previous open's position before snapping to the
correct one.
- **MultiSelect trigger label honors `selectedTextStyle`** once
items are selected. Previously it stayed on `placeholderStyle`.
- **Row padding is customizable.** `itemContainerStyle` can shrink
(or expand) the item row. Previously the `padding: 17` was
hardcoded deeper in the tree and could only be overridden via
`renderItem`.
- **Duplicate-key warnings from `FlatList` are gone.** The list
now extracts keys from `valueField` when present.
- **Accessibility is announced properly.** Triggers expose
`accessibilityRole="combobox"` plus `expanded` and `disabled`
states; items expose `selected` and `disabled`.
## What new props are available?
All new props are optional:
- **[`disabledField`](./components/dropdown#behavior)** — mark
individual items as non-interactive.
- **`hitSlop`** — enlarge the trigger tap target without changing
layout.
- **`allowFontScaling`** — respect or override the system font
scale for the trigger, the search input, and item labels.
- **`isInsideModal`** — tells the component it's rendered inside
a React Native `` so positioning math doesn't
double-count the status bar.
## Anything to watch out for?
- The TS type-only re-exports now use `export type`, which means
that downstream code that imported `IDropdownRef` as a **value**
(e.g. via `typeof`) needs to import it as a type. In practice
this trips code only if you were misusing the type in the first
place.
- If your project depends on the exact previous row padding of
`17`, no action needed — the default is unchanged. The
difference is that `itemContainerStyle` can now override it.
## Still stuck?
Open an issue at
[`carlos3g/element-dropdown`](https://github.com/carlos3g/element-dropdown/issues).
If the same symptom appears in the upstream and it's not covered
by the roadmap in
[`docs/upstream-triage.md`](https://github.com/carlos3g/element-dropdown/blob/master/docs/upstream-triage.md),
it's worth reporting.
---
# Dropdown
Source: https://carlos3g.github.io/element-dropdown/docs/components/dropdown
# `Dropdown`
Single-select dropdown. The user taps the trigger, picks one item
from a list, and the list closes.
## Minimal example
```tsx
import { useState } from 'react';
import { Dropdown } from '@carlos3g/element-dropdown';
const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
];
export function FruitPicker() {
const [value, setValue] = useState(null);
return (
setValue(item.value)}
/>
);
}
```
## Props
### Required
| Prop | Type | Description |
|---|---|---|
| `data` | `T[]` | Flat array of items. Pass `sections` instead for grouped rendering. |
| `labelField` | `keyof T` | Field on each item to use as the visible label. |
| `valueField` | `keyof T` | Field on each item that identifies it uniquely. |
| `onChange` | `(item: T) => void` | Fires with the selected item when the user picks from the list. |
### Sections (optional — alternative to `data`)
| Prop | Type | Description |
|---|---|---|
| `sections` | `{ title: string; data: T[] }[]` | Groups of items rendered under section headers. When provided, `data` is ignored. See [Sectioned lists](../guides/sectioned-lists). |
| `renderSectionHeader` | `(section) => ReactElement \| null` | Fully custom header renderer. |
| `sectionHeaderStyle` | `ViewStyle` | Style for the default header container. |
| `sectionHeaderTextStyle` | `TextStyle` | Style for the default header ``. |
### Value and display
| Prop | Type | Default | Description |
|---|---|---|---|
| `value` | `T \| string \| null` | `undefined` | Currently selected value. Can be the full item or just the `valueField` value. |
| `placeholder` | `string` | `'Select item'` | Shown when no value is selected. |
| `placeholderStyle` | `TextStyle` | — | Style for the placeholder text. |
| `selectedTextStyle` | `TextStyle` | — | Style for the label when an item is selected. |
| `selectedTextProps` | `TextProps` | `{}` | Extra props spread onto the selected-label `` (e.g. `numberOfLines`). |
### Container and layout
| Prop | Type | Default | Description |
|---|---|---|---|
| `style` | `ViewStyle` | — | Style for the outer wrapper. |
| `containerStyle` | `ViewStyle` | — | Style for the floating list container. |
| `backgroundColor` | `string` | — | Color of the scrim behind the modal in full-screen modes. |
| `modalAnimationType` | `'none' \| 'slide' \| 'fade'` | RN default | Forwarded to the underlying React Native ``. When the OS "Reduce Motion" setting is on, this is always forced to `'none'`. |
| `maxHeight` | `number` | `340` | Max height of the list. |
| `minHeight` | `number` | `0` | Min height of the list. |
| `mode` | `'default' \| 'modal' \| 'auto'` | `'default'` | `'modal'` centers the list on screen; `'auto'` measures trigger position. |
| `dropdownPosition` | `'auto' \| 'top' \| 'bottom'` | `'auto'` | Force the list to open above or below the trigger. |
| `inverted` | `boolean` | `true` | Reverses scroll direction when positioned above the trigger. |
| `isInsideModal` | `boolean` | `false` | Set to `true` when the Dropdown is rendered inside a React Native `` so the status-bar offset isn't double-counted. See [Nest inside a Modal](../guides/nested-in-modal). |
### Items
| Prop | Type | Default | Description |
|---|---|---|---|
| `itemContainerStyle` | `ViewStyle` | — | Style merged on top of the built-in row style. Use this to change padding. |
| `itemTextStyle` | `TextStyle` | — | Style for the default item label text. |
| `activeItemTextStyle` | `TextStyle` | — | Extra text style applied only to the currently-selected row. |
| `activeColor` | `string` | `'#F6F7F8'` | Background color of the currently selected row in the list. |
| `renderItem` | `(item: T, selected?: boolean, index?: number) => ReactElement` | — | Fully custom row renderer. Overrides the default label. The optional `index` is the row index in the current list (per-section when `sections` is used) — handy for staggered enter animations. See [Animations guide](../guides/animations). |
| `disabledField` | `keyof T` | — | When set, items whose value at this field is truthy are non-interactive. |
| `hideSelectedFromList` | `boolean` | `false` | When `true`, the currently selected item is removed from the rendered list. |
### Search
| Prop | Type | Default | Description |
|---|---|---|---|
| `search` | `boolean` | `false` | Show the search input above the list. |
| `searchField` | `keyof T \| (keyof T)[]` | `labelField` | Which field(s) to match against. Pass an array to search several at once. See [Custom search field](../guides/custom-search-field). |
| `searchQuery` | `(keyword: string, labelValue: string) => boolean` | — | Fully custom matcher. See [Custom matcher](../guides/custom-search-matcher). |
| `searchKeyboardType` | `KeyboardTypeOptions` | — | `keyboardType` for the search input (e.g. `'numeric'`, `'email-address'`). |
| `searchInputProps` | `TextInputProps` | — | Extra props spread onto the underlying search `` (`selectionColor`, `returnKeyType`, `autoCapitalize`, etc.). See [Search input passthrough](../guides/search-input-props). |
| `persistSearch` | `boolean` | `false` | Keep the search text across opens / selections instead of clearing it. |
| `searchDebounce` | `number` | `0` | Debounce the filter pass by this many ms. The text input stays responsive; only the filter is throttled. Useful for lists in the thousands. |
| `inputSearchStyle` | `ViewStyle` | — | Style for the search input. |
| `searchPlaceholder` | `string` | — | Placeholder text for the search input. |
| `searchPlaceholderTextColor` | `string` | `'gray'` | Placeholder color for the search input. |
| `renderInputSearch` | `(onSearch: (text: string) => void) => ReactElement` | — | Fully custom search input. |
| `renderSearchClearIcon` | `() => ReactElement \| null` | — | Replace only the clear glyph on the built-in search input while keeping the clear-on-press behaviour. Ignored when `renderInputSearch` is supplied. |
| `onChangeText` | `(text: string) => void` | — | Fires whenever the search text changes (including when the dropdown closes). |
### Icons & trigger
| Prop | Type | Default | Description |
|---|---|---|---|
| `iconStyle` | `ImageStyle` | — | Style for the default right-side chevron. |
| `iconColor` | `string` | `'gray'` | Tint for the default right-side chevron. |
| `renderLeftIcon` | `(visible?: boolean) => ReactElement \| null` | — | Custom left icon; receives whether the list is open. |
| `renderRightIcon` | `(visible?: boolean) => ReactElement \| null` | — | Custom right icon; receives whether the list is open. See [Icons per state](../guides/icon-per-state). |
| `renderSelectedItem` | `(visible?: boolean) => ReactElement \| null` | — | Replace the entire trigger body (left icon, label, right icon) with a custom layout. See [Custom trigger](../guides/custom-trigger). |
| `renderModalHeader` | `(close: () => void) => ReactElement \| null` | — | Renders a header view above the list inside the modal. Receives a `close()` to dismiss. See [Modal header](../guides/modal-header). |
### Behavior
| Prop | Type | Default | Description |
|---|---|---|---|
| `disable` | `boolean` | `false` | When `true`, tapping the trigger does nothing. |
| `autoScroll` | `boolean` | `true` | On open, scroll the list to the currently-selected row. Ignored while the list is filtered. |
| `keyboardAvoiding` | `boolean` | `true` | Lift the list when the search input raises the keyboard. |
| `confirmSelectItem` | `boolean` | `false` | When `true`, selecting an item calls `onConfirmSelectItem` instead of `onChange`. |
| `onConfirmSelectItem` | `(item: T) => void` | — | Called when `confirmSelectItem` is `true`. |
| `closeModalWhenSelectedItem` | `boolean` | `true` | When `false`, the list stays open after a selection. |
| `showsVerticalScrollIndicator` | `boolean` | `true` | Shows the vertical scroll indicator on the list. |
| `flatListProps` | `Omit, 'renderItem' \| 'data'>` | — | Passthrough to the underlying `FlatList`. |
| `renderEmpty` | `(searchText: string) => ReactElement \| null` | — | Custom view rendered when the list has no rows — either empty `data` / `sections` or a search that filters everything out. The callback receives the current search query so you can switch between "no data" and "no results for X" copy. |
| `onEndReached` | `() => void` | — | Fires when the list scrolls within `onEndReachedThreshold` of the bottom. See [Pagination](../guides/end-reached-pagination). |
| `onEndReachedThreshold` | `number` | `0.5` | Distance from the end (in viewport units) at which `onEndReached` fires. |
| `excludeItems` | `T[]` | `[]` | Items to hide from the rendered list. |
| `excludeSearchItems` | `T[]` | `[]` | Items that show in the list but are excluded from search matches. |
### Callbacks
| Prop | Type | Description |
|---|---|---|
| `onFocus` | `() => void` | Fires when the list opens. |
| `onBlur` | `() => void` | Fires when the list closes. |
### Text rendering
| Prop | Type | Default | Description |
|---|---|---|---|
| `fontFamily` | `string` | — | Applied to trigger label, item labels, and the search input. |
| `allowFontScaling` | `boolean` | RN default | Propagated to every `Text` and `TextInput` the component renders. |
### Accessibility
| Prop | Type | Description |
|---|---|---|
| `accessibilityLabel` | `string` | Label for the trigger. Propagated as `{label} input` to the search field and `{label} flatlist` to the list. |
| `accessibilityHint` | `string` | Hint for the trigger, announced after the label and role. |
| `itemAccessibilityLabelField` | `string` | Field on each item to use for per-item `accessibilityLabel`. Defaults to `labelField`. |
| `testID` | `string` | testID for the trigger. Propagated as `{testID} input` / `{testID} flatlist`. |
| `itemTestIDField` | `string` | Field on each item to use as its `testID`. Defaults to `labelField`. |
| `hitSlop` | `Insets \| number` | Expand the trigger's tap target. |
Triggers expose `accessibilityRole="combobox"` and
`accessibilityState.expanded` / `.disabled`. Items expose
`accessibilityRole="button"` plus `accessibilityState.selected`
and `.disabled`. The open modal is scoped with
`accessibilityViewIsModal`, and the OS-level "Reduce Motion"
preference disables the modal animation automatically. See
[Accessibility](../accessibility).
## Imperative ref
```tsx
import { useRef } from 'react';
import { Dropdown } from '@carlos3g/element-dropdown';
import type { IDropdownRef } from '@carlos3g/element-dropdown';
const ref = useRef(null);