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
Workshop order
On the recipe page, show the ingredients as a bulleted list and the steps as a numbered list.
rx.list stacks items from top to bottom. When order doesn't matter, use the bulleted rx.list.unordered (HTML ul); when it does, use the numbered rx.list.ordered (HTML ol). Each item is an rx.list.item (HTML li).
rx.flex(
rx.list.unordered(
rx.list.item("Example 1"),
rx.list.item("Example 2"),
rx.list.item("Example 3"),
),
rx.list.ordered(
rx.list.item("Example 1"),
rx.list.item("Example 2"),
rx.list.item("Example 3"),
),
spacing="6",
)For a numbered list you can change the marker style and count backwards. The starting number start is covered in a section below.
Try the props
list_style_type
reversed
rx.list.ordered(
rx.list.item("Preheat the oven"),
rx.list.item("Mix the batter"),
rx.list.item("Bake for 30 minutes"),
list_style_type="decimal",
reversed=False,
)| Prop | Applies to | Values | Default | Use |
|---|---|---|---|---|
list_style_type | All three lists | Bullets: "disc" "circle" "square" "none", numbers: "decimal" "lower-roman" "upper-alpha" … | "none" for list, "disc" for unordered, "decimal" for ordered | The leading marker |
items | All three lists | List (State values too) | None | Pass the item texts all at once instead of children |
start | ordered | Integer | 1 | First number |
reversed | ordered | True / False | False | Count the numbers backwards |
type | ordered | "1" "a" "A" "i" "I" | None | HTML numbering type; usually you use list_style_type instead |
Bulleted lists take CSS values like "disc" (default), "circle" and "square"; numbered lists take "decimal" (default), "upper-roman", "lower-alpha" and so on. unordered and ordered leave 1.5rem of space on the left for the markers.
rx.flex(
rx.list.unordered(rx.list.item("disc"), rx.list.item("disc"), list_style_type="disc"),
rx.list.unordered(rx.list.item("circle"), rx.list.item("circle"), list_style_type="circle"),
rx.list.unordered(rx.list.item("square"), rx.list.item("square"), list_style_type="square"),
rx.list.ordered(rx.list.item("upper-roman"), rx.list.item("upper-roman"), list_style_type="upper-roman"),
rx.list.ordered(rx.list.item("lower-alpha"), rx.list.item("lower-alpha"), list_style_type="lower-alpha"),
spacing="5",
wrap="wrap",
)start sets the first number, which is handy when one list continues the numbering of another. reversed=True counts down from the highest number. Even with letter markers (upper-alpha), start=3 begins at C.
rx.flex(
rx.list.ordered(rx.list.item("Seven"), rx.list.item("Eight"), rx.list.item("Nine"), start=7),
rx.list.ordered(rx.list.item("Three"), rx.list.item("Two"), rx.list.item("One"), reversed=True),
rx.list.ordered(rx.list.item("Alpha"), rx.list.item("Bravo"), list_style_type="upper-alpha", start=3),
spacing="6",
wrap="wrap",
)list_style_type="none" removes both bullets and numbers. That is practically the same as a plain rx.list(), which has no markers, except that unordered and ordered keep their left padding. The official docs say lists are built on flex and inherit all of its props, but in Reflex 0.10 lists are plain HTML elements and only gap gets special handling.
rx.hstack(
rx.list(
rx.list.item("Example 1"),
rx.list.item("Example 2"),
rx.list.item("Example 3"),
),
rx.list.unordered(
rx.list.item("Example 1"),
rx.list.item("Example 2"),
rx.list.item("Example 3"),
list_style_type="none",
),
spacing="6",
)Remove the markers and put an icon in front of each item, and you have a checklist. Icons inside rx.list.item automatically get display: inline so they sit on the same line as the text.
rx.list(
rx.list.item(rx.icon("circle_check_big", color="green"), " Allowed"),
rx.list.item(rx.icon("octagon_x", color="red"), " Not"),
rx.list.item(rx.icon("settings", color="grey"), " Settings"),
list_style_type="none",
)Instead of writing children one by one, pass a list to items and an rx.list.item is created for each entry. Pass a State value and rx.foreach is used under the hood, so the list follows when the value changes.
class ListTodoState(rx.State):
todos: list[str] = ["Buy milk", "Walk the dog"]
new_todo: str = ""
@rx.event
def set_list_new_todo(self, value: str):
self.new_todo = value
@rx.event
def add_list_todo(self):
if self.new_todo.strip():
self.todos = self.todos + [self.new_todo.strip()[:40]]
self.new_todo = ""
@rx.event
def clear_list_todos(self):
self.todos = []
rx.vstack(
rx.hstack(
rx.input(value=ListTodoState.new_todo, on_change=ListTodoState.set_list_new_todo, placeholder="New item"),
rx.button("Add", on_click=ListTodoState.add_list_todo),
rx.button("Clear", on_click=ListTodoState.clear_list_todos, variant="soft", color_scheme="gray"),
),
rx.list.ordered(items=ListTodoState.todos),
)Ingredients have no order, so they get a bulleted list; the steps depend on order, so they get a numbered list.
Ingredients
Steps
rx.flex(
rx.box(
rx.text("Ingredients", weight="bold"),
rx.list.unordered(
rx.list.item("2 eggs"),
rx.list.item("200 g flour"),
rx.list.item("1 cup milk"),
),
),
rx.box(
rx.text("Steps", weight="bold"),
rx.list.ordered(
rx.list.item("Whisk the eggs and milk."),
rx.list.item("Fold in the flour."),
rx.list.item("Cook on a hot pan."),
),
),
spacing="6",
wrap="wrap",
)Workshop notes
Unordered lists use rx.list.unordered, ordered lists rx.list.ordered, and items rx.list.item.
list_style_type changes the marker; "none" removes it (the default for rx.list).
ordered has start (first number) and reversed (count backwards).
Pass items all at once with items=[…] or items=State.some_list.
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.