R

ReflexKR

Reflex Docs

The Component Workshop: Reflex's 100 Library Components

·

Course overview

Layout

·

Box

·

Flex

·

Stack

·

Grid

·

Container

·

Section

·

Center

·

Spacer

·

Separator

·

Card

·

Inset

·

Aspect Ratio

·

Fragment

Typography

·

Text

·

Heading

·

Link

·

Code

·

Markdown

·

Blockquote

·

Quote

·

Strong

·

Em

·

Kbd

Forms

·

Button

·

Input

·

Text Area

·

Checkbox

·

Switch

·

Radio Group

·

Select

·

Slider

·

Form

·

Upload

Data display

·

Badge

·

Avatar

·

Icon

·

Callout

·

List

·

Data List

·

Code Block

·

Progress

·

Spinner

·

Scroll Area

·

Moment

Disclosure

·

Tabs

·

Accordion

·

Segmented Control

Overlay

·

Tooltip

·

Popover

·

Hover Card

·

Dialog

·

Alert Dialog

·

Drawer

·

Dropdown Menu

·

Context Menu

·

Toast

Dynamic rendering

·

Cond

·

Match

·

Foreach

·

Auto Scroll

Media

·

Image

·

Audio

·

Video

Tables and data grids

·

Table

·

Data Table

·

Data Editor

Charts

·

Area Chart

·

Bar Chart

·

Line Chart

·

Composed Chart

·

Pie Chart

·

Radar Chart

·

Radial Bar Chart

·

Scatter Chart

·

Funnel Chart

·

Treemap

·

Sankey Chart

·

Error Bar

Chart parts

·

Axis

·

Cartesian Grid

·

Chart Tooltip

·

Legend

·

Label

·

Reference

·

Brush

Other chart libraries

·

Plotly

·

Pyplot

HTML elements

·

HTML

·

HTML Text

·

HTML Layout

·

HTML Forms

·

HTML Media

·

HTML Tables

·

SVG

Other tools

·

Theme

·

Skeleton

·

Clipboard

·

Html Embed

·

Script

·

Memo

The Component Workshop: Reflex's 100 Library Components
Forms

Checkbox

rx.checkbox

Official docs

Workshop order

Add an "I agree to the terms" checkbox to the sign-up screen. The sign-up button must stay disabled until it is checked.

rx.checkbox takes a single on/off value. Use it wherever the answer is yes or no: agreeing to terms, "don't show this again", picking several items from a list. Pass text as the first argument and a label appears next to the box; clicking the label checks the box too.

rx.checkbox("Basic Checkbox")

Try the props

Try the props

text

size

variant

color

spacing

high_contrast

disabled

rx.checkbox("Remember me", size="2", variant="surface", color_scheme="indigo", spacing="2", high_contrast=False, disabled=False)
size changes both the box and the label text; spacing is the gap between the box and the label.
PropValuesDefaultUse
first argument (text)string""Label next to the box
checkedTrue / False / VarnoneControlled value (with on_change)
default_checkedTrue / FalseFalseValue set only once at the start (uncontrolled)
size"1" – "3""2"Size of box and label
variant"classic" "surface" "soft""surface"Look
color_scheme, high_contrastRadix color name / Truetheme valueChecked color and contrast
spacing"0" – "9""2"Gap between box and label
disabled, requiredTrue / FalseFalseDisable; must be checked to submit
name, valuestringnone / "on"Name and value on form submit
on_changeeventWhen the check changes. Passes True/False

Getting the value with on_change

Every time you click, on_change passes the new value (True or False). No checked is given here, so the browser holds the box's state and the State just records the value it receives.

false

class CheckboxBasicState(rx.State):
    checked: bool = False

    @rx.event
    def set_checked(self, value: bool):
        self.checked = value


rx.vstack(
    rx.heading(CheckboxBasicState.checked.to_string(), size="5"),
    rx.checkbox("Click me", on_change=CheckboxBasicState.set_checked),
)

Controlled checkbox: checked + on_change

Give checked a State value and the box always shows that value. When the user clicks, on_change updates the State, and if a button or another checkbox updates the State, the box follows. The official docs call this the input prop in their prose, but in 0.10 the prop is named checked.

class CheckboxControlState(rx.State):
    apples: bool = True
    pears: bool = False

    @rx.event
    def set_apples(self, value: bool):
        self.apples = value

    @rx.event
    def set_pears(self, value: bool):
        self.pears = value

    @rx.event
    def set_all(self, value: bool):
        self.apples = value
        self.pears = value


rx.vstack(
    rx.checkbox(
        "All fruits",
        checked=CheckboxControlState.apples & CheckboxControlState.pears,
        on_change=CheckboxControlState.set_all,
    ),
    rx.checkbox("Apples", checked=CheckboxControlState.apples, on_change=CheckboxControlState.set_apples, margin_left="1.5em"),
    rx.checkbox("Pears", checked=CheckboxControlState.pears, on_change=CheckboxControlState.set_pears, margin_left="1.5em"),
    rx.hstack(
        rx.button("Check all", on_click=CheckboxControlState.set_all(True), size="1", variant="soft"),
        rx.button("Clear", on_click=CheckboxControlState.set_all(False), size="1", variant="soft", color_scheme="gray"),
    ),
)

Initial value and disabled

If you don't need State and just want to set the initial state, use default_checked (uncontrolled). With disabled=True it can't be clicked.

rx.flex(
    rx.checkbox("Starts checked", default_checked=True),
    rx.checkbox("Starts empty"),
    rx.checkbox("Locked on", default_checked=True, disabled=True),
    spacing="4",
    wrap="wrap",
)

Using it in a form

Inside a form, name becomes the key in the submitted data. Only checked boxes are sent, as "on" (or the value you gave); unchecked boxes are left out entirely. That's why the handler reads them like form_data.get("news"). A box with required=True must be checked before the form submits.

The official docs' form example passes the text with label=, but in 0.10 the label of rx.checkbox is the first argument (text).

Results:

{}
class CheckboxFormState(rx.State):
    form_data: dict = {}

    @rx.event
    def handle_submit(self, form_data: dict):
        self.form_data = form_data


rx.card(
    rx.vstack(
        rx.form.root(
            rx.vstack(
                rx.checkbox("Accept terms and conditions", name="terms", required=True),
                rx.checkbox("Send me news", name="news", value="yes"),
                rx.button("Submit", type="submit"),
            ),
            on_submit=CheckboxFormState.handle_submit,
            reset_on_submit=True,
        ),
        rx.divider(),
        rx.hstack(rx.text("Results:", weight="bold"), rx.badge(CheckboxFormState.form_data.to_string())),
    ),
)

Filling the order

The State holds the agreement through checked, and the sign-up button is disabled with disabled=~CheckboxSignupState.agreed until the user agrees. ~ negates a Var (not).

class CheckboxSignupState(rx.State):
    agreed: bool = False
    done: bool = False

    @rx.event
    def set_agreed(self, value: bool):
        self.agreed = value
        self.done = False

    @rx.event
    def sign_up(self):
        self.done = True


rx.card(
    rx.vstack(
        rx.checkbox(
            "I agree to the Terms of Service",
            checked=CheckboxSignupState.agreed,
            on_change=CheckboxSignupState.set_agreed,
        ),
        rx.button("Sign up", on_click=CheckboxSignupState.sign_up, disabled=~CheckboxSignupState.agreed),
        rx.cond(CheckboxSignupState.done, rx.badge("Welcome aboard!", color_scheme="green")),
        spacing="3",
    ),
)

Workshop notes

  • Create it with rx.checkbox("Label"); on_change passes True/False.

  • To control it, use checked + on_change; to set only the initial value, use default_checked.

  • In a form, only checked boxes are sent, as name: "on" (or value). Read missing keys with .get().

  • size, variant, color_scheme and spacing set the look; required makes it a submit condition.

← Previous

Forms · Text Area

Next →

Forms · Switch

Get news about new lessons

We'll email you when this course gets new lessons or a follow-up course opens.

We collect: your email address · Purpose: news about new lessons or the launch of this course · Kept until: you ask us to remove it. We never use it for anything else or share it. Reply to any notice email and we'll delete it right away.

Questions & answers

Ask anything about this lesson. Questions from every language version of this page appear together.

Shown as plain text, without links or formatting.

R

ReflexKR

Learn Python and Reflex by doing. Every example was run and verified on Reflex 0.10.0.

ReflexKR is free, with no banner ads. If it helped you, you can support it with a coffee. ☕ Buy us a coffee

Affiliate disclosure
한국어English日本語简体中文EspañolDeutsch

© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0

Built with Reflex