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
rx.progressOfficial 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%",
)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)| Prop | Values | Default | Use |
|---|---|---|---|
value | Integer | None | Current progress; without it, the bar keeps moving |
max | Integer | 100 | The value when full |
size | "1" "2" "3" | "2" | Bar thickness |
variant | "classic" "surface" "soft" | "surface" | Track style |
color_scheme | Radix color name | Theme color | Fill color |
high_contrast | True / False | False | Stronger contrast |
radius | "none" "small" "medium" "large" "full" | Theme value | Corner rounding |
duration | A time such as "5s" | None | Time to fill up when there is no value |
fill_color | CSS color | None | Sets the color of the filled part directly |
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%",
)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",
)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%",
)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%",
)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.
Get news about new lessons
We'll email you when this course gets new lessons or a follow-up course opens.
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© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
Questions & answers
Ask anything about this lesson. Questions from every language version of this page appear together.