π’ animated_otp_input
A highly customizable, animated, and accessible One-Time Password (OTP) input widget for Flutter. Supports advanced theming, error handling, accessibility, and smooth user experience for OTP, PIN, or verification code entry.
β¨ Features
- π§© Customizable OTP length and appearance: Choose the number of fields, field size, spacing, and border style.
- π Smart paste detection: Autofills all fields when a full OTP is pasted.
- π― Auto-focus navigation: Focus automatically shifts as the user types or deletes.
- π‘οΈ Obscured input for privacy: Hide digits for PIN entry with a custom obscuring character.
- π¨ Advanced theming: Use
OtpInputTheme
to style borders, colors, text, animation, and error messages. - π Consistent LTR layout: Always left-to-right for digit entry, even in RTL locales.
- π§ Auto-submit support: Easily trigger actions when the OTP is complete via
onChanged
. - π« Disable input: Make fields read-only during loading or verification.
- βΏ Accessibility: Semantics labels and hints for screen readers, fully customizable.
- β οΈ Error handling: Per-field error indication and group-level error messages with custom styles.
- π Animated focus: Customizable scale, duration, and curve for field focus animations.
- π³ Haptic feedback: Optionally trigger haptic feedback on success or error, with customizable feedback type for tactile confirmation.
π Installation
Add the package using the command line:
flutter pub add animated_otp_input
Or manually add to your pubspec.yaml
:
dependencies:
animated_otp_input: ^1.0.6
Then run:
flutter pub get
Import the package:
import 'package:animated_otp_input/animated_otp_input.dart';
π¦ Usage
Basic Example
AnimatedOtpInput(
length: 6,
onChanged: (otp) {
print('Entered OTP: $otp');
},
)
Error Message Example
AnimatedOtpInput(
length: 4,
errorMessage: 'Please fill all fields', // Show error message below the fields
theme: OtpInputTheme(
errorMessageStyle: TextStyle(
color: Colors.deepOrange,
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
onChanged: (otp) {
// Show error if not all fields are filled
},
)
π§βπ» Parameters
Name | Type | Default | Description |
---|---|---|---|
length |
int |
6 |
Number of OTP digits. |
onChanged |
void Function(String)? |
null |
Callback triggered when the OTP value changes. |
enabled |
bool |
true |
Enables or disables the input fields. |
fieldWidth |
double |
45 |
Width of each OTP input field. |
fieldSpacing |
double |
4 |
Horizontal spacing between input fields. |
theme |
OtpInputTheme |
const OtpInputTheme() |
Customize input decoration, text style, colors, animation, errors. |
obscureText |
bool |
false |
Whether to obscure each input (e.g., for PIN input). |
obscureCharacter |
String |
'β’' |
The character used when obscureText is true. |
autoFocusFirstField |
bool |
false |
Whether to autofocus the first input field when the widget builds. |
errorMessage |
String? |
null |
Group-level error message shown below the fields. If set, empty fields will show error borders and the message will be displayed. |
semanticsLabel |
String |
'OTP digit' |
Base label for accessibility (screen readers). |
semanticsHint |
String? |
null |
Base hint for accessibility. |
enableSuccessHaptic |
bool? |
true |
Enable haptic feedback on successful OTP entry. |
enableErrorHaptic |
bool? |
true |
Enable haptic feedback on OTP entry error. |
successHapticFeedback |
OtpHapticType? |
OtpHapticType.light |
Custom haptic feedback type for success. |
errorHapticFeedback |
OtpHapticType? |
OtpHapticType.heavy |
Custom haptic feedback type for error. |
π¨ Customization
Theming with OtpInputTheme
AnimatedOtpInput(
length: 4,
fieldWidth: 48,
fieldSpacing: 8,
theme: OtpInputTheme(
border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)),
fillColor: Colors.grey.shade100,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.deepPurple),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
textStyle: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
errorMessageStyle: TextStyle(
color: Colors.deepOrange,
fontWeight: FontWeight.bold,
fontSize: 14,
),
borderSideWidth: 2.0, // Custom border width
focusedScale: 1.2, // Custom scale animation
animationDuration: Duration(milliseconds: 300),
animationCurve: Curves.easeInOut, // Custom animation curve
),
)
Enable Obscured Input
AnimatedOtpInput(
obscureText: true,
obscureCharacter: '*', // Default: β’
)
Disable Input
AnimatedOtpInput(
enabled: false,
)
Autofocus First Field
AnimatedOtpInput(
autoFocusFirstField: true,
)
Accessibility Customization
AnimatedOtpInput(
semanticsLabel: 'Verification digit',
semanticsHint: 'Enter the digit for verification',
)
Haptic Feedback Customization
You can control the type and intensity of haptic feedback for both success and error events using the following parameters:
enableSuccessHaptic
: Enable/disable haptic feedback when OTP is successfully entered.enableErrorHaptic
: Enable/disable haptic feedback when an error occurs.successHapticFeedback
: Choose the feedback type for success (light
,medium
,heavy
,vibrate
,none
).errorHapticFeedback
: Choose the feedback type for error (light
,medium
,heavy
,vibrate
,none
).
Example:
AnimatedOtpInput(
enableSuccessHaptic: true,
enableErrorHaptic: true,
successHapticFeedback: OtpHapticType.medium,
errorHapticFeedback: OtpHapticType.vibrate,
)
π§ͺ Testing
Comprehensive widget tests are included for error indication, error message display, custom error styles, accessibility, animation, and more. See the test/
directory for details.
πΈ Demo
π License
This project is licensed under the MIT License.
π€ Contributions
Contributions, issues, and feature requests are welcome!
Feel free to open an issue or submit a pull request.
β Feedback
If you find this package helpful, please give it a β on pub.flutter-io.cn and share it with others.
Libraries
- animated_otp_input
- A beautiful animated OTP input widget with paste detection, auto-submit, and more.