Skip to content

Accordion Nuevo ​

El componente hp-accordion implementa el patrón WAI-ARIA Accordion, permitiendo crear interfaces de acordeón accesibles con múltiples paneles expandibles, navegación por teclado completa y soporte para modo de panel único.

Demostración ​

Sin estilos (solo base.css) ​

Así se ve hp-accordion usando únicamente @headless-primitives/utils/base.css. La navegación por teclado, aria-expanded y la visibilidad de paneles funcionan completamente.

¿Qué es Headless Primitives?

Una librería de componentes headless accesibles.

¿Por qué usarla?

Comportamiento y accesibilidad listos, tú pones los estilos.

Con estilos personalizados ​

¿Qué es Headless Primitives?▼

Es una librería de componentes headless que proveen la accesibilidad y comportamiento nativo.

¿Por qué usar acordeones?▼

Son perfectos para organizar contenido en secciones expandibles.

html
<hp-accordion class="faq-accordion">
  <hp-accordion-item class="faq-item" value="faq-1">
    <hp-accordion-trigger class="faq-trigger">
      ¿Qué es Headless Primitives?
      <span class="faq-icon">▼</span>
    </hp-accordion-trigger>
    <hp-accordion-content class="faq-content">
      <p>
        Es una librería de componentes headless que proveen la accesibilidad y comportamiento
        nativo, dejando total libertad creativa para el diseño visual.
      </p>
    </hp-accordion-content>
  </hp-accordion-item>

  <hp-accordion-item class="faq-item" value="faq-2">
    <hp-accordion-trigger class="faq-trigger">
      ¿Por qué usar acordeones?
      <span class="faq-icon">▼</span>
    </hp-accordion-trigger>
    <hp-accordion-content class="faq-content">
      <p>
        Los acordeones son perfectos para organizar contenido en secciones que pueden
        expandirse/contraerse, mejorando la experiencia de usuario en interfaces densas.
      </p>
    </hp-accordion-content>
  </hp-accordion-item>
</hp-accordion>
css
.faq-accordion {
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  overflow: hidden;
  background: white;
}

.faq-item {
  border-bottom: 1px solid #e2e8f0;
}

.faq-item:last-child {
  border-bottom: none;
}

.faq-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 16px 20px;
  background: #f8fafc;
  border: none;
  cursor: pointer;
  font-size: 15px;
  font-weight: 500;
  color: #1a202c;
  transition: background-color 0.2s;
}

.faq-trigger:hover {
  background: #f1f5f9;
}

.faq-trigger:focus {
  outline: 2px solid #3b82f6;
  outline-offset: -2px;
}

.faq-trigger[aria-expanded="true"] .faq-icon {
  transform: rotate(180deg);
}

.faq-content {
  padding: 20px;
  background: white;
  border-top: 1px solid #e2e8f0;
}

.faq-content[hidden] {
  display: none;
}

.faq-content p {
  margin: 0;
  color: #475569;
  line-height: 1.6;
}

.faq-icon {
  font-size: 12px;
  transition: transform 0.2s;
  color: #64748b;
}

Instalación ​

bash
pnpm add @headless-primitives/accordion
bash
npm install @headless-primitives/accordion
bash
yarn add @headless-primitives/accordion
bash
bun add @headless-primitives/accordion

Features ​

  • ⌨️ Navegación completa por teclado (flechas, Home, End).
  • ♿️ Relaciones ARIA gestionadas automáticamente (aria-expanded, aria-controls, aria-labelledby).
  • 🎨 Sin estilos visuales (Headless) — tú decides el diseño.
  • ⚡️ Modo single-panel para acordeones tipo exclusivo.
  • 🔒 Estado disabled propagable desde el root a todos los ítems.

Anatomía ​

html
<hp-accordion>
  <hp-accordion-item>
    <hp-accordion-trigger></hp-accordion-trigger>
    <hp-accordion-content></hp-accordion-content>
  </hp-accordion-item>
</hp-accordion>

API Reference ​

hp-accordion ​

Contenedor principal que coordina múltiples paneles de acordeón.

Atributos / Propiedades ​

Atributo / PropiedadTipoPor DefectoDescripción
single-panelbooleanfalseSi está presente, solo un panel puede estar abierto a la vez.
disabledbooleanfalseSi está presente, deshabilita todos los paneles del acordeón.

Eventos ​

EventoDetalleDescripción
hp-change{ open: boolean, value: string }Se dispara cuando cambia el estado de cualquier panel (bubbles).

hp-accordion-item ​

Panel individual dentro del acordeón.

Atributos / Propiedades ​

Atributo / PropiedadTipoPor DefectoDescripción
valuestringauto (UUID)Identificador único del panel.
openbooleanfalseSi está presente, el panel está expandido.
disabledbooleanfalseSi está presente, deshabilita solo este panel.

Eventos ​

EventoDetalleDescripción
hp-open{ value: string }Se dispara cuando el panel se expande.
hp-close{ value: string }Se dispara cuando el panel se contrae.
hp-change{ open: boolean, value: string }Se dispara en cualquier cambio de estado.

hp-accordion-trigger ​

Botón que controla la visibilidad del contenido del panel.

Atributos / Propiedades ​

Atributo / PropiedadTipoPor DefectoDescripción
disabledbooleanheredadoHeredado del contenedor hp-accordion-item.

Atributos ARIA gestionados automáticamente ​

  • role="button" — Asignado automáticamente si no se especifica.
  • aria-expanded — Sincronizado con el estado open del panel.
  • aria-controls — Referencia al ID del contenido.
  • aria-disabled — Sincronizado con el estado disabled.
  • tabindex="0" — Habilitado cuando no está deshabilitado.

hp-accordion-content ​

Panel de contenido que se muestra u oculta según el estado.

Atributos ARIA gestionados automáticamente ​

  • role="region" — Asignado automáticamente si no se especifica.
  • aria-labelledby — Referencia al ID del trigger.
  • data-state — "open" | "closed" para estilizado CSS.
  • data-hp-panel — Presente siempre (usado por base.css).

Accesibilidad ​

Adhiere al patrón WAI-ARIA APG para Accordion.

TeclaAcción
Enter / SpaceActiva el trigger y abre/cierra el contenido.
ArrowDownMueve el foco al siguiente trigger.
ArrowUpMueve el foco al trigger anterior.
HomeMueve el foco al primer trigger.
EndMueve el foco al último trigger.

Ejemplos ​

Modo de Panel Único ​

html
<hp-accordion single-panel>
  <hp-accordion-item value="panel-1">
    <hp-accordion-trigger>Panel 1</hp-accordion-trigger>
    <hp-accordion-content>Contenido del panel 1...</hp-accordion-content>
  </hp-accordion-item>

  <hp-accordion-item value="panel-2">
    <hp-accordion-trigger>Panel 2</hp-accordion-trigger>
    <hp-accordion-content>Contenido del panel 2...</hp-accordion-content>
  </hp-accordion-item>
</hp-accordion>

Control Programático ​

javascript
const accordion = document.querySelector("hp-accordion");
const item = document.querySelector("hp-accordion-item");

// Abrir un panel específico
item.open = true;

// Escuchar cambios
item.addEventListener("hp-change", (e) => {
  console.log("Panel cambiado:", e.detail.open, e.detail.value);
});

// Cambiar a modo de panel único
accordion.singlePanel = true;

Paneles Deshabilitados ​

html
<hp-accordion>
  <hp-accordion-item value="enabled">
    <hp-accordion-trigger>Panel Habilitado</hp-accordion-trigger>
    <hp-accordion-content>Contenido accesible...</hp-accordion-content>
  </hp-accordion-item>

  <hp-accordion-item value="disabled" disabled>
    <hp-accordion-trigger>Panel Deshabilitado</hp-accordion-trigger>
    <hp-accordion-content>Contenido no accesible...</hp-accordion-content>
  </hp-accordion-item>
</hp-accordion>

Lanzado bajo la MIT License.