Skip to content

CheckboxField

CheckboxField allows users to select one or more options from a set.

Basic Usage

To implement the CheckboxField component, you need to import it first:

import { CheckboxField } from '@react-ui-org/react-ui';

And use it:

React.createElement(() => {
  const [agree, setAgree] = React.useState(true);
  return (
    <CheckboxField
      checked={agree}
      label={(
          <>
            I have read and agree with
            {' '}
            <TextLink href="#" label="terms and conditions" />
          </>
        )}
      onChange={() => setAgree(!agree)}
    />
  );
});

See API for all available options.

General Guidelines

  • Use the CheckboxField when there are lists of options and the user may select any number of choices, including zero, one, or several. For selecting just a single option from the list, use either the Radio or SelectField component.

  • Use the CheckboxField for boolean (true/false) input in forms that require to be confirmed by a button to become active. To toggle things on or off with an immediate effect (without confirmation), use rather the Toggle component.

  • Use positive wording for the checkbox label, so that it's clear what will happen when the user turns on the checkbox. Avoid negations such as “Don't send me any emails” which would mean that the user needs to turn the checkbox on in order for something not to happen.

  • Use text labels unless it is necessary to wrap text label into Popover-like to component to provide additional info about the field.

  • Only make the CheckboxField's label invisible when there is another visual clue to guide users through toggling the input.

  • When a short label is not enough, use help texts to guide users before they enter anything.

  • Use clear, calm error messages when there's a problem with what they entered.

  • Visually present groups of choices as groups, and clearly separate them from other groups on the same page.

📖 Read more about checkboxes and radios at Nielsen Norman Group.

Help Text

You may provide an additional help text to clarify what will be the impact of turning the checkbox on or off.

React.createElement(() => {
  const [getNewsletter, setGetNewsletter] = React.useState(true);
  return (
    <CheckboxField
      checked={getNewsletter}
      helpText="We will not bother you more than once a month, we promise!"
      label="Send me newsletter"
      onChange={() => setGetNewsletter(!getNewsletter)}
    />
  );
});

Label Options

In some cases, it may be convenient to visually hide the checkbox label. The label remains accessible to assistive technologies.

React.createElement(() => {
  const [checked, setChecked] = React.useState(true);
  return (
    <CheckboxField
      checked={checked}
      isLabelVisible={false}
      label="You cannot see this"
      onChange={() => setChecked(!checked)}
    />
  );
});

It's also possible to display label before input:

React.createElement(() => {
  const [checked, setChecked] = React.useState(true);
  return (
    <CheckboxField
      checked={checked}
      label="Label precedes input"
      labelPosition="before"
      onChange={() => setChecked(!checked)}
    />
  );
});

States

Validation States

Validation states visually present the result of validation of the input. You should always provide validation message for states other than valid so users know what happened and what action they should take or what options they have.

React.createElement(() => {
  const [agree, setAgree] = React.useState(true);
  return (
    <>
      <CheckboxField
        checked={agree}
        label={(
          <>
            I have read and agree with
            {' '}
            <TextLink href="#" label="terms and conditions" />
          </>
        )}
        onChange={() => setAgree(!agree)}
        state="valid"
      />
      <CheckboxField
        checked={agree}
        label={(
          <>
            I have read and agree with
            {' '}
            <TextLink href="#" label="terms and conditions" />
          </>
        )}
        onChange={() => setAgree(!agree)}
        state="warning"
        validationText={(
          <>
            Please wait 10 minutes until we verify your data.
            {' '}
            <TextLink href="#" label="Cancel" />
          </>
        )}
      />
      <CheckboxField
        checked={agree}
        label={(
          <>
            I have read and agree with
            {' '}
            <TextLink href="#" label="terms and conditions" />
          </>
        )}
        onChange={() => setAgree(!agree)}
        required
        state="invalid"
        validationText="You must agree to be able to proceed."
      />
    </>
  );
});

Changed State

Changed state highlights fields whose value differs from the saved one, so users can review their edits before saving.

A field shows one state at a time. When a changed value is also invalid, it's up to you to pick the state that matters more to the user.

React.createElement(() => {
  const [newsletter, setNewsletter] = React.useState(true);
  return (
    <CheckboxField
      checked={newsletter}
      label="Subscribe to newsletter"
      onChange={() => setNewsletter(!newsletter)}
      state="changed"
    />
  );
});

Required State

The required state indicates that the input is mandatory. Required fields display an asterisk * after the label by default.

React.createElement(() => {
  const [agree, setAgree] = React.useState(true);
  return (
    <CheckboxField
      checked={agree}
      label="I agree"
      onChange={() => setAgree(!agree)}
      required
    />
  );
});

Rendering as Required

A form field may be valid in both checked and unchecked states, for example to turn on or off a feature, while your design still needs it to look required. For this edge case, there is the renderAsRequired prop:

React.createElement(() => {
  const [optional, setOptional] = React.useState(false);
  const [renderAsRequired, setRenderAsRequired] = React.useState(false);
  return (
    <>
      <CheckboxField
        checked={optional}
        label="This field is optional"
        onChange={() => setOptional(!optional)}
      />
      <CheckboxField
        checked={renderAsRequired}
        label="This field is optional but looks like required"
        onChange={() => setRenderAsRequired(!renderAsRequired)}
        renderAsRequired
      />
    </>
  );
});

It renders the field as if it was required, but doesn't add the required attribute to the actual input.

Disabled State

Disabled state makes the input unavailable.

<CheckboxField
  disabled
  label="Disabled checkbox"
/>
<CheckboxField
  checked
  disabled
  label="Disabled checkbox, checked"
/>

Forwarding HTML Attributes

In addition to the options below in the component's API section, you can specify any HTML attribute you like. All attributes that don't interfere with the API of the React component and that aren't filtered out by transferProps helper are forwarded to the <input> HTML element. This enables making the component interactive and helps to improve its accessibility.

👉 For the full list of supported attributes refer to:

Forwarding ref

If you provide ref, it is forwarded to the native HTML <input> element.

API

Theming

Head to Forms Theming to see shared form theming options. On top of that, the following options are available for CheckboxField.

Custom Property Description
--rui-FormField--check__input--checkbox__border-radius Input corner radius
--rui-FormField--check__input--checkbox--checked__background-image Background image of checked input

Theming the Required State

Required fields are indicated by shared theming options.

If your project uses the label color as the primary means to indicate the required state of input fields and the usual asterisk * is omitted, you may want to keep the label color consistent for fields that are valid in both checked and unchecked states. Pair the theming options with the renderAsRequired prop to achieve that:

React.createElement(() => {
  const [optional, setOptional] = React.useState(false);
  const [renderAsRequired, setRenderAsRequired] = React.useState(false);
  return (
    <React.Fragment>
      <style>
      {`
        .example {
          display: flex;
          flex-wrap: wrap;
          gap: 1rem 0.5rem;
        }

        .example--themed-form-fields {
          --rui-FormField__label__color: var(--rui-color-text-secondary);
          --rui-FormField--required__label__color: var(--rui-color-text-primary);
          --rui-FormField--required__sign: '';
        }
      `}
      </style>
      <div class="example example--themed-form-fields">
        <CheckboxField
          checked={optional}
          label="This field is optional"
          onChange={() => setOptional(!optional)}
        />
        <CheckboxField
          checked={renderAsRequired}
          label="This field is optional but looks like required"
          onChange={() => setRenderAsRequired(!renderAsRequired)}
          renderAsRequired
        />
      </div>
    </React.Fragment>
  );
});