# RadioGroup

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

## Imports

Note: Before importing this component, ensure you have completed the setup as per the [Quick Start guide](../../../README.md).

```tsx
import { RadioGroup } from 'heroui-native';
```

## Usage

### Basic Usage

RadioGroup with simple string children automatically renders title and indicator.

```tsx
<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.

```tsx
<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.

```tsx
<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.

```tsx
<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.

```tsx
<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

```tsx
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>
  );
}
```

## Anatomy

```tsx
<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.

## API Reference

### RadioGroup

| prop            | type                         | default     | description                                                                               |
| --------------- | ---------------------------- | ----------- | ----------------------------------------------------------------------------------------- |
| `children`      | `React.ReactNode`            | `undefined` | Radio group content                                                                       |
| `value`         | `string \| undefined`        | `undefined` | The currently selected value of the radio group                                           |
| `onValueChange` | `(val: string) => void`      | `undefined` | Callback fired when the selected value changes                                            |
| `isDisabled`    | `boolean`                    | `false`     | Whether the entire radio group is disabled                                                |
| `isInvalid`     | `boolean`                    | `false`     | Whether the radio group is invalid                                                        |
| `isOnSurface`   | `boolean`                    | `undefined` | Whether the radio group is on surface                                                     |
| `animation`     | `"disable-all" \| undefined` | `undefined` | Animation configuration. Use `"disable-all"` to disable all animations including children |
| `className`     | `string`                     | `undefined` | Custom class name                                                                         |
| `...ViewProps`  | `ViewProps`                  | -           | All standard React Native View props are supported                                        |

### RadioGroup.Item

| prop                | type                                                                         | default     | description                                                               |
| ------------------- | ---------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------- |
| `children`          | `React.ReactNode \| ((props: RadioGroupItemRenderProps) => React.ReactNode)` | `undefined` | Radio item content or render function to customize the radio item         |
| `value`             | `string`                                                                     | `undefined` | The value associated with this radio item                                 |
| `isDisabled`        | `boolean`                                                                    | `false`     | Whether this specific radio item is disabled                              |
| `isInvalid`         | `boolean`                                                                    | `false`     | Whether the radio item is invalid                                         |
| `isOnSurface`       | `boolean`                                                                    | `undefined` | Whether the radio item is on surface (auto-detected if not set)           |
| `hitSlop`           | `number`                                                                     | `6`         | Hit slop for the pressable area                                           |
| `className`         | `string`                                                                     | `undefined` | Custom class name                                                         |
| `...PressableProps` | `PressableProps`                                                             | -           | All standard React Native Pressable props are supported (except disabled) |

#### RadioGroupItemRenderProps

| prop         | type      | description                        |
| ------------ | --------- | ---------------------------------- |
| `isSelected` | `boolean` | Whether the radio item is selected |
| `isInvalid`  | `boolean` | Whether the radio item is invalid  |
| `isDisabled` | `boolean` | Whether the radio item is disabled |

### RadioGroup.Indicator

| prop                    | type                       | default     | description                                      |
| ----------------------- | -------------------------- | ----------- | ------------------------------------------------ |
| `children`              | `React.ReactNode`          | `undefined` | Indicator content                                |
| `className`             | `string`                   | `undefined` | Custom class name                                |
| `...Animated.ViewProps` | `AnimatedProps<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

| prop                    | type                                | default     | description                                      |
| ----------------------- | ----------------------------------- | ----------- | ------------------------------------------------ |
| `className`             | `string`                            | `undefined` | Custom class name                                |
| `animation`             | `RadioGroupIndicatorThumbAnimation` | -           | Animation configuration                          |
| `isAnimatedStyleActive` | `boolean`                            | `true`      | Whether animated styles (react-native-reanimated) are active |
| `...Animated.ViewProps` | `AnimatedProps<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

| prop                 | type                          | default                                              | description                         |
| -------------------- | ----------------------------- | ---------------------------------------------------- | ----------------------------------- |
| `state`              | `'disabled' \| boolean`       | -                                                    | Disable animations while customizing properties |
| `scale.value`        | `[number, number]`            | `[1.5, 1]`                                           | Scale values [unselected, selected] |
| `scale.timingConfig` | `WithTimingConfig`            | `{ duration: 300, easing: Easing.out(Easing.ease) }` | Animation timing configuration      |

### RadioGroup.Label

| prop                    | type                       | default     | description                                      |
| ----------------------- | -------------------------- | ----------- | ------------------------------------------------ |
| `children`              | `React.ReactNode`          | `undefined` | Label text content                               |
| `className`             | `string`                   | `undefined` | Custom class name for the label element          |
| `...Animated.TextProps` | `AnimatedProps<TextProps>` | -           | All Reanimated Animated.Text props are supported |

### RadioGroup.Description

| prop                    | type                       | default     | description                                      |
| ----------------------- | -------------------------- | ----------- | ------------------------------------------------ |
| `children`              | `React.ReactNode`          | `undefined` | Description text content                         |
| `className`             | `string`                   | `undefined` | Custom class name for the description element    |
| `...Animated.TextProps` | `AnimatedProps<TextProps>` | -           | All Reanimated Animated.Text props are supported |

### RadioGroup.ErrorMessage

| prop                    | type                           | default     | description                                      |
| ----------------------- | ------------------------------ | ----------- | ------------------------------------------------ |
| `children`              | `React.ReactNode`              | `undefined` | The content of the error field                   |
| `isInvalid`             | `boolean`                      | `false`     | Controls the visibility of the error field       |
| `className`             | `string`                       | `undefined` | Additional CSS class for styling                 |
| `classNames`            | `ElementSlots<ErrorViewSlots>` | `undefined` | Additional CSS classes for different parts       |
| `textProps`             | `TextProps`                    | `undefined` | Additional props to pass to the Text component   |
| `...Animated.ViewProps` | `AnimatedProps<ViewProps>`     | -           | All Reanimated Animated.View props are supported |

## Hooks

### useRadioGroup

**Returns:**

| Property        | Type                      | Description                                    |
| --------------- | ------------------------- | ---------------------------------------------- |
| `value`         | `string \| undefined`     | Currently selected value                       |
| `isDisabled`    | `boolean`                 | Whether the radio group is disabled            |
| `isInvalid`     | `boolean`                 | Whether the radio group is in an invalid state |
| `onValueChange` | `(value: string) => void` | Function to change the selected value          |

### useRadioGroupItem

**Returns:**

| Property      | Type      | Description                          |
| ------------- | --------- | ------------------------------------ |
| `isSelected`  | `boolean` | Whether the radio item is selected   |
| `isDisabled`  | `boolean` | Whether the radio item is disabled   |
| `isInvalid`   | `boolean` | Whether the radio item is invalid    |
| `isOnSurface` | `boolean` | Whether the radio item is on surface |
