Skip to content
RTL Support: Full
Accessibility: Full
Translations: Not Needed

Input OTP

Component for OTP Input.

Default

Vue
html
<template>
  <HLInputOtp @onComplete="onCompleteHandler" @onChange="onChangeHandler" />
</template>

<script setup lang="ts">
  import { ref } from 'vue'
  import { HLInputOtp } from '@platform-ui/highrise'

  const otpValue = ref('')
  const onChangeHandler = (value: string) => {
    // do something
  }
  const onCompleteHandler = (value: { otp: string; state: 'completed' }) => {
    otpValue.value = value.otp
  }
</script>

Fileds

Vue
html
<template>
  <HLInputOtp size="sm" :fields="4" @onComplete="onCompleteHandler" @onChange="onChangeHandler" />
</template>

<script setup lang="ts">
  import { ref } from 'vue'
  import { HLInputOtp } from '@platform-ui/highrise'

  const otpValue = ref('')
  const onChangeHandler = (value: string) => {
    // do something
  }
  const onCompleteHandler = (value: { otp: string; state: 'completed' }) => {
    otpValue.value = value.otp
  }
</script>

Seperator Position

Vue
html
<template>
  <HLInputOtp size="sm" :fields="6" :separatorPosition="3" @onComplete="onCompleteHandler" @onChange="onChangeHandler" />
</template>

<script setup lang="ts">
  import { ref } from 'vue'
  import { HLInputOtp } from '@platform-ui/highrise'

  const otpValue = ref('')
  const onChangeHandler = (value: string) => {
    // do something
  }
  const onCompleteHandler = (value: { otp: string; state: 'completed' }) => {
    otpValue.value = value.otp
  }
</script>

Custom Placeholder

Vue
html
<template>
  <HLInputOtp size="sm" :fields="4" placeholder="#" @onComplete="onCompleteHandler" @onChange="onChangeHandler" />
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLInputOtp } from '@platform-ui/highrise'

  const otpValue = ref('')
  const onChangeHandler = (value: string) => {
    // do something
  }
  const onCompleteHandler = (value: { otp: string; state: 'completed' }) => {
    otpValue.value = value.otp
  }
</script>

Disabled

Vue
html
<template>
  <HLInputOtp size="sm" :fields="4" disabled @onComplete="onCompleteHandler" @onChange="onChangeHandler" />
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { HLInputOtp } from '@platform-ui/highrise'

  import { useRTL } from '../../.vitepress/theme/useRTL'
  const { direction } = useRTL()
  const otpValue = ref('')
  const onChangeHandler = (value: string) => {
    // do something
  }
  const onCompleteHandler = (value: { otp: string; state: 'completed' }) => {
    otpValue.value = value.otp
  }

</script>

Design Guidelines

Input components use a box-shadow to render their focus ring. Box-shadows render outside the element's bounds and may be clipped by any ancestor using overflow: hidden (e.g. Tab Panels or Dropdown Menus).

To prevent this, add a small gutter padding to the component's wrapper to ensure there is enough room for the focus ring to render without being cut off.

vue
<div class="p-[3px]">
  <!-- Your component here -->
</div>

Accessibility

  • Describe the OTP request via aria-label / aria-labelledby on the container (e.g., “Enter the 6-digit code”).
  • Give each cell an aria-label that announces its index (“Digit 2 of 6”) or hook helper text through aria-describedby.
  • Announce expired or incorrect codes inside an aria-live="assertive" region near the group.

Imports

ts
import { HLInputOtp } from '@platform-ui/highrise'

Props

NameTypeDefaultDescription
id *string | undefinedundefinedThe id of the element
fieldsnumber4Number of fields to display
disabledbooleanfalseDisables the otp
placeholderstring'0'Placeholder text for the otp
size'3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg''md'Size of the otp
separatorPositionnumber | undefinedundefinedPosition of the separator

Emits

NameTypeDescription
@onCompletefunctionCallback function for when the otp is completed
@onChangefunctionCallback function for when the otp is changed