Checkbox

Input for selecting one or multiple options.

import { Checkbox } from "ui-lab-components";
 
export function Example() {
  return <Checkbox label="Accept terms and conditions" />;
}

Basic States

The default checkbox states: unchecked, checked, disabled, and disabled checked.

import { Checkbox, Flex } from 'ui-lab-components';
 
export const metadata = {
  title: 'Basic States',
  description: 'The default checkbox states: unchecked, checked, disabled, and disabled checked.',
};
 
export default function Example() {
  return (
    <Flex direction="column" gap="md" style={{ width: 280 }}>
      <Checkbox id="basic-unchecked" label="Unchecked" />
      <Checkbox id="basic-checked" label="Checked" defaultChecked />
      <Checkbox id="basic-disabled" label="Disabled" disabled />
      <Checkbox id="basic-disabled-checked" label="Disabled checked" disabled defaultChecked />
    </Flex>
  );
}
 

Helper and Error Text

A labeled checkbox can include supporting text and an invalid state for form feedback.

Get a short product update when a new version ships.

You must accept the terms before continuing.

import { Checkbox, Flex } from 'ui-lab-components';
 
export const metadata = {
  title: 'Helper and Error Text',
  description: 'A labeled checkbox can include supporting text and an invalid state for form feedback.',
};
 
export default function Example() {
  return (
    <Flex direction="column" gap="lg" style={{ width: 320 }}>
      <Checkbox
        id="helper-release-notes"
        label="Release notes"
        helper="Get a short product update when a new version ships."
        defaultChecked
      />
      <Checkbox
        id="helper-terms"
        label="Accept terms"
        helper="You must accept the terms before continuing."
        helperTextError
        aria-invalid="true"
      />
    </Flex>
  );
}
 

Controlled

Use checked and onChange when checkbox state is owned by the surrounding interface.

Notifications are enabled.

"use client";
 
import { useState } from 'react';
import { Button, Checkbox, Flex } from 'ui-lab-components';
 
export const metadata = {
  title: 'Controlled',
  description: 'Use checked and onChange when checkbox state is owned by the surrounding interface.',
};
 
export default function Example() {
  const [checked, setChecked] = useState(true);
 
  return (
    <Flex direction="column" gap="md" style={{ width: 300 }}>
      <Checkbox
        id="controlled-email"
        label="Email notifications"
        helper={checked ? 'Notifications are enabled.' : 'Notifications are paused.'}
        checked={checked}
        onChange={(event) => setChecked(event.currentTarget.checked)}
      />
      <Button variant="secondary" onClick={() => setChecked((value) => !value)}>
        {checked ? 'Turn off' : 'Turn on'}
      </Button>
    </Flex>
  );
}
 

Checkbox Group

Use a small group when a user can select any number of related options.

Subscriptions

Choose the emails this workspace receives.

"use client";
 
import { useState } from 'react';
import { Checkbox, Flex } from 'ui-lab-components';
 
export const metadata = {
  title: 'Checkbox Group',
  description: 'Use a small group when a user can select any number of related options.',
};
 
const subscriptionOptions = [
  'Product updates',
  'Security alerts',
  'Billing reminders',
];
 
export default function Example() {
  const [selected, setSelected] = useState<Set<string>>(
    new Set(['Product updates', 'Security alerts'])
  );
 
  const toggleOption = (option: string) => {
    setSelected((current) => {
      const next = new Set(current);
      next.has(option) ? next.delete(option) : next.add(option);
      return next;
    });
  };
 
  return (
    <Flex direction="column" gap="md" style={{ width: 300 }}>
      <div>
        <p className="text-sm font-medium text-foreground-100">Subscriptions</p>
        <p className="text-xs text-foreground-400">Choose the emails this workspace receives.</p>
      </div>
      <Flex direction="column" gap="sm">
        {subscriptionOptions.map((option) => (
          <Checkbox
            key={option}
            id={`subscription-${option.toLowerCase().replace(/ /g, '-')}`}
            label={option}
            checked={selected.has(option)}
            onChange={() => toggleOption(option)}
          />
        ))}
      </Flex>
    </Flex>
  );
}
 

Indeterminate

A parent checkbox can show partial selection when only some child options are checked.

"use client";
 
import { useState } from 'react';
import { Checkbox, Divider, Flex } from 'ui-lab-components';
 
export const metadata = {
  title: 'Indeterminate',
  description: 'A parent checkbox can show partial selection when only some child options are checked.',
};
 
const tableColumns = ['Name', 'Email', 'Role', 'Last active'];
 
export default function Example() {
  const [visibleColumns, setVisibleColumns] = useState<Set<string>>(
    new Set(['Name', 'Email'])
  );
 
  const allSelected = visibleColumns.size === tableColumns.length;
  const isIndeterminate = visibleColumns.size > 0 && !allSelected;
 
  const toggleAll = () => {
    setVisibleColumns(allSelected ? new Set() : new Set(tableColumns));
  };
 
  const toggleColumn = (column: string) => {
    setVisibleColumns((current) => {
      const next = new Set(current);
      next.has(column) ? next.delete(column) : next.add(column);
      return next;
    });
  };
 
  return (
    <Flex direction="column" gap="sm" style={{ width: 280 }}>
      <Checkbox
        id="columns-all"
        label="Show all columns"
        checked={allSelected}
        isIndeterminate={isIndeterminate}
        onChange={toggleAll}
      />
      <Divider />
      <Flex direction="column" gap="sm" styles={{ root: 'pl-8' }}>
        {tableColumns.map((column) => (
          <Checkbox
            key={column}
            id={`column-${column.toLowerCase().replace(/ /g, '-')}`}
            label={column}
            checked={visibleColumns.has(column)}
            onChange={() => toggleColumn(column)}
          />
        ))}
      </Flex>
    </Flex>
  );
}
 
UI Lab