Skip to content

PIN Input

A sequence of one-character inputs, normally used for entering PINs or OTPs.

Props


Features

  • 🎹 Keyboard navigation
  • 🔒 Multiple entry validation types
  • 📋 Paste support
  • 📱 Uses the appropriate keyboard in mobile
  • TODO password manager support

Usage

<script lang="ts">
import { PinInput } from "melt/builders";
const pinInput = new PinInput();
</script>
<div {...pinInput.root}>
{#each pinInput.inputs as input}
<input {...input} />
{/each}
</div>

API Reference

Constructor Props

The props that are passed when calling
new PinInput()
    export type PinInputProps = {
    /**
    * The value for the Pin Input.
    *
    * When passing a getter, it will be used as source of truth,
    * meaning that the value only changes when the getter returns a new value.
    *
    * Otherwise, if passing a static value, it'll serve as the default value.
    *
    *
    * @default ''
    */
    value?: MaybeGetter<string | undefined>;
    /**
    * Called when the `PinInput` instance tries to change the value.
    */
    onValueChange?: (value: string) => void;
    /**
    * Called when the `PinInput` instance is filled.
    */
    onComplete?: (value: string) => void;
    /**
    * Override the default behavior when pasting a value.
    *
    * @param value The pasted value.
    *
    * @example ```ts
    * const pin = new PinInput({
    * onPaste(value) {
    * if (!valid(value)) {
    * // do something
    * return
    * }
    * pin.value = value
    * }
    * });
    */
    onPaste?: (value: string) => void;
    /**
    * Called when the PinInput encounters an error.
    */
    onError?: (error: PinInputError) => void;
    /**
    * The amount of digits in the Pin Input.
    *
    * @default 4
    */
    maxLength?: MaybeGetter<number | undefined>;
    /**
    * An optional placeholder to display when the input is empty.
    *
    * @default ''
    */
    placeholder?: MaybeGetter<string | undefined>;
    /**
    * If `true`, prevents the user from interacting with the input.
    *
    * @default false
    */
    disabled?: MaybeGetter<boolean | undefined>;
    /**
    * If the input should be masked like a password.
    *
    * @default false
    */
    mask?: MaybeGetter<boolean | undefined>;
    /**
    * What characters the input accepts.
    *
    * @default 'text'
    */
    type?: MaybeGetter<"alphanumeric" | "numeric" | "text" | undefined>;
    /**
    * If `true`, allows pasting values from the clipboard.
    *
    * @default true
    */
    allowPaste?: MaybeGetter<boolean | undefined>;
    };

Properties

The properties returned from
new PinInput()
  • maxLength

    number
  • placeholder

    string
  • disabled

    boolean
  • mask

    boolean
  • type

    "alphanumeric" | "numeric" | "text"
  • allowPaste

    boolean
  • isFilled

    boolean
  • value

    string
  • root

    {
    readonly "data-melt-pin-input-root": ""
    readonly id: string
    readonly "data-complete": "" | undefined
    }
    The root element's props.
  • inputs

    {
    readonly "data-melt-pin-input-input": ""
    readonly placeholder: string | undefined
    readonly disabled: true | undefined
    readonly type: "text" | "password"
    readonly "data-filled": "" | undefined
    readonly tabindex: 0 | -1
    readonly inputmode: "numeric" | "text"
    readonly style: "caret-color: transparent;" | undefined
    readonly onkeydown: (e: KeyboardEvent) => void
    readonly onpointerdown: (e: Event) => void
    readonly onpointerup: (e: Event) => void
    readonly oninput: (e: Event) => void
    readonly onfocus: () => void
    readonly onblur: () => void
    readonly onpaste: (
    e: ClipboardEvent & { currentTarget: EventTarget & HTMLInputElement },
    ) => void
    }[]
    An array of props that should be spread to the input elements.