Skip to content
ARC UI ARC Reactive Components
Docs Components Tokens Synthesizer
v2.1.0
Getting Started Frameworks Design Tokens Theming Theme Synthesizer Accessibility Browser Support Changelog Contributing All Components App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageInfinite ScrollMarqueeScroll AreaSeparatorSkeletonSpinnerStackVirtual List Animated NumberBadgeComparisonCountdown TimerData TableDescription ListDiffKey ValueListMeterSparklineStatStepperTableTagTimelineValue Card BlockquoteCode BlockGradient TextHighlightKbdMarkdownNumber FormatProseTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerFieldsetFile UploadFormHotkeyIcon ButtonInputInput GroupLabelMulti SelectNumber InputOTP InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSliderSortable ListSwitch GroupTextareaTheme ToggleTime PickerToggle AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip
Components Pin Input
input interactive
<arc-pin-input>

Overview

Guidelines

When to use

  • Set `length` to match the expected code length -- 4 for PINs, 6 for OTPs, etc.
  • Use `type="number"` for numeric-only codes and set `inputmode="numeric"` for mobile keyboards
  • Enable `mask` for sensitive codes like passwords or security PINs
  • Listen for `arc-complete` to auto-submit or validate once the full code is entered
  • Provide a `label` so users understand what code they are entering

When not to use

  • Do not use Pin Input for general text entry -- it is designed exclusively for fixed-length codes
  • Do not set `length` higher than ~8 -- long codes are better handled with a standard text input
  • Do not omit the `label` prop when the pin input is used standalone without surrounding context
  • Do not use `separator` values that produce uneven groups at the end (e.g. `separator="4"` on a 6-digit code)
  • Avoid placing Pin Input in very narrow containers -- each box needs at least 42px width plus gaps

Features

  • Auto-advance focus to the next box after each valid character entry
  • Backspace navigates to and clears the previous box when the current box is empty
  • Arrow key navigation between boxes without modifying content
  • Clipboard paste support that fills multiple boxes from the cursor position
  • Configurable `type` validation: `"number"`, `"alphanumeric"`, or `"text"`
  • Mask mode via `mask` prop for obscuring sensitive codes with dots
  • Visual separator dashes between groups via the `separator` prop (e.g. every 3 boxes)
  • Dual events: `arc-change` on every keystroke, `arc-complete` when all boxes are filled

Preview

Usage

This component requires JavaScript. No pure HTML/CSS version is available — use the Web Component directly or a framework wrapper.

<arc-pin-input label="OTP Code" length="6" separator="3"></arc-pin-input>

<script>
  document.querySelector('arc-pin-input')
    .addEventListener('arc-complete', e => {
      console.log('Code entered:', e.detail.value);
    });
</script>
import { PinInput } from '@arclux/arc-ui-react';

<PinInput
  label="OTP Code"
  length={6}
  separator={3}
  onArcComplete={(e) => console.log('Code:', e.detail.value)}
/>
<script setup>
import { PinInput } from '@arclux/arc-ui-vue';
</script>

<template>
  <PinInput
    label="OTP Code"
    :length="6"
    :separator="3"
    @arc-complete="(e) => console.log('Code:', e.detail.value)"
  />
</template>
<script>
  import { PinInput } from '@arclux/arc-ui-svelte';
</script>

<PinInput
  label="OTP Code"
  length={6}
  separator={3}
  on:arc-complete={(e) => console.log('Code:', e.detail.value)}
/>
import { Component } from '@angular/core';
import { PinInput } from '@arclux/arc-ui-angular';

@Component({
  imports: [PinInput],
  template: `
    <PinInput
      label="OTP Code"
      [length]="6"
      [separator]="3"
      (arc-complete)="onComplete($event)"
    ></PinInput>
  `,
})
export class MyComponent {
  onComplete(e: CustomEvent) {
    console.log('Code:', e.detail.value);
  }
}
import { PinInput } from '@arclux/arc-ui-solid';

<PinInput
  label="OTP Code"
  length={6}
  separator={3}
  onArcComplete={(e) => console.log('Code:', e.detail.value)}
/>
import { PinInput } from '@arclux/arc-ui-preact';

<PinInput
  label="OTP Code"
  length={6}
  separator={3}
  onArcComplete={(e) => console.log('Code:', e.detail.value)}
/>

API

Prop Type Default Description
length number 4 Number of input boxes to render. Determines the expected code length.
value string '' Current combined value across all boxes. Reflected as an attribute.
type 'number' | 'alphanumeric' | 'text' 'number' Character validation mode. `number` allows digits only, `alphanumeric` allows letters and digits, `text` allows any character.
mask boolean false When true, obscures entered characters with dots for sensitive codes.
separator number 0 Inserts a visual dash separator every N boxes. Set to 0 to disable separators.
label string '' Label text displayed above the input boxes in uppercase accent font.
disabled boolean false Disables all boxes, reducing opacity to 40% and blocking input.

Events

Event Description
arc-change Fired on every character entry or deletion. `event.detail.value` contains the current partial value.
arc-complete Fired when all boxes are filled. `event.detail.value` contains the full value string.

See Also