Input OTP

Accessible one-time password component.

Installation

ng g @spartan-ng/cli:ui input-otp

Usage

import { HlmInputOtpImports } from '@spartan-ng/helm/input-otp';
<hlm-input-otp length="6">
  <hlm-input-otp-group>
    <hlm-input-otp-slot index="0" />
    <hlm-input-otp-slot index="1" />
    <hlm-input-otp-slot index="2" />
  </hlm-input-otp-group>
  <hlm-input-otp-separator />
  <hlm-input-otp-group>
    <hlm-input-otp-slot index="3" />
    <hlm-input-otp-slot index="4" />
    <hlm-input-otp-slot index="5" />
  </hlm-input-otp-group>
</hlm-input-otp>

Animation

The fake caret animation animate-caret-blink is provided by tw-animate-css , which is included in @spartan-ng/brain/hlm-tailwind-preset.css . Here are three options for adding the animation to your project.

src/styles.css
/* 1. default import includes 'tw-animate-css' */
@import '@spartan-ng/brain/hlm-tailwind-preset.css';

/* 2. import 'tw-animate-css' direclty */
@import 'tw-animate-css';

/* 3. add animate-caret-blink animation from 'tw-animate-css'  */
@theme inline {
	--animate-caret-blink: caret-blink 1.25s ease-out infinite;
	@keyframes caret-blink {
		0%,
		70%,
		100% {
			opacity: 1;
		}
		20%,
		50% {
			opacity: 0;
		}
	}
}

Adjust the animation to your needs by changing duration, easing function or keyframes by overriding the CSS variable --animate-caret-blink or the @keyframes caret-blink in your global styles.

src/styles.css
@import '@spartan-ng/brain/hlm-tailwind-preset.css';

/* adjust animation duration  */
@theme inline {
-	--animate-caret-blink: caret-blink 1.25s ease-out infinite;
+	--animate-caret-blink: caret-blink 2s ease-out infinite;
}

Examples

Pattern

Use the slotPattern prop to restrict the characters that can be entered. The example below only accepts digits.

Separator

Use the hlm-input-otp-separator component to add a separator between input groups.

Disabled

Use the disabled prop to disable the input.

1 2 3 4 5 6

Invalid

Use the forceInvalid prop to mark the slots as invalid.

Four Digits

A common pattern for PIN codes. Use slotPattern="[0-9]" and length="4" .

Alphanumeric

Use slotPattern="[A-Za-z0-9]" to accept both letters and numbers.

Masked

Use the mask prop to visually obscure entered characters. The form value remains unmasked. Customize the mask character with maskChar .

Form

Sync the OTP to an Angular Signal Form by binding [formField] to hlm-input-otp .

Verify your login
Enter the verification code we sent to your email address: m@example.com .
I no longer have access to this email address.
Having trouble signing in? Contact support

RTL

To enable RTL support in spartan-ng, see the RTL configuration guide.

1 2 3 4 5 6

Brain API

BrnInputOtpInput

Selector: input[brnInputOtpInput]

ExportAs: brnInputOtpInput

Inputs

PropTypeDefaultDescription
autocomplete 'one-time-code' | 'off' 'one-time-code' Custom autocomplete attribute applied to the input element
inputMode InputMode 'numeric' Virtual keyboard appearance on mobile
inputStyles string | undefined undefined Styles applied to the input element to make it invisible and clickable.

BrnInputOtpSlot

Selector: brn-input-otp-slot

ExportAs: brnInputOtpSlot

Inputs

PropTypeDefaultDescription
index* (required) number - The index of the slot to render the char or a fake caret
forceInvalid boolean false Whether to force the input into an invalid state.

BrnInputOtp

Selector: brn-input-otp, [brnInputOtp]

ExportAs: brnInputOtp

Inputs

PropTypeDefaultDescription
hostStyles string 'position: relative; cursor: text; user-select: none; pointer-events: none;' Styles applied to the host element.
inputId string `brn-input-otp-${++BrnInputOtp._id}` Custom id applied to the input element
disabled boolean false Determine if the input is disabled.
length* (required) number - The number of slots.
slotPattern string | RegExp | null null Optional per-character pattern. Each typed or pasted character must match this pattern. Strings are treated as a single-character regular expression. Examples: '[0-9]', '[A-Za-z0-9]'
mask boolean false Whether entered characters should be visually masked.
maskChar string '•' The character used to mask entered characters.
autofocus boolean false If true, the element is focused automatically on init *
transformPaste (pastedText: string, length: number) => string (text) => text Defines how the pasted text should be transformed before saving to model/form. Allows pasting text which contains extra characters like spaces, dashes, etc. and are longer than the length. "XXX-XXX": (pastedText) => pastedText.replaceAll('-', '') "XXX XXX": (pastedText) => pastedText.replaceAll(/\s+/g, '')
value string | null null The value controlling the input

Outputs

PropTypeDefaultDescription
valueChange string - Emits when the value changes.
completed string - Emitted when the input is complete, triggered through input or paste.

Helm API

HlmInputOtpFakeCaret

Selector: hlm-input-otp-fake-caret

ExportAs: hlmInputOtpFakeCaret

HlmInputOtpGroup

Selector: [hlmInputOtpGroup],hlm-input-otp-group

ExportAs: hlmInputOtpGroup

HlmInputOtpSeparator

Selector: hlm-input-otp-separator

ExportAs: hlmInputOtpSeparator

HlmInputOtpSlot

Selector: hlm-input-otp-slot

ExportAs: hlmInputOtpSlot

Inputs

PropTypeDefaultDescription
index* (required) number - The index of the slot to render the char or a fake caret
forceInvalid boolean false Whether to force the input into an invalid state.

HlmInputOtp

Selector: hlm-input-otp

ExportAs: hlmInputOtp

Inputs

PropTypeDefaultDescription
inputAutocomplete 'one-time-code' | 'off' 'one-time-code' Custom autocomplete attribute applied to the input element
inputMode InputMode 'numeric' Virtual keyboard appearance on mobile
inputClass ClassValue '' Classes applied to the input element.
inputStyles string | undefined undefined Overrides the default styles applied to the input element.
length* (required) number - The number of slots.
value string | null null The value controlling the input
disabled boolean false Determine if the input is disabled.
inputId string `brn-input-otp-${++BrnInputOtp._id}` Custom id applied to the input element
hostStyles string 'position: relative; cursor: text; user-select: none; pointer-events: none;' Styles applied to the host element.
autofocus boolean false If true, the element is focused automatically on init *
transformPaste (pastedText: string, length: number) => string (text) => text Defines how the pasted text should be transformed before saving to model/form. Allows pasting text which contains extra characters like spaces, dashes, etc. and are longer than the length. "XXX-XXX": (pastedText) => pastedText.replaceAll('-', '') "XXX XXX": (pastedText) => pastedText.replaceAll(/\s+/g, '')
mask boolean false Whether entered characters should be visually masked.
maskChar string '•' The character used to mask entered characters.
slotPattern string | RegExp | null null Optional per-character pattern. Each typed or pasted character must match this pattern. Strings are treated as a single-character regular expression. Examples: '[0-9]', '[A-Za-z0-9]'

Outputs

PropTypeDefaultDescription
valueChange string - Emits when the value changes.
completed string - Emitted when the input is complete, triggered through input or paste.
Input Input Group