Skip to main content
Checkbox
@coinbase/cds-web@8.13.6
Checkbox is a type of control component that allows user to select one or more options from a set. They can also be used alone to switch between on and off.
Import
import { Checkbox } from '@coinbase/cds-web/controls/Checkbox'
SourceView source codeStorybookView StorybookFigmaView Figma
Peer dependencies
  • framer-motion: ^10.18.0

Basic Usage

Checkbox UI and state management are separated so that you can swap in any form or state code you like.

Loading...
Live Code
function BasicCheckbox() {
  const [isChecked, setIsChecked] = useState(false);
  return (
    <Checkbox
      value="newsletter"
      onChange={(e) => setIsChecked(e.target.checked)}
      checked={isChecked}
    >
      Subscribe to newsletter
    </Checkbox>
  );
}

Custom Layout

If you don't want to use the default label or layout style, you can just not provide children to the Checkbox component. However, you should think about wrapping the custom label and Checkbox in a <label> if it makes sense to increase the tap target of the component and allow users to toggle by pressing on the label as well.

Loading...
Live Code
function CustomLayoutCheckbox() {
  const [isChecked, setIsChecked] = useState(false);
  return (
    <Box as="label" justifyContent="space-between" maxWidth="350px">
      <VStack gap={0} alignItems="flex-start">
        <Text font="body">Premium Features</Text>
        <Text font="caption" color="fgMuted">
          Access to advanced tools and priority support
        </Text>
      </VStack>
      <Checkbox
        value="premium"
        onChange={(e) => setIsChecked(e.target.checked)}
        checked={isChecked}
      />
    </Box>
  );
}

Different States

Checkboxes support various states including disabled and indeterminate.

Loading...
Live Code
function CheckboxStates() {
  const [checked, setChecked] = useState(false);
  const [indeterminate, setIndeterminate] = useState(true);

  return (
    <VStack gap={2}>
      <Checkbox value="enabled" onChange={(e) => setChecked(e.target.checked)} checked={checked}>
        Normal checkbox
      </Checkbox>
      <Checkbox value="disabled-unchecked" checked={false} disabled>
        Disabled & unchecked
      </Checkbox>
      <Checkbox value="disabled-checked" checked={true} disabled>
        Disabled & checked
      </Checkbox>
      <Checkbox
        value="indeterminate"
        indeterminate={indeterminate}
        onChange={(e) => {
          setIndeterminate(false);
          // Handle the change as needed
        }}
      >
        Indeterminate state
      </Checkbox>
    </VStack>
  );
}

Custom Colors

Like other control components (i.e. Radio, Switch), you can customize the color of the Checkbox by setting the controlColor prop.

Loading...
Live Code
function CustomColors() {
  const [checked, setChecked] = useState(false);

  return (
    <Checkbox
      controlColor="accentBoldGreen"
      onChange={() => setChecked((s) => !s)}
      checked={checked}
    >
      Custom control color
    </Checkbox>
  );
}

For more advanced customization, you can also control the border shape and thickness using borderRadius and borderWidth, along with background and borderColor:

Loading...
Live Code
function AdvancedCustomColors() {
  const [checked, setChecked] = useState(false);

  return (
    <Checkbox
      background={checked ? 'accentBoldPurple' : 'bgNegative'}
      borderColor={checked ? 'bgPositive' : 'bgPrimary'}
      borderRadius={200}
      borderWidth={300}
      checked={checked}
      controlColor="bgPositive"
      onChange={() => setChecked((s) => !s)}
    >
      Advanced styling (rounded corners + thick border)
    </Checkbox>
  );
}

Multiple Checkboxes

For multiple checkbox scenarios, use ControlGroup with role="group" for better accessibility and state management:

Loading...
Live Code
function MultipleCheckboxes() {
  const options = [
    { value: 'email', children: 'Email notifications' },
    { value: 'sms', children: 'SMS notifications' },
    { value: 'push', children: 'Push notifications' },
  ];

  const [selectedValues, setSelectedValues] = useState(['email']);

  const handleChange = (e) => {
    const { value, checked } = e.target;
    setSelectedValues((prev) => (checked ? [...prev, value] : prev.filter((v) => v !== value)));
  };

  return (
    <ControlGroup
      role="group"
      ControlComponent={Checkbox}
      label="Notification Preferences"
      options={options}
      value={selectedValues}
      onChange={handleChange}
      name="notifications"
    />
  );
}

Is this page useful?

Coinbase Design is an open-source, adaptable system of guidelines, components, and tools that aid the best practices of user interface design for crypto products.