Select

Displays a list of options for the user to pick from — triggered by a button.

Import

import { Select } from 'heroui-native';

Anatomy

<Select>
  <Select.Trigger>
    <Select.Value />
  </Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content>
      <Select.Close />
      <Select.ListLabel>...</Select.ListLabel>
      <Select.Item>
        <Select.ItemLabel />
        <Select.ItemDescription>...</Select.ItemDescription>
        <Select.ItemIndicator />
      </Select.Item>
    </Select.Content>
  </Select.Portal>
</Select>
  • 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.
  • Select.Value: Displays the selected value or placeholder text. Automatically updates when selection changes.
  • 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 that dismisses the select when pressed. Renders a default X icon if no children provided.
  • 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.

<Select>
  <Select.Trigger>...</Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content>
      <Select.Item value="1" label="Option 1" />
      <Select.Item value="2" label="Option 2" />
    </Select.Content>
  </Select.Portal>
</Select>

With Value Display

Display the selected value in the trigger using the Value component.

<Select>
  <Select.Trigger>
    <Select.Value placeholder="Choose an option" />
  </Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content>
      <Select.Item value="apple" label="Apple" />
      <Select.Item value="orange" label="Orange" />
      <Select.Item value="banana" label="Banana" />
    </Select.Content>
  </Select.Portal>
</Select>

Popover Presentation

Use popover presentation for floating content with automatic positioning.

<Select>
  <Select.Trigger>...</Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content presentation="popover" placement="bottom" align="center">
      <Select.Item value="1" label="Item 1" />
      <Select.Item value="2" label="Item 2" />
    </Select.Content>
  </Select.Portal>
</Select>

Width Control

Control the width of the select content using the width prop. This only works with popover presentation.

{
  /* Fixed width in pixels */
}
<Select>
  <Select.Trigger>...</Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content width={280} presentation="popover">
      <Select.Item value="1" label="Item 1" />
    </Select.Content>
  </Select.Portal>
</Select>;

{
  /* Match trigger width */
}
<Select>
  <Select.Trigger>...</Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content width="trigger" presentation="popover">
      <Select.Item value="1" label="Item 1" />
    </Select.Content>
  </Select.Portal>
</Select>;

{
  /* Full width (100%) */
}
<Select>
  <Select.Trigger>...</Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content width="full" presentation="popover">
      <Select.Item value="1" label="Item 1" />
    </Select.Content>
  </Select.Portal>
</Select>;

{
  /* Auto-size to content (default) */
}
<Select>
  <Select.Trigger>...</Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content width="content-fit" presentation="popover">
      <Select.Item value="1" label="Item 1" />
    </Select.Content>
  </Select.Portal>
</Select>;

Bottom Sheet Presentation

Use bottom sheet for mobile-optimized selection experience.

<Select>
  <Select.Trigger>...</Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content presentation="bottom-sheet" snapPoints={['35%']}>
      <Select.Item value="1" label="Item 1" />
      <Select.Item value="2" label="Item 2" />
    </Select.Content>
  </Select.Portal>
</Select>

Dialog Presentation

Use dialog presentation for centered modal-style selection.

<Select>
  <Select.Trigger>...</Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content presentation="dialog">
      <Select.Close />
      <Select.ListLabel>Choose an option</Select.ListLabel>
      <Select.Item value="1" label="Item 1" />
      <Select.Item value="2" label="Item 2" />
    </Select.Content>
  </Select.Portal>
</Select>

Custom Item Content

Customize item appearance with custom content and indicators.

<Select>
  <Select.Trigger>...</Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content>
      <Select.Item value="us" label="United States">
        <View className="flex-row items-center gap-3 flex-1">
          <Text>🇺🇸</Text>
          <Select.ItemLabel />
        </View>
        <Select.ItemIndicator />
      </Select.Item>
      <Select.Item value="uk" label="United Kingdom">
        <View className="flex-row items-center gap-3 flex-1">
          <Text>🇬🇧</Text>
          <Select.ItemLabel />
        </View>
        <Select.ItemIndicator />
      </Select.Item>
    </Select.Content>
  </Select.Portal>
</Select>

With Render Function

Use a render function on Select.Item to access state and customize content based on selection.

<Select>
  <Select.Trigger>...</Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content>
      <Select.Item value="us" label="United States">
        {({ isSelected, value, isDisabled }) => (
          <>
            <View className="flex-row items-center gap-3 flex-1">
              <Text>🇺🇸</Text>
              <Select.ItemLabel
                className={
                  isSelected ? 'text-accent font-medium' : 'text-foreground'
                }
              />
            </View>
            <Select.ItemIndicator />
          </>
        )}
      </Select.Item>
      <Select.Item value="uk" label="United Kingdom">
        {({ isSelected }) => (
          <>
            <View className="flex-row items-center gap-3 flex-1">
              <Text>🇬🇧</Text>
              <Select.ItemLabel
                className={
                  isSelected ? 'text-accent font-medium' : 'text-foreground'
                }
              />
            </View>
            <Select.ItemIndicator />
          </>
        )}
      </Select.Item>
    </Select.Content>
  </Select.Portal>
</Select>

With Item Description

Add descriptions to items for additional context.

<Select>
  <Select.Trigger>...</Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content>
      <Select.Item value="basic" label="Basic">
        <View className="flex-1">
          <Select.ItemLabel />
          <Select.ItemDescription>
            Essential features for personal use
          </Select.ItemDescription>
        </View>
        <Select.ItemIndicator />
      </Select.Item>
    </Select.Content>
  </Select.Portal>
</Select>

Controlled Mode

Control the select state programmatically.

const [value, setValue] = useState();
const [isOpen, setIsOpen] = useState(false);

<Select
  value={value}
  onValueChange={setValue}
  isOpen={isOpen}
  onOpenChange={setIsOpen}
>
  <Select.Trigger>
    <Select.Value placeholder="Select..." />
  </Select.Trigger>
  <Select.Portal>
    <Select.Overlay />
    <Select.Content>
      <Select.Item value="1" label="Option 1" />
      <Select.Item value="2" label="Option 2" />
    </Select.Content>
  </Select.Portal>
</Select>;

Example

import { Button, Select } from 'heroui-native';
import { useState } from 'react';
import { ScrollView, Text, View } from 'react-native';

type CountryOption = {
  value: string;
  label: string;
  flag: string;
  code: string;
};

const COUNTRIES: CountryOption[] = [
  { value: 'US', label: 'United States', flag: '🇺🇸', code: '+1' },
  { value: 'GB', label: 'United Kingdom', flag: '🇬🇧', code: '+44' },
  { value: 'CA', label: 'Canada', flag: '🇨🇦', code: '+1' },
  { value: 'AU', label: 'Australia', flag: '🇦🇺', code: '+61' },
];

export default function SelectExample() {
  const [country, setCountry] = useState<CountryOption>();

  return (
    <Select
      value={country}
      onValueChange={(value) => {
        const selected = COUNTRIES.find((c) => c.value === value?.value);
        setCountry(selected);
      }}
    >
      <Select.Trigger asChild>
        <Button variant="tertiary" size="sm">
          {country ? (
            <View className="flex-row items-center gap-2">
              <Text className="text-base">{country.flag}</Text>
              <Text className="text-sm text-foreground">{country.code}</Text>
            </View>
          ) : (
            <Text className="text-foreground">Select Country</Text>
          )}
        </Button>
      </Select.Trigger>
      <Select.Portal>
        <Select.Overlay />
        <Select.Content width={280} className="rounded-2xl" placement="bottom">
          <ScrollView>
            {COUNTRIES.map((item) => (
              <Select.Item
                key={item.value}
                value={item.value}
                label={item.label}
              >
                <View className="flex-row items-center gap-3 flex-1">
                  <Text className="text-2xl">{item.flag}</Text>
                  <Text className="text-sm text-muted w-10">{item.code}</Text>
                  <Text className="text-base text-foreground flex-1">
                    {item.label}
                  </Text>
                </View>
                <Select.ItemIndicator />
              </Select.Item>
            ))}
          </ScrollView>
        </Select.Content>
      </Select.Portal>
    </Select>
  );
}

API Reference

Select

proptypedefaultdescription
childrenReactNode-The content of the select
valueSelectOption-The selected value (controlled mode)
onValueChange(value: SelectOption) => void-Callback when the value changes
defaultValueSelectOption-The default selected value (uncontrolled mode)
isOpenboolean-Whether the select is open (controlled mode)
isDefaultOpenboolean-Whether the select is open when initially rendered (uncontrolled mode)
onOpenChange(isOpen: boolean) => void-Callback when the select open state changes
closeDelaynumber400Delay in milliseconds before closing the select
isDisabledbooleanfalseWhether the select is disabled
isDismissKeyboardOnClosebooleantrueWhether to dismiss keyboard when select closes
animationSelectRootAnimation-Animation configuration
asChildbooleanfalseWhether to render as a child element
...ViewPropsViewProps-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
proptypedefaultdescription
entering.valueSpringAnimationConfig | TimingAnimationConfig-Animation configuration for when select opens
exiting.valueSpringAnimationConfig | TimingAnimationConfig-Animation configuration for when select closes

SpringAnimationConfig

proptypedefaultdescription
type'spring'-Animation type (must be 'spring')
configWithSpringConfig-Reanimated spring animation configuration

TimingAnimationConfig

proptypedefaultdescription
type'timing'-Animation type (must be 'timing')
configWithTimingConfig-Reanimated timing animation configuration

Select.Trigger

proptypedefaultdescription
childrenReactNode-The trigger element content
classNamestring-Additional CSS classes for the trigger
asChildbooleantrueWhether to render as a child element
...PressablePropsPressableProps-All standard React Native Pressable props are supported

Select.Value

proptypedefaultdescription
placeholderstring-Placeholder text when no value is selected
classNamestring-Additional CSS classes for the value
...TextPropsTextProps-All standard React Native Text props are supported

Select.Portal

proptypedefaultdescription
childrenReactNode-The portal content (required)
classNamestring-Additional CSS classes for the portal container
hostNamestring-Optional name of the host element for the portal
forceMountboolean-Whether to force mount the component in the DOM
...ViewPropsViewProps-All standard React Native View props are supported

Select.Overlay

proptypedefaultdescription
classNamestring-Additional CSS classes for the overlay
animationSelectOverlayAnimation-Animation configuration
closeOnPressbooleantrueWhether to close the select when overlay is pressed
forceMountboolean-Whether to force mount the component in the DOM
asChildbooleanfalseWhether to render as a child element
...Animated.ViewPropsAnimated.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
  • object: Custom animation configuration
proptypedefaultdescription
opacity.value[number, number, number][0, 1, 0]Opacity values [idle, open, close]

Select.Content (Popover Presentation)

proptypedefaultdescription
childrenReactNode-The select content
widthnumber | '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
avoidCollisionsbooleantrueWhether to flip placement when close to viewport edges
offsetnumber8Distance from trigger element in pixels
alignOffsetnumber0Offset along the alignment axis in pixels
classNamestring-Additional CSS classes for the content container
animationSelectContentPopoverAnimation-Animation configuration
forceMountboolean-Whether to force mount the component in the DOM
insetsInsets-Screen edge insets to respect when positioning
asChildbooleanfalseWhether to render as a child element
...Animated.ViewPropsAnimated.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 animations
  • object: Custom animation configuration
proptypedefaultdescription
opacity.value[number, number, number][0, 1, 0]Opacity values [idle, open, close]
scale.value[number, number, number][0.95, 1, 0.95]Scale values [idle, open, close]
translateX.value[number, number, number]Based on placementTranslateX values [idle, open, close]
translateY.value[number, number, number]Based on placementTranslateY values [idle, open, close]
transformOrigin.valuestringBased on placementTransform origin value

Select.Content (Bottom Sheet Presentation)

proptypedefaultdescription
childrenReactNode-The bottom sheet content
presentation'bottom-sheet'-Presentation mode for the select
bottomSheetViewClassNamestring-Additional CSS classes for the bottom sheet view
...BottomSheetPropsBottomSheetProps-All @gorhom/bottom-sheet props are supported

Select.Content (Dialog Presentation)

proptypedefaultdescription
childrenReactNode-The dialog content
presentation'dialog'-Presentation mode for the select
classNames{ wrapper?: string; content?: string }-Additional CSS classes for wrapper and content
animationSelectContentAnimation-Animation configuration
isSwipeablebooleantrueWhether the dialog content can be swiped to dismiss
forceMountboolean-Whether to force mount the component in the DOM
asChildbooleanfalseWhether to render as a child element
...Animated.ViewPropsAnimated.ViewProps-All Reanimated Animated.View props are supported

SelectContentAnimation

Animation configuration for Select.Content component (dialog presentation). Can be:

  • false or "disabled": Disable all animations
  • true or undefined: Use default animations
  • object: Custom animation configuration
proptypedefaultdescription
opacity.value[number, number, number][0, 1, 0]Opacity values [idle, open, close]
scale.value[number, number, number][0.97, 1, 0.97]Scale values [idle, open, close]

Select.Close

proptypedefaultdescription
childrenReactNode-The close button content
classNamestring-Additional CSS classes for the close button
iconPropsSelectCloseIconProps-Close icon configuration
asChildboolean-Whether to render as a child element
...PressablePropsPressableProps-All standard React Native Pressable props are supported

SelectCloseIconProps

proptypedefaultdescription
sizenumber18Size of the icon
colorstring--colors-mutedColor of the icon

Select.ListLabel

proptypedefaultdescription
childrenReactNode-The label text content
classNamestring-Additional CSS classes for the list label
...TextPropsTextProps-All standard React Native Text props are supported

Select.Item

proptypedefaultdescription
childrenReactNode | ((props: SelectItemRenderProps) => ReactNode)-Custom item content. Defaults to label and indicator, or a render function
valueany-The value associated with this item (required)
labelstring-The label text for this item (required)
isDisabledbooleanfalseWhether this item is disabled
classNamestring-Additional CSS classes for the item
...PressablePropsPressableProps-All standard React Native Pressable props are supported

SelectItemRenderProps

When using a render function for children, the following props are provided:

propertytypedescription
isSelectedbooleanWhether this item is currently selected
valuestringThe value of the item
isDisabledbooleanWhether the item is disabled

Select.ItemLabel

proptypedefaultdescription
classNamestring-Additional CSS classes for the item label
...TextPropsTextProps-All standard React Native Text props are supported

Select.ItemDescription

proptypedefaultdescription
childrenReactNode-The description text content
classNamestring-Additional CSS classes for the item description
...TextPropsTextProps-All standard React Native Text props are supported

Select.ItemIndicator

proptypedefaultdescription
childrenReactNode-Custom indicator content. Defaults to check icon
classNamestring-Additional CSS classes for the item indicator
iconPropsSelectItemIndicatorIconProps-Check icon configuration
...ViewPropsViewProps-All standard React Native View props are supported

SelectItemIndicatorIconProps

proptypedefaultdescription
sizenumber16Size of the icon
colorstring--colors-mutedColor of the icon

Hooks

useSelect

Hook to access the Select root context. Returns the select state and control functions.

import { useSelect } from 'heroui-native';

const {
  isOpen,
  onOpenChange,
  isDefaultOpen,
  isDisabled,
  triggerPosition,
  setTriggerPosition,
  contentLayout,
  setContentLayout,
  nativeID,
  closeDelay,
  value,
  onValueChange,
} = useSelect();

Return Value

propertytypedescription
isOpenbooleanWhether the select is currently open
onOpenChange(open: boolean) => voidCallback to change the open state
isDefaultOpenboolean | undefinedWhether the select is open by default (uncontrolled mode)
isDisabledboolean | undefinedWhether the select is disabled
triggerPositionLayoutPosition | nullPosition of the trigger element relative to viewport
setTriggerPosition(position: LayoutPosition | null) => voidUpdates the trigger element's position
contentLayoutLayoutRectangle | nullLayout measurements of the select content
setContentLayout(layout: LayoutRectangle | null) => voidUpdates the content layout measurements
nativeIDstringUnique identifier for the select instance
closeDelaynumber | undefinedDelay in milliseconds before the select closes
valueSelectOptionCurrently selected option
onValueChange(option: SelectOption) => voidCallback 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.

import { useSelectAnimation } from 'heroui-native';

const { selectState, progress, isDragging, isGestureReleaseAnimationRunning } =
  useSelectAnimation();

Return Value

propertytypedescription
selectState'idle' | 'open' | 'close'Extended internal state for coordinating animations
progressSharedValue<number>Progress value for animations (0=idle, 1=open, 2=close)
isDraggingSharedValue<boolean>Whether the select content is currently being dragged
isGestureReleaseAnimationRunningSharedValue<boolean>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

propertytypedescription
valuestringThe value of the option
labelstringThe label text of the option

useSelectItem

Hook to access the Select Item context. Returns the item's value and label.

import { useSelectItem } from 'heroui-native';

const { itemValue, label } = useSelectItem();

Return Value

propertytypedescription
itemValuestringThe value of the current item
labelstringThe label text of the current item

On this page