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.clipboardDocumentación oficial
Pedido del taller
Añade al formulario de informe de errores una zona en la que, con solo pegar una captura de pantalla, la imagen quede adjuntada al momento.
rx.clipboard recibe el evento de pegar (paste) y pasa al State el contenido pegado, separado por tipos. Acepta no solo texto, sino también datos binarios como imágenes.
Es un componente transparente que no dibuja nada en pantalla y escucha los pegados que ocurren en los hijos que envuelve. Está incluido desde Reflex 0.5.6.
class ClipboardBasicState(rx.State):
items: list[str] = []
@rx.event
def on_paste(self, data: list[tuple[str, str]]):
self.items = [f"{mime_type}: {item[:60]}" for mime_type, item in data]
rx.vstack(
rx.clipboard(
rx.input(placeholder="Copy some text, then paste here"),
on_paste=ClipboardBasicState.on_paste,
),
rx.foreach(ClipboardBasicState.items, lambda line: rx.code(line, size="1")),
width="100%",
max_width="420px",
)rx.clipboard no tiene propiedades visibles, así que en lugar de un banco de pruebas lo vemos con un ejemplo que reacciona al pegar.
Si pegas texto llega text/plain; si pegas texto copiado de una página web, también text/html, y si pegas una imagen, un tipo como image/png.
Paste events: 0
class ClipboardTypesState(rx.State):
count: int = 0
types: list[str] = []
@rx.event
def on_paste(self, data: list[tuple[str, str]]):
self.count += 1
self.types = [mime_type for mime_type, _ in data]
rx.card(
rx.clipboard(
rx.text_area(placeholder="Paste text, an image, or a copied web page", rows="3"),
on_paste=ClipboardTypesState.on_paste,
),
rx.text("Paste events: ", ClipboardTypesState.count, size="2", margin_top="8px"),
rx.flex(rx.foreach(ClipboardTypesState.types, lambda t: rx.badge(t)), spacing="2", wrap="wrap", margin_top="6px"),
max_width="420px",
)| Propiedad | Valores | Por defecto | Uso |
|---|---|---|---|
on_paste | Event handler | Ninguno | Recibe una lista de tuplas (tipo MIME, datos) |
targets | Lista de id de elementos | Los hijos; sin hijos, todo el documento | Elementos en los que se escucha el pegado |
.stop_propagation | Acción de evento | Ninguno | Evita que llegue a los gestores de pegado exteriores |
.prevent_default | Acción de evento | Ninguno | Impide el comportamiento por defecto de pegar de verdad en la casilla |
El data que recibe on_paste es una lista de tuplas (mime_type, data). El texto llega tal cual como cadena,
y los datos binarios como imágenes llegan como data URI codificado en base64 (data:image/png;base64,...). Esa cadena se puede poner directamente en el src de rx.image,
y si en el servidor necesitas los bytes, puedes decodificarla en Python con urllib.request.urlopen(data_uri).read().
Si pones solo rx.clipboard(), sin hijos, se engancha al evento paste del documento y se ejecuta peguen donde peguen en la página.
Si lo pusiéramos así en esta página capturaría también los pegados de los demás ejemplos, así que el ejemplo de la documentación oficial se muestra solo como código.
class ClipboardPasteState(rx.State):
@rx.event
def on_paste(self, data: list[tuple[str, str]]):
for mime_type, item in data:
yield rx.toast(f"Pasted {mime_type} data: {item}")
def clipboard_example():
return rx.fragment(
rx.clipboard(on_paste=ClipboardPasteState.on_paste), # no children: listens for paste on the whole document
"Paste Content Here",
)Para recibir pegados solo en un elemento concreto, envuelve ese elemento con rx.clipboard. Si fuera hay un gestor para toda la página, usa .stop_propagation para que el evento no suba.
Con .prevent_default, el texto no llega a pegarse en la casilla. Prueba a pegar texto en la segunda casilla: se queda vacía.
No image yet. Copy an image (or take a screenshot) and paste above.
class ClipboardImageState(rx.State):
last_image_uri: str = ""
@rx.event
def on_paste(self, data: list[tuple[str, str]]):
for mime_type, item in data:
if mime_type.startswith("image/"):
if len(item) > 2_000_000:
return rx.toast("This image is too large for the demo")
self.last_image_uri = item
break
else:
return rx.toast("Did not find an image in the pasted data")
rx.vstack(
rx.clipboard(
rx.input(placeholder="Paste Image (stop propagation)"),
on_paste=ClipboardImageState.on_paste.stop_propagation,
),
rx.clipboard(
rx.input(placeholder="Paste Image (prevent default)"),
on_paste=ClipboardImageState.on_paste.prevent_default,
),
rx.cond(
ClipboardImageState.last_image_uri != "",
rx.image(src=ClipboardImageState.last_image_uri, alt="Image pasted from clipboard", max_width="240px", border_radius="6px"),
rx.text("No image yet. Copy an image (or take a screenshot) and paste above.", size="2", color_scheme="gray"),
),
width="100%",
max_width="420px",
)Si das a targets el id de un elemento, escucha solo ese elemento sin necesidad de envolverlo. Cuando envuelves hijos, Reflex les asigna un id y rellena targets automáticamente.
Pasted characters: 0
class ClipboardTargetState(rx.State):
pasted_chars: int = 0
@rx.event
def on_paste(self, data: list[tuple[str, str]]):
self.pasted_chars += sum(len(item) for mime_type, item in data if mime_type == "text/plain")
rx.vstack(
rx.clipboard(on_paste=ClipboardTargetState.on_paste, targets=["clipboard_target_note"]),
rx.text_area(id="clipboard_target_note", placeholder="Only this box is watched", rows="2"),
rx.input(placeholder="This box is not watched"),
rx.text("Pasted characters: ", ClipboardTargetState.pasted_chars, size="2"),
width="100%",
max_width="420px",
)Haz clic en la caja de borde discontinuo para darle el foco y pega una captura: la imagen queda adjuntada. La caja no es una casilla de entrada, así que recibe el foco gracias a tab_index=0,
y las acciones de evento se encadenan como .prevent_default.stop_propagation. La imagen entra en el State como data URI, así que se descartan las imágenes demasiado grandes.
Click here, then paste a screenshot (Ctrl + V)
class ClipboardTicketState(rx.State):
shot: str = ""
note: str = ""
@rx.event
def on_paste(self, data: list[tuple[str, str]]):
for mime_type, item in data:
if mime_type.startswith("image/") and len(item) <= 2_000_000:
self.shot = item
return
return rx.toast("Paste a screenshot (an image) here")
@rx.event
def change_note(self, value: str):
self.note = value
@rx.event
def clear_shot(self):
self.shot = ""
rx.card(
rx.heading("Bug report", size="3"),
rx.text_area(
value=ClipboardTicketState.note,
on_change=ClipboardTicketState.change_note,
placeholder="What went wrong?",
rows="2",
margin_y="8px",
),
rx.clipboard(
rx.box(
rx.cond(
ClipboardTicketState.shot != "",
rx.image(src=ClipboardTicketState.shot, alt="Pasted screenshot", max_height="160px"),
rx.text("Click here, then paste a screenshot (Ctrl + V)", size="2", color_scheme="gray"),
),
tab_index=0,
padding="16px",
border=f"2px dashed {rx.color('gray', 7)}",
border_radius="8px",
text_align="center",
),
on_paste=ClipboardTicketState.on_paste.prevent_default.stop_propagation,
),
rx.button("Remove screenshot", on_click=ClipboardTicketState.clear_shot, variant="soft", color_scheme="gray", size="1", margin_top="8px"),
max_width="420px",
)Notas del taller
rx.clipboard(hijo, on_paste=...) escucha los pegados que ocurren en el hijo. Sin hijos, en todo el documento.
on_paste recibe [(mime_type, data), ...]. Los datos binarios llegan como data URI en base64.
Un data URI se puede usar directamente en el src de rx.image.
.stop_propagation evita que llegue a los gestores exteriores; .prevent_default impide el pegado real.
Con targets=[id, ...] escucha solo elementos concretos sin envolverlos.
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.