Skip to content

Collapsible Nuevo

El componente hp-collapsible implementa el patrón WAI-ARIA Disclosure, permitiendo mostrar u ocultar contenido de manera accesible. Base ideal para FAQs, secciones expandibles y patrones de revelación de contenido.

Demostración

Sin estilos (solo base.css)

Así se ve hp-collapsible usando únicamente @headless-primitives/utils/base.css. El toggle, aria-expanded y visibilidad del contenido funcionan completamente.

¿Qué es headless?

Comportamiento sin estilos impuestos.

Con estilos personalizados

¿Qué es Headless Primitives?

Es una librería de componentes headless que proveen la accesibilidad y comportamiento nativo, dejando total libertad creativa para el diseño visual.

html
<hp-collapsible class="faq-item">
  <hp-collapsible-trigger class="faq-question">
    ¿Pregunta frecuente?
    <span class="faq-icon">▼</span>
  </hp-collapsible-trigger>
  <hp-collapsible-content class="faq-answer">
    <p>Respuesta detallada a la pregunta frecuente...</p>
  </hp-collapsible-content>
</hp-collapsible>
css
.faq-item {
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 1rem;
}

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

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

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

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

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

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

hp-collapsible[open] .faq-icon {
  transform: rotate(180deg);
}

Instalación

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

Features

  • ⌨️ Activación por teclado con Enter y Space.
  • ♿️ aria-expanded, aria-controls y aria-labelledby gestionados automáticamente.
  • 🎨 Sin estilos visuales (Headless).
  • ⚡️ Controlable via atributo open o propiedad JS.
  • 🔒 Estado disabled propagable al trigger.

Anatomía

html
<hp-collapsible>
  <hp-collapsible-trigger></hp-collapsible-trigger>
  <hp-collapsible-content></hp-collapsible-content>
</hp-collapsible>

API Reference

hp-collapsible

Contenedor principal que gestiona el estado de expansión/contracción.

Atributos / Propiedades

Atributo / PropiedadTipoPor DefectoDescripción
openbooleanfalseSi está presente, el contenido está visible.
disabledbooleanfalseDeshabilita todo el collapsible.

Eventos

EventoDetalleDescripción
hp-open{ open: boolean }Se dispara cuando el collapsible se abre.
hp-close{ open: boolean }Se dispara cuando el collapsible se cierra.
hp-change{ open: boolean }Se dispara en cualquier cambio de estado.

hp-collapsible-trigger

Botón que controla la visibilidad del contenido.

Atributos / Propiedades

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

Atributos ARIA gestionados automáticamente

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

hp-collapsible-content

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

Atributos ARIA gestionados automáticamente

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

Accesibilidad

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

TeclaAcción
EnterAbre/cierra el contenido.
SpaceAbre/cierra el contenido.

Ejemplos

Control Programático

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

// Abrir programáticamente
collapsible.open = true;

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

Anidación

html
<hp-collapsible>
  <hp-collapsible-trigger>Exterior</hp-collapsible-trigger>
  <hp-collapsible-content>
    <p>Contenido exterior...</p>
    <hp-collapsible>
      <hp-collapsible-trigger>Interior</hp-collapsible-trigger>
      <hp-collapsible-content>
        <p>Contenido anidado...</p>
      </hp-collapsible-content>
    </hp-collapsible>
  </hp-collapsible-content>
</hp-collapsible>

Lanzado bajo la MIT License.