Skip to content

Pin Input Nuevo

El componente hp-pin-input captura un código PIN u OTP de longitud fija, con un campo individual por carácter. Auto-avanza el foco, retrocede con Backspace y distribuye texto pegado automáticamente.

Demostración

Sin estilos (solo base.css)

Con estilos personalizados

Numérico — 4 dígitos

OTP — 6 dígitos

Alfanumérico

Deshabilitado

html
<hp-pin-input id="my-pin" length="6" type="numeric"></hp-pin-input>

<script type="module">
  import "@headless-primitives/pin-input";

  const pin = document.getElementById("my-pin");

  pin.addEventListener("hp-change", (e) => {
    console.log("Valor actual:", e.detail.value);
  });

  pin.addEventListener("hp-complete", (e) => {
    console.log("PIN completo:", e.detail.value);
  });
</script>
css
hp-pin-input {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

hp-pin-input input {
  width: 2.75rem;
  height: 2.75rem;
  text-align: center;
  font-family: monospace;
  font-size: 1.25rem;
  font-weight: 700;
  border: 2px solid #e2e8f0;
  border-radius: 0.5rem;
  outline: none;
}

hp-pin-input input:focus {
  border-color: #2563eb;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2);
}

hp-pin-input[data-state="complete"] input {
  border-color: #16a34a;
}

Instalación

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

Features

  • ⌨️ Auto-avance, Backspace inteligente, ArrowLeft/Right, Home/End.
  • ♿️ role="group", aria-label por slot y autocomplete="one-time-code" automáticos.
  • 🎨 Sin estilos visuales (Headless).
  • 📋 Soporte de pegado con distribución automática.
  • 🔢 Tipos: numeric (solo dígitos) o alphanumeric.

Anatomía

html
<hp-pin-input length="4" type="numeric">
  <!-- Generado automáticamente: -->
  <!-- <input data-hp-pin-slot="0" aria-label="Digit 1" ... /> -->
  <!-- <input data-hp-pin-slot="1" aria-label="Digit 2" ... /> -->
  <!-- <input data-hp-pin-slot="2" aria-label="Digit 3" ... /> -->
  <!-- <input data-hp-pin-slot="3" aria-label="Digit 4" ... /> -->
</hp-pin-input>

API Reference

hp-pin-input

Atributos / Propiedades

Atributo / PropiedadTipoPor DefectoDescripción
lengthnumber4Número de slots.
type"numeric" | "alphanumeric""numeric"Caracteres permitidos.
placeholderstring"○"Carácter de placeholder por slot.
disabledbooleanfalseDeshabilita todos los inputs.

Propiedades de solo lectura

PropiedadTipoDescripción
valuestringValor combinado de todos los slots.

Métodos

MétodoDescripción
clear()Vacía todos los slots y mueve foco al primero.

Eventos

EventoDetalleDescripción
hp-change{ value: string }Cada vez que cambia algún slot.
hp-complete{ value: string }Cuando todos los slots están llenos.

Atributos ARIA gestionados automáticamente

  • role="group" — Siempre presente.
  • aria-label"PIN input" por defecto.
  • aria-disabled — Sincronizado con disabled.
  • data-state"complete" | "incomplete".
  • data-type — Espejo del type.

Atributos de cada slot (<input>)

  • aria-label"Digit N" (1-based).
  • maxlength="1" — Solo un carácter.
  • inputmode"numeric" o "text".
  • autocomplete="one-time-code" — OTP en dispositivos móviles.

Accesibilidad

Implementa el patrón OTP Input Group con role="group".

TeclaAcción
Carácter válidoIngresa y avanza al siguiente slot.
BackspaceBorra y retrocede al slot anterior si vacío.
ArrowLeftMueve foco al slot anterior.
ArrowRightMueve foco al slot siguiente.
HomeMueve foco al primer slot.
EndMueve foco al último slot.
Ctrl+V / PegarDistribuye texto desde el slot activo.

Lanzado bajo la MIT License.