Skip to content

saadkhalidkhan/PinFlow

Repository files navigation

PinFlow

CI Docs Maven Central JitPack Release License API Kotlin Compose

PinFlow is a lightweight, animated, and customizable OTP / PIN input library for Jetpack Compose. Built with Material 3, smart paste handling, secure PIN mode, and smooth interaction states — add polished verification flows in minutes.

Report a bug · Contributing · Security

PinFlow sample app demo


Table of contents

Features

Feature Description
Single hidden field One BasicTextField — reliable keyboard, paste, and a11y
Smart paste Paste 123456 and all slots fill automatically
Modes Boxes, Underline, Circle, SingleField, SecurePin
Motion Bounce, Glow, ShakeOnError, Slide — pick per screen
Secure PIN Masking + optional reveal-last-digit
Validation PinFlowValidator helpers + onComplete callback
Material 3 PinFlowDefaults.colors() / dimensions()

Preview

Boxes + smart paste Underline + shake Alphanumeric (6)
Boxes + paste Underline Alphanumeric

Installation

Maven Central

// settings.gradle.kts
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}
// build.gradle.kts
dependencies {
    implementation("io.github.saadkhalidkhan:pinflow-compose:1.0.0")
}

Available on Maven Central. See PUBLISHING.md for newer versions and RELEASE_CHECKLIST.md to ship releases.

JitPack

JitPack v1.0.0

Step 1. Add the JitPack repository in settings.gradle.kts (at the end of repositories):

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://jitpack.io") }
    }
}

Step 2. Add the dependency in build.gradle.kts:

dependencies {
    implementation("com.github.saadkhalidkhan:PinFlow:1.0.0")
}

Build status: green on JitPack for v1.0.0.

Local module (development)

dependencies {
    implementation(project(":pinflow"))
}

Quick start

import com.pinflow.compose.PinFlow
import com.pinflow.compose.PinFlowMode
import com.pinflow.compose.PinFlowValidator

var code by remember { mutableStateOf("") }

PinFlow(
    value = code,
    onValueChange = { code = it },
    length = 6,
    mode = PinFlowMode.Boxes,
    isSuccess = PinFlowValidator.isComplete(code, 6),
    onComplete = { submitted -> verifyOnServer(submitted) },
)

Usage examples

Secure PIN (app lock / payment)

PinFlow(
    value = pin,
    onValueChange = { pin = it },
    mode = PinFlowMode.SecurePin,
    revealLastDigit = true,
)

Error shake

val isError = code == "1234"

PinFlow(
    value = code,
    onValueChange = { code = it },
    mode = PinFlowMode.Underline,
    isError = isError,
    animations = setOf(PinFlowAnimation.ShakeOnError, PinFlowAnimation.Bounce),
)

Success + slide (demo code 5678)

PinFlow(
    value = code,
    onValueChange = { code = it },
    isSuccess = PinFlowValidator.isComplete(code, 4) && code == "5678",
    animations = setOf(PinFlowAnimation.Slide, PinFlowAnimation.Glow),
)

Custom theme & size

PinFlow(
    value = otp,
    onValueChange = { otp = it },
    colors = PinFlowDefaults.colors(),
    dimensions = PinFlowDefaults.dimensions(
        cellWidth = 52.dp,
        spacing = 10.dp,
        cornerRadius = 14.dp,
    ),
    animations = setOf(PinFlowAnimation.Slide, PinFlowAnimation.Glow),
)

Single-field layout

PinFlow(
    value = code,
    onValueChange = { code = it },
    length = 6,
    mode = PinFlowMode.SingleField,
)

Validation helpers

PinFlowValidator.isComplete(otp, length = 6)
PinFlowValidator.isNumeric(otp)
PinFlowValidator.hasRepeatedDigits(otp)

API documentation

HTML API reference is generated with Dokka and published to GitHub Pages:

https://saadkhalidkhan.github.io/PinFlow/

Generate locally:

./gradlew :pinflow:dokkaGeneratePublicationHtml
# open pinflow/build/dokka/html/index.html

Sample app

./gradlew :sample:installDebug

The sample demonstrates all modes, secure PIN, success/slide, single-field, and alphanumeric input.


Project structure

Module Description
:pinflow Android library (minSdk 23)
:sample Demo application

Publishing & CI

Workflow Purpose
CI Tests, assemble, Dokka on every push/PR
Docs Deploy Dokka to GitHub Pages
Release Publish to Maven Central on v* tags (or manual run)
Guide Purpose
PUBLISHING.md Maven Central + JitPack install & troubleshooting
RELEASE_CHECKLIST.md Step-by-step for each new version
.github/SETUP_SECRETS.md Optional GitHub Actions secrets for CI publish
.github/SETUP_PAGES.md One-time GitHub Pages enablement for API docs
gradle.properties.example Local credentials template (do not commit secrets)

Contributing

Contributions are welcome. Please read CONTRIBUTING.md and SECURITY.md before opening an issue or pull request.

  1. Open an issue to discuss larger changes.
  2. Fork the repo and create a branch from master.
  3. Run ./gradlew :pinflow:testDebugUnitTest :sample:assembleDebug before opening a PR.
  4. Open a pull request with a clear description and media for UI changes.

License

This project is licensed under the Apache License 2.0 — see LICENSE.

Copyright 2026 Saad Khan

Author

Saad KhanGitHub · Medium · ranasaad0799@gmail.com

If this library helps you, consider starring the repo.

About

No description, website, or topics provided.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages