Ir al contenido
Fundamentos

CopyButton

Copia un texto al portapapeles: el botón de ícono plain de 28, o texto e ícono. Pasa a ✓ durante 1,5 s, el tooltip dice «Copiado» y se anuncia.

import { CopyButton } from "sebs7n-ui/copy-button"

Ejemplos

Solo ícono

El botón `plain` de 28 de una barra de iCloud: copia, pasa a ✓ y el tooltip dice «Copiado».

import { CopyButton } from "sebs7n-ui/copy-button"
import { Field, FieldLabel, Input } from "sebs7n-ui"

function IconOnly() {
  return (
    <div className="flex w-full max-w-sm items-end gap-2">
      <Field className="flex-1">
        <FieldLabel>Link de pago</FieldLabel>
        <Input readOnly value="https://pagos.example.com/f/0012" />
      </Field>
      <CopyButton aria-label="Copiar el link de pago" className="mb-1" value="https://pagos.example.com/f/0012" />
    </div>
  )
}

Con texto

Un id corto que se copia entero: el texto es el nombre del botón.

import { CopyButton } from "sebs7n-ui/copy-button"

function WithText() {
  return (
    <p className="text-callout text-label-secondary">
      Factura{" "}
      <CopyButton className="font-mono" value="a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d">
        a1b2c3d4
      </CopyButton>
    </p>
  )
}

En línea

`variant="inline"`: el ID en mono chico con un ícono de 14, sin el alto de un botón, para una fila densa. Muestra los primeros ocho caracteres y copia el ID entero.

import { CopyButton } from "sebs7n-ui/copy-button"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "sebs7n-ui"

function Inline() {
  return (
    <Table className="max-w-lg" density="compact">
      <TableHeader>
        <TableRow>
          <TableHead>ID</TableHead>
          <TableHead>Cliente</TableHead>
          <TableHead className="text-right">Total</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {invoices.map((invoice) => (
          <TableRow key={invoice.id}>
            <TableCell>
              <CopyButton aria-label={`Copiar el ID ${invoice.id.slice(0, 8)}`} translate="no" value={invoice.id} variant="inline">
                {invoice.id.slice(0, 8)}
              </CopyButton>
            </TableCell>
            <TableCell>{invoice.client}</TableCell>
            <TableCell className="text-right tabular-nums">{invoice.total}</TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  )
}

Props

Generadas del TypeScript del paquete. Las propias del componente, más las heredadas del primitivo que tienen algo que explicar —marcadas «heredada de Base UI»—. El resto está en la línea «hereda de».

CopyButton

Hereda las props de <button>.

PropTipoPor defectoDescripción
value*string—El texto que se copia. Vacío apaga el botón.
disabledboolean—Apaga el botón. Un value vacío también.
labelsPartial<Labels["copyButton"]>—Textos: copy (nombre y tooltip), copied y failed (tooltip y anuncio).
onCopy(value: string) => void—Se llama después de copiar, con el texto copiado (no con el evento del portapapeles).
size"sm" | "md" | "lg""sm"28 (sm, default), 36 o 40: los altos de los botones.
variant"button" | "inline""button"inline: el dato en mono chico (12) con un ícono de 14 al lado, sin el alto de 28 de un botón: para IDs en filas densas de una tabla. Sin children muestra value. El feedback es el mismo.
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.

Teclado

Enter · Espacio
Copia.
Tab
Entra y sale, como cualquier botón.

Accesibilidad

  • Solo ícono se llama «Copiar» (labels.copy); mejor uno que diga qué copia: aria-label="Copiar el link de pago". Con children, el nombre es el texto.
  • Al copiar, una región viva (role="status") dice «Copiado»: el ✓ y el tooltip no se anuncian solos.
  • Si el portapapeles no deja copiar (contexto inseguro, permiso negado), el tooltip dice «No se pudo copiar» y se anuncia, sin ✓: el texto sigue a la vista para copiarlo a mano.

Reglas de uso

  • Al lado de un dato que se copia para pegarlo en otro lado: un CUIT, un número de factura, un link de pago. Para copiar desde adentro de un campo, InputGroupButton con el mismo ícono.
  • Con children reemplaza a un id corto que se copia entero: el texto visible puede ser el comienzo y value el id completo.
  • Adentro de una fila clickeable o de un link, copiar no abre la fila: el click no sube.
  • variant="inline" para IDs en filas densas: mono de 12 con un ícono de 14 y 24 de alto (no los 28 de un botón), mismo tooltip, ✓ y anuncio. Sin aria-label se llama «Copiar» y el valor («Copiar F-0012»). Con translate="no" el traductor del navegador no toca el ID.
  • Solo por subpath (sebs7n-ui/copy-button): no está en el barrel, por peso.

Relacionados