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
rx.auto_scrollDocumentación oficial
Pedido del taller
Crea una ventana de chat de atención al cliente. Cuando llegue un mensaje nuevo debe bajar hasta el final, pero si el usuario ha subido para leer la conversación anterior, no debe arrastrarlo hacia abajo.
rx.auto_scroll es una caja (div) que se desplaza sola hasta abajo cuando se añade contenido nuevo. Se usa con contenido que se va acumulando por abajo, como chats, logs o feeds, para tener siempre a la vista lo más reciente. No hace falta escribir código para gestionar la posición del scroll.
class AutoScrollBasicState(rx.State):
messages: list[str] = ["Initial message"]
count: int = 1
@rx.event
def add_message(self):
self.count += 1
self.messages = (self.messages + [f"New message #{self.count}"])[-50:]
rx.vstack(
rx.auto_scroll(
rx.foreach(
AutoScrollBasicState.messages,
lambda message: rx.box(
message,
padding="0.5em",
border_bottom=f"1px solid {rx.color('gray', 4)}",
width="100%",
),
),
height="200px",
width="300px",
border=f"1px solid {rx.color('gray', 6)}",
border_radius="8px",
),
rx.button("Add Message", on_click=AutoScrollBasicState.add_message),
width="300px",
align_items="center",
)Cada vez que pulsas Add Message se añade un mensaje, y cuando la caja empieza a desbordarse baja sola para que se vea el mensaje nuevo.
rx.auto_scroll se basa en rx.el.div, así que acepta todas las propiedades y estilos de un div. Como es una caja con scroll, lo más importante es height. La caja de abajo contiene veinte líneas y desde el principio se ve la última (Line 20). Aunque reduzcas la altura para que se desborde, sigue mostrando la parte de abajo.
Prueba las propiedades
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
Line 10
Line 11
Line 12
Line 13
Line 14
Line 15
Line 16
Line 17
Line 18
Line 19
Line 20
height
padding
radius
rx.auto_scroll(
*[rx.text("Line " + str(i), size="2") for i in range(1, 21)],
height="160px",
padding="8px",
border_radius="8px",
border=f"1px solid {rx.color('gray', 6)}",
width="260px",
)| Propiedad | Valores | Por defecto | Uso |
|---|---|---|---|
height | Longitud CSS | Ninguno | Altura de la caja con scroll. Sin ella, crece con el contenido y no aparece scroll |
width | Longitud CSS | Ninguno | Ancho |
overflow | Valor CSS | "auto" | Qué hacer con el contenido que desborda. Por defecto, scroll |
padding, border, border_radius | Valor CSS | Ninguno | Relleno interior, borde, esquinas |
id | Cadena | Automático | Si no das uno, se asigna automáticamente un id único |
| Resto de propiedades de div | title, role, on_click … | Igual que rx.el.div |
Cuando se añade contenido, solo baja hasta el final en estos dos casos:
Por eso, si el usuario ha subido para leer contenido anterior, no lo arrastra a la fuerza hacia abajo. Sube en la caja de logs de abajo y pulsa Add 10: la posición se mantiene. Vuelve a bajar del todo y púlsalo de nuevo: ahora sí baja.
import random
class AutoScrollLogState(rx.State):
lines: list[str] = []
count: int = 0
@rx.event
def add(self, n: int):
levels = ["INFO", "INFO", "INFO", "WARN", "ERROR"]
new = []
for _ in range(n):
self.count += 1
new.append(f"{self.count:04d} {random.choice(levels)} request handled")
self.lines = (self.lines + new)[-100:]
@rx.event
def clear(self):
self.lines = []
self.count = 0
rx.vstack(
rx.auto_scroll(
rx.foreach(AutoScrollLogState.lines, lambda line: rx.text(line, size="1", font_family="var(--code-font-family)")),
height="160px",
width="100%",
padding="8px 10px",
background=rx.color("gray", 2),
border=f"1px solid {rx.color('gray', 6)}",
border_radius="8px",
),
rx.hstack(
rx.button("Add 1", on_click=AutoScrollLogState.add(1), size="1"),
rx.button("Add 10", on_click=AutoScrollLogState.add(10), size="1", variant="soft"),
rx.button("Clear", on_click=AutoScrollLogState.clear, size="1", variant="soft", color_scheme="gray"),
),
width="100%",
max_width="420px",
)Se da display="flex" y flex_direction="column" a rx.auto_scroll para apilar los bocadillos en vertical, y rx.cond cambia la alineación y el color según quién envía. Al mandar un mensaje se añaden el tuyo y la respuesta, y la ventana baja con ellos. Si has subido para leer, se queda donde está.
class AutoScrollChatState(rx.State):
messages: list[dict[str, str]] = [{"who": "bot", "text": "Hi! Ask me about your order."}]
@rx.event
def send(self, form_data: dict):
text = form_data.get("text", "").strip()[:200]
if not text:
return
reply = {"who": "bot", "text": f"Got it: {text}"}
self.messages = (self.messages + [{"who": "me", "text": text}, reply])[-40:]
rx.vstack(
rx.auto_scroll(
rx.foreach(
AutoScrollChatState.messages,
lambda m: rx.flex(
rx.box(
m["text"],
padding="6px 10px",
border_radius="12px",
max_width="80%",
background=rx.cond(m["who"] == "me", rx.color("indigo", 9), rx.color("gray", 4)),
color=rx.cond(m["who"] == "me", "white", rx.color("gray", 12)),
),
justify=rx.cond(m["who"] == "me", "end", "start"),
width="100%",
),
),
display="flex",
flex_direction="column",
gap="6px",
height="240px",
width="100%",
padding="10px",
border=f"1px solid {rx.color('gray', 6)}",
border_radius="10px",
),
rx.form(
rx.hstack(
rx.input(name="text", placeholder="Type a message", flex="1", auto_complete=False),
rx.button(rx.icon("send", size=16), type="submit", aria_label="Send"),
width="100%",
),
on_submit=AutoScrollChatState.send,
reset_on_submit=True,
width="100%",
),
width="100%",
max_width="360px",
)Notas del taller
rx.auto_scroll(...) es un div que baja hasta el final cuando aparece contenido nuevo.
Dale siempre height. overflow="auto" ya viene por defecto.
Solo baja si estás cerca del final (50px) o si aparece por primera vez la barra de scroll.
No arrastra hacia abajo a quien ha subido para leer. Ideal para chats, logs y feeds.
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.