Skip to main content

Checkbox

Checkboxes allow users to select one or more items from a set, or turn an option on or off. Follows the Material Design 3 Checkbox specification.

Usage​

import { Checkbox } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { useState } from 'react'
import { View } from 'react-native'

export default function App() {
const [isChecked, setIsChecked] = useState(false)
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Checkbox value={isChecked} onValueChange={setIsChecked} />
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}
Controlled or uncontrolled

Pass value with onValueChange to own the state, as above. Omit value and Checkbox manages its own, starting from defaultValue:

<Checkbox defaultValue onValueChange={handleChange} />

onValueChange still fires either way. In earlier prereleases, passing onValueChange without value did nothing visually — the callback fired but the control never moved. See the changelog if you are upgrading.

Multiple Checkboxes​

import { Checkbox } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { useState } from 'react'
import { View } from 'react-native'

export default function App() {
const [a, setA] = useState(true)
const [b, setB] = useState(false)
const [c, setC] = useState(false)
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', gap: 12 }}>
<Checkbox value={a} onValueChange={setA} />
<Checkbox value={b} onValueChange={setB} />
<Checkbox value={c} onValueChange={setC} />
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}

Disabled​

import { Checkbox } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'

export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', gap: 12 }}>
<Checkbox value={false} onValueChange={() => {}} disabled />
<Checkbox value onValueChange={() => {}} disabled />
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}

In a list row​

To let the full ListItem toggle the checkbox, put onPress on the row and give the checkbox value with no onValueChange. The checkbox then only shows the state, and the row takes the press. See Selection controls in a row.

Props​

PropTypeDefaultRequiredDescription
valueboolean-NoWhether the checkbox is checked (controlled). Pass this together with `onValueChange` to own the state. Omit it and the component manages its own state, starting from `defaultValue`.
defaultValuebooleanNoInitial value when uncontrolled. Ignored once `value` is passed.
onValueChange(value: boolean) => void-NoCallback fired when the checkbox is toggled. Receives the new value. With `value` set and no `onValueChange`, the checkbox only shows the state. It takes no press, leaves the tab order, and is hidden from assistive technology. Use this in a pressable `ListItem`, and give the row `role="checkbox"` and `aria-checked`. The row then carries the press and the state. A disabled checkbox is never hidden.
indeterminatebooleanNoRender the MD3 indeterminate ("mixed") state — a dash mark on the selected container colors. Wins over `value` visually, and reports `checked: 'mixed'` to accessibility.
errorbooleanNoRender the MD3 error state: `error`-colored outline when unchecked, and an `error` container with `onError` mark when checked or indeterminate. State-layer (hover, focus, press) colors also use `error`. The standard disabled treatment wins over the error state.
checkIconIconSourcecheckNoIcon shown when the checkbox is checked. Accepts a string name (resolved via the theme's `iconResolver`, for example `mdiResolver`), a pre-rendered element, or a render function that receives `{ size, color }`. Override this when your `iconResolver` doesn't map the default `'check'` name (e.g. a Lucide-only resolver).
containerColorstring-NoOverride the container (box) color when checked. State-layer colors (hover, press) are derived automatically.
contentColorstring-NoOverride the checkmark icon color.
styleStyleProp<ViewStyle>-NoStyle applied to the root container. Static form only — the function form `(state) => style` is not supported because the component drives its container background through Reanimated. Use `containerColor` / `contentColor` for state-aware styling.
hrefAttrs{ target?: string; rel?: string; download?: string | boolean; }-NoWeb only. The `target`, `rel` and `download` of the `<a>` that a view with an `href` renders, for example under Expo Router's `<Link asChild>`. `target: '_blank'` opens the link in a new tab. Native ignores it.
onKeyDown(event: PressableKeyDownEvent) => void-No-