React Clean UI
Form

Checkbox

A clickable checkbox control with configurable icons, intents, spacing, and scale.

Checkbox demonstration

The Checkbox component allows users to toggle a boolean value.

It can be used uncontrolled, managing its own state from an optional defaultChecked starting value, or controlled, showing whatever you pass as checked. It can also show its own clickable text label.

When used inside a Fieldset, clicking the fieldset label also toggles the checkbox.

Import

import { Checkbox } from "@rbxts/react-clean-ui";

Basic usage

Loom Previewv0.13.2

The checkbox starts unchecked by default.

Behaviour change in 2.0.0

Passing checked now makes the checkbox controlled: it always shows the prop's value, and a click only calls onChange(!checked). A checked without an onChange that feeds the new value back leaves the checkbox frozen. onChange also no longer fires on mount or when the checked prop changes, only when the user toggles it. Use defaultChecked for the old "initial value only" behaviour, and read the initial value yourself if you relied on the mount-time onChange call.

Uncontrolled

Leave checked unset and the checkbox keeps its own state. Use defaultChecked to choose the starting value.

<Checkbox defaultChecked />
<Checkbox
    defaultChecked={true}
    onChange={(checked) => {
        print(`Checked: ${checked}`);
    }}
/>

defaultChecked is only read when the checkbox mounts. Changing it later has no effect.

Controlled

Pass checked to drive the checkbox from your own state. Clicking it calls onChange with the requested value but changes nothing by itself, so feed the value back through checked.

import React, { useState } from "@rbxts/react";
import { Checkbox } from "@rbxts/react-clean-ui";

export function ControlledCheckbox() {
    const [checked, setChecked] = useState(false);

    return (
        <Checkbox
            checked={checked}
            onChange={setChecked}
        />
    );
}

Because the visual always follows checked, you can also reject or change the value in onChange, or update checked from elsewhere. Changing checked from outside does not call onChange.

With a label

Set label to show text next to the box. Clicking the text toggles the checkbox, the same as clicking the box.

Loom Previewv0.13.2

The label text uses the theme typography for the checkbox's scale, and the gap between box and label is half the checkbox's resolved spacing at that scale, rounded up. Both can be changed through theme.components.checkbox.label (see Theme values). For richer label content, such as rich text or other components, use a Fieldset instead.

With a fieldset

Use Fieldset.Control and Fieldset.Label to associate the checkbox with a label.

<Fieldset checkbox>
    <Fieldset.Control>
        <Checkbox
            onChange={(checked) => {
                print(`Checked: ${checked}`);
            }}
        />
    </Fieldset.Control>

    <Fieldset.Label>
        <Text text="Receive email notifications" />
    </Fieldset.Label>
</Fieldset>

When the user clicks either the checkbox or its label, the checked state will toggle.

Scale and spacing

The scale prop controls the size of the checkbox icon.

The spacing prop controls the internal padding around the icon.

<Fieldset checkbox>
    <Fieldset.Control>
        <Checkbox
            scale="xl"
            spacing="xl"
        />
    </Fieldset.Control>

    <Fieldset.Label>
        <Text text="<b>xl</b> Scale and Spacing" />
    </Fieldset.Label>
</Fieldset>

Scale and spacing can be configured independently.

<Fieldset checkbox>
    <Fieldset.Control>
        <Checkbox
            scale="xs"
            spacing="xl"
        />
    </Fieldset.Control>

    <Fieldset.Label>
        <Text text="<b>xs</b> Scale with <b>xl</b> Spacing" />
    </Fieldset.Label>
</Fieldset>

Custom icons

Use icon-checked and icon-unchecked to customise the icon displayed for each state.

<Checkbox
    icon-checked="thumbs-up"
    icon-unchecked="thumbs-down"
/>

If icon-unchecked is omitted, no icon is displayed while the checkbox is unchecked.

Checked and unchecked intents

The appearance of each state can be configured independently.

<Checkbox
    icon-checked="thumbs-up"
    icon-unchecked="thumbs-down"
    intent-checked="info"
    intent-unchecked="danger"
/>

The selected intent controls the border and icon colours for each state.

Complete example

<Fieldset checkbox>
    <Fieldset.Control>
        <Checkbox
            defaultChecked
            icon-checked="thumbs-up"
            icon-unchecked="thumbs-down"
            intent-checked="info"
            intent-unchecked="danger"
            onChange={(checked) => {
                print(`Checked: ${checked}`);
            }}
        />
    </Fieldset.Control>

    <Fieldset.Label>
        <Text text="Enable advanced mode" />
    </Fieldset.Label>
</Fieldset>

Props

Checkbox-specific props

PropTypeDefaultDescription
checkedbooleanundefinedControlled checked state. When set, the checkbox always shows this value.
defaultCheckedbooleanfalseStarting state when uncontrolled (checked unset). Only read on mount.
onChange(value: boolean) => voidundefinedCalled with the new value when the user toggles the checkbox. Never called on mount or when checked changes.
labelstringundefinedText shown next to the box. Clicking it toggles the checkbox.
namestring"Checkbox"Name of the root instance.
icon-checkedIconName"check"Icon displayed while checked.
icon-uncheckedIconNameundefinedIcon displayed while unchecked.
intent-checkedIntent"success"Intent used for the checked border and icon colours.
intent-uncheckedIntent"primary"Intent used for the unchecked border and icon colours.

Shared props

The checkbox also supports props inherited from the following interfaces.

InterfacePurpose
IntentElementPropsConfigures the checkbox's base background intent, independent of intent-checked/intent-unchecked.
PaddingPropsConfigures individual padding values.
BackgroundElementPropsConfigures background colour and transparency.
SpacedElementPropsConfigures theme-based internal spacing.
ScalableElementPropsConfigures the icon scale.

Behaviour

  • The checkbox is unchecked by default.
  • With checked set, the checkbox is controlled: it shows checked, and a click calls onChange(!checked) without changing anything internally. Without checked, it starts at defaultChecked and flips its own state on each click before calling onChange.
  • Clicking the box, its label, or a paired Fieldset.Label toggles the checkbox.
  • onChange only fires in response to a user toggle. It never fires on mount, and never fires when a controlled checked prop changes.
  • Without label, the checkbox renders a single ImageButton named by name. With label, the root becomes a transparent, content-sized Frame named by name, holding the box (renamed "CheckboxBox") and a "CheckboxLabel" button with the text. The label button is not gamepad-selectable, so gamepad selection stays on the box.
  • Setting or clearing label after mount remounts the box.

The state transitions follow this pattern:

false → true → false

Theme values

The checkbox uses values from theme.components.checkbox for:

  • Corner radius
  • Border thickness and transparency
  • Border and icon colours, based on the checked/unchecked intent
  • Default spacing/padding
  • Background image
  • The optional label styling:
    • label.typography — merged over the theme typography for the checkbox's scale
    • label.textColor — the label text colour; unset uses Text's default text colour
    • label.gap — the gap between box and label, in pixels; unset uses half the resolved spacing at the checkbox's scale, rounded up

No shipped theme sets checkbox.label.

const theme = createTheme({
    components: {
        checkbox: {
            label: {
                textColor: Color3.fromHex("#9CA3AF"),
                gap: 12,
            },
        },
    },
});

The solid background colour (based on the intent prop's default state) and background transparency fall back to the values from theme.components.button.

GitHub Repository

On this page