---
title: Checkbox
description: A selectable control that allows users to toggle between checked and unchecked states.
links:
  source_native: checkbox/checkbox.tsx
  styles_native: checkbox/checkbox.styles.ts
---

<NativeVideoPlayerView
  target="auto"
  srcLight="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/native/components/videos/checkbox-docs-light.mp4"
  srcDark="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/native/components/videos/checkbox-docs-dark.mp4"
/>

## Import

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

## Anatomy

```tsx
<Checkbox>
  <Checkbox.Indicator>...</Checkbox.Indicator>
</Checkbox>
```

- **Checkbox**: Main container that handles selection state and user interaction. Renders default indicator with animated checkmark if no children provided. Automatically detects surface context for proper styling. Features press scale animation that can be customized or disabled. Supports render function children to access state (`isSelected`, `isInvalid`, `isDisabled`).
- **Checkbox.Background**: Optional theme-aware background container rendered behind the checkbox content. Mounted automatically for the `secondary` variant while not invalid, when the active theme registers default background content (e.g. `glass`). Replace or remove it via the `background` prop.
- **Checkbox.Indicator**: Optional checkmark container with default slide, scale, opacity, and border radius animations when selected. Renders animated check icon with SVG path drawing animation if no children provided. All animations can be individually customized or disabled. Supports render function children to access state.

## Usage

### Basic Usage

The Checkbox component renders with a default animated indicator if no children are provided. It automatically detects whether it's on a surface background for proper styling.

```tsx
<Checkbox isSelected={isSelected} onSelectedChange={setIsSelected} />
```

### With Custom Indicator

Use a render function in the Indicator to show/hide custom icons based on state.

```tsx
<Checkbox isSelected={isSelected} onSelectedChange={setIsSelected}>
  <Checkbox.Indicator>
    {({ isSelected }) => (isSelected ? <CheckIcon /> : null)}
  </Checkbox.Indicator>
</Checkbox>
```

### Invalid State

Show validation errors with the `isInvalid` prop, which applies danger color styling.

```tsx
<Checkbox
  isSelected={isSelected}
  onSelectedChange={setIsSelected}
  isInvalid={hasError}
/>
```

### Custom Animations

Customize or disable animations for both the root checkbox and indicator.

```tsx
{
  /* Disable all animations (root and indicator) */
}
<Checkbox
  animation="disable-all"
  isSelected={isSelected}
  onSelectedChange={setIsSelected}
>
  <Checkbox.Indicator />
</Checkbox>;

{
  /* Disable only root animation */
}
<Checkbox
  animation="disabled"
  isSelected={isSelected}
  onSelectedChange={setIsSelected}
>
  <Checkbox.Indicator />
</Checkbox>;

{
  /* Disable only indicator animation */
}
<Checkbox isSelected={isSelected} onSelectedChange={setIsSelected}>
  <Checkbox.Indicator animation="disabled" />
</Checkbox>;

{
  /* Custom animation configuration */
}
<Checkbox
  animation={{ scale: { value: [1, 0.9], timingConfig: { duration: 200 } } }}
  isSelected={isSelected}
  onSelectedChange={setIsSelected}
>
  <Checkbox.Indicator
    animation={{
      scale: { value: [0.5, 1] },
      opacity: { value: [0, 1] },
      translateX: { value: [-8, 0] },
      borderRadius: { value: [12, 0] },
    }}
  />
</Checkbox>;
```

## Example

```tsx
import {
  Checkbox,
  Description,
  ControlField,
  Label,
  Separator,
  Surface,
} from "heroui-native";
import React from 'react';
import { View, Text } from 'react-native';

interface CheckboxFieldProps {
  isSelected: boolean;
  onSelectedChange: (value: boolean) => void;
  title: string;
  description: string;
}

const CheckboxField: React.FC<CheckboxFieldProps> = ({
  isSelected,
  onSelectedChange,
  title,
  description,
}) => {
  return (
    <ControlField isSelected={isSelected} onSelectedChange={onSelectedChange}>
      <ControlField.Indicator>
        <Checkbox className="mt-0.5" />
      </ControlField.Indicator>
      <View className="flex-1">
        <Label className="text-lg">{title}</Label>
        <Description className="text-base">
          {description}
        </Description>
      </View>
    </ControlField>
  );
};

export default function BasicUsage() {
  const [fields, setFields] = React.useState({
    newsletter: true,
    marketing: false,
    terms: false,
  });

  const fieldConfigs: Record<
    keyof typeof fields,
    { title: string; description: string }
  > = {
    newsletter: {
      title: 'Subscribe to newsletter',
      description: 'Get weekly updates about new features and tips',
    },
    marketing: {
      title: 'Marketing communications',
      description: 'Receive promotional emails and special offers',
    },
    terms: {
      title: 'Accept terms and conditions',
      description: 'Agree to our Terms of Service and Privacy Policy',
    },
  };

  const handleFieldChange = (key: keyof typeof fields) => (value: boolean) => {
    setFields((prev) => ({ ...prev, [key]: value }));
  };

  const fieldKeys = Object.keys(fields) as Array<keyof typeof fields>;

  return (
    <View className="flex-1 items-center justify-center px-5">
      <Surface className="py-5 w-full">
        {fieldKeys.map((key, index) => (
          <React.Fragment key={key}>
            {index > 0 && <Separator className="my-4" />}
            <CheckboxField
              isSelected={fields[key]}
              onSelectedChange={handleFieldChange(key)}
              title={fieldConfigs[key].title}
              description={fieldConfigs[key].description}
            />
          </React.Fragment>
        ))}
      </Surface>
    </View>
  );
}
```

You can find more examples in the [GitHub repository](<https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/(home)/components/checkbox.tsx>).

## API Reference

### Checkbox

| prop                    | type                                                                   | default     | description                                                               |
| ----------------------- | ---------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------- |
| `children`              | `React.ReactNode \| ((props: CheckboxRenderProps) => React.ReactNode)` | `undefined` | Child elements or render function to customize the checkbox               |
| `isSelected`            | `boolean`                                                              | `undefined` | Whether the checkbox is currently selected                                |
| `onSelectedChange`      | `(isSelected: boolean) => void`                                        | `undefined` | Callback fired when the checkbox selection state changes                  |
| `isDisabled`            | `boolean`                                                              | `false`     | Whether the checkbox is disabled and cannot be interacted with            |
| `isInvalid`             | `boolean`                                                              | `false`     | Whether the checkbox is invalid (shows danger color)                      |
| `variant`               | `'primary' \| 'secondary'`                                             | `'primary'` | Variant style for the checkbox                                            |
| `hitSlop`               | `number`                                                               | `6`         | Hit slop for the pressable area                                           |
| `animation`             | `CheckboxRootAnimation`                                                | -           | Animation configuration                                                   |
| `isAnimatedStyleActive` | `boolean`                                                              | `true`      | Whether animated styles (react-native-reanimated) are active              |
| `className`             | `string`                                                               | `undefined` | Additional CSS classes to apply                                           |
| `background` | `React.ReactNode` | - | Background layer behind the checkbox content. `undefined` renders the theme-aware default for the `secondary` variant while not invalid; custom node replaces it; `null` removes it |
| `...PressableProps`     | `PressableProps`                                                       | -           | All standard React Native Pressable props are supported (except disabled) |

#### CheckboxRenderProps

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

#### CheckboxRootAnimation

Animation configuration for checkbox root 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 |
| `scale.value`        | `[number, number]`                       | `[1, 0.96]`         | Scale values [unpressed, pressed]               |
| `scale.timingConfig` | `WithTimingConfig`                       | `{ duration: 150 }` | Animation timing configuration                  |

### Checkbox.Background

Absolute-fill container rendered behind the checkbox content. With no children, the active library theme decides the default content (e.g. a glass blur layer); pass children to host custom content with the same positioning and clipping.

| prop           | type              | default | description                                    |
| -------------- | ----------------- | ------- | ---------------------------------------------- |
| `children`     | `React.ReactNode` | -       | Custom content inside the background container |
| `className`    | `string`          | -       | Additional CSS classes                         |
| `...ViewProps` | `ViewProps`       | -       | All standard View props are supported          |

### Checkbox.Indicator

| prop                    | type                                                                   | default     | description                                                  |
| ----------------------- | ---------------------------------------------------------------------- | ----------- | ------------------------------------------------------------ |
| `children`              | `React.ReactNode \| ((props: CheckboxRenderProps) => React.ReactNode)` | `undefined` | Content or render function for the checkbox indicator        |
| `className`             | `string`                                                               | `undefined` | Additional CSS classes for the indicator                     |
| `iconProps`             | `CheckboxIndicatorIconProps`                                           | `undefined` | Custom props for the default animated check icon             |
| `animation`             | `CheckboxIndicatorAnimation`                                           | -           | Animation configuration                                      |
| `isAnimatedStyleActive` | `boolean`                                                              | `true`      | Whether animated styles (react-native-reanimated) are active |
| `...AnimatedViewProps`  | `AnimatedProps<ViewProps>`                                             | -           | All standard React Native Animated View props are supported  |

#### CheckboxIndicatorIconProps

Props for customizing the default animated check icon.

| prop            | type     | description                                      |
| --------------- | -------- | ------------------------------------------------ |
| `size`          | `number` | Icon size                                        |
| `strokeWidth`   | `number` | Icon stroke width                                |
| `color`         | `string` | Icon color (defaults to theme accent-foreground) |
| `enterDuration` | `number` | Duration of enter animation (check appearing)    |
| `exitDuration`  | `number` | Duration of exit animation (check disappearing)  |

#### CheckboxIndicatorAnimation

Animation configuration for checkbox indicator 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 |
| `opacity.value`             | `[number, number]`      | `[0, 1]`            | Opacity values [unselected, selected]           |
| `opacity.timingConfig`      | `WithTimingConfig`      | `{ duration: 100 }` | Animation timing configuration                  |
| `borderRadius.value`        | `[number, number]`      | `[8, 0]`            | Border radius values [unselected, selected]     |
| `borderRadius.timingConfig` | `WithTimingConfig`      | `{ duration: 50 }`  | Animation timing configuration                  |
| `translateX.value`          | `[number, number]`      | `[-4, 0]`           | TranslateX values [unselected, selected]        |
| `translateX.timingConfig`   | `WithTimingConfig`      | `{ duration: 100 }` | Animation timing configuration                  |
| `scale.value`               | `[number, number]`      | `[0.8, 1]`          | Scale values [unselected, selected]             |
| `scale.timingConfig`        | `WithTimingConfig`      | `{ duration: 100 }` | Animation timing configuration                  |

## Hooks

### useCheckbox

Hook to access checkbox context values within custom components or compound components.

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

const CustomIndicator = () => {
  const { isSelected, isInvalid, isDisabled } = useCheckbox();
  // ... your implementation
};
```

**Returns:** `UseCheckboxReturn`

| property           | type                                           | description                                                    |
| ------------------ | ---------------------------------------------- | -------------------------------------------------------------- |
| `isSelected`       | `boolean \| undefined`                         | Whether the checkbox is currently selected                     |
| `onSelectedChange` | `((isSelected: boolean) => void) \| undefined` | Callback function to change the checkbox selection state       |
| `isDisabled`       | `boolean`                                      | Whether the checkbox is disabled and cannot be interacted with |
| `isInvalid`        | `boolean`                                      | Whether the checkbox is invalid (shows danger color)           |
| `nativeID`         | `string \| undefined`                          | Native ID for the checkbox element                             |

**Note:** This hook must be used within a `Checkbox` component. It will throw an error if called outside of the checkbox context.
