{"id":24614126,"url":"https://github.com/tkko/flutter_pinput","last_synced_at":"2025-05-14T09:06:45.157Z","repository":{"id":33190626,"uuid":"154554778","full_name":"Tkko/Flutter_Pinput","owner":"Tkko","description":"Flutter package to create Pin code input text field with every pixel customization possibility 🎨 with beautiful animations, iOS autofill, Android autofill","archived":false,"fork":false,"pushed_at":"2025-01-15T14:25:43.000Z","size":8033,"stargazers_count":803,"open_issues_count":23,"forks_count":184,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-05T22:02:25.569Z","etag":null,"topics":["android-autofill","autofill","code","flutter","flutter-package","flutter-pin-code","flutter-widget","ios-autofill","otp","phone-verification","pin","pincode","sms","smsautofill","smsretrieverapi","smsuserconsentapi","verification","verification-code"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/pinput","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tkko.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"ko_fi":"flutterman","custom":["https://www.buymeacoffee.com/fman"]}},"created_at":"2018-10-24T19:08:24.000Z","updated_at":"2025-04-05T18:22:20.000Z","dependencies_parsed_at":"2023-02-19T05:31:19.462Z","dependency_job_id":"92812f9f-5813-4d75-827f-0c35338f0fa3","html_url":"https://github.com/Tkko/Flutter_Pinput","commit_stats":{"total_commits":223,"total_committers":22,"mean_commits":"10.136363636363637","dds":"0.17488789237668156","last_synced_commit":"4970eaffdbe9e5058cb4939bc7b576abe8dfca8a"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tkko%2FFlutter_Pinput","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tkko%2FFlutter_Pinput/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tkko%2FFlutter_Pinput/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tkko%2FFlutter_Pinput/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tkko","download_url":"https://codeload.github.com/Tkko/Flutter_Pinput/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248646179,"owners_count":21138962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android-autofill","autofill","code","flutter","flutter-package","flutter-pin-code","flutter-widget","ios-autofill","otp","phone-verification","pin","pincode","sms","smsautofill","smsretrieverapi","smsuserconsentapi","verification","verification-code"],"created_at":"2025-01-24T21:15:06.214Z","updated_at":"2025-04-12T23:27:38.301Z","avatar_url":"https://github.com/Tkko.png","language":"Dart","readme":"\u003cdiv align=\"center\"\u003e  \n \u003ch1 align=\"center\" style=\"font-size: 70px;\"\u003eFlutter pin code input\u003c/h1\u003e\n\n\u003c!--  Donations --\u003e\n \u003ca href=\"https://ko-fi.com/flutterman\"\u003e\n  \u003cimg width=\"300\" src=\"https://user-images.githubusercontent.com/26390946/161375567-9e14cd0e-1675-4896-a576-a449b0bcd293.png\"\u003e\n \u003c/a\u003e\n \u003cdiv align=\"center\"\u003e\n   \u003ca href=\"https://www.buymeacoffee.com/fman\"\u003e\n    \u003cimg width=\"150\" alt=\"buymeacoffee\" src=\"https://user-images.githubusercontent.com/26390946/161375563-69c634fd-89d2-45ac-addd-931b03996b34.png\"\u003e\n  \u003c/a\u003e\n   \u003ca href=\"https://ko-fi.com/flutterman\"\u003e\n    \u003cimg width=\"150\" alt=\"Ko-fi\" src=\"https://user-images.githubusercontent.com/26390946/161375565-e7d64410-bbcf-4a28-896b-7514e106478e.png\"\u003e\n  \u003c/a\u003e\n \u003c/div\u003e\n\u003c!--  Donations --\u003e\n\n\u003ch3 align=\"center\" style=\"font-size: 35px;\"\u003eNeed anything Flutter related? Reach out on \u003ca href=\"https://www.linkedin.com/in/thornike/\"\u003eLinkedIn\u003c/a\u003e\n\u003c/h3\u003e\n\n\n[![Pub package](https://img.shields.io/pub/v/pinput.svg)](https://pub.dev/packages/pinput)\n[![Github starts](https://img.shields.io/github/stars/tkko/flutter_pinput.svg?style=flat\u0026logo=github\u0026colorB=deeppink\u0026label=stars)](https://github.com/tkko/flutter_pinput)\n[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://github.com/tenhobi/effective_dart)\n[![pub package](https://img.shields.io/badge/license-MIT-purple.svg)](https://opensource.org/licenses/MIT)\n\n\u003c/div\u003e\n\nFlutter Pinput is a package that provides an easy-to-use and customizable Pin code input field. It offers several features such as animated decoration switching, form validation, SMS autofill, custom cursor, copying from clipboard, and more. It also provides beautiful examples that you can choose from.\n\n## Features:\n- Animated Decoration Switching\n- Form validation\n- SMS Autofill on iOS\n- SMS Autofill on Android\n- Standard Cursor\n- Custom Cursor\n- Cursor Animation\n- Copy From Clipboard\n- Ready For Custom Keyboard\n- Standard Paste option\n- Obscuring Character\n- Obscuring Widget\n- Haptic Feedback\n- Close Keyboard After Completion\n- Beautiful [Examples](https://github.com/Tkko/Flutter_PinPut/tree/master/example/lib)\n\n## Support\n\nPRs Welcome\n\nDiscord [Channel](https://rebrand.ly/qwc3s0d)\n\n[Examples](https://github.com/Tkko/Flutter_PinPut/tree/master/example/lib) app on Github has multiple templates to choose from\n\nDon't forget to give it a star ⭐\n\n## Demo\n\n| [Live Demo](https://rebrand.ly/6390b8) | Rounded With Shadows | Rounded With Cursor |\n| - | - | - |\n| \u003ca href=\"https://rebrand.ly/6390b8\"\u003e\u003cimg width=\"300\" src=\"https://user-images.githubusercontent.com/26390946/155666045-aa93bf48-f8e7-407c-bb19-bc247d9e12bd.png\"/\u003e\u003c/a\u003e | \u003cimg width=\"300\" src=\"https://user-images.githubusercontent.com/26390946/155599527-fe934f2c-5124-4754-bbf6-bb97d55a77c0.gif\"/\u003e | \u003cimg width=\"300\" src=\"https://user-images.githubusercontent.com/26390946/155599870-03387689-7be2-4a30-8e6f-90136a0515be.gif\"/\u003e |\n\n| Rounded Filled | With Bottom Cursor | Filled |\n| - | - | - |\n| \u003cimg width=\"300\" src=\"https://user-images.githubusercontent.com/26390946/155600099-d0a02f55-09e6-4142-92de-066cd71cf211.gif\"/\u003e | \u003cimg width=\"300\" src=\"https://user-images.githubusercontent.com/26390946/155600276-0380b3b4-3d9c-4ea8-87d0-4f7ebd86e460.gif\"/\u003e | \u003cimg width=\"300\" src=\"https://user-images.githubusercontent.com/26390946/155600427-901c1eae-e565-4cf8-a338-8ac40eb1149c.gif\"/\u003e |\n\n## Getting Started\n\nThe pin has 6 states `default` `focused`, `submitted`, `following`, `disabled`, `error`, you can customize each state by specifying theme parameter.\nPin smoothly animates from one state to another automatically.\n`PinTheme Class`\n\n\n| Property    |    Default/Type    |\n|-------------|:------------------:|\n| width       |        56.0        |\n| height      |        60.0        |\n| textStyle   |    TextStyle()     |\n| margin      | EdgeInsetsGeometry |\n| padding     | EdgeInsetsGeometry |\n| constraints |   BoxConstraints   |\n\nYou can use standard Pinput like so\n\n```dart\nWidget buildPinPut() {\n  return Pinput(\n    onCompleted: (pin) =\u003e print(pin),\n  );\n}\n```\n\nIf you want to customize it, create `defaultPinTheme` first.\n\n```dart\nfinal defaultPinTheme = PinTheme(\n  width: 56,\n  height: 56,\n  textStyle: TextStyle(fontSize: 20, color: Color.fromRGBO(30, 60, 87, 1), fontWeight: FontWeight.w600),\n  decoration: BoxDecoration(\n    border: Border.all(color: Color.fromRGBO(234, 239, 243, 1)),\n    borderRadius: BorderRadius.circular(20),\n  ),\n);\n```\n\nif you want all pins to be the same don't pass other theme parameters,\nIf not, create `focusedPinTheme`, `submittedPinTheme`, `followingPinTheme`, `errorPinTheme` from `defaultPinTheme`\n\n```dart\nfinal focusedPinTheme = defaultPinTheme.copyDecorationWith(\n  border: Border.all(color: Color.fromRGBO(114, 178, 238, 1)),\n  borderRadius: BorderRadius.circular(8),\n);\n\nfinal submittedPinTheme = defaultPinTheme.copyWith(\n  decoration: defaultPinTheme.decoration.copyWith(\n    color: Color.fromRGBO(234, 239, 243, 1),\n  ),\n);\n```\n\nPut everything together\n\n```dart\nfinal defaultPinTheme = PinTheme(\n  width: 56,\n  height: 56,\n  textStyle: TextStyle(fontSize: 20, color: Color.fromRGBO(30, 60, 87, 1), fontWeight: FontWeight.w600),\n  decoration: BoxDecoration(\n    border: Border.all(color: Color.fromRGBO(234, 239, 243, 1)),\n    borderRadius: BorderRadius.circular(20),\n  ),\n);\n\nfinal focusedPinTheme = defaultPinTheme.copyDecorationWith(\n  border: Border.all(color: Color.fromRGBO(114, 178, 238, 1)),\n  borderRadius: BorderRadius.circular(8),\n);\n\nfinal submittedPinTheme = defaultPinTheme.copyWith(\n  decoration: defaultPinTheme.decoration.copyWith(\n    color: Color.fromRGBO(234, 239, 243, 1),\n  ),\n);\n\nreturn Pinput(\ndefaultPinTheme: defaultPinTheme,\nfocusedPinTheme: focusedPinTheme,\nsubmittedPinTheme: submittedPinTheme,\nvalidator: (s) {\nreturn s == '2222' ? null : 'Pin is incorrect';\n},\npinputAutovalidateMode: PinputAutovalidateMode.onSubmit,\nshowCursor: true,\nonCompleted: (pin) =\u003e print(pin),\n);\n```\n\n## SMS Autofill\n\n### iOS\n\nWorks out of the box, by tapping the code on top of the keyboard\n\n### Android\n\nIf you are using [firebase_auth](https://firebase.flutter.dev/docs/auth/phone#verificationcompleted) you have to set `controller'`s value in `verificationCompleted` callback, here is an example code:\n``` dart\n    Pinput(\n      controller: pinController,\n    );\n```\nAnd set pinController's value in `verificationCompleted` callback:\n``` dart\n    await FirebaseAuth.instance.verifyPhoneNumber(\n      verificationCompleted: (PhoneAuthCredential credential) {\n        pinController.setText(credential.smsCode);\n      },\n      verificationFailed: (FirebaseAuthException e) {},\n      codeSent: (String verificationId, int? resendToken) {},\n      codeAutoRetrievalTimeout: (String verificationId) {},\n    );\n```\n---\nIf you aren't using firebase_auth, you have two options, [SMS Retriever API](https://developers.google.com/identity/sms-retriever/overview?hl=en) and [SMS User Consent API](https://developers.google.com/identity/sms-retriever/user-consent/overview),\n\n[SmartAuth](https://pub.dev/packages/smart_auth) is a wrapper package for Flutter for these APIs, so go ahead and add it as a dependency.\n\n###### SMS Retriever API\n\nTo use Retriever API you need the App signature - [guide](https://stackoverflow.com/questions/53849023/android-sms-retriever-api-computing-apps-hash-string-problem)\n\n`Note that The App Signature might be different for debug and release mode`\n\nOnce you get the app signature, you should include it in the SMS message in you backend like so:\n\nSMS example:\n```\nYour ExampleApp code is: 123456\nkg+TZ3A5qzS\n```\n[Example Code](/example/lib/demo/sms_retriever_api_example.dart)\n\nSms code will be automatically applied, without user interaction.\n\n###### SMS User Consent API\n\nYou don't need the App signature, the user will be prompted to confirm reading the message\n[Example Code](/example/lib/demo/user_consent_api_example.dart)\n\n\n\u003cimg src=\"https://user-images.githubusercontent.com/26390946/158870589-a2d631fa-55d7-487f-8c30-d378bab4c21d.png\" style=\"height: 700px; width: auto; image-rendering: pixelated;\" alt=\"Request Hint\" /\u003e\n\n## See Example app for more [templates](https://github.com/Tkko/Flutter_PinPut/tree/master/example/lib)\n\n## Tips\n\n- #### Controller\n\n```dart\n/// Create Controller  \nfinal pinController = TextEditingController();\n\n/// Set text programmatically  \npinController.setText('1222');\n\n/// Append typed character, useful if you are using custom keyboard  \npinController.append('1', 4);\n\n/// Delete last character  \npinController.delete();\n\n/// Don't call setText, append, delete in build method, this is just illustration.  \n\nreturn Pinput(\n  controller: pinController,  \n);  \n```\n\n- #### Focus\n\n```dart\n/// Create FocusNode  \nfinal pinputFocusNode = FocusNode();\n\n/// Focus pinput  \npinputFocusNode.requestFocus();\n\n/// UnFocus pinput  \npinputFocusNode.unfocus();\n\n/// Don't call requestFocus, unfocus in build method, this is just illustration.  \n\nreturn Pinput(\n  focusNode: pinputFocusNode,\n);  \n```\n\n- #### Validation\n\n```dart\n/// Create key\nfinal formKey = GlobalKey\u003cFormState\u003e();\n\n/// Validate manually\n/// Don't call validate in build method, this is just illustration.\nformKey.currentState!.validate();\n\nreturn Form(\n  key: formKey,\n  child: Pinput(\n  // Without Validator\n  // If true error state will be applied no matter what validator returns\n  forceErrorState: true,\n  // Text will be displayed under the Pinput\n  errorText: 'Error',\n\n  /// ------------\n  /// With Validator\n  /// Auto validate after user tap on keyboard done button, or completes Pinput\n  pinputAutovalidateMode: PinputAutovalidateMode.onSubmit,\n  validator: (pin) {\n    if (pin == '2224') return null;\n\n    /// Text will be displayed under the Pinput\n    return 'Pin is incorrect';\n    },\n  ),\n);\n```\n\n## FAQ\n\n#### autofill isn't working on iOS?\n\n- Make sure you are using real device, not simulator\n- Temporary replace Pinput with TextField, and check if autofill works. If, not it's probably a\n  problem with SMS you are getting, autofill doesn't work with most of the languages\n- If you are using non stable version of Flutter that might be cause because something might be\n  broken inside the Framework\n\n#### are you using firebase_auth?\n\nYou should set `controller'`s value in `verificationCompleted` callback, here is an example code:\n``` dart\n    Pinput(\n      controller: pinController,\n    );\n    \n    await FirebaseAuth.instance.verifyPhoneNumber(\n      verificationCompleted: (PhoneAuthCredential credential) {\n        pinController.setText(credential.smsCode);\n      },\n      verificationFailed: (FirebaseAuthException e) {},\n      codeSent: (String verificationId, int? resendToken) {},\n      codeAutoRetrievalTimeout: (String verificationId) {},\n    );\n```","funding_links":["https://ko-fi.com/flutterman","https://www.buymeacoffee.com/fman"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftkko%2Fflutter_pinput","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftkko%2Fflutter_pinput","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftkko%2Fflutter_pinput/lists"}