Skip to content

Checkbox

Checkbox group

You can wrap checkbox controls into group using <fieldset> and adding <legend>.

tsx
import React from 'react';
import Checkbox from 'intergalactic/checkbox';

const fieldsetStyle = { border: 'none' };
const ulStyle = {};
const liStyle = { listStyle: 'none', margin: 0 };

const Demo = () => {
  const [checked, setChecked] = React.useState([false, false, false]);

  const handleItemChange = React.useCallback(
    (index: number) => (value: boolean) => {
      setChecked((checked) => checked.map((item, i) => (i === index ? value : item)));
    },
    [setChecked],
  );

  return (
    <fieldset style={fieldsetStyle}>
      <legend>Options list label</legend>
      <ul style={ulStyle}>
        {checked.map((value, index) => (
          <li key={index} style={liStyle}>
            <Checkbox
              mb={3}
              key={index}
              checked={value}
              onChange={handleItemChange(index)}
              label={`Option ${index + 1}`}
            />
          </li>
        ))}
      </ul>
    </fieldset>
  );
};

export default Demo;
import React from 'react';
import Checkbox from 'intergalactic/checkbox';

const fieldsetStyle = { border: 'none' };
const ulStyle = {};
const liStyle = { listStyle: 'none', margin: 0 };

const Demo = () => {
  const [checked, setChecked] = React.useState([false, false, false]);

  const handleItemChange = React.useCallback(
    (index: number) => (value: boolean) => {
      setChecked((checked) => checked.map((item, i) => (i === index ? value : item)));
    },
    [setChecked],
  );

  return (
    <fieldset style={fieldsetStyle}>
      <legend>Options list label</legend>
      <ul style={ulStyle}>
        {checked.map((value, index) => (
          <li key={index} style={liStyle}>
            <Checkbox
              mb={3}
              key={index}
              checked={value}
              onChange={handleItemChange(index)}
              label={`Option ${index + 1}`}
            />
          </li>
        ))}
      </ul>
    </fieldset>
  );
};

export default Demo;

Partial selection

When one or more options are selected from the list, the parent checkbox gets an indeterminate (mixed) state.

tsx
import React from 'react';
import { Flex } from 'intergalactic/flex-box';
import Checkbox from 'intergalactic/checkbox';

const Demo = () => {
  const [checked, setChecked] = React.useState([false, false, false]);
  const handleGroupChange = React.useCallback(
    (value: boolean) => {
      setChecked((checked) => checked.map(() => value));
    },
    [setChecked],
  );
  const handleItemChange = React.useCallback(
    (index: number) => (value: boolean) => {
      setChecked((checked) => checked.map((item, i) => (i === index ? value : item)));
    },
    [setChecked],
  );

  return (
    <>
      <Flex>
        <Checkbox
          mb={3}
          label='Options group'
          onChange={handleGroupChange}
          indeterminate={checked.includes(false) && checked.includes(true)}
          checked={checked.includes(true)}
        />
      </Flex>
      {checked.map((value, index) => (
        <Flex key={index} ml={6}>
          <Checkbox
            mb={3}
            key={index}
            checked={value}
            onChange={handleItemChange(index)}
            label={`Option ${index + 1}`}
          />
        </Flex>
      ))}
    </>
  );
};

export default Demo;
import React from 'react';
import { Flex } from 'intergalactic/flex-box';
import Checkbox from 'intergalactic/checkbox';

const Demo = () => {
  const [checked, setChecked] = React.useState([false, false, false]);
  const handleGroupChange = React.useCallback(
    (value: boolean) => {
      setChecked((checked) => checked.map(() => value));
    },
    [setChecked],
  );
  const handleItemChange = React.useCallback(
    (index: number) => (value: boolean) => {
      setChecked((checked) => checked.map((item, i) => (i === index ? value : item)));
    },
    [setChecked],
  );

  return (
    <>
      <Flex>
        <Checkbox
          mb={3}
          label='Options group'
          onChange={handleGroupChange}
          indeterminate={checked.includes(false) && checked.includes(true)}
          checked={checked.includes(true)}
        />
      </Flex>
      {checked.map((value, index) => (
        <Flex key={index} ml={6}>
          <Checkbox
            mb={3}
            key={index}
            checked={value}
            onChange={handleItemChange(index)}
            label={`Option ${index + 1}`}
          />
        </Flex>
      ))}
    </>
  );
};

export default Demo;

Checkbox with other components

You can place other components next to the Checkbox or inside the Checkbox.Text components.

tsx
import React from 'react';
import { Flex } from 'intergalactic/flex-box';
import Checkbox from 'intergalactic/checkbox';
import { DescriptionTooltip } from 'intergalactic/tooltip';
import InfoM from 'intergalactic/icon/Info/m';
import Link from 'intergalactic/link';

function noop(e) {
  e.preventDefault();
}

const Demo = () => (
  <>
    <Flex>
      <Checkbox mb={3} label='Option 1' />
      <DescriptionTooltip placement='right'>
        <DescriptionTooltip.Trigger
          ml={1}
          tag={InfoM}
          color='icon-secondary-neutral'
          interactive
          aria-label='Additional info'
        />
        <DescriptionTooltip.Popper aria-label={'Additional info about checkbox item'}>
          Place an additional information here!
        </DescriptionTooltip.Popper>
      </DescriptionTooltip>
    </Flex>

    <Flex>
      <Checkbox mb={3}>
        <Checkbox.Value />
        <Checkbox.Text>
          Option 2
          <Link ml={2} href='#' onClick={noop}>
            Learn more
          </Link>
        </Checkbox.Text>
      </Checkbox>
    </Flex>
  </>
);

export default Demo;
import React from 'react';
import { Flex } from 'intergalactic/flex-box';
import Checkbox from 'intergalactic/checkbox';
import { DescriptionTooltip } from 'intergalactic/tooltip';
import InfoM from 'intergalactic/icon/Info/m';
import Link from 'intergalactic/link';

function noop(e) {
  e.preventDefault();
}

const Demo = () => (
  <>
    <Flex>
      <Checkbox mb={3} label='Option 1' />
      <DescriptionTooltip placement='right'>
        <DescriptionTooltip.Trigger
          ml={1}
          tag={InfoM}
          color='icon-secondary-neutral'
          interactive
          aria-label='Additional info'
        />
        <DescriptionTooltip.Popper aria-label={'Additional info about checkbox item'}>
          Place an additional information here!
        </DescriptionTooltip.Popper>
      </DescriptionTooltip>
    </Flex>

    <Flex>
      <Checkbox mb={3}>
        <Checkbox.Value />
        <Checkbox.Text>
          Option 2
          <Link ml={2} href='#' onClick={noop}>
            Learn more
          </Link>
        </Checkbox.Text>
      </Checkbox>
    </Flex>
  </>
);

export default Demo;

Additional props for input

Checkbox.Value is made of a CheckMark div and a hidden input. When you pass props to Checkbox.Value, it passes specific set of them to input props and all others goes to CheckMark div.

For more control over the input, you can pass props to Checkbox.Value.Control.

WARNING

🚨 Checkbox.Value.CheckMark should always be the next element after Checkbox.Value.Control in DOM.

tsx
import React from 'react';
import Checkbox from 'intergalactic/checkbox';

const Demo = () => {
  return (
    <Checkbox>
      <Checkbox.Value>
        <Checkbox.Value.Control data-testid='checkbox_input_tag' />
        <Checkbox.Value.CheckMark />
      </Checkbox.Value>
      <Checkbox.Text>Value</Checkbox.Text>
    </Checkbox>
  );
};

export default Demo;
import React from 'react';
import Checkbox from 'intergalactic/checkbox';

const Demo = () => {
  return (
    <Checkbox>
      <Checkbox.Value>
        <Checkbox.Value.Control data-testid='checkbox_input_tag' />
        <Checkbox.Value.CheckMark />
      </Checkbox.Value>
      <Checkbox.Text>Value</Checkbox.Text>
    </Checkbox>
  );
};

export default Demo;

Released under the MIT License.

Released under the MIT License.