diff --git a/CHANGELOG.md b/CHANGELOG.md index 11be543..c057c96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # [3.0.8](https://github.com/SimformSolutionsPvtLtd/flutter_credit_card/tree/3.0.8) (Unreleased) - Added web support for example app [#148](https://github.com/SimformSolutionsPvtLtd/flutter_credit_card/pull/148). +- Added card float animation [#144](https://github.com/SimformSolutionsPvtLtd/flutter_credit_card/pull/144). +- Fixed credit card padding in RTL [#139](https://github.com/SimformSolutionsPvtLtd/flutter_credit_card/pull/139). # [3.0.7](https://github.com/SimformSolutionsPvtLtd/flutter_credit_card/tree/3.0.7) diff --git a/README.md b/README.md index 7e3dc10..5d2ffa8 100644 --- a/README.md +++ b/README.md @@ -2,21 +2,48 @@ # Flutter Credit Card -![build](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/workflows/Build/badge.svg?branch=master) +![build](https://github.com/SimformSolutionsPvtLtd/flutter_credit_card/workflows/Build/badge.svg?branch=master) [![flutter_credit_card](https://img.shields.io/pub/v/flutter_credit_card?label=flutter_credit_card)](https://pub.dev/packages/flutter_credit_card) A Flutter package allows you to easily implement the Credit card's UI easily with the Card detection. ## Preview -![The example app running in Android](https://github.com/simformsolutions/flutter_credit_card/blob/master/readme_assets/preview.gif) + + + + + + + + + + +
+
+
Glassmorphism and Card Background
+
+ The example app showing credit card widget +
+
+
+
Floating Card on Mobile
+
+ The example app showing card floating animation in mobile +
+
+
+
Floating Card on Web
+
+ The example app showing card floating animation in web +
+
## Installing 1. Add dependency to `pubspec.yaml` - Get the latest version in the 'Installing' tab - on [pub.dev](https://pub.dev/packages/flutter_credit_card/install) + Get the latest version from the 'Installing' tab on [pub.dev](https://pub.dev/packages/flutter_credit_card/install) ```dart dependencies: @@ -38,6 +65,7 @@ import 'package:flutter_credit_card/flutter_credit_card.dart'; cardHolderName: cardHolderName, cvvCode: cvvCode, showBackView: isCvvFocused, //true when you want to show cvv(back) view + onCreditCardWidgetChange: (CreditCardBrand brand) {}, // Callback for anytime credit card brand is changed ), ``` @@ -49,7 +77,9 @@ import 'package:flutter_credit_card/flutter_credit_card.dart'; cardHolderName: cardHolderName, cvvCode: cvvCode, showBackView: isCvvFocused, - cardbgColor: Colors.black, + onCreditCardWidgetChange: (CreditCardBrand brand) {}, + bankName: 'Name of the Bank', + cardBgColor: Colors.black87, glassmorphismConfig: Glassmorphism.defaultConfig(), enableFloatingCard: true, floatConfig: FloatConfig( @@ -58,10 +88,14 @@ import 'package:flutter_credit_card/flutter_credit_card.dart'; shadowConfig: FloatShadowConfig.preset(), ), backgroundImage: 'assets/card_bg.png', + backgroundNetworkImage: 'https://www.xyz.com/card_bg.png', labelValidThru: 'VALID\nTHRU', obscureCardNumber: true, obscureInitialCardNumber: false, obscureCardCvv: true, + labelCardHolder: 'CARD HOLDER', + labelValidThru: 'VALID\nTHRU', + cardType: CardType.mastercard, isHolderNameVisible: false, height: 175, textStyle: TextStyle(color: Colors.yellowAccent), @@ -71,8 +105,10 @@ import 'package:flutter_credit_card/flutter_credit_card.dart'; animationDuration: Duration(milliseconds: 1000), frontCardBorder: Border.all(color: Colors.grey), backCardBorder: Border.all(color: Colors.grey), - customCardIcons: [ - CustomCardTypeImage( + chipColor: Colors.red, + padding: 16, + customCardTypeIcons: [ + CustomCardTypeIcons( cardType: CardType.mastercard, cardImage: Image.asset( 'assets/mastercard.png', @@ -155,18 +191,27 @@ You can do so by following ways: ```dart CreditCardForm( formKey: formKey, // Required + cardNumber: cardNumber, // Required + expiryDate: expiryDate, // Required + cardHolderName: cardHolderName, // Required + cvvCode: cvvCode, // Required cardNumberKey: cardNumberKey, cvvCodeKey: cvvCodeKey, expiryDateKey: expiryDateKey, cardHolderKey: cardHolderKey, onCreditCardModelChange: (CreditCardModel data) {}, // Required - themeColor: Colors.red, + themeColor: Colors.black, // Required + textColor: Colors.white, + cursorColor: Colors.blue, obscureCvv: true, obscureNumber: true, isHolderNameVisible: true, isCardNumberVisible: true, isExpiryDateVisible: true, enableCvv: true, + cvvValidationMessage: 'Please input a valid CVV', + dateValidationMessage: 'Please input a valid date', + numberValidationMessage: 'Please input a valid number', cardNumberValidator: (String? cardNumber){}, expiryDateValidator: (String? expiryDate){}, cvvValidator: (String? cvv){}, @@ -174,6 +219,8 @@ You can do so by following ways: onFormComplete: () { // callback to execute at the end of filling card data }, + autovalidateMode: AutovalidateMode.always, + disableCardNumberAutoFillHints: false, cardNumberDecoration: const InputDecoration( border: OutlineInputBorder(), labelText: 'Number', @@ -196,7 +243,6 @@ You can do so by following ways: ), ``` - ## How to use Check out the **example** app in the [example](example) directory or the 'Example' tab on pub.dartlang.org for a more complete example. @@ -217,12 +263,14 @@ Check out the **example** app in the [example](example) directory or the 'Exampl
Shweta Chauhan

Kavan Trivedi

Ujas Majithiya
+
Aditya Chavda

## Awesome Mobile Libraries - Check out our other available [awesome mobile libraries](https://github.com/SimformSolutionsPvtLtd/Awesome-Mobile-Libraries) + ## Note We have updated license of flutter_credit_card from BSD 2-Clause "Simplified" to MIT. @@ -250,6 +298,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - ``` diff --git a/example/assets/bg.png b/example/assets/bg-dark.png similarity index 100% rename from example/assets/bg.png rename to example/assets/bg-dark.png diff --git a/example/assets/bg-light.png b/example/assets/bg-light.png new file mode 100644 index 0000000..f7bcfb8 Binary files /dev/null and b/example/assets/bg-light.png differ diff --git a/example/lib/app_colors.dart b/example/lib/app_colors.dart index 0393a37..1d676a4 100644 --- a/example/lib/app_colors.dart +++ b/example/lib/app_colors.dart @@ -4,8 +4,9 @@ class AppColors { AppColors._(); static const Color cardBgColor = Color(0xff363636); + static const Color cardBgLightColor = Color(0xff999999); static const Color colorB58D67 = Color(0xffB58D67); static const Color colorE5D1B2 = Color(0xffE5D1B2); static const Color colorF9EED2 = Color(0xffF9EED2); - static const Color colorFFFFFD = Color(0xffFFFFFD); + static const Color colorEFEFED = Color(0xffEFEFED); } diff --git a/example/lib/main.dart b/example/lib/main.dart index d3dd552..be7a210 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,5 +1,6 @@ import 'package:example/app_colors.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_credit_card/credit_card_brand.dart'; import 'package:flutter_credit_card/flutter_credit_card.dart'; @@ -13,6 +14,7 @@ class MySample extends StatefulWidget { } class MySampleState extends State { + bool isLightTheme = false; String cardNumber = ''; String expiryDate = ''; String cardHolderName = ''; @@ -31,235 +33,256 @@ class MySampleState extends State { @override Widget build(BuildContext context) { + SystemChrome.setSystemUIOverlayStyle( + isLightTheme ? SystemUiOverlayStyle.dark : SystemUiOverlayStyle.light, + ); return MaterialApp( title: 'Flutter Credit Card View Demo', debugShowCheckedModeBanner: false, + themeMode: isLightTheme ? ThemeMode.light : ThemeMode.dark, theme: ThemeData( - primarySwatch: Colors.blue, + brightness: Brightness.light, + primaryColor: Colors.white, + scaffoldBackgroundColor: Colors.black, + ), + darkTheme: ThemeData( + brightness: Brightness.dark, + primaryColor: Colors.black, + scaffoldBackgroundColor: Colors.white, ), home: Scaffold( resizeToAvoidBottomInset: false, - body: Container( - decoration: const BoxDecoration( - image: DecorationImage( - image: ExactAssetImage('assets/bg.png'), - fit: BoxFit.fill, - ), - color: Colors.black, - ), - child: SafeArea( - child: Column( - children: [ - const SizedBox( - height: 30, + body: Builder( + builder: (BuildContext context) { + final Color bgColor = Theme.of(context).scaffoldBackgroundColor; + return Container( + decoration: BoxDecoration( + color: bgColor, + image: DecorationImage( + image: ExactAssetImage( + isLightTheme ? 'assets/bg-light.png' : 'assets/bg-dark.png', + ), + fit: BoxFit.fill, ), - CreditCardWidget( - enableFloatingCard: useFloatingAnimation, - glassmorphismConfig: - useGlassMorphism ? Glassmorphism.defaultConfig() : null, - cardNumber: cardNumber, - expiryDate: expiryDate, - cardHolderName: cardHolderName, - cvvCode: cvvCode, - bankName: 'Axis Bank', - frontCardBorder: - !useGlassMorphism ? Border.all(color: Colors.grey) : null, - backCardBorder: - !useGlassMorphism ? Border.all(color: Colors.grey) : null, - showBackView: isCvvFocused, - obscureCardNumber: true, - obscureCardCvv: true, - isHolderNameVisible: true, - cardBgColor: AppColors.cardBgColor, - backgroundImage: - useBackgroundImage ? 'assets/card_bg.png' : null, - isSwipeGestureEnabled: true, - onCreditCardWidgetChange: - (CreditCardBrand creditCardBrand) {}, - customCardTypeIcons: [ - CustomCardTypeIcon( - cardType: CardType.mastercard, - cardImage: Image.asset( - 'assets/mastercard.png', - height: 48, - width: 48, + ), + child: SafeArea( + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + IconButton( + onPressed: () => setState(() { + isLightTheme = !isLightTheme; + }), + icon: Icon( + isLightTheme ? Icons.light_mode : Icons.dark_mode, ), ), - ], - ), - Expanded( - child: SingleChildScrollView( - child: Column( - children: [ - CreditCardForm( - formKey: formKey, - obscureCvv: true, - obscureNumber: true, - cardNumber: cardNumber, - cvvCode: cvvCode, - isHolderNameVisible: true, - isCardNumberVisible: true, - isExpiryDateVisible: true, - cardHolderName: cardHolderName, - expiryDate: expiryDate, - themeColor: Colors.blue, - textColor: Colors.white, - cardNumberDecoration: InputDecoration( - labelText: 'Number', - hintText: 'XXXX XXXX XXXX XXXX', - hintStyle: const TextStyle(color: Colors.white), - labelStyle: const TextStyle(color: Colors.white), - focusedBorder: border, - enabledBorder: border, + CreditCardWidget( + enableFloatingCard: useFloatingAnimation, + glassmorphismConfig: _getGlassmorphismConfig(), + cardNumber: cardNumber, + expiryDate: expiryDate, + cardHolderName: cardHolderName, + cvvCode: cvvCode, + bankName: 'Axis Bank', + frontCardBorder: useGlassMorphism + ? null + : Border.all(color: Colors.grey), + backCardBorder: useGlassMorphism + ? null + : Border.all(color: Colors.grey), + showBackView: isCvvFocused, + obscureCardNumber: true, + obscureCardCvv: true, + isHolderNameVisible: true, + cardBgColor: isLightTheme + ? AppColors.cardBgLightColor + : AppColors.cardBgColor, + backgroundImage: + useBackgroundImage ? 'assets/card_bg.png' : null, + isSwipeGestureEnabled: true, + onCreditCardWidgetChange: + (CreditCardBrand creditCardBrand) {}, + customCardTypeIcons: [ + CustomCardTypeIcon( + cardType: CardType.mastercard, + cardImage: Image.asset( + 'assets/mastercard.png', + height: 48, + width: 48, ), - expiryDateDecoration: InputDecoration( - hintStyle: const TextStyle(color: Colors.white), - labelStyle: const TextStyle(color: Colors.white), - focusedBorder: border, - enabledBorder: border, - labelText: 'Expired Date', - hintText: 'XX/XX', - ), - cvvCodeDecoration: InputDecoration( - hintStyle: const TextStyle(color: Colors.white), - labelStyle: const TextStyle(color: Colors.white), - focusedBorder: border, - enabledBorder: border, - labelText: 'CVV', - hintText: 'XXX', - ), - cardHolderDecoration: InputDecoration( - hintStyle: const TextStyle(color: Colors.white), - labelStyle: const TextStyle(color: Colors.white), - focusedBorder: border, - enabledBorder: border, - labelText: 'Card Holder', - ), - onCreditCardModelChange: onCreditCardModelChange, ), - const SizedBox( - height: 20, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'Glassmorphism', - style: TextStyle( - color: Colors.white, - fontSize: 18, - ), + ], + ), + Expanded( + child: SingleChildScrollView( + child: Column( + children: [ + CreditCardForm( + formKey: formKey, + obscureCvv: true, + obscureNumber: true, + cardNumber: cardNumber, + cvvCode: cvvCode, + isHolderNameVisible: true, + isCardNumberVisible: true, + isExpiryDateVisible: true, + cardHolderName: cardHolderName, + expiryDate: expiryDate, + themeColor: Theme.of(context).primaryColor, + textColor: bgColor, + cardNumberDecoration: InputDecoration( + labelText: 'Number', + hintText: 'XXXX XXXX XXXX XXXX', + hintStyle: TextStyle(color: bgColor), + labelStyle: TextStyle(color: bgColor), + focusedBorder: border, + enabledBorder: border, ), - const Spacer(), - Switch( - value: useGlassMorphism, - inactiveTrackColor: Colors.grey, - activeColor: Colors.white, - activeTrackColor: AppColors.colorE5D1B2, - onChanged: (bool value) => setState(() { - useGlassMorphism = value; - }), + expiryDateDecoration: InputDecoration( + hintStyle: TextStyle(color: bgColor), + labelStyle: TextStyle(color: bgColor), + focusedBorder: border, + enabledBorder: border, + labelText: 'Expired Date', + hintText: 'XX/XX', ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'Card Image', - style: TextStyle( - color: Colors.white, - fontSize: 18, - ), + cvvCodeDecoration: InputDecoration( + hintStyle: TextStyle(color: bgColor), + labelStyle: TextStyle(color: bgColor), + focusedBorder: border, + enabledBorder: border, + labelText: 'CVV', + hintText: 'XXX', ), - const Spacer(), - Switch( - value: useBackgroundImage, - inactiveTrackColor: Colors.grey, - activeColor: Colors.white, - activeTrackColor: AppColors.colorE5D1B2, - onChanged: (bool value) => setState(() { - useBackgroundImage = value; - }), + cardHolderDecoration: InputDecoration( + hintStyle: TextStyle(color: bgColor), + labelStyle: TextStyle(color: bgColor), + focusedBorder: border, + enabledBorder: border, + labelText: 'Card Holder', ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'Floating Card', - style: TextStyle( - color: Colors.white, - fontSize: 18, - ), + onCreditCardModelChange: onCreditCardModelChange, + ), + const SizedBox(height: 20), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + 'Glassmorphism', + style: TextStyle(fontSize: 18), + ), + const Spacer(), + Switch( + value: useGlassMorphism, + inactiveTrackColor: Colors.grey, + activeColor: Colors.white, + activeTrackColor: AppColors.colorE5D1B2, + onChanged: (bool value) => setState(() { + useGlassMorphism = value; + }), + ), + ], ), - const Spacer(), - Switch( - value: useFloatingAnimation, - inactiveTrackColor: Colors.grey, - activeColor: Colors.white, - activeTrackColor: AppColors.colorE5D1B2, - onChanged: (bool value) => setState(() { - useFloatingAnimation = value; - }), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + 'Card Image', + style: TextStyle(fontSize: 18), + ), + const Spacer(), + Switch( + value: useBackgroundImage, + inactiveTrackColor: Colors.grey, + activeColor: Colors.white, + activeTrackColor: AppColors.colorE5D1B2, + onChanged: (bool value) => setState(() { + useBackgroundImage = value; + }), + ), + ], ), - ], - ), - ), - const SizedBox( - height: 20, - ), - GestureDetector( - onTap: _onValidate, - child: Container( - margin: const EdgeInsets.symmetric( - horizontal: 16, vertical: 8), - decoration: BoxDecoration( - gradient: const LinearGradient( - colors: [ - AppColors.colorB58D67, - AppColors.colorB58D67, - AppColors.colorE5D1B2, - AppColors.colorF9EED2, - AppColors.colorFFFFFD, - AppColors.colorF9EED2, - AppColors.colorB58D67, + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 16), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + 'Floating Card', + style: TextStyle(fontSize: 18), + ), + const Spacer(), + Switch( + value: useFloatingAnimation, + inactiveTrackColor: Colors.grey, + activeColor: Colors.white, + activeTrackColor: AppColors.colorE5D1B2, + onChanged: (bool value) => setState(() { + useFloatingAnimation = value; + }), + ), ], - begin: Alignment(-1, -4), - end: Alignment(1, 4), ), - borderRadius: BorderRadius.circular(8), ), - padding: const EdgeInsets.symmetric(vertical: 15), - width: double.infinity, - alignment: Alignment.center, - child: const Text( - 'Validate', - style: TextStyle( - color: Colors.black, - fontFamily: 'halter', - fontSize: 14, - package: 'flutter_credit_card', + const SizedBox(height: 20), + GestureDetector( + onTap: _onValidate, + child: Container( + margin: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [ + AppColors.colorB58D67, + AppColors.colorB58D67, + AppColors.colorE5D1B2, + AppColors.colorF9EED2, + AppColors.colorEFEFED, + AppColors.colorF9EED2, + AppColors.colorB58D67, + ], + begin: Alignment(-1, -4), + end: Alignment(1, 4), + ), + borderRadius: BorderRadius.all( + Radius.circular(8), + ), + ), + padding: + const EdgeInsets.symmetric(vertical: 15), + alignment: Alignment.center, + child: const Text( + 'Validate', + style: TextStyle( + color: Colors.black, + fontFamily: 'halter', + fontSize: 14, + package: 'flutter_credit_card', + ), + ), ), ), - ), + ], ), - ], + ), ), - ), + ], ), - ], - ), - ), + ), + ); + }, ), ), ); @@ -273,6 +296,23 @@ class MySampleState extends State { } } + Glassmorphism? _getGlassmorphismConfig() { + if (!useGlassMorphism) { + return null; + } + + final LinearGradient gradient = LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [Colors.grey.withAlpha(50), Colors.grey.withAlpha(50)], + stops: const [0.3, 0], + ); + + return isLightTheme + ? Glassmorphism(blurX: 8.0, blurY: 16.0, gradient: gradient) + : Glassmorphism.defaultConfig(); + } + void onCreditCardModelChange(CreditCardModel creditCardModel) { setState(() { cardNumber = creditCardModel.cardNumber; diff --git a/ios/.gitignore b/ios/.gitignore index 0c88507..034771f 100644 --- a/ios/.gitignore +++ b/ios/.gitignore @@ -35,4 +35,4 @@ Icon? /Flutter/Generated.xcconfig /Flutter/ephemeral/ -/Flutter/flutter_export_environment.sh \ No newline at end of file +/Flutter/flutter_export_environment.sh diff --git a/lib/constants.dart b/lib/constants.dart index 269930e..eefe99e 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -23,7 +23,8 @@ class AppConstants { /// Gyroscope channel constants static const String gyroMethodChannelName = 'com.simform.flutter_credit_card'; - static const String gyroEventChannelName = 'com.simform.flutter_credit_card/gyroscope'; + static const String gyroEventChannelName = + 'com.simform.flutter_credit_card/gyroscope'; static const String isGyroAvailableMethod = 'isGyroscopeAvailable'; static const String initiateMethod = 'initiateEvents'; static const String cancelMethod = 'cancelEvents'; diff --git a/readme_assets/credit_card_float_cursor_preview.gif b/readme_assets/credit_card_float_cursor_preview.gif new file mode 100644 index 0000000..d37c7fa Binary files /dev/null and b/readme_assets/credit_card_float_cursor_preview.gif differ diff --git a/readme_assets/credit_card_float_preview.gif b/readme_assets/credit_card_float_preview.gif new file mode 100644 index 0000000..3b69c4c Binary files /dev/null and b/readme_assets/credit_card_float_preview.gif differ diff --git a/readme_assets/preview.gif b/readme_assets/preview.gif index a2cb684..a8c2d1b 100644 Binary files a/readme_assets/preview.gif and b/readme_assets/preview.gif differ