Ir al contenido
FundamentosServer Component

Tag

Un dato que puso el usuario y puede sacar: un filtro, una etiqueta, un destinatario.

import { Tag } from "sebs7n-ui/tag"

Ejemplos

Filtros aplicados

Un dato que puso el usuario: por eso se puede sacar.

import { Button } from "sebs7n-ui/button"
import { Tag } from "sebs7n-ui/tag"
import { useState } from "react"

function Filtros() {
  const [filtros, setFiltros] = useState(["Pendientes", "Acme S.A.", "Septiembre"])
  return (
    <div className="flex w-full flex-col items-start gap-3">
      <div aria-live="polite" className="flex min-h-6 flex-wrap items-center gap-2">
        {filtros.map((filtro) => (
          <Tag key={filtro} onRemove={() => setFiltros((previos) => previos.filter((otro) => otro !== filtro))}>
            {filtro}
          </Tag>
        ))}
        {filtros.length === 0 && <span className="text-callout text-label-secondary">Sin filtros</span>}
      </div>
      <Button disabled={filtros.length === 3} onClick={() => setFiltros(["Pendientes", "Acme S.A.", "Septiembre"])} size="sm" variant="secondary">
        Restaurar
      </Button>
    </div>
  )
}

Colores y tamaños

La misma paleta del Badge: el sistema tiene una sola forma de etiqueta.

import { Tag } from "sebs7n-ui/tag"

function ColoresYTamanos() {
  return (
    <div className="flex flex-col gap-3">
      <div className="flex flex-wrap items-center gap-2">
        <Tag onRemove={() => {}}>Sin color</Tag>
        <Tag color="brand" onRemove={() => {}}>
          Marca
        </Tag>
        <Tag color="green" onRemove={() => {}}>
          Cobrado
        </Tag>
        <Tag color="purple" onRemove={() => {}}>
          Diseño
        </Tag>
      </div>
      <div className="flex flex-wrap items-center gap-2">
        <Tag onRemove={() => {}} size="sm">
          Chico
        </Tag>
        <Tag size="sm">Sin quitar</Tag>
      </div>
    </div>
  )
}

Badge o Tag

El estado lo calculó el sistema y no se saca: Badge. El filtro lo puso el usuario: Tag.

import { Badge } from "sebs7n-ui/badge"
import { Tag } from "sebs7n-ui/tag"

function BadgeOTag() {
  return (
    <div className="flex flex-col gap-3 text-callout text-label-secondary">
      <div className="flex flex-wrap items-center gap-2">
        <span className="w-28">Estado:</span>
        <Badge color="green">Pagada</Badge>
        <Badge color="amber">Pendiente</Badge>
      </div>
      <div className="flex flex-wrap items-center gap-2">
        <span className="w-28">Filtros:</span>
        <Tag color="green" onRemove={() => {}}>
          Pagadas
        </Tag>
        <Tag onRemove={() => {}}>Últimos 30 días</Tag>
      </div>
    </div>
  )
}

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».

Tag

Hereda las props de <span>.

PropTipoPor defectoDescripción
color"brand" | "gray" | "red" | "amber" | "green" | "blue" | "teal" | "purple" | "pink""gray"Los mismos nueve tonos del Badge.
onRemove() => void—Qué hacer al quitar. Sin esto no aparece el botón — y sin botón, probablemente sea un Badge.
removeLabelstring | ((name: string) => string)"Quitar"Nombre del botón de quitar. Un string es el prefijo del dato («Quitar» → «Quitar Chile»); una función recibe el dato y devuelve la frase entera, que es lo único que sirve donde el verbo no va adelante: (name) => name + " entfernen".
size"sm" | "md""md"Las dos alturas del Badge: sm 16px · md 20px. El botón de quitar mide 12 y 16, con área de 24.
textValuestring—El texto del tag para el nombre del botón, cuando children no es texto.
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.

Teclado

Tab
Entra al botón de quitar. El cuerpo del tag no es interactivo.
Enter · Espacio
Quita el tag.

Accesibilidad

  • El botón de quitar siempre tiene nombre accesible: «Quitar Chile», armado con el texto del tag. Si children no es texto, pasale textValue; si el idioma no pone el verbo adelante, removeLabel acepta una función y arma la frase entera.
  • El cuerpo es un <span>: lo único enfocable es el botón, así que una lista de diez tags son diez paradas de tabulación, no veinte.
  • Quitar un tag saca el foco de la página. Devolvelo al contenedor de la lista o al control que los genera, y anunciá el cambio con una región aria-live si la lista es lo único que cambió.
  • El color no puede ser la única señal de nada: el texto del tag es el dato.
  • Sin "use client": sirve en un Server Component (aunque onRemove lo pasa, por definición, un componente cliente).

Reglas de uso

  • Badge informa, Tag es un dato. El Badge cuenta un estado que calculó el sistema y que el usuario no eligió ni puede sacar («Pagada», «Vencida», «Admin»). El Tag es algo que el usuario puso —un filtro aplicado, una etiqueta, un destinatario— y por eso se puede quitar. Si tiene ×, es Tag; si no se puede sacar, es Badge.
  • Comparte forma y paleta con Badge a propósito —sólido, sin borde, 4 px de radio—: el sistema tiene una sola forma de etiqueta. Lo que cambia es qué significa, no el radio.
  • Dentro de un Combobox múltiple ya está ComboboxChip, conectado al estado del combobox: ahí no va Tag.
  • size="sm" dentro de una fila de tabla; md suelto, arriba de una lista de resultados.
  • Si la etiqueta además filtra al hacer click en el cuerpo, eso es un Toggle, no un Tag con onClick.

Relacionados