Skip to main content

OTP

The OTP component provides a One-Time Password input with a countdown timer, resend functionality, and customizable UI. It supports integration with form flows that require SMS, email, or Absher verification.

import { OTP } from "tawuniya/components";

👉 View in Storybook


Props​

PropTypeDefaultDescription
titlestring—Custom title displayed above the OTP input.
descriptionstring—Custom description displayed below the title.
channelstring—Channel for OTP delivery (e.g., phone/email). Automatically masked.
initialMinutesnumber0Initial countdown minutes.
initialSecondsnumber59Initial countdown seconds.
isAbsherbooleanfalseIf true, shows the Absher style with Absher icon.
centeredbooleanfalseIf true, centers content horizontally.
disabledbooleanfalseDisables OTP input and actions.
classNamestring—Additional Tailwind classes for the wrapper.
verifyOTP(otp: string) => void—Callback fired when clicking the Verify button.
resendOTP() => void—Callback fired when clicking the Resend button (after countdown ends).
hideIconbooleanfalseHides the otp icon.
disableAutoSubmittingbooleanfalseDisables auto submitting OTP when all slots are filled.
viewType"normal" | "modal"normalControls whether the OTP is displayed in normal view or inside a modal.
openModalbooleanfalseControls the modal visibility.
onOpenModalDispatch<SetStateAction<boolean>>falseControls the modal visibility.

Usage​

Basic Example​

import { OTP } from "tawuniya/components";

export default function BasicExample() {
return (
<OTP
title="Verify your identity"
description="Enter the code sent to you"
/>
);
}

With Channel Masking​

<OTP
title="Enter OTP"
description="We have sent a code to"
channel="+966500000000"
verifyOTP={(otp) => console.log("Submitted OTP:", otp)}
resendOTP={() => console.log("Resend triggered")}
/>

With Custom Countdown​

<OTP initialMinutes={1} initialSeconds={30} />

With Absher Branding​

<OTP isAbsher centered />

With Hide Icon​

<OTP hideIcon />

With Disable Auto Submitting​

<OTP
disableAutoSubmitting
verifyOTP={(otp) => console.log("Submitted OTP:", otp)}
/>

With Modal​

const [openModal, setOpenModal] = useState(false);

<OTP
title="Enter OTP"
description="We have sent a code to"
channel="+966500000000"
verifyOTP={(otp) => {
console.log("Submitted OTP:", otp);
setOpenModal(false);
}}
resendOTP={() => console.log("Resend triggered")}
viewType="modal"
openModal={openModal}
onOpenModal={setOpenModal}
/>;

Notes​

  • OTP input is 4 digits by default.
  • The Resend button becomes active only after the countdown reaches 0.
  • channel is automatically masked for security (e.g., +966******000).
  • If isAbsher is true, the Absher branding will be displayed instead of Tawuniya.
  • The Verify button is disabled until 4 digits are entered.