Ir al contenido
Contenido y datos

Accordion

Secciones plegables como el disclosure de iCloud: filas de 44 con separador y un chevron › que gira. Una sola abierta, o varias.

import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "sebs7n-ui/accordion"

Ejemplos

Preguntas frecuentes

Una sola abierta a la vez: abrir otra cierra la anterior. Cada trigger vive dentro de un `<h3>`, que es lo que deja saltar de sección en sección con un lector de pantalla.

import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "sebs7n-ui/accordion"

function Basico() {
  return (
    <Accordion className="w-full max-w-lg" defaultValue={["facturacion"]}>
      <AccordionItem value="facturacion">
        <AccordionTrigger>¿Cuándo se emite la factura?</AccordionTrigger>
        <AccordionContent>
          El primer día hábil de cada mes, por el período vencido. Se envía al email de facturación y queda en
          Ajustes → Facturación.
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="cancelar">
        <AccordionTrigger>¿Se puede cancelar en cualquier momento?</AccordionTrigger>
        <AccordionContent>
          Sí. El plan sigue activo hasta el final del período ya pagado y no se renueva. No hay costo de baja.
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="datos">
        <AccordionTrigger>¿Qué pasa con mis datos si me doy de baja?</AccordionTrigger>
        <AccordionContent>
          Quedan disponibles para exportar durante 90 días. Después se borran, y eso no se puede deshacer.
        </AccordionContent>
      </AccordionItem>
      <AccordionItem disabled value="convenio">
        <AccordionTrigger>Facturación por convenio</AccordionTrigger>
        <AccordionContent>Solo para cuentas enterprise.</AccordionContent>
      </AccordionItem>
    </Accordion>
  )
}

Varias abiertas, con contenido a la derecha del título

`multiple` cuando comparar dos secciones es parte del uso. El trigger es un flex: lo que pongas antes del chevron se alinea solo.

import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "sebs7n-ui/accordion"
import { Badge } from "sebs7n-ui/badge"

function Multiple() {
  const secciones = [
    { id: "pendientes", titulo: "Pendientes", cantidad: 3, color: "amber" as const, detalle: "0012 Acme · 0014 Bruma · 0015 Cortina" },
    { id: "vencidas", titulo: "Vencidas", cantidad: 1, color: "red" as const, detalle: "0009 Delta, vencida el 12/08." },
    { id: "pagadas", titulo: "Pagadas este mes", cantidad: 8, color: "green" as const, detalle: "$ 1.284.000 acreditados." },
  ]
  return (
    <Accordion className="w-full max-w-lg" defaultValue={["pendientes", "vencidas"]} multiple>
      {secciones.map((seccion) => (
        <AccordionItem key={seccion.id} value={seccion.id}>
          <AccordionTrigger>
            <span className="flex items-center gap-2">
              {seccion.titulo}
              <Badge color={seccion.color} size="sm">
                {seccion.cantidad}
              </Badge>
            </span>
          </AccordionTrigger>
          <AccordionContent>{seccion.detalle}</AccordionContent>
        </AccordionItem>
      ))}
    </Accordion>
  )
}

Encontrable con ⌘F

`hiddenUntilFound` deja el contenido cerrado en el DOM y el buscador del navegador lo encuentra y abre la sección. Cuesta markup: se pone cuando ese texto es la razón por la que alguien llega a la página.

import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "sebs7n-ui/accordion"

function BuscableConElNavegador() {
  return (
    <Accordion className="w-full max-w-lg">
      <AccordionItem value="cuit">
        <AccordionTrigger>Datos fiscales</AccordionTrigger>
        <AccordionContent hiddenUntilFound>CUIT 30-71234567-8 · IVA Responsable Inscripto · IIBB Santa Fe.</AccordionContent>
      </AccordionItem>
      <AccordionItem value="domicilio">
        <AccordionTrigger>Domicilio</AccordionTrigger>
        <AccordionContent hiddenUntilFound>Av. Siempreviva 742, piso 3.</AccordionContent>
      </AccordionItem>
    </Accordion>
  )
}

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

Accordion

Hereda las props de Accordion.Root.

PropTipoPor defectoDescripción
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.
defaultValueAccordionValue<Value>—Heredada de Base UI. El valor inicial. Es la versión no controlada de value.
disabledboolean—Heredada de Base UI. Apaga la interacción y lo marca con data-disabled, que es el atributo del que cuelgan los estilos de apagado.
keepMountedboolean—Heredada de Base UI. Deja el contenido en el DOM mientras está cerrado, en vez de desmontarlo. Cuesta peso; sirve para que un crawler lo vea.
loopFocusboolean—Heredada de Base UI. Si al pasar del último elemento el foco vuelve al primero.
multipleboolean—Heredada de Base UI. Deja varias secciones abiertas a la vez.
onValueChange((value: AccordionValue<Value>, eventDetails: AccordionRootChangeEventDetails) => void)—Heredada de Base UI. Se llama con el valor nuevo cada vez que cambia.
orientation"horizontal" | "vertical"—Heredada de Base UI. horizontal (default) o vertical. Define qué flechas mueven el foco.
valueAccordionValue<Value>—Heredada de Base UI. Los value de las secciones abiertas, siempre un array. Pasarlo lo vuelve controlado.

AccordionContent

Hereda las props de Accordion.Panel.

PropTipoPor defectoDescripción
panelClassNamestring—Clases del panel que anima el alto. El className viaja al contenido, no acá.
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.

AccordionItem

Hereda las props de Accordion.Item.

PropTipoPor defectoDescripción
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.

AccordionTrigger

Hereda las props de Accordion.Trigger.

PropTipoPor defectoDescripción
chevronbooleantrueSaca el chevron para poner otro indicador.
headerClassNamestring—Clases del <h3> que envuelve al botón.
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.

Teclado

Enter · Espacio
Abre y cierra la sección enfocada.
Tab
Cada trigger es su propia parada: desde Base UI 1.8 no hay foco rotativo, siguiendo la corrección de la APG.

Accesibilidad

  • Cada trigger va dentro de un <h3>: eso es lo que deja saltar de sección en sección con un lector de pantalla.
  • aria-expanded y aria-controls los pone Base UI; el panel es un role="region" con el nombre del trigger.
  • El alto y el chevron pasan por motion-reduce, además del reset global del paquete.
  • hiddenUntilFound deja que el buscador del navegador (⌘F) encuentre y abra el contenido cerrado.

Reglas de uso

  • Una sola sección plegable es un `Collapsible`. El Accordion existe para el grupo.
  • Por defecto se abre una a la vez. multiple solo si comparar dos secciones es parte del uso.
  • El trigger dice de qué es la sección, no «Ver más».
  • No escondas ahí lo que la pantalla tiene que mostrar: lo plegado no se lee.
  • Si las secciones son excluyentes y cortas, probablemente sean Tabs.

Relacionados