Installation
npx @park-ui/cli add checkboxAdd Component
Copy the code snippet below into you components folder.
'use client'
import { Checkbox, useCheckboxContext } from '@ark-ui/react/checkbox'
import { type ComponentProps, forwardRef } from 'react'
import { createStyleContext, styled } from 'styled-system/jsx'
import { checkbox } from 'styled-system/recipes'
import type { HTMLStyledProps } from 'styled-system/types'
const { withProvider, withContext } = createStyleContext(checkbox)
export type RootProps = ComponentProps<typeof Root>
export type HiddenInputProps = ComponentProps<typeof HiddenInput>
export const Root = withProvider(Checkbox.Root, 'root')
export const RootProvider = withProvider(Checkbox.RootProvider, 'root')
export const Control = withContext(Checkbox.Control, 'control')
export const Group = withProvider(Checkbox.Group, 'group')
export const Label = withContext(Checkbox.Label, 'label')
export const HiddenInput = Checkbox.HiddenInput
export {
type CheckboxCheckedState as CheckedState,
CheckboxGroupProvider as GroupProvider,
} from '@ark-ui/react/checkbox'
export const Indicator = forwardRef<SVGSVGElement, HTMLStyledProps<'svg'>>(
function Indicator(props, ref) {
const { indeterminate, checked } = useCheckboxContext()
return (
<Checkbox.Indicator indeterminate={indeterminate} asChild>
<styled.svg
ref={ref}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="3px"
strokeLinecap="round"
strokeLinejoin="round"
{...props}
>
<title>Checkmark</title>
{indeterminate ? <path d="M5 12h14" /> : checked ? <path d="M20 6 9 17l-5-5" /> : null}
</styled.svg>
</Checkbox.Indicator>
)
},
)
Integrate Recipe
Integrate this recipe in to your Panda config.
import { checkboxAnatomy } from '@ark-ui/react/checkbox'
import { defineSlotRecipe } from '@pandacss/dev'
export const checkbox = defineSlotRecipe({
slots: checkboxAnatomy.keys(),
className: 'checkbox',
base: {
root: {
display: 'inline-flex',
gap: '2',
alignItems: 'center',
verticalAlign: 'top',
position: 'relative',
_disabled: {
layerStyle: 'disabled',
},
},
control: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
flexShrink: '0',
borderWidth: '1px',
borderColor: 'transparent',
borderRadius: 'l1',
cursor: 'pointer',
focusVisibleRing: 'outside',
_icon: {
boxSize: 'full',
},
},
label: {
fontWeight: 'medium',
userSelect: 'none',
},
},
variants: {
size: {
sm: {
root: { gap: '2' },
label: { textStyle: 'sm' },
control: { boxSize: '4.5', _icon: { boxSize: '3' } },
},
md: {
root: { gap: '3' },
label: { textStyle: 'md' },
control: { boxSize: '5', _icon: { boxSize: '3.5' } },
},
lg: {
root: { gap: '3' },
label: { textStyle: 'lg' },
control: { boxSize: '5.5', _icon: { boxSize: '4' } },
},
},
variant: {
solid: {
control: {
control: {
borderColor: 'border',
_checked: {
bg: 'colorPalette.solid.bg',
borderColor: 'colorPalette.solid.bg',
color: 'colorPalette.solid.fg',
},
_invalid: {
background: 'error',
},
},
},
},
surface: {
control: {
bg: 'colorPalette.surface.bg',
borderWidth: '1px',
borderColor: 'colorPalette.surface.border',
color: 'colorPalette.surface.fg',
},
},
subtle: {
control: {
bg: 'colorPalette.subtle.bg',
color: 'colorPalette.subtle.fg',
},
},
outline: {
control: {
borderWidth: '1px',
borderColor: 'colorPalette.outline.border',
color: 'colorPalette.outline.fg',
_checked: {
borderColor: 'colorPalette.solid.bg',
},
},
},
plain: {
control: {
color: 'colorPalette.plain.fg',
},
},
},
},
defaultVariants: {
variant: 'solid',
size: 'md',
},
})
Usage
import { Checkbox } from '@/components/ui'
<Checkbox.Root>
<Checkbox.HiddenInput />
<Checkbox.Control>
<Checkbox.Indicator />
</Checkbox.Control>
<Checkbox.Label />
</Checkbox.Root>
If you prefer a closed component composition, check out the snippet below.
Examples
Variants
Customize the appearance with different visual styles to match your design:
Colors
Use the colorPalette prop to change the color of the checkbox:
Sizes
Adjust the size to match surrounding text or interface elements:
States
Pass the disabled or invalid prop to the Checkbox.Root component to change the visual state of the checkbox.
Controlled
Use the checked and onCheckedChange props to control the checkbox state.
'use client'
import { useState } from 'react'
import { Checkbox } from '@/components/ui'
export const App = () => {
const [checked, setChecked] = useState<Checkbox.CheckedState>(false)
return (
<Checkbox.Root checked={checked} onCheckedChange={(e) => setChecked(e.checked)}>
<Checkbox.HiddenInput />
<Checkbox.Control>
<Checkbox.Indicator />
</Checkbox.Control>
<Checkbox.Label>Label</Checkbox.Label>
</Checkbox.Root>
)
}
Label
Here's an example of how to change the label position to the left:
Indeterminate
Set the checked prop to indeterminate to show the checkbox in an indeterminate state.
Description
Here's an example of how to add some further description to the checkbox:
Link
Render an anchor tag within the Checkbox.Label to add a link to the label.
Closed Component
Here's how to setup the avatar for a closed component composition.
import { forwardRef } from 'react'
import { VisuallyHidden } from 'styled-system/jsx'
import { Checkbox as StyledCheckbox } from '@/components/ui'
export type { CheckboxCheckedState } from '@ark-ui/react/checkbox'
export interface CheckboxProps extends StyledCheckbox.RootProps {
inputProps?: StyledCheckbox.HiddenInputProps
}
export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(props, ref) {
const { children, inputProps, ...rootProps } = props
return (
<StyledCheckbox.Root {...rootProps}>
<StyledCheckbox.HiddenInput ref={ref} {...inputProps} />
<StyledCheckbox.Control>
<StyledCheckbox.Indicator />
</StyledCheckbox.Control>
{children && <StyledCheckbox.Label>{children}</StyledCheckbox.Label>}
{props['aria-label'] && (
<StyledCheckbox.Label asChild>
<VisuallyHidden>{props['aria-label']}</VisuallyHidden>
</StyledCheckbox.Label>
)}
</StyledCheckbox.Root>
)
})
To use the closed component, simply import and use it like this:
<Checkbox>Label</Checkbox>
Props
Root
| Prop | Default | Type |
|---|---|---|
size | 'md' | 'sm' | 'md' | 'lg' |
variant | 'solid' | 'solid' | 'surface' | 'subtle' | 'outline' | 'plain' |
value | \on\ | stringThe value of checkbox input. Useful for form submission. |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. | |
checked | CheckedStateThe controlled checked state of the checkbox | |
defaultChecked | CheckedStateThe initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | |
disabled | booleanWhether the checkbox is disabled | |
form | stringThe id of the form that the checkbox belongs to. | |
id | stringThe unique identifier of the machine. | |
ids | Partial<{ root: string; hiddenInput: string; control: string; label: string }>The ids of the elements in the checkbox. Useful for composition. | |
invalid | booleanWhether the checkbox is invalid | |
name | stringThe name of the input field in a checkbox. Useful for form submission. | |
onCheckedChange | (details: CheckedChangeDetails) => voidThe callback invoked when the checked state changes. | |
readOnly | booleanWhether the checkbox is read-only | |
required | booleanWhether the checkbox is required |
Group
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. | |
defaultValue | string[]The initial value of `value` when uncontrolled | |
disabled | booleanIf `true`, the checkbox group is disabled | |
invalid | booleanIf `true`, the checkbox group is invalid | |
name | stringThe name of the input fields in the checkbox group (Useful for form submission). | |
onValueChange | (value: string[]) => voidThe callback to call when the value changes | |
readOnly | booleanIf `true`, the checkbox group is read-only | |
value | string[]The controlled value of the checkbox group |
GroupProvider
| Prop | Default | Type |
|---|---|---|
value* | UseCheckboxGroupContext | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. |
Indicator
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. | |
indeterminate | boolean |