Meet Frontfriend.Your brand. Your rules. Your agents, connected.Explore what’s new
DocumentationInputOTP

InputOTP

Accessible one-time password component with copy paste functionality.

Interactive preview

Rendered from the shared Frontfriend stories with React Base, the same preview Studio shows. Styling comes from your Design System; the code below is native to Reka UI.

Installation

Complete project setup first. Your configuration must select vue/reka and include your Design System ID.

pnpm exec frontfriend download input-otp -f vue --primitive reka

Review dependencies reported by the downloader and keep your source changes in version control.

Usage

<script setup lang="ts">
import { InputOTP } from "@/components/ui/input-otp";
import { InputOTPGroup } from "@/components/ui/input-otp";
import { InputOTPSlot } from "@/components/ui/input-otp";
import { InputOTPSeparator } from "@/components/ui/input-otp";
import * as UI from "@/components/ui/input-otp";

const Component = UI.InputOTP;

const args = {
  "disabled": false,
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <InputOTP :maxlength="6" v-bind="args"
    ><InputOTPGroup
      ><InputOTPSlot :index="0" /><InputOTPSlot :index="1" /><InputOTPSlot
        :index="2" /></InputOTPGroup
    ><InputOTPSeparator /><InputOTPGroup
      ><InputOTPSlot :index="3" /><InputOTPSlot :index="4" /><InputOTPSlot
        :index="5" /></InputOTPGroup
  ></InputOTP>
</template>

Examples

Default

<script setup lang="ts">
import { InputOTP } from "@/components/ui/input-otp";
import { InputOTPGroup } from "@/components/ui/input-otp";
import { InputOTPSlot } from "@/components/ui/input-otp";
import { InputOTPSeparator } from "@/components/ui/input-otp";
import * as UI from "@/components/ui/input-otp";

const Component = UI.InputOTP;

const args = {

} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <InputOTP :maxlength="6" v-bind="args"
    ><InputOTPGroup
      ><InputOTPSlot :index="0" /><InputOTPSlot :index="1" /><InputOTPSlot
        :index="2" /></InputOTPGroup
    ><InputOTPSeparator /><InputOTPGroup
      ><InputOTPSlot :index="3" /><InputOTPSlot :index="4" /><InputOTPSlot
        :index="5" /></InputOTPGroup
  ></InputOTP>
</template>

Pattern

<script setup lang="ts">
import { REGEXP_ONLY_DIGITS_AND_CHARS } from "vue-input-otp";
import { InputOTP } from "@/components/ui/input-otp";
import { InputOTPGroup } from "@/components/ui/input-otp";
import { InputOTPSlot } from "@/components/ui/input-otp";
import * as UI from "@/components/ui/input-otp";

const Component = UI.InputOTP;

const args = {

} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <InputOTP :maxlength="6" :pattern="REGEXP_ONLY_DIGITS_AND_CHARS"
    ><InputOTPGroup
      ><InputOTPSlot :index="0" /><InputOTPSlot :index="1" /><InputOTPSlot
        :index="2" /><InputOTPSlot :index="3" /><InputOTPSlot
        :index="4" /><InputOTPSlot :index="5" /></InputOTPGroup
  ></InputOTP>
</template>

Separator

<script setup lang="ts">
import { InputOTP } from "@/components/ui/input-otp";
import { InputOTPGroup } from "@/components/ui/input-otp";
import { InputOTPSlot } from "@/components/ui/input-otp";
import { InputOTPSeparator } from "@/components/ui/input-otp";
import * as UI from "@/components/ui/input-otp";

const Component = UI.InputOTP;

const args = {

} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <InputOTP :maxlength="4"
    ><InputOTPGroup
      ><InputOTPSlot :index="0" /><InputOTPSlot :index="1" /></InputOTPGroup
    ><InputOTPSeparator /><InputOTPGroup
      ><InputOTPSlot :index="2" /><InputOTPSlot :index="3" /></InputOTPGroup
  ></InputOTP>
</template>

Disabled

<script setup lang="ts">
import { InputOTP } from "@/components/ui/input-otp";
import { InputOTPGroup } from "@/components/ui/input-otp";
import { InputOTPSlot } from "@/components/ui/input-otp";
import { InputOTPSeparator } from "@/components/ui/input-otp";
import * as UI from "@/components/ui/input-otp";

const Component = UI.InputOTP;

const args = {

} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <InputOTP :maxlength="6" disabled
    ><InputOTPGroup
      ><InputOTPSlot :index="0" /><InputOTPSlot :index="1" /><InputOTPSlot
        :index="2" /></InputOTPGroup
    ><InputOTPSeparator /><InputOTPGroup
      ><InputOTPSlot :index="3" /><InputOTPSlot :index="4" /><InputOTPSlot
        :index="5" /></InputOTPGroup
  ></InputOTP>
</template>

API reference

Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Reka UI.

InputOTP

Prop Type Default Description
class HTMLAttributes["class"] —
containerClassName HTMLAttributes["class"] —

InputOTPGroup

Prop Type Default Description
class HTMLAttributes["class"] —

InputOTPSlot

Prop Type Default Description
class HTMLAttributes["class"] —
index number —

Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.