A checkbox group allows a user to select multiple items from a list of options.
< CheckboxGroup label = "React frameworks" defaultValue = { [ "nextjs" ] } >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
< Checkbox value = "gatsby" >Gatsby</ Checkbox >
</ CheckboxGroup >
Installation
Install the following dependencies: npm install react-aria-components
Copy and paste the following code into your project. checkbox-group.tsx
field.tsx
"use client" ;
import * as React from "react" ;
import {
CheckboxGroup as AriaCheckboxGroup ,
composeRenderProps ,
type CheckboxGroupProps as AriaCheckboxGroupProps ,
} from "react-aria-components" ;
import { tv , type VariantProps } from "tailwind-variants" ;
import { CheckboxContext } from "./checkbox" ;
import { Field , type FieldProps } from "./field" ;
const checkboxGroupStyles = tv ({
slots: {
root: "flex flex-col gap-2 items-start" ,
wrapper: "flex" ,
},
variants: {
variant: {
default: {
wrapper: "flex-col gap-0.5" ,
},
card: {
wrapper: "flex gap-2" ,
},
},
},
defaultVariants: {
variant: "default" ,
},
});
interface CheckboxGroupProps extends CheckboxGroupRootProps , Omit < FieldProps , "children" > {}
const CheckboxGroup = React . forwardRef <
React . ElementRef < typeof AriaCheckboxGroup > ,
CheckboxGroupProps
> (
(
{ label , description , errorMessage , necessityIndicator , contextualHelp , variant , ... props },
ref
) => {
const { wrapper } = checkboxGroupStyles ({ variant });
return (
< CheckboxGroupRoot ref = { ref } variant = { variant } { ... props } >
{ composeRenderProps ( props . children , ( children , { isRequired }) => (
< Field
label = { label }
description = { description }
errorMessage = { errorMessage }
isRequired = { isRequired }
necessityIndicator = { necessityIndicator }
contextualHelp = { contextualHelp }
>
< div className = { wrapper () } > { children } </ div >
</ Field >
)) }
</ CheckboxGroupRoot >
);
}
);
CheckboxGroup . displayName = "CheckboxGroup" ;
interface CheckboxGroupRootProps
extends Omit < AriaCheckboxGroupProps , "className" >,
VariantProps < typeof checkboxGroupStyles > {
className ?: string ;
}
const CheckboxGroupRoot = React . forwardRef <
React . ElementRef < typeof AriaCheckboxGroup > ,
CheckboxGroupRootProps
> (({ className , variant , ... props }, ref ) => {
const { root } = checkboxGroupStyles ({ variant });
return (
< CheckboxContext.Provider value = { { variant } } >
< AriaCheckboxGroup ref = { ref } className = { root ({ className }) } { ... props } />
</ CheckboxContext.Provider >
);
});
CheckboxGroupRoot . displayName = "CheckboxGroupRoot" ;
export type { CheckboxGroupProps , CheckboxGroupRootProps };
export { CheckboxGroup , CheckboxGroupRoot };
Update the import paths to match your project setup.
Usage
Use CheckboxGroup to allow users to select multiple items from a list of individual items, or to mark one individual item as selected.
Best practices
If users are only allowed to select a single option, consider using a radio group instead.
Each checkbox's state should be independent from other checkboxes in the group. For example: checking one checkbox should not check or disable any other checkboxes.
Options
Variant
Use the variant prop to control the visual style of the CheckBoxGroup .
< CheckboxGroup label = "React frameworks" defaultValue = { [ "nextjs" ] } variant = "card" >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
< Checkbox value = "gatsby" >Gatsby</ Checkbox >
</ CheckboxGroup >
Label
A visual label can be provided for the CheckboxGroup using the label prop or a hidden label using aria - label prop.
< CheckboxGroup label = "React frameworks" defaultValue = { [ "nextjs" ] } >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
</ CheckboxGroup >
< CheckboxGroup aria-label = "React frameworks" defaultValue = { [ "nextjs" ] } >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
</ CheckboxGroup >
Description
A description can be supplied to a CheckboxGroup via the description prop. The description is always visible unless the isInvalid prop is true and an error message is provided.
React frameworks You can pick any frameworks. < CheckboxGroup
label = "React frameworks"
defaultValue = { [ "nextjs" ] }
description = "You can pick any frameworks."
>
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
< Checkbox value = "gatsby" >Gatsby</ Checkbox >
</ CheckboxGroup >
Contextual help
A ContextualHelp element may be placed next to the label to provide additional information or help about a CheckboxGroup.
< CheckboxGroup
label = "React frameworks"
defaultValue = { [ "nextjs" ] }
contextualHelp = { < ContextualHelp /> }
>
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
< Checkbox value = "gatsby" >Gatsby</ Checkbox >
</ CheckboxGroup >
Error message
An error message can be supplied to a CheckboxGroup, which will be displayed when the validationState is “invalid” .
React frameworks Please select a framework. < CheckboxGroup label = "React frameworks" isInvalid errorMessage = "Please select a framework." >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
< Checkbox value = "gatsby" >Gatsby</ Checkbox >
</ CheckboxGroup >
Disabled
Use the isDisabled prop to disable the CheckboxGroup.
< CheckboxGroup label = "React frameworks" isDisabled >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
< Checkbox value = "gatsby" >Gatsby</ Checkbox >
</ CheckboxGroup >
ReadOnly
The isReadOnly boolean prop makes the CheckboxGroup's text content immutable. Unlike isDisabled, the CheckboxGroup remains focusable and the contents can still be copied.
< CheckboxGroup label = "React frameworks" isReadOnly >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
< Checkbox value = "gatsby" >Gatsby</ Checkbox >
</ CheckboxGroup >
Required
Use the isRequired prop to mark the CheckboxGroup as required.
Use the necessityIndicator prop to control the visual style of the required state.
React frameworks (required) React frameworks (optional) < CheckboxGroup label = "React frameworks" isRequired >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
</ CheckboxGroup >
< CheckboxGroup label = "React frameworks" isRequired necessityIndicator = "icon" >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
</ CheckboxGroup >
< CheckboxGroup label = "React frameworks" isRequired necessityIndicator = "label" >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
</ CheckboxGroup >
< CheckboxGroup label = "React frameworks" necessityIndicator = "label" >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
</ CheckboxGroup >
Uncontrolled
The defaultValue prop can be used to set the default state.
< CheckboxGroup label = "React frameworks" defaultValue = { [ "nextjs" ] } >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
< Checkbox value = "gatsby" >Gatsby</ Checkbox >
</ CheckboxGroup >
Controlled
Use the value and onChange props to control the value of the input.
const [ frameworks , setFrameworks ] = React. useState ([ "nextjs" ]);
return (
< CheckboxGroup label = "React frameworks" defaultValue = { [ "nextjs" ] } >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
< Checkbox value = "gatsby" >Gatsby</ Checkbox >
</ CheckboxGroup >
);
Composition
If you need to customize things further, you can drop down to the composition level.
React frameworks You can pick any frameworks. < CheckboxGroupRoot defaultValue = { [ "nextjs" ] } >
< Label >React frameworks</ Label >
< Description >You can pick any frameworks.</ Description >
< div className = "flex items-center gap-4" >
< Checkbox value = "nextjs" >Next.js</ Checkbox >
< Checkbox value = "remix" >Remix</ Checkbox >
< Checkbox value = "gatsby" >Gatsby</ Checkbox >
</ div >
< FieldError />
</ CheckboxGroupRoot >
API Reference
Prop Type Default Description variant
"default" | "card"
"default"
The visual style of the checkbox group.
value
string[]
-
The current value (controlled).
defaultValue
string[]
-
The default value (uncontrolled).
isDisabled
boolean
-
Whether the input is disabled.
isReadOnly
boolean
-
Whether the input can be selected but not changed by the user.
name
string
-
The name of the input element, used when submitting an HTML form.
isRequired
boolean
-
Whether user input is required on the input before form submission.
isInvalid
boolean
-
Whether the input value is invalid.
validate
( value : string []) => ValidationError | true | null | undefined
-
A function that returns an error message if a given value is invalid. Validation errors are displayed to the user when the form is submitted if validationBehavior="native". For realtime validation, use the isInvalid prop instead.
validationBehavior
'native' | 'aria'
'native'
Whether to use native HTML form validation to prevent form submission when the value is missing or invalid, or mark the field as required or invalid via ARIA.
children
ReactNode | ( values : CheckboxGroupRenderProps & { defaultChildren : ReactNode | undefined }) => ReactNode
-
The children of the component. A function may be provided to alter the children based on component state.
className
string
-
The CSS className for the element.
style
CSSProperties | ( values : CheckboxGroupRenderProps & { defaultStyle : CSSProperties }) => CSSProperties
-
The inline style for the element. A function may be provided to compute the style based on component state.
Event Type Description onChange
( value : T ) => void
Handler that is called when the value changes.
onFocus
( e : FocusEvent < Target >) => void
Handler that is called when the element receives focus.
onBlur
( e : FocusEvent < Target >) => void
Handler that is called when the element loses focus.
onFocusChange
( isFocused : boolean ) => void
Handler that is called when the element's focus status changes.
Data attribute Description [data - disabled]
Whether the checkbox group is disabled.
[data - readonly]
Whether the checkbox group is read only.
[data - required]
Whether the checkbox group is required.
[data - invalid]
Whether the checkbox group invalid.
Accessibility
Keyboard interactions
Key Description Tab
Moves focus to the next checkbox in the group.
Shift + Tab
Moves focus to the previous checkbox in the group.
Space
Checks/unchecks the focused checkbox.