RadioGroup

A set of radio buttons where only one option can be selected at a time.

Import

import { RadioGroup } from 'heroui-native';

Anatomy

<RadioGroup>
  <RadioGroup.Item>
    <RadioGroup.Label>...</RadioGroup.Label>
    <RadioGroup.Description>...</RadioGroup.Description>
    <RadioGroup.Indicator>
      <RadioGroup.IndicatorThumb />
    </RadioGroup.Indicator>
  </RadioGroup.Item>
  <RadioGroup.ErrorMessage>...</RadioGroup.ErrorMessage>
</RadioGroup>
  • RadioGroup: Container that manages the selection state of radio items. Supports both horizontal and vertical orientations.
  • RadioGroup.Item: Individual radio option within a RadioGroup. Must be used inside RadioGroup. Handles selection state and renders default indicator if no children provided. Supports render function children to access state (isSelected, isInvalid, isDisabled).
  • RadioGroup.Label: Optional clickable text label for the radio option. Linked to the radio for accessibility.
  • RadioGroup.Description: Optional secondary text below the label. Provides additional context about the radio option.
  • RadioGroup.Indicator: Optional container for the radio circle. Renders default thumb if no children provided. Manages the visual selection state.
  • RadioGroup.IndicatorThumb: Optional inner circle that appears when selected. Animates scale based on selection. Can be replaced with custom content.
  • RadioGroup.ErrorMessage: Error message displayed when radio group is invalid. Shown with animation below the radio group content.

Usage

Basic Usage

RadioGroup with simple string children automatically renders title and indicator.

<RadioGroup value={value} onValueChange={setValue}>
  <RadioGroup.Item value="option1">Option 1</RadioGroup.Item>
  <RadioGroup.Item value="option2">Option 2</RadioGroup.Item>
  <RadioGroup.Item value="option3">Option 3</RadioGroup.Item>
</RadioGroup>

With Descriptions

Add descriptive text below each radio option for additional context.

<RadioGroup value={value} onValueChange={setValue}>
  <RadioGroup.Item value="standard">
    <View>
      <RadioGroup.Label>Standard Shipping</RadioGroup.Label>
      <RadioGroup.Description>
        Delivered in 5-7 business days
      </RadioGroup.Description>
    </View>
    <RadioGroup.Indicator />
  </RadioGroup.Item>
  <RadioGroup.Item value="express">
    <View>
      <RadioGroup.Label>Express Shipping</RadioGroup.Label>
      <RadioGroup.Description>
        Delivered in 2-3 business days
      </RadioGroup.Description>
    </View>
    <RadioGroup.Indicator />
  </RadioGroup.Item>
</RadioGroup>

Custom Indicator

Replace the default indicator thumb with custom content.

<RadioGroup value={value} onValueChange={setValue}>
  <RadioGroup.Item value="custom">
    <RadioGroup.Label>Custom Option</RadioGroup.Label>
    <RadioGroup.Indicator>
      {value === 'custom' && (
        <Animated.View entering={FadeIn}>
          <Icon name="check" size={12} />
        </Animated.View>
      )}
    </RadioGroup.Indicator>
  </RadioGroup.Item>
</RadioGroup>

With Render Function

Use a render function on RadioGroup.Item to access state and customize the entire content.

<RadioGroup value={value} onValueChange={setValue}>
  <RadioGroup.Item value="option1">
    {({ isSelected, isInvalid, isDisabled }) => (
      <>
        <RadioGroup.Label>Option 1</RadioGroup.Label>
        <RadioGroup.Indicator>
          {isSelected && <CustomIcon />}
        </RadioGroup.Indicator>
      </>
    )}
  </RadioGroup.Item>
</RadioGroup>

With Error Message

Display validation errors below the radio group.

<RadioGroup value={value} onValueChange={setValue} isInvalid={!value}>
  <RadioGroup.Item value="agree">I agree to the terms</RadioGroup.Item>
  <RadioGroup.Item value="disagree">I do not agree</RadioGroup.Item>
  <RadioGroup.ErrorMessage>
    Please select an option to continue
  </RadioGroup.ErrorMessage>
</RadioGroup>

Example

import { RadioGroup, useThemeColor } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import React from 'react';
import { View } from 'react-native';

export default function PaymentMethodExample() {
  const [paymentMethod, setPaymentMethod] = React.useState('card');
  const themeColorForeground = useThemeColor('foreground');

  return (
    <RadioGroup value={paymentMethod} onValueChange={setPaymentMethod}>
      <RadioGroup.Item value="card">
        <View>
          <View className="flex-row items-center gap-1.5">
            <Ionicons
              name="card-outline"
              size={16}
              color={themeColorForeground}
            />
            <RadioGroup.Label>Credit/Debit Card</RadioGroup.Label>
          </View>
          <RadioGroup.Description>
            Pay securely with your credit or debit card
          </RadioGroup.Description>
        </View>
        <RadioGroup.Indicator />
      </RadioGroup.Item>

      <RadioGroup.Item value="paypal">
        <View>
          <RadioGroup.Label>PayPal</RadioGroup.Label>
          <RadioGroup.Description>
            Fast and secure payment with PayPal
          </RadioGroup.Description>
        </View>
        <RadioGroup.Indicator />
      </RadioGroup.Item>

      <RadioGroup.Item value="bank">
        <View>
          <RadioGroup.Label>Bank Transfer</RadioGroup.Label>
          <RadioGroup.Description>
            Direct transfer from your bank account
          </RadioGroup.Description>
        </View>
        <RadioGroup.Indicator />
      </RadioGroup.Item>
    </RadioGroup>
  );
}

API Reference

RadioGroup

proptypedefaultdescription
childrenReact.ReactNodeundefinedRadio group content
valuestring | undefinedundefinedThe currently selected value of the radio group
onValueChange(val: string) => voidundefinedCallback fired when the selected value changes
isDisabledbooleanfalseWhether the entire radio group is disabled
isInvalidbooleanfalseWhether the radio group is invalid
isOnSurfacebooleanundefinedWhether the radio group is on surface
animation"disable-all" | undefinedundefinedAnimation configuration. Use "disable-all" to disable all animations including children
classNamestringundefinedCustom class name
...ViewPropsViewProps-All standard React Native View props are supported

RadioGroup.Item

proptypedefaultdescription
childrenReact.ReactNode | ((props: RadioGroupItemRenderProps) => React.ReactNode)undefinedRadio item content or render function to customize the radio item
valuestringundefinedThe value associated with this radio item
isDisabledbooleanfalseWhether this specific radio item is disabled
isInvalidbooleanfalseWhether the radio item is invalid
isOnSurfacebooleanundefinedWhether the radio item is on surface (auto-detected if not set)
hitSlopnumber6Hit slop for the pressable area
classNamestringundefinedCustom class name
...PressablePropsPressableProps-All standard React Native Pressable props are supported (except disabled)

RadioGroupItemRenderProps

proptypedescription
isSelectedbooleanWhether the radio item is selected
isInvalidbooleanWhether the radio item is invalid
isDisabledbooleanWhether the radio item is disabled

RadioGroup.Indicator

proptypedefaultdescription
childrenReact.ReactNodeundefinedIndicator content
classNamestringundefinedCustom class name
...Animated.ViewPropsAnimatedProps<ViewProps>-All Reanimated Animated.View props are supported

Note: The isOnSurface state is automatically provided via context from the parent RadioGroup.Item component.

RadioGroup.IndicatorThumb

proptypedefaultdescription
classNamestringundefinedCustom class name
animationRadioGroupIndicatorThumbAnimation-Animation configuration
...Animated.ViewPropsAnimatedProps<ViewProps>-All Reanimated Animated.View props are supported

RadioGroupIndicatorThumbAnimation

Animation configuration for RadioGroupIndicatorThumb component. Can be:

  • false or "disabled": Disable all animations
  • true or undefined: Use default animations
  • object: Custom animation configuration
proptypedefaultdescription
scale.value[number, number][1.5, 1]Scale values [unselected, selected]
scale.timingConfigWithTimingConfig{ duration: 300, easing: Easing.out(Easing.ease) }Animation timing configuration

RadioGroup.Label

proptypedefaultdescription
childrenReact.ReactNodeundefinedLabel text content
classNamestringundefinedCustom class name for the label element
...Animated.TextPropsAnimatedProps<TextProps>-All Reanimated Animated.Text props are supported

RadioGroup.Description

proptypedefaultdescription
childrenReact.ReactNodeundefinedDescription text content
classNamestringundefinedCustom class name for the description element
...Animated.TextPropsAnimatedProps<TextProps>-All Reanimated Animated.Text props are supported

RadioGroup.ErrorMessage

proptypedefaultdescription
childrenReact.ReactNodeundefinedThe content of the error field
isInvalidbooleanfalseControls the visibility of the error field
classNamestringundefinedAdditional CSS class for styling
classNamesElementSlots<ErrorViewSlots>undefinedAdditional CSS classes for different parts
textPropsTextPropsundefinedAdditional props to pass to the Text component
...Animated.ViewPropsAnimatedProps<ViewProps>-All Reanimated Animated.View props are supported

Hooks

useRadioGroup

Returns:

PropertyTypeDescription
valuestring | undefinedCurrently selected value
isDisabledbooleanWhether the radio group is disabled
isInvalidbooleanWhether the radio group is in an invalid state
onValueChange(value: string) => voidFunction to change the selected value

useRadioGroupItem

Returns:

PropertyTypeDescription
isSelectedbooleanWhether the radio item is selected
isDisabledbooleanWhether the radio item is disabled
isInvalidbooleanWhether the radio item is invalid
isOnSurfacebooleanWhether the radio item is on surface

On this page