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
Data display

Progress

rx.progress

Official docs

Workshop order

While a file is being sent, show how far it has got as a bar, and turn it green when it's done.

rx.progress shows as a bar how far a long-running or multi-step task has got. Give value a number between 0 and 100. By default it takes 100% of its parent's width.

rx.vstack(
    rx.progress(value=0),
    rx.progress(value=50),
    rx.progress(value=100),
    width="50%",
)

Try the props

value and max only take integers, so they aren't in this lab. An example that moves the progress value is under "Driving it with State" below.

Try the props

size

variant

color

radius

high_contrast

rx.progress(value=60, size="2", variant="surface", color_scheme="indigo", radius="full", high_contrast=False)
size picks the thickness, variant the track style and color_scheme the color.
PropValuesDefaultUse
valueIntegerNoneCurrent progress; without it, the bar keeps moving
maxInteger100The value when full
size"1" "2" "3""2"Bar thickness
variant"classic" "surface" "soft""surface"Track style
color_schemeRadix color nameTheme colorFill color
high_contrastTrue / FalseFalseStronger contrast
radius"none" "small" "medium" "large" "full"Theme valueCorner rounding
durationA time such as "5s"NoneTime to fill up when there is no value
fill_colorCSS colorNoneSets the color of the filled part directly

Counting steps with max

Change max and you can count value in steps. Step 3 of 5 is value=3, max=5.

3 of 5 steps

rx.vstack(
    rx.text("3 of 5 steps"),
    rx.progress(value=3, max=5),
    width="50%",
)

Driving it with State

To change the progress, pass a State value to value. Move the slider and the bar follows.

30%

class ProgressSliderState(rx.State):
    value: int = 30

    @rx.event
    def set_progress_value(self, value: list[float]):
        self.value = int(value[0])


rx.vstack(
    rx.slider(default_value=[30], on_change=ProgressSliderState.set_progress_value),
    rx.progress(value=ProgressSliderState.value),
    rx.text(ProgressSliderState.value, "%"),
    width="50%",
)

For work that takes time, like a real task, raise the value bit by bit in a background event (@rx.event(background=True)). Each State change must happen inside async with self: so it reaches the screen right away. This example adds 5 every 0.1 seconds and finishes in 2 seconds; clicking again while it runs is ignored.

import asyncio


class ProgressLiveState(rx.State):
    value: int = 0
    running: bool = False

    @rx.event(background=True)
    async def start_progress(self):
        async with self:
            if self.running:
                return
            self.running = True
            self.value = 0
        while self.value < 100:
            await asyncio.sleep(0.1)
            async with self:
                self.value += 5
        async with self:
            self.running = False


rx.hstack(
    rx.progress(value=ProgressLiveState.value),
    rx.button("Start", on_click=ProgressLiveState.start_progress, loading=ProgressLiveState.running),
    width="60%",
    align="center",
)

When the amount is unknown

Without value, the bar becomes an endless back-and-forth animation. Use it for waits where you don't know how much is left. With duration, the bar pretends to fill up over that time, then switches to the endless animation once the time is up.

No value: endless animation

duration="5s": fills in 5 seconds, then keeps moving

rx.vstack(
    rx.text("No value: endless animation", size="2"),
    rx.progress(),
    rx.text('duration="5s": fills in 5 seconds, then keeps moving', size="2"),
    rx.progress(duration="5s"),
    width="60%",
)

Choosing the fill color yourself

fill_color sets the color of the filled part directly as a CSS color. Use it when you need a color that isn't among the Radix color names.

rx.vstack(
    rx.progress(value=70, fill_color="orange"),
    rx.progress(value=40, fill_color="#2e8b57"),
    width="50%",
)

Filling the order

Click the button and a background event raises the bar 10% at a time; once full, the status text becomes "Done" and the bar turns green. No real file is sent.

report.pdf

0%

Ready

import asyncio


class ProgressUploadState(rx.State):
    percent: int = 0
    status: str = "Ready"

    @rx.event(background=True)
    async def send_files(self):
        async with self:
            if self.status == "Uploading...":
                return
            self.status = "Uploading..."
            self.percent = 0
        for _ in range(10):
            await asyncio.sleep(0.2)
            async with self:
                self.percent += 10
        async with self:
            self.status = "Done"


rx.card(
    rx.vstack(
        rx.hstack(rx.icon("upload"), rx.text("report.pdf", weight="bold"), rx.spacer(), rx.text(ProgressUploadState.percent, "%"), width="100%", align="center"),
        rx.progress(value=ProgressUploadState.percent, color_scheme=rx.cond(ProgressUploadState.status == "Done", "green", "indigo")),
        rx.hstack(
            rx.text(ProgressUploadState.status, size="2", color_scheme="gray"),
            rx.spacer(),
            rx.button("Upload", size="1", on_click=ProgressUploadState.send_files),
            width="100%",
            align="center",
        ),
        width="100%",
    ),
    max_width="360px",
)

Workshop notes

  • rx.progress(value=…) is a 0–100 progress bar; max changes the scale.

  • Pass a State value to value; for long tasks, raise it in a background event with async with self.

  • No value means an endless animation; with duration, it fills up over that time.

  • Shape it with size · variant · color_scheme · radius · high_contrast; fill_color sets the fill color.

← Previous

Data display · Code Block

Next →

Data display · Spinner

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