# Select
**Category**: native
**URL**: https://www.heroui.com/docs/native/components/select
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/components/(forms)/select.mdx
> Displays a list of options for the user to pick from β triggered by a button.
***
## Import
```tsx
import { Select } from 'heroui-native';
```
## Anatomy
```tsx
```
- **Select**: Main container that manages open/close state, value selection and provides context to child components.
- **Select.Trigger**: Clickable element that toggles the select visibility. Wraps any child element with press handlers. Supports `variant` prop (`'default'` or `'unstyled'`).
- **Select.Value**: Displays the selected value or placeholder text. Automatically updates when selection changes. Styling changes based on selection state.
- **Select.TriggerIndicator**: Optional visual indicator showing open/close state. Renders an animated chevron icon by default that rotates when the select opens/closes.
- **Select.Portal**: Renders select content in a portal layer above other content. Ensures proper stacking and positioning.
- **Select.Overlay**: Optional background overlay. Can be transparent or semi-transparent to capture outside clicks.
- **Select.Content**: Container for select content with three presentation modes: popover (floating with positioning), bottom sheet modal, or dialog modal.
- **Select.Close**: Close button for the select. Can accept custom children or uses default close icon.
- **Select.ListLabel**: Label for the list of items with pre-styled typography.
- **Select.Item**: Selectable option item. Handles selection state and press events.
- **Select.ItemLabel**: Displays the label text for an item.
- **Select.ItemDescription**: Optional description text for items with muted styling.
- **Select.ItemIndicator**: Optional indicator shown for selected items. Renders a check icon by default.
## Usage
### Basic Usage
The Select component uses compound parts to create dropdown selection interfaces.
```tsx
```
### With Value Display
Display the selected value in the trigger using the Value component.
```tsx
```
### Popover Presentation
Use popover presentation for floating content with automatic positioning.
```tsx
```
### Width Control
Control the width of the select content using the `width` prop. This only works with popover presentation.
```tsx
{
/* Fixed width in pixels */
}
;
{
/* Match trigger width */
}
;
{
/* Full width (100%) */
}
;
{
/* Auto-size to content (default) */
}
;
```
### Bottom Sheet Presentation
Use bottom sheet for mobile-optimized selection experience.
```tsx
```
### Dialog Presentation
Use dialog presentation for centered modal-style selection.
```tsx
```
### Custom Item Content
Customize item appearance with custom content and indicators.
```tsx
```
### With Render Function
Use a render function on `Select.Item` to access state and customize content based on selection.
```tsx
```
### With Item Description
Add descriptions to items for additional context.
```tsx
```
### With Trigger Indicator
Add a visual indicator to show the open/close state of the select. The indicator rotates when the select opens/closes.
```tsx
```
### Custom Trigger with Unstyled Variant
Use the `unstyled` variant when composing a custom trigger with other components like Button.
```tsx
```
### Controlled Mode
Control the select state programmatically.
```tsx
const [value, setValue] = useState();
const [isOpen, setIsOpen] = useState(false);
;
```
## Example
```tsx
import { Select, Separator } from 'heroui-native';
import React, { useState } from 'react';
type SelectOption = {
value: string;
label: string;
};
const US_STATES: SelectOption[] = [
{ value: 'CA', label: 'California' },
{ value: 'NY', label: 'New York' },
{ value: 'TX', label: 'Texas' },
{ value: 'FL', label: 'Florida' },
];
export default function SelectExample() {
const [value, setValue] = useState();
return (
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/(home)/components/select.tsx).
## API Reference
### Select
| prop | type | default | description |
| --------------- | ----------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| `children` | `ReactNode` | - | The content of the select |
| `value` | `SelectOption \| SelectOption[]` | - | The selected value(s) (controlled mode) |
| `onValueChange` | `(value: SelectOption \| SelectOption[]) => void` | - | Callback when the value changes |
| `defaultValue` | `SelectOption \| SelectOption[]` | - | The default selected value(s) (uncontrolled mode) |
| `isOpen` | `boolean` | - | Whether the select is open (controlled mode) |
| `isDefaultOpen` | `boolean` | - | Whether the select is open when initially rendered (uncontrolled mode) |
| `onOpenChange` | `(isOpen: boolean) => void` | - | Callback when the select open state changes |
| `isDisabled` | `boolean` | `false` | Whether the select is disabled |
| `presentation` | `'popover' \| 'bottom-sheet' \| 'dialog'` | `'popover'` | Presentation mode for the select content |
| `animation` | `SelectRootAnimation` | - | Animation configuration |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### SelectRootAnimation
Animation configuration for Select component. Can be:
- `false` or `"disabled"`: Disable only root animations
- `"disable-all"`: Disable all animations including children
- `true` or `undefined`: Use default animations
- `object`: Custom animation configuration
| prop | type | default | description |
| ---------------- | ------------------------------------------------ | ------- | ----------------------------------------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Disable animations while customizing properties |
| `entering.value` | `SpringAnimationConfig \| TimingAnimationConfig` | - | Animation configuration for when select opens |
| `exiting.value` | `SpringAnimationConfig \| TimingAnimationConfig` | - | Animation configuration for when select closes |
#### SpringAnimationConfig
| prop | type | default | description |
| -------- | ------------------ | ------- | ----------------------------------------- |
| `type` | `'spring'` | - | Animation type (must be `'spring'`) |
| `config` | `WithSpringConfig` | - | Reanimated spring animation configuration |
#### TimingAnimationConfig
| prop | type | default | description |
| -------- | ------------------ | ------- | ----------------------------------------- |
| `type` | `'timing'` | - | Animation type (must be `'timing'`) |
| `config` | `WithTimingConfig` | - | Reanimated timing animation configuration |
### Select.Trigger
| prop | type | default | description |
| ------------------- | ------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------- |
| `variant` | `'default' \| 'unstyled'` | `'default'` | The variant of the trigger. `'default'` applies pre-styled container styles, `'unstyled'` removes default styling |
| `children` | `ReactNode` | - | The trigger element content |
| `className` | `string` | - | Additional CSS classes for the trigger |
| `asChild` | `boolean` | `true` | Whether to render as a child element |
| `isDisabled` | `boolean` | - | Whether the trigger is disabled |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
### Select.Value
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------- |
| `placeholder` | `string` | - | Placeholder text when no value is selected |
| `className` | `string` | - | Additional CSS classes for the value |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
**Note:** The value component automatically applies different text colors based on selection state:
- When a value is selected: `text-foreground`
- When no value is selected (placeholder): `text-field-placeholder`
### Select.TriggerIndicator
| prop | type | default | description |
| ----------------------- | --------------------------------- | ------- | ------------------------------------------------------------ |
| `children` | `ReactNode` | - | Custom indicator content. Defaults to animated chevron icon |
| `className` | `string` | - | Additional CSS classes for the trigger indicator |
| `style` | `ViewStyle` | - | Custom styles for the trigger indicator |
| `iconProps` | `SelectTriggerIndicatorIconProps` | - | Chevron icon configuration |
| `animation` | `SelectTriggerIndicatorAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
**Note:** The following style properties are occupied by animations and cannot be set via className:
- `transform` (specifically `rotate`) - Animated for open/close rotation transitions
To customize this property, use the `animation` prop. To completely disable animated styles and use your own via className or style prop, set `isAnimatedStyleActive={false}`.
#### SelectTriggerIndicatorIconProps
| prop | type | default | description |
| ------- | -------- | ------- | ------------------------------------------------------ |
| `size` | `number` | `16` | Size of the icon |
| `color` | `string` | - | Color of the icon (defaults to foreground theme color) |
#### SelectTriggerIndicatorAnimation
Animation configuration for Select.TriggerIndicator component. Can be:
- `false` or `"disabled"`: Disable all animations
- `true` or `undefined`: Use default animations (rotation from 0Β° to -180Β°)
- `object`: Custom animation configuration
| prop | type | default | description |
| ----------------------- | ----------------------- | -------------------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `rotation.value` | `[number, number]` | `[0, -180]` | Rotation values [closed, open] in degrees |
| `rotation.springConfig` | `WithSpringConfig` | `{ damping: 140, stiffness: 1000, mass: 4 }` | Spring animation configuration for rotation |
### Select.Portal
| prop | type | default | description |
| -------------------------- | ----------- | ------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `children` | `ReactNode` | - | The portal content (required) |
| `disableFullWindowOverlay` | `boolean` | `false` | When true on iOS, uses View instead of FullWindowOverlay. Enables element inspector; overlay won't appear above native modals |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | Controls whether VoiceOver treats the overlay window as a modal container. When `true`, VoiceOver is restricted to elements inside the overlay. iOS only. Unstable: may change with react-native-screens updates |
| `className` | `string` | - | Additional CSS classes for the portal container |
| `hostName` | `string` | - | Optional name of the host element for the portal |
| `forceMount` | `boolean` | - | Whether to force mount the component in the DOM |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Select.Overlay
| prop | type | default | description |
| ----------------------- | ------------------------ | ------- | ------------------------------------------------------------ |
| `className` | `string` | - | Additional CSS classes for the overlay |
| `animation` | `SelectOverlayAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `closeOnPress` | `boolean` | `true` | Whether to close the select when overlay is pressed |
| `forceMount` | `boolean` | - | Whether to force mount the component in the DOM |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
#### SelectOverlayAnimation
Animation configuration for Select.Overlay component. Can be:
- `false` or `"disabled"`: Disable all animations
- `true` or `undefined`: Use default animations (progress-based opacity for bottom-sheet/dialog, Keyframe animations for popover)
- `object`: Custom animation configuration
| prop | type | default | description |
| --------------- | -------------------------- | ----------- | ---------------------------------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `opacity.value` | `[number, number, number]` | `[0, 1, 0]` | Opacity values [idle, open, close] (for bottom-sheet/dialog presentation) |
| `entering` | `EntryOrExitLayoutType` | - | Custom Keyframe animation for entering transition (for popover presentation) |
| `exiting` | `EntryOrExitLayoutType` | - | Custom Keyframe animation for exiting transition (for popover presentation) |
### Select.Content (Popover Presentation)
| prop | type | default | description |
| ----------------------- | ------------------------------------------------ | --------------- | ------------------------------------------------------ |
| `children` | `ReactNode` | - | The select content |
| `width` | `number \| 'trigger' \| 'content-fit' \| 'full'` | `'content-fit'` | Width sizing strategy for the content |
| `presentation` | `'popover'` | `'popover'` | Presentation mode for the select |
| `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'bottom'` | Placement of the content relative to trigger |
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | Alignment along the placement axis |
| `avoidCollisions` | `boolean` | `true` | Whether to flip placement when close to viewport edges |
| `offset` | `number` | `8` | Distance from trigger element in pixels |
| `alignOffset` | `number` | `0` | Offset along the alignment axis in pixels |
| `className` | `string` | - | Additional CSS classes for the content container |
| `animation` | `SelectContentPopoverAnimation` | - | Animation configuration |
| `forceMount` | `boolean` | - | Whether to force mount the component in the DOM |
| `insets` | `Insets` | - | Screen edge insets to respect when positioning |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
#### SelectContentPopoverAnimation
Animation configuration for Select.Content component (popover presentation). Can be:
- `false` or `"disabled"`: Disable all animations
- `true` or `undefined`: Use default Keyframe animations (translateY/translateX, scale, opacity based on placement)
- `object`: Custom animation configuration with `entering` and/or `exiting` Keyframe animations
| prop | type | default | description |
| ---------- | ----------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `entering` | `EntryOrExitLayoutType` | - | Custom Keyframe animation for entering transition (default: Keyframe with translateY/translateX, scale, opacity based on placement, 200ms) |
| `exiting` | `EntryOrExitLayoutType` | - | Custom Keyframe animation for exiting transition (default: Keyframe mirroring entering animation, 150ms) |
### Select.Content (Bottom Sheet Presentation)
| prop | type | default | description |
| --------------------------- | ------------------ | ------- | ------------------------------------------------ |
| `children` | `ReactNode` | - | The bottom sheet content |
| `presentation` | `'bottom-sheet'` | - | Presentation mode for the select |
| `contentContainerClassName` | `string` | - | Additional CSS classes for the content container |
| `...BottomSheetProps` | `BottomSheetProps` | - | All @gorhom/bottom-sheet props are supported |
### Select.Content (Dialog Presentation)
| prop | type | default | description |
| -------------- | -------------------------------------------------------- | ------- | --------------------------------------------------- |
| `children` | `ReactNode` | - | The dialog content |
| `presentation` | `'dialog'` | - | Presentation mode for the select |
| `classNames` | `{ wrapper?: string; content?: string }` | - | Additional CSS classes for wrapper and content |
| `styles` | `Partial>` | - | Styles for different parts of the dialog content |
| `animation` | `SelectContentAnimation` | - | Animation configuration |
| `isSwipeable` | `boolean` | `true` | Whether the dialog content can be swiped to dismiss |
| `forceMount` | `boolean` | - | Whether to force mount the component in the DOM |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### `styles`
| prop | type | description |
| --------- | ----------- | -------------------------------- |
| `wrapper` | `ViewStyle` | Styles for the wrapper container |
| `content` | `ViewStyle` | Styles for the dialog content |
#### SelectContentAnimation
Animation configuration for Select.Content component (dialog presentation). Can be:
- `false` or `"disabled"`: Disable all animations
- `true` or `undefined`: Use default Keyframe animations (scale and opacity transitions)
- `object`: Custom animation configuration with `entering` and/or `exiting` Keyframe animations
| prop | type | default | description |
| ---------- | ----------------------- | ------- | -------------------------------------------------------------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `entering` | `EntryOrExitLayoutType` | - | Custom Keyframe animation for entering transition (default: Keyframe with scale and opacity, 200ms) |
| `exiting` | `EntryOrExitLayoutType` | - | Custom Keyframe animation for exiting transition (default: Keyframe mirroring entering animation, 150ms) |
### Select.Close
Select.Close extends [CloseButton](./close-button) and automatically handles select dismissal when pressed.
### Select.ListLabel
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------- |
| `children` | `ReactNode` | - | The label text content |
| `className` | `string` | - | Additional CSS classes for the list label |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Select.Item
| prop | type | default | description |
| ------------------- | ------------------------------------------------------------ | ------- | -------------------------------------------------------------------------- |
| `children` | `ReactNode \| ((props: SelectItemRenderProps) => ReactNode)` | - | Custom item content. Defaults to label and indicator, or a render function |
| `value` | `any` | - | The value associated with this item (required) |
| `label` | `string` | - | The label text for this item (required) |
| `isDisabled` | `boolean` | `false` | Whether this item is disabled |
| `className` | `string` | - | Additional CSS classes for the item |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
#### SelectItemRenderProps
When using a render function for `children`, the following props are provided:
| property | type | description |
| ------------ | --------- | --------------------------------------- |
| `isSelected` | `boolean` | Whether this item is currently selected |
| `value` | `string` | The value of the item |
| `isDisabled` | `boolean` | Whether the item is disabled |
### Select.ItemLabel
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------- |
| `className` | `string` | - | Additional CSS classes for the item label |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Select.ItemDescription
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------- |
| `children` | `ReactNode` | - | The description text content |
| `className` | `string` | - | Additional CSS classes for the item description |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Select.ItemIndicator
| prop | type | default | description |
| -------------- | ------------------------------ | ------- | -------------------------------------------------- |
| `children` | `ReactNode` | - | Custom indicator content. Defaults to check icon |
| `className` | `string` | - | Additional CSS classes for the item indicator |
| `iconProps` | `SelectItemIndicatorIconProps` | - | Check icon configuration |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### SelectItemIndicatorIconProps
| prop | type | default | description |
| ------- | -------- | ---------------- | ----------------- |
| `size` | `number` | `16` | Size of the icon |
| `color` | `string` | `--colors-muted` | Color of the icon |
## Hooks
### useSelect
Hook to access the Select root context. Returns the select state and control functions.
```tsx
import { useSelect } from 'heroui-native';
const {
isOpen,
onOpenChange,
isDefaultOpen,
isDisabled,
presentation,
triggerPosition,
setTriggerPosition,
contentLayout,
setContentLayout,
nativeID,
value,
onValueChange,
} = useSelect();
```
#### Return Value
| property | type | description |
| -------------------- | -------------------------------------------- | --------------------------------------------------------- |
| `isOpen` | `boolean` | Whether the select is currently open |
| `onOpenChange` | `(open: boolean) => void` | Callback to change the open state |
| `isDefaultOpen` | `boolean \| undefined` | Whether the select is open by default (uncontrolled mode) |
| `isDisabled` | `boolean \| undefined` | Whether the select is disabled |
| `presentation` | `'popover' \| 'bottom-sheet' \| 'dialog'` | Presentation mode for the select content |
| `triggerPosition` | `LayoutPosition \| null` | Position of the trigger element relative to viewport |
| `setTriggerPosition` | `(position: LayoutPosition \| null) => void` | Updates the trigger element's position |
| `contentLayout` | `LayoutRectangle \| null` | Layout measurements of the select content |
| `setContentLayout` | `(layout: LayoutRectangle \| null) => void` | Updates the content layout measurements |
| `nativeID` | `string` | Unique identifier for the select instance |
| `value` | `SelectOption \| SelectOption[]` | Currently selected option |
| `onValueChange` | `(option: SelectOption \| SelectOption[]) => void` | Callback fired when the selected value changes |
**Note:** This hook must be used within a `Select` component. It will throw an error if called outside of the select context.
### useSelectAnimation
Hook to access the Select animation state values within custom components or compound components.
```tsx
import { useSelectAnimation } from 'heroui-native';
const { selectState, progress, isDragging, isGestureReleaseAnimationRunning } =
useSelectAnimation();
```
#### Return Value
| property | type | description |
| ---------------------------------- | ---------------------- | ---------------------------------------------------------- |
| `progress` | `SharedValue` | Progress value for animations (0=idle, 1=open, 2=close) |
| `isDragging` | `SharedValue` | Whether the select content is currently being dragged |
| `isGestureReleaseAnimationRunning` | `SharedValue` | Whether the gesture release animation is currently running |
**Note:** This hook must be used within a `Select` component. It will throw an error if called outside of the select animation context.
#### SelectOption
| property | type | description |
| -------- | -------- | ---------------------------- |
| `value` | `string` | The value of the option |
| `label` | `string` | The label text of the option |
### useSelectItem
Hook to access the Select Item context. Returns the item's value and label.
```tsx
import { useSelectItem } from 'heroui-native';
const { itemValue, label } = useSelectItem();
```
#### Return Value
| property | type | description |
| ----------- | -------- | ---------------------------------- |
| `itemValue` | `string` | The value of the current item |
| `label` | `string` | The label text of the current item |
## Special Notes
### Element Inspector (iOS)
Select uses FullWindowOverlay on iOS. To enable the React Native element inspector during development, set `disableFullWindowOverlay={true}` on `Select.Portal`. Tradeoff: the select dropdown will not appear above native modals when disabled.