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.el.svgrx.el.svg.circlerx.el.svg.defsrx.el.svg.linear_gradientrx.el.svg.polygonrx.el.svg.pathrx.el.svg.rectrx.el.svg.stopOfficial docs
Workshop order
One verified-badge graphic: a star on a gradient circle with a check mark on top, drawn in code without any image file.
SVG is vector graphics drawn with coordinates. It never gets blurry no matter how large you make it, and you can change shapes and colors in code.
rx.el.svg is the canvas, and the shapes inside it live in the rx.el.svg namespace, as in rx.el.svg.circle and rx.el.svg.rect.
rx.el.svg(
rx.el.svg.circle(cx=50, cy=50, r=40, fill=rx.color("indigo", 9)),
view_box="0 0 100 100",
width="100",
height="100",
)Shapes get their form from position and size attributes, and their color from fill and stroke. The values are numbers in the view_box coordinate system.
Try the props
rect_width
corner
radius
fill
stroke
stroke_width
rx.el.svg(
rx.el.svg.rect(
x="10",
y="10",
width="100",
height="80",
rx="10",
fill="#6e56cf",
stroke="none",
stroke_width="4",
),
rx.el.svg.circle(cx="160", cy="50", r="35", fill="#6e56cf", fill_opacity="0.6", stroke="none", stroke_width="4"),
view_box="0 0 220 100",
width="264",
height="120",
)| Prop | Values | Default | Use |
|---|---|---|---|
view_box width height (svg) | "0 0 100 100" / length | none | The drawing's coordinate system and its on-screen size |
preserve_aspect_ratio (svg) | "xMidYMid meet" "none" … | "xMidYMid meet" | How to fit when the aspect ratios differ |
cx cy r (circle) | number | 0 | Center and radius |
x y width height rx ry (rect) | number | 0 | Position, size, corners. Giving only rx sets ry to match |
points (polygon) | "x,y x,y …" | none | List of vertices. The shape closes automatically |
d (path) | path commands | none | M move, L line, Q/C curves, Z close |
path_length (all shapes) | number | actual length | Treat the stroke length as this value (for dash calculations) |
id x1 y1 x2 y2 (linear_gradient) | string, number | left → right | Gradient name and direction |
gradient_units gradient_transform spread_method href (linear_gradient) | string | none | Coordinate basis, transform, edge handling, inherit from another gradient |
offset stop_color stop_opacity (stop) | "0%"–"100%" / color / 0–1 | none | Where a color sits, and the color |
fill stroke stroke_width … | color, number | black fill | Not shape attributes; they go in as CSS (see below) |
view_box="0 0 100 100" means "the inner coordinates are 100 wide and 100 tall", while width and height are the size on screen. The same drawing stays sharp at any size.
When the aspect ratios differ, it is scaled down and centered by default; with preserve_aspect_ratio="none" it is stretched to fill (the third drawing).
rx.el.div(
rx.el.svg(
rx.el.svg.rect(x=0, y=0, width=100, height=100, fill=rx.color("gray", 4)),
rx.el.svg.circle(cx=50, cy=50, r=30, fill=rx.color("tomato", 9)),
view_box="0 0 100 100",
width="60",
height="60",
),
rx.el.svg(
rx.el.svg.rect(x=0, y=0, width=100, height=100, fill=rx.color("gray", 4)),
rx.el.svg.circle(cx=50, cy=50, r=30, fill=rx.color("tomato", 9)),
view_box="0 0 100 100",
width="120",
height="120",
),
rx.el.svg(
rx.el.svg.rect(x=0, y=0, width=100, height=100, fill=rx.color("gray", 4)),
rx.el.svg.circle(cx=50, cy=50, r=30, fill=rx.color("tomato", 9)),
view_box="0 0 100 100",
preserve_aspect_ratio="none",
width="200",
height="80",
),
display="flex",
gap="16px",
align_items="end",
)rect, circle and polygon are the shapes in the official docs, and Reflex 0.10 also includes elements such as ellipse, line, polyline, g and text.
In 0.10, fill, stroke and stroke_width aren't in the shapes' attribute lists, so they go in as CSS. SVG color attributes work the same way as CSS, so the result is identical, and you can use theme colors like rx.color(...) too.
rx.el.svg(
rx.el.svg.rect(x=10, y=20, width=60, height=60, rx=12, fill=rx.color("teal", 9)),
rx.el.svg.circle(cx=120, cy=50, r=30, fill=rx.color("amber", 9)),
rx.el.svg.polygon(points="200,20 230,80 170,80", fill=rx.color("crimson", 9)),
rx.el.svg.ellipse(cx=290, cy=50, rx=40, ry=22, fill=rx.color("blue", 9)),
rx.el.svg.line(x1=10, y1=95, x2=330, y2=95, stroke="gray", stroke_width=2),
view_box="0 0 340 100",
width="340",
height="100",
)Chain commands in d. M10 80 moves the pen, Q draws a quadratic curve, and T continues the previous curve smoothly. To draw only the line, use fill="none".
path_length=100 treats the length as 100, which makes it easy to calculate dashes such as stroke_dasharray="10 5" as proportions.
rx.el.svg(
rx.el.svg.path(
d="M10 80 Q 55 10, 100 80 T 190 80",
fill="none",
stroke=rx.color("indigo", 9),
stroke_width=4,
),
rx.el.svg.path(
d="M10 95 L 190 95",
path_length=100,
stroke="gray",
stroke_width=3,
stroke_dasharray="10 5",
),
view_box="0 0 200 100",
width="300",
height="150",
)Whatever you put in defs isn't drawn directly; it becomes a material you refer to by name (id). x1/y1 → x2/y2 on linear_gradient is the direction, and each stop is where a color sits.
Give a shape's fill "url(#id)" and it is painted with the gradient. Choose ids that don't clash anywhere on the page.
rx.el.svg(
rx.el.svg.defs(
rx.el.svg.linear_gradient(
rx.el.svg.stop(offset="0%", stop_color="#6e56cf"),
rx.el.svg.stop(offset="100%", stop_color="#e54d2e", stop_opacity="0.8"),
id="htmlsvg_sunset",
x1="0",
y1="0",
x2="1",
y2="1",
),
),
rx.el.svg.rect(x=0, y=0, width=200, height=100, rx=16, fill="url(#htmlsvg_sunset)"),
view_box="0 0 200 100",
width="240",
height="120",
)Put State values into a shape's attributes and the drawing follows the data. The bars' x is calculated from the second argument of rx.foreach (the index).
import random
class HtmlSvgBarState(rx.State):
values: list[int] = [40, 75, 55, 90, 30]
@rx.event
def shuffle(self):
self.values = [random.randint(10, 95) for _ in self.values]
rx.el.div(
rx.el.svg(
rx.foreach(
HtmlSvgBarState.values,
lambda v, i: rx.el.svg.rect(x=i * 40 + 10, y=100 - v, width=28, height=v, rx=4, fill=rx.color("grass", 9)),
),
view_box="0 0 210 100",
width="210",
height="100",
),
rx.el.button("Shuffle", on_click=HtmlSvgBarState.shuffle, padding="4px 12px", border="1px solid gray", border_radius="6px", margin_top="8px"),
)The circle is painted with the gradient from defs, the star is a polygon with 10 vertices, and the check on top is a path with rounded ends.
rx.el.svg(
rx.el.svg.defs(
rx.el.svg.linear_gradient(
rx.el.svg.stop(offset="0%", stop_color="#3e63dd"),
rx.el.svg.stop(offset="100%", stop_color="#12a594"),
id="htmlsvg_badge",
x1="0",
y1="0",
x2="0",
y2="1",
),
),
rx.el.svg.circle(cx=60, cy=60, r=56, fill="url(#htmlsvg_badge)"),
rx.el.svg.polygon(points="60,18 70,44 98,46 76,63 84,90 60,75 36,90 44,63 22,46 50,44", fill="#ffd60a"),
rx.el.svg.path(d="M44 62 L56 74 L78 50", fill="none", stroke="white", stroke_width=6, stroke_linecap="round", stroke_linejoin="round"),
view_box="0 0 120 120",
width="120",
height="120",
)Workshop notes
rx.el.svg is the canvas: view_box is the inner coordinates, width and height the size on screen.
Shapes are rx.el.svg.rect, circle, polygon and path; 0.10 also has ellipse, line, g and text.
In 0.10, fill and stroke go in as CSS, but the result is the same. Theme colors via rx.color work too.
Gradients are defs > linear_gradient(id) > stop, used with fill="url(#id)".
Put State values in attributes and build shapes with rx.foreach to get a data graphic.
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.