# 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.