Skip to main content
CheckboxGroup
@coinbase/cds-web@8.13.6
CheckboxGroup is a control component that allows users to select multiple options from a set of choices. It manages the state and layout of multiple checkbox inputs as a cohesive group.
Import
import { CheckboxGroup } from '@coinbase/cds-web/controls/CheckboxGroup'
SourceView source codeStorybookView StorybookFigmaView Figma

Deprecation Notice

Deprecated Component

CheckboxGroup is deprecated and will be removed in a future version.

Use ControlGroup with role="group" instead for better accessibility, consistency, and maintainability.

Migration Guide

The new recommended approach provides better accessibility, cleaner API, and consistent behavior across the design system.

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

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

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

  return (
    <VStack gap={2}>
      <ControlGroup
        role="group"
        ControlComponent={Checkbox}
        label="Notification Preferences"
        options={options}
        value={selectedValues}
        onChange={handleChange}
        name="notifications"
      />
      <Text font="caption" color="fgMuted">
        Selected: {selectedValues.join(', ') || 'None'}
      </Text>
    </VStack>
  );
}

Migration Steps

  1. Replace CheckboxGroup with ControlGroup:

    // Old (deprecated)
    <CheckboxGroup selectedValues={new Set(values)} onChange={onChange}>
    <Checkbox value="option1">Option 1</Checkbox>
    <Checkbox value="option2">Option 2</Checkbox>
    </CheckboxGroup>

    // New (recommended)
    <ControlGroup
    role="group"
    ControlComponent={Checkbox}
    options={[
    { value: 'option1', children: 'Option 1' },
    { value: 'option2', children: 'Option 2' }
    ]}
    value={values}
    onChange={onChange}
    />
  2. Update state management:

    // Old: Used Set<string>
    const [selectedValues, setSelectedValues] = useState(new Set(['value1']));

    // New: Use Array<string>
    const [selectedValues, setSelectedValues] = useState(['value1']);
  3. Update onChange handler:

    // Old: Toggle logic handled manually
    const oldOnChange = (e) => {
    const { value, checked } = e.target;
    setSelectedValues((prev) => {
    const newSet = new Set(prev);
    if (checked) {
    newSet.add(value);
    } else {
    newSet.delete(value);
    }
    return newSet;
    });
    };

    // New: Simplified toggle logic
    const newOnChange = (e) => {
    const { value, checked } = e.target;
    setSelectedValues((prev) => (checked ? [...prev, value] : prev.filter((v) => v !== value)));
    };

Legacy Usage (Deprecated)

Legacy Example

The following examples show the deprecated CheckboxGroup usage. Do not use this in new code. Use ControlGroup instead.

Basic CheckboxGroup (Legacy)

Loading...
Live Code
function LegacyCheckboxGroup() {
  const [selectedValues, setSelectedValues] = useState(new Set(['feature1']));

  const handleToggle = (e) => {
    const { value, checked } = e.target;
    setSelectedValues((prev) => {
      const newSet = new Set(prev);
      if (checked) {
        newSet.add(value);
      } else {
        newSet.delete(value);
      }
      return newSet;
    });
  };

  return (
    <VStack gap={2}>
      <Text font="headline">Features (Legacy CheckboxGroup)</Text>
      <CheckboxGroup
        aria-labelledby="features-label"
        selectedValues={selectedValues}
        onChange={handleToggle}
        name="features"
      >
        <Checkbox value="feature1">Dark mode</Checkbox>
        <Checkbox value="feature2">Two-factor authentication</Checkbox>
        <Checkbox value="feature3">Email notifications</Checkbox>
        <Checkbox value="feature4">Auto-save</Checkbox>
      </CheckboxGroup>
      <Text font="caption" color="fgMuted">
        Selected: {Array.from(selectedValues).join(', ') || 'None'}
      </Text>
    </VStack>
  );
}

With Custom Label (Legacy)

Loading...
Live Code
function LegacyCheckboxGroupWithLabel() {
  const [permissions, setPermissions] = useState(new Set(['read']));

  const handlePermissionChange = (e) => {
    const { value, checked } = e.target;
    setPermissions((prev) => {
      const newSet = new Set(prev);
      if (checked) {
        newSet.add(value);
      } else {
        newSet.delete(value);
      }
      return newSet;
    });
  };

  return (
    <CheckboxGroup
      label={<Text font="headline">User Permissions</Text>}
      selectedValues={permissions}
      onChange={handlePermissionChange}
      name="permissions"
    >
      <Checkbox value="read">Read access</Checkbox>
      <Checkbox value="write">Write access</Checkbox>
      <Checkbox value="admin">Admin access</Checkbox>
    </CheckboxGroup>
  );
}

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.