Skip to content

Chaintech-Network/CMP-otp-pin-view

Repository files navigation

CMP OTP PinView

Maven Central Kotlin Compose Multiplatform

badge-android badge-ios

CMP OTP PinView is a Kotlin Multiplatform library that provides highly customizable OTP/PIN input fields for Android and iOS. Built with Compose Multiplatform, it allows developers to create secure and visually appealing OTP input experiences which is completely customizable.


Features

  • Multi-Platform OTP Components – Reusable OTP input fields for Android, iOS, and Web.
  • Customizable Styles – Control colors, borders, spacing, corner radius, and shapes.
  • Obscure / Visibility Toggle – Show or hide entered PIN digits dynamically.
  • Reactive Focus Handling – Automatically focuses next input and hides keyboard when complete.
  • Android OTP Autofill – Automatically observes system OTPs for Android.

📦 Installation

Add the library to your project:

dependencies {
  implementation("network.chaintech.cmp-otp-pin-view:1.0.0")
}

Make sure to include Maven Central in your repositories:

repositories {
    mavenCentral()
}

Usage

Basic OTPField

@Composable
fun BasicOTPExample() {
  var hasError by remember { mutableStateOf(false) }

  OTPField(
    otpLength = 4,
    stylePreset = OtpFieldStylePreset.Normal,
    isError = hasError,
    isObserveAndroidOTP = true,
    instanceKey = "normal",
    obscureField = true
  )
}

OTPField Composable Properties

Property Type Default Description
otpLength Int 4 Number of OTP/PIN input fields to display.
instanceKey String? null Unique key for this OTPField instance (used internally for state handling).
stylePreset OtpFieldStylePreset? null Predefined style preset (shape, colors, borders, spacing).
borderColorFocused Color Color.Blue Border color when the field is focused.
borderColorUnfocused Color Color.Gray Border color when the field is not focused.
borderWidth Dp 1.dp Width of the field border.
backgroundColorFocused Color Color.White Background color when focused.
backgroundColorUnFocused Color Color.White Background color when not focused.
textColor Color Color.Blue Color of the entered digits.
cursorColor Color Color.Blue Cursor color.
cornerRadius Dp 12.dp Corner radius for rounded shapes.
shape Shape RoundedCornerShape(cornerRadius) Custom shape for input fields.
obscureField Boolean false Hide the entered PIN; shows a toggle eye icon if true.
isError Boolean false Marks the field as error for styling.
isObserveAndroidOTP Boolean false Observes system OTP autofill on Android.

Predefined Style Presets

OTPField(otpLength = 5, stylePreset = OtpFieldStylePreset.Normal)
OTPField(otpLength = 5, stylePreset = OtpFieldStylePreset.Circle)
OTPField(otpLength = 5, stylePreset = OtpFieldStylePreset.Hexagon)
OTPField(otpLength = 5, stylePreset = OtpFieldStylePreset.Heart)
OTPField(otpLength = 5, stylePreset = OtpFieldStylePreset.Triangle)
OTPField(otpLength = 5, stylePreset = OtpFieldStylePreset.Pentagon)
OTPField(otpLength = 5, stylePreset = OtpFieldStylePreset.FilledParallelogram)

Custom Shape Example

val customShape = RoundedCornerShape(topStart = 16.dp, bottomEnd = 16.dp)

OTPField(
  otpLength = 4,
  stylePreset = OtpFieldStylePreset.Normal.copy(shape = customShape),
  instanceKey = "custom"
)

Error Handling Example

var isError by remember { mutableStateOf(false) }
val enteredOtp = remember { mutableStateOf("") }

OTPField(
  otpLength = 6,
  stylePreset = OtpFieldStylePreset.Hexagon,
  isError = isError,
  instanceKey = "hexagon"
)

Button(onClick = {
  isError = enteredOtp.value != "123456" // Example validation
}) {
  Text("Validate OTP")
}

Obscure / Visibility Toggle

OTPField(
  otpLength = 4,
  obscureField = true,
  instanceKey = "obscure"
)

The field will display a toggle icon to show or hide PIN digits.


Android OTP Autofill

Set isObserveAndroidOTP = true to automatically observe system OTPs (SMS Retriever) and populate the fields.


Supported Shapes

  • Rounded Rectangle
  • Circle
  • Hexagon
  • Heart
  • Triangle
  • Pentagon
  • Parallelogram

Visual Preview Example

@Composable
fun OTPPreview() {
  Column(
    modifier = Modifier
      .fillMaxSize()
      .padding(16.dp),
    horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.spacedBy(16.dp)
  ) {
    Text("Normal")
    OTPField(otpLength = 4, stylePreset = OtpFieldStylePreset.Normal, instanceKey = "normal")

    Text("Circle")
    OTPField(otpLength = 4, stylePreset = OtpFieldStylePreset.Circle, instanceKey = "circle")

    Text("Hexagon")
    OTPField(otpLength = 4, stylePreset = OtpFieldStylePreset.Hexagon, instanceKey = "hex")

    Text("Heart")
    OTPField(otpLength = 4, stylePreset = OtpFieldStylePreset.Heart, instanceKey = "heart")

    Text("Triangle")
    OTPField(otpLength = 4, stylePreset = OtpFieldStylePreset.Triangle, instanceKey = "triangle")

    Text("Pentagon")
    OTPField(otpLength = 4, stylePreset = OtpFieldStylePreset.Pentagon, instanceKey = "pentagon")

    Text("Filled Parallelogram")
    OTPField(otpLength = 4, stylePreset = OtpFieldStylePreset.FilledParallelogram, instanceKey = "parallelogram")
  }
}

About

No description, website, or topics provided.

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published