El taller de componentes: los 100 componentes de Reflex
·
Resumen del curso
Diseño
·
Box
·
Flex
·
Stack
·
Grid
·
Container
·
Section
·
Center
·
Spacer
·
Separator
·
Card
·
Inset
·
Aspect Ratio
·
Fragment
Tipografía
·
Text
·
Heading
·
Link
·
Code
·
Markdown
·
Blockquote
·
Quote
·
Strong
·
Em
·
Kbd
Formularios
·
Button
·
Input
·
Text Area
·
Checkbox
·
Switch
·
Radio Group
·
Select
·
Slider
·
Form
·
Upload
Visualización de datos
·
Badge
·
Avatar
·
Icon
·
Callout
·
List
·
Data List
·
Code Block
·
Progress
·
Spinner
·
Scroll Area
·
Moment
Mostrar y ocultar
·
Tabs
·
Accordion
·
Segmented Control
Superposiciones
·
Tooltip
·
Popover
·
Hover Card
·
Dialog
·
Alert Dialog
·
Drawer
·
Dropdown Menu
·
Context Menu
·
Toast
Renderizado dinámico
·
Cond
·
Match
·
Foreach
·
Auto Scroll
Multimedia
·
Image
·
Audio
·
Video
Tablas y cuadrículas de datos
·
Table
·
Data Table
·
Data Editor
Gráficos
·
Area Chart
·
Bar Chart
·
Line Chart
·
Composed Chart
·
Pie Chart
·
Radar Chart
·
Radial Bar Chart
·
Scatter Chart
·
Funnel Chart
·
Treemap
·
Sankey Chart
·
Error Bar
Piezas de gráficos
·
Axis
·
Cartesian Grid
·
Chart Tooltip
·
Legend
·
Label
·
Reference
·
Brush
Otras bibliotecas de gráficos
·
Plotly
·
Pyplot
Elementos HTML
·
HTML
·
HTML Text
·
HTML Layout
·
HTML Forms
·
HTML Media
·
HTML Tables
·
SVG
Otras herramientas
·
Theme
·
Skeleton
·
Clipboard
·
Html Embed
·
Script
·
Memo
Pedido del taller
Sin sistema de diseño, solo con HTML puro, diseña tú una pequeña tarjeta de aviso con un botón de cerrar y un enlace.
rx.el contiene tal cual los elementos HTML del desarrollo web. rx.el.div se convierte en <div> y rx.el.button en <button>.
A diferencia de rx.button, basado en Radix, no tiene propiedades de aspecto como variant o size y aparece sin ningún estilo.
Este sitio tiene activado el reseteo básico de Tailwind (preflight), así que incluso el borde de los botones y la línea de las casillas de entrada desaparecen.
A plain paragraph.
rx.el.div(
rx.el.p("A plain paragraph."),
rx.el.button("A plain button"),
rx.el.input(placeholder="A plain input"),
)El aspecto se aplica directamente con propiedades de estilo (palabras clave con el nombre de la propiedad CSS escrito con guiones bajos). Cambia los valores y mira cómo cambia un botón desnudo.
Prueba las propiedades
label
background
color
padding
radius
weight
disabled
rx.el.button(
"Buy now",
background="#4f46e5",
color="white",
padding="8px 16px",
border_radius="6px",
font_weight="600",
disabled=False,
cursor="pointer",
)| Propiedad | Valores | Por defecto | Uso |
|---|---|---|---|
Propiedades CSS (padding, color …) | Valor CSS | Ninguno | Aplican estilo directamente como palabra clave |
class_name | Cadena de clases | Ninguno | Clases CSS, como las de Tailwind |
id title hidden role tab_index lang dir | Cadena · bool · int | Ninguno | Atributos HTML comunes a todos los elementos |
custom_attrs | dict | Ninguno | Atributos con - en el nombre, como aria-* o data-* |
type (button) | "submit" "reset" "button" | Navegador: "submit" | Qué hace al pulsarlo dentro de un formulario |
type (input) | "text" "email" "range" "date" … 22 tipos | "text" | Tipo de casilla de entrada |
value / on_change (input) | Cadena · número / evento | Ninguno | Casilla controlada. default_value es no controlada |
href target (a) | URL / "_blank" … | Ninguno | Dirección del enlace y dónde se abre |
on_click on_key_down … | Event handler | Ninguno | Eventos básicos de todos los elementos |
Propiedades de estilo con palabra clave, el diccionario style y clases CSS en class_name. Se pueden combinar las tres.
Si usas colores del tema, como rx.color("indigo", 3), el color se adapta también al modo oscuro.
rx.el.div(
rx.el.div(
"Style props",
padding="12px",
border=f"1px solid {rx.color('indigo', 7)}",
border_radius="8px",
background=rx.color("indigo", 3),
),
rx.el.div(
"style dict",
style={"padding": "12px", "border": "1px dashed gray", "border_radius": "8px"},
),
rx.el.div(
"Tailwind classes",
class_name="p-3 rounded-lg border-2 border-dotted font-semibold",
),
display="flex",
gap="12px",
flex_wrap="wrap",
)title es el tooltip básico que aparece al pasar el ratón, hidden oculta, dir es la dirección del texto y tab_index, el orden de la tecla Tab.
Los atributos con guion en el nombre, como aria-label o data-kind, se pasan con custom_attrs.
Right to left
rx.el.div(
rx.el.span("Hover me", title="A native tooltip", text_decoration="underline dotted"),
rx.el.span("You cannot see me", hidden=True),
rx.el.p("Right to left", dir="rtl", lang="en"),
rx.el.div(
"Focus me with Tab",
tab_index=0,
role="note",
custom_attrs={"aria-label": "Demo note", "data-kind": "demo"},
padding="8px",
border="1px solid gray",
border_radius="6px",
),
display="flex",
flex_direction="column",
gap="8px",
)Cambiar el State con on_click funciona igual que en rx.button. Dentro de un formulario, type es importante.
Si no lo indicas, toma el valor por defecto del navegador, "submit", y el formulario se envía al pulsarlo; por eso los botones normales se escriben con type="button".
name·value son valores que se envían junto con el formulario, y los atributos form_*, como form_action o form_method, cambian la configuración del formulario solo para ese botón.
class HtmlElButtonState(rx.State):
count: int = 0
@rx.event
def add_one(self):
self.count += 1
rx.el.div(
rx.el.button(
"Add one",
type="button",
on_click=HtmlElButtonState.add_one,
padding="6px 14px",
border="1px solid gray",
border_radius="6px",
cursor="pointer",
),
rx.el.button("Disabled", disabled=True, padding="6px 14px", border="1px solid gray", border_radius="6px", opacity="0.5"),
rx.el.span("Count: ", HtmlElButtonState.count),
display="flex",
gap="12px",
align_items="center",
)Si das value y on_change a la vez, es una casilla controlada cuyo valor guarda el State. rx.el.input tiene además los eventos on_change, on_key_down y on_key_up.
on_key_down pasa el nombre de la tecla pulsada, así que abajo se muestra la última tecla. type="range" lo convierte en un slider.
Hello, (last key: )
Level: 40
class HtmlElInputState(rx.State):
name: str = ""
level: int = 40
last_key: str = ""
@rx.event
def change_name(self, value: str):
self.name = value
@rx.event
def change_level(self, value: float):
self.level = int(value)
@rx.event
def remember_key(self, key: str):
self.last_key = key
rx.el.div(
rx.el.input(
type="text",
value=HtmlElInputState.name,
on_change=HtmlElInputState.change_name,
on_key_down=HtmlElInputState.remember_key,
placeholder="Your name",
max_length=20,
padding="6px 10px",
border="1px solid gray",
border_radius="6px",
),
rx.el.p("Hello, ", HtmlElInputState.name, " (last key: ", HtmlElInputState.last_key, ")"),
rx.el.input(
type="range",
min=0,
max=100,
step=5,
value=HtmlElInputState.level,
on_change=HtmlElInputState.change_level,
),
rx.el.p("Level: ", HtmlElInputState.level),
display="flex",
flex_direction="column",
gap="8px",
max_width="320px",
)Con solo type se obtienen casillas de fecha, color, checkbox, correo o número. Para dar solo un valor inicial sin State, usa default_value·default_checked.
Los atributos de validación como required, min·max, pattern o max_length los comprueba el navegador al enviar el formulario.
rx.el.div(
rx.el.input(type="date"),
rx.el.input(type="color", default_value="#6e56cf"),
rx.el.label(rx.el.input(type="checkbox", default_checked=True), " Remember me"),
rx.el.input(type="email", placeholder="you@example.com", required=True, border="1px solid gray", padding="4px 8px"),
rx.el.input(type="number", min=1, max=9, default_value=3, border="1px solid gray", padding="4px 8px", width="80px"),
display="flex",
gap="12px",
flex_wrap="wrap",
align_items="center",
)p es un párrafo y ocupa toda la línea; span es un fragmento que se queda dentro de la línea de texto. div es una caja sin significado que sirve para agrupar cualquier cosa.
A p is a block. A span stays inside the line.
rx.el.div(
rx.el.p(
"A p is a block. A ",
rx.el.span("span", color=rx.color("tomato", 11), font_weight="bold"),
" stays inside the line.",
),
rx.el.div("A div is a box with no meaning.", padding="8px", background=rx.color("gray", 3)),
)En Reflex 0.10, rx.el.a se renderiza como el Link de React Router, y href se traslada internamente a to.
Por eso las direcciones internas del sitio, como "/", navegan sin recargar la página, mientras que las externas se abren como un enlace normal.
Para navegar recargando, reload_document=True; para sustituir la entrada del historial, replace=True; para el efecto de transición, view_transition=True. download hace que se descargue como archivo.
rx.el.div(
rx.el.a(
"Reflex docs (new tab)",
href="https://reflex.dev/docs/library/html/html/",
target="_blank",
rel="noopener noreferrer",
color=rx.color("indigo", 11),
text_decoration="underline",
),
rx.el.a("Home page", href="/", color=rx.color("indigo", 11), text_decoration="underline"),
display="flex",
gap="16px",
)rx.el tiene más de 100 elementos. Los elementos de texto, la estructura del documento, los formularios, los medios, las tablas y SVG se tratan por grupos en las cinco páginas siguientes.
El badge se hace con span, el texto con p y las acciones con a y button, todo decorado con propiedades de estilo. Al cerrar, el State oculta la tarjeta.
class HtmlElNoticeState(rx.State):
visible: bool = True
@rx.event
def dismiss(self):
self.visible = False
@rx.event
def show_again(self):
self.visible = True
rx.cond(
HtmlElNoticeState.visible,
rx.el.div(
rx.el.p(
rx.el.span(
"New",
background=rx.color("indigo", 9),
color="white",
padding="2px 8px",
border_radius="999px",
font_size="12px",
margin_right="8px",
),
"Version 2 is out.",
font_weight="600",
),
rx.el.p("Read what changed before you update.", color=rx.color("gray", 11), margin_y="6px"),
rx.el.div(
rx.el.a(
"Release notes",
href="https://reflex.dev/docs/",
target="_blank",
rel="noopener noreferrer",
color=rx.color("indigo", 11),
text_decoration="underline",
),
rx.el.button(
"Dismiss",
type="button",
on_click=HtmlElNoticeState.dismiss,
padding="4px 12px",
border=f"1px solid {rx.color('gray', 7)}",
border_radius="6px",
cursor="pointer",
),
display="flex",
gap="16px",
align_items="center",
),
padding="16px",
border=f"1px solid {rx.color('indigo', 6)}",
border_radius="10px",
background=rx.color("indigo", 2),
max_width="360px",
),
rx.el.button("Show again", on_click=HtmlElNoticeState.show_again, text_decoration="underline", cursor="pointer"),
)Notas del taller
rx.el.<etiqueta> es el elemento HTML tal cual, sin estilos. El aspecto se aplica con propiedades CSS de palabra clave, style o class_name.
title·hidden·dir·tab_index·role son comunes a todos los elementos. aria-*·data-*, con custom_attrs.
Un rx.el.button dentro de un formulario es submit por defecto. Para un botón normal, type="button".
rx.el.input se controla con value + on_change; sin control, con default_value. on_key_down pasa la tecla pulsada.
En 0.10, rx.el.a es un Link de React Router: href pasa a ser to y dentro del sitio navega sin recargar.
Recibe avisos de nuevas lecciones
Te avisaremos por correo cuando este curso tenga lecciones nuevas o se abra un curso de continuación.
R
ReflexKR
Aprende Python y Reflex haciendo. Todos los ejemplos se ejecutaron y verificaron en Reflex 0.10.0.
ReflexKR es gratis y sin banners publicitarios. Si te ayudó, puedes apoyarlo con un café. ☕ Invítanos un café
Aviso de afiliados© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
Preguntas y respuestas
Pregunta lo que quieras sobre esta lección. Aquí se reúnen las preguntas de todas las versiones de idioma de esta página.