Input OTP: HextaUI y shadcn/ui

El Input OTP de HextaUI mantiene los nombres y tokens de tema de shadcn/ui y se instala con la misma CLI. Esta página lista lo que cambia, leído del código de ambos. El lado de shadcn/ui es su registro base-vega a fecha de 2026-10-16.

De un vistazo

MedidaHextaUIshadcn/ui
Partes exportadas44
Props que gestiona el envoltorio242
Líneas de código91292
Dependencias de npm@base-ui/react@^1.8.0@tabler/icons-reactclass-variance-authoritycncninput-otp
Construido conmotiontheme–

Más código no es mejor por sí solo. La mayoría de las líneas extra de HextaUI cubren estados, animaciones y casos límite que de otro modo escribirías tú.

Props que añade HextaUI

Props que gestiona el propio envoltorio de HextaUI y el de shadcn/ui no. Se omiten las props que pasan directamente a Base UI o a la librería subyacente, porque ambas versiones las aceptan.

PropQué hace
variantInputOTPVer la referencia de la API
animatedInputOTPAnima la entrada y salida de caracteres, encadena en cascada la entrada de varios caracteres y anima el estado.
loadingLabelInputOTPVer la referencia de la API
successLabelInputOTPVer la referencia de la API
errorLabelInputOTPVer la referencia de la API

Variantes

PropEn ambosSolo HextaUISolo shadcn/ui
variantInputOTPGroup–joinedseparate–
sizeInputOTPGroup–smdefaultlg–
variantInputOTPSlot–joinedseparate–
sizeInputOTPSlot–smdefaultlg–

La versión de HextaUI

Type or paste 123456 to pass. Anything else fails.

"use client"

import * as React from "react"

import {
  InputOTP,
  InputOTPGroup,
  InputOTPSeparator,
  InputOTPSlot,
  type InputOTPStatus,
} from "@/components/ui/input-otp"
import { Label } from "@/components/ui/label"

export function InputOTPDemo() {
  const [value, setValue] = React.useState("")
  const [status, setStatus] = React.useState<InputOTPStatus>("idle")
  const timer = React.useRef<ReturnType<typeof setTimeout>>(undefined)

  React.useEffect(() => () => clearTimeout(timer.current), [])

  function verify(code: string) {
    setStatus("loading")
    clearTimeout(timer.current)
    timer.current = setTimeout(() => {
      if (code === "123456") {
        setStatus("success")
        return
      }
      setStatus("error")
      timer.current = setTimeout(() => {
        setValue("")
        setStatus("idle")
      }, 900)
    }, 1200)
  }

  return (
    <div className="flex max-w-full min-w-0 flex-col items-center gap-3">
      <Label htmlFor="input-otp-demo">Verification code</Label>
      <InputOTP
        id="input-otp-demo"
        length={6}
        variant="separate"
        animated
        status={status}
        value={value}
        onValueChange={(next) => {
          setValue(next)
          setStatus("idle")
        }}
        onValueComplete={verify}
        aria-describedby="input-otp-demo-hint"
      >
        <InputOTPGroup>
          <InputOTPSlot />
          <InputOTPSlot />
          <InputOTPSlot />
        </InputOTPGroup>
        <InputOTPSeparator />
        <InputOTPGroup>
          <InputOTPSlot />
          <InputOTPSlot />
          <InputOTPSlot />
        </InputOTPGroup>
      </InputOTP>
      <p id="input-otp-demo-hint" className="text-sm text-muted-foreground">
        Type or paste 123456 to pass. Anything else fails.
      </p>
    </div>
  )
}

Todos los estados, el mapa de teclado y la referencia de la API están en la página del componente.

14 de sus ejemplos también tienen su propia página.

Cambia un componente

Ejecuta el comando add con --overwrite para reemplazar el archivo de shadcn/ui en @/components/ui y revisa el diff en git antes de quedártelo. Los imports no cambian y los componentes que no reemplaces siguen funcionando.

pnpm dlx shadcn@latest add https://hextaui.com/r/input-otp.json --overwrite
  • Cada prop de la tabla anterior es nueva, así que el código escrito para shadcn/ui todavía no la pasa.
  • Antes de cambiar, revisa cualquier parte o variante que solo aparezca en shadcn/ui y asígnala a la más parecida de HextaUI.

Otros componentes comparados

Más comparaciones