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
Al pulsar el botón «Comentar» bajo una publicación, abre una ventanita en ese mismo lugar para escribir un comentario breve sin salir de la página.
rx.popover es una ventanita que aparece junto a un botón al pulsarlo. A diferencia del tooltip, se abre con un clic y puede contener elementos con los que interactuar, como campos de texto o botones. Se construye con cuatro partes.
popover.root: envuelve todas las partes del popover.popover.trigger: envuelve el botón que abre y cierra el popover.popover.content: el contenido que aparece al abrirse.popover.close: envuelve un botón que cierra el popover al pulsarlo.rx.popover.root(
rx.popover.trigger(
rx.button("Popover"),
),
rx.popover.content(
rx.flex(
rx.text("Simple Example"),
rx.popover.close(
rx.button("Close"),
),
direction="column",
spacing="3",
),
),
)La posición y el tamaño van en popover.content; el modo modal, en popover.root. Cambia un valor y pulsa Open para comprobarlo.
Prueba las propiedades
text
size
side
align
modal
rx.popover.root(
rx.popover.trigger(rx.button("Open")),
rx.popover.content(
rx.flex(
rx.text("Simple Example"),
rx.popover.close(rx.button("Close", size="1")),
direction="column",
spacing="3",
),
size="2",
side="bottom",
align="center",
),
modal=False,
)| Parte | Propiedad | Valores | Uso |
|---|---|---|---|
root | open | True / False | Decidir la apertura desde el State (controlado). Junto con on_open_change |
root | default_open | True / False | Abierto en el primer renderizado (no controlado) |
root | modal | True / False | Bloquea la interacción exterior mientras está abierto y oculta el resto a los lectores de pantalla |
root | on_open_change | Evento | Al abrirse o cerrarse. Pasa el nuevo valor de apertura (bool) |
content | size | "1" ~ "4" | Tamaño del relleno y de las esquinas |
content | side · align | Nombre de posición | Lado en el que aparece y alineación (por defecto "bottom", "center") |
content | side_offset · align_offset | Número (px) | Separación con el botón y desplazamiento extra desde la alineación |
content | avoid_collisions · collision_padding | bool · número | Moverse al chocar con el borde de la pantalla y ese margen |
content | sticky · hide_when_detached | "partial" "always" · bool | Cuánto sigue pegado al hacer scroll; ocultarse si el botón queda tapado |
content | on_open_auto_focus · on_close_auto_focus | Evento | Cuando el foco entra al abrirse o vuelve al botón al cerrarse |
content | on_escape_key_down · on_pointer_down_outside | Evento | Tecla Esc, pulsar fuera |
content | on_focus_outside · on_interact_outside | Evento | Cuando el foco o la interacción salen fuera |
trigger y close no tienen propiedades propias; solo aceptan los eventos comunes (on_click, etc.).
Dentro de un popover cabe cualquier cosa. Esta es una ventana de comentarios con un campo de texto, una casilla y un botón de enviar junto al avatar. Si envuelves el botón de enviar con popover.close, la ventana se cierra en cuanto lo pulsas. El ancho se da directamente en content, como style={"width": 360}.
rx.popover.root(
rx.popover.trigger(
rx.button("Comment", variant="soft"),
),
rx.popover.content(
rx.flex(
rx.avatar("2", fallback="RX", radius="full"),
rx.box(
rx.text_area(placeholder="Write a comment…", style={"height": 80}),
rx.flex(
rx.checkbox("Send to group"),
rx.popover.close(rx.button("Comment", size="1")),
spacing="3",
margin_top="12px",
justify="between",
),
flex_grow="1",
),
spacing="3",
),
style={"width": 360},
),
)Si pones rx.inset(side="top") como primer hijo de content, puedes añadir una imagen de cabecera que llegue hasta el borde, sin el relleno superior del popover.
rx.popover.root(
rx.popover.trigger(
rx.button("Feedback", variant="classic"),
),
rx.popover.content(
rx.inset(
side="top",
background="url('https://picsum.photos/id/29/720/200') center/cover",
height="100px",
),
rx.box(
rx.text_area(placeholder="Write a comment…", style={"height": 80}),
rx.flex(
rx.checkbox("Send to group"),
rx.popover.close(rx.button("Comment", size="1")),
spacing="3",
margin_top="12px",
justify="between",
),
padding_top="12px",
),
style={"width": 360},
),
)Para usar un valor del State como texto del botón, envuélvelo una vez en rx.text, como en rx.button(rx.text(State.valor)). La documentación oficial advierte que pasarlo directamente, como en rx.button(State.valor), no funciona como se espera. Elige un idioma abajo y verás cambiar el texto del botón.
class PopoverLanguageState(rx.State):
language: str = "EN"
@rx.event
def set_language(self, value: str):
self.language = value
rx.popover.root(
rx.popover.trigger(
rx.button(rx.text(PopoverLanguageState.language), variant="outline"),
),
rx.popover.content(
rx.flex(
rx.popover.close(rx.button("EN", size="1", variant="soft", on_click=PopoverLanguageState.set_language("EN"))),
rx.popover.close(rx.button("KO", size="1", variant="soft", on_click=PopoverLanguageState.set_language("KO"))),
rx.popover.close(rx.button("JA", size="1", variant="soft", on_click=PopoverLanguageState.set_language("JA"))),
spacing="2",
),
),
)El on_open_change de popover.root pasa True al handler cuando se abre y False cuando se cierra.
Opened or closed: 0 times
Popover open: no
class PopoverEventState(rx.State):
num_opens: int = 0
opened: bool = False
@rx.event
def count_opens(self, value: bool):
self.opened = value
self.num_opens += 1
rx.flex(
rx.text("Opened or closed: ", PopoverEventState.num_opens, " times"),
rx.text("Popover open: ", rx.cond(PopoverEventState.opened, "yes", "no")),
rx.popover.root(
rx.popover.trigger(
rx.button("Popover"),
),
rx.popover.content(
rx.flex(
rx.text("Simple Example"),
rx.popover.close(
rx.button("Close"),
),
direction="column",
spacing="3",
),
),
on_open_change=PopoverEventState.count_opens,
),
direction="column",
spacing="3",
align="start",
)Si conectas open y on_open_change a la vez, el botón del lápiz y el clic fuera funcionan como siempre, y además el código puede cerrar la ventana. Abajo, cambia el nombre y pulsa Rename: el handler guarda el valor y cierra la ventana con self.open = False. Cada vez que se abre, el campo se vuelve a rellenar con el nombre actual.
class PopoverControlState(rx.State):
open: bool = False
name: str = "Untitled"
draft: str = ""
@rx.event
def set_open(self, value: bool):
self.open = value
if value:
self.draft = self.name
@rx.event
def set_draft(self, value: str):
self.draft = value
@rx.event
def rename(self):
self.name = self.draft.strip() or "Untitled"
self.open = False
rx.flex(
rx.heading(PopoverControlState.name, size="4"),
rx.popover.root(
rx.popover.trigger(rx.icon_button(rx.icon("pencil"), variant="soft", size="1", aria_label="Rename")),
rx.popover.content(
rx.flex(
rx.input(value=PopoverControlState.draft, on_change=PopoverControlState.set_draft),
rx.button("Rename", size="1", on_click=PopoverControlState.rename),
spacing="2",
),
),
open=PopoverControlState.open,
on_open_change=PopoverControlState.set_open,
),
align="center",
spacing="3",
)Una ventanita de comentarios que se abre desde el botón «Comentar» bajo la publicación. side="top" hace que se abra hacia arriba y align="start" la alinea con el borde izquierdo del botón.
Shipping is now free over $30.
rx.card(
rx.text("Shipping is now free over $30.", size="2"),
rx.popover.root(
rx.popover.trigger(rx.button(rx.icon("message-circle"), "Comment", variant="ghost", size="1", margin_top="8px")),
rx.popover.content(
rx.flex(
rx.text_area(placeholder="Write a comment…", rows="3"),
rx.flex(
rx.popover.close(rx.button("Cancel", size="1", variant="soft", color_scheme="gray")),
rx.popover.close(rx.button("Post", size="1")),
spacing="2",
justify="end",
),
direction="column",
spacing="2",
),
side="top",
align="start",
width="300px",
),
),
max_width="360px",
)Notas del taller
Se construye con cuatro partes: root · trigger · content · close. Se abre al pulsar trigger y se cierra con close o pulsando fuera.
Posición y tamaño en content (side, align, side_offset, size); el modo modal en root (modal).
Para usar un valor del State como texto del botón trigger, envuélvelo en rx.text.
on_open_change pasa el nuevo valor de apertura (bool). Si lo controlas con open, el handler puede cerrar la ventana.
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.