R

ReflexKR

Documentación de Reflex

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

El taller de componentes: los 100 componentes de Reflex
Otras herramientas

Clipboard

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",
)

Pruébalo pegando

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",
)
PropiedadValoresPor defectoUso
on_pasteEvent handlerNingunoRecibe una lista de tuplas (tipo MIME, datos)
targetsLista de id de elementosLos hijos; sin hijos, todo el documentoElementos en los que se escucha el pegado
.stop_propagationAcción de eventoNingunoEvita que llegue a los gestores de pegado exteriores
.prevent_defaultAcción de eventoNingunoImpide el comportamiento por defecto de pegar de verdad en la casilla

La forma de los datos

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().

Recibir en toda la página

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",
    )

Pegado con alcance limitado

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",
)

targets: indicar por id sin envolver

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",
)

Completar el pedido

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.

Bug report

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.

← Anterior

Otras herramientas · Skeleton

Siguiente →

Otras herramientas · Html Embed

Recibe avisos de nuevas lecciones

Te avisaremos por correo cuando este curso tenga lecciones nuevas o se abra un curso de continuación.

Datos: tu correo electrónico · Finalidad: avisos de nuevas lecciones o de la publicación de este curso · Conservación: hasta que pidas que lo borremos. No lo usamos para nada más ni lo compartimos. Responde a cualquier aviso y lo borraremos enseguida.

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.

Se muestra como texto plano, sin enlaces ni formato.

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
한국어English日本語简体中文EspañolDeutsch

© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0

Built with Reflex