{"id":13551014,"url":"https://github.com/gbmiranda/flutter_plus","last_synced_at":"2025-10-31T23:30:20.832Z","repository":{"id":40568203,"uuid":"303819818","full_name":"gbmiranda/flutter_plus","owner":"gbmiranda","description":"Develop applications in Flutter more quickly and easily. Customize Containers, Buttons, Texts and TextFields in a few lines. Navigate between Screens and open BottomSheets, Dialogs and Snackbars without context from any point.","archived":false,"fork":false,"pushed_at":"2024-05-29T15:13:48.000Z","size":3034,"stargazers_count":21,"open_issues_count":2,"forks_count":8,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-29T09:43:37.116Z","etag":null,"topics":["android","biblioteca","dart","flutter","ingles","ios","portugues","pubspec","yaml"],"latest_commit_sha":null,"homepage":"","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/gbmiranda.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"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}},"created_at":"2020-10-13T20:21:21.000Z","updated_at":"2024-07-12T16:41:38.000Z","dependencies_parsed_at":"2023-11-20T22:27:10.635Z","dependency_job_id":"21b6e5cf-4289-4eaf-b95a-42ac4edc955a","html_url":"https://github.com/gbmiranda/flutter_plus","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbmiranda%2Fflutter_plus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbmiranda%2Fflutter_plus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbmiranda%2Fflutter_plus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbmiranda%2Fflutter_plus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gbmiranda","download_url":"https://codeload.github.com/gbmiranda/flutter_plus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238829554,"owners_count":19537720,"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","biblioteca","dart","flutter","ingles","ios","portugues","pubspec","yaml"],"created_at":"2024-08-01T12:01:41.184Z","updated_at":"2025-10-31T23:30:20.769Z","avatar_url":"https://github.com/gbmiranda.png","language":"Dart","funding_links":[],"categories":["Dart"],"sub_categories":[],"readme":"\u003e #### 🌐 _Languages: EN_ - [PT](README_PT.md)\n\n[![likes](https://badges.bar/flutter_plus/likes)](https://pub.dev/packages/flutter_plus/score)\n[![popularity](https://badges.bar/flutter_plus/popularity)](https://pub.dev/packages/flutter_plus/score)\n[![pub points](https://badges.bar/flutter_plus/pub%20points)](https://pub.dev/packages/flutter_plus/score) \n\n# 🗂 Index\n\n- [FlutterPlus](#-flutterplus)\n\t- [Demonstration](#-demonstration)\n- [Installation](#-installation)\n- [Examples](#-examples)\n\t- [Widgets](#-widgets)\n\t\t- [ContainerPlus](#-containerplus)\n\t\t- [ButtonPlus](#-buttonplus)\n\t\t- [TextFieldPlus](#-textfieldplus)\n\t\t- [TextPlus](#-textplus)\n\t\t- [RichTextPlus](#-richtextplus)\n\t- [Utils](#-utils)\n\t\t- [NavigatorPlus](#-navigatorplus)\n\t\t- [BottomSheetPlus](#-bottomsheetplus)\n\t\t- [DialogPlus](#-dialogplus)\n\t\t- [SnackBarPlus](#-snackbarplus)\n\t\t- [LocalStoragePlus](#-localstorageplus)\n\t\t- [UtilsPlus](#-utilsplus)\n\t- [Extensions](#-extensions)\n\t\t- [StringExtensionPlus](#-stringextensionplus)\n\t\t- [DateExtensionPlus](#-dateextensionplus)\n\t\t- [NumExtensionPlus](#-numextensionplus)\n\t\t- [FileExtensionPlus](#-fileextensionplus)\n\t\t- [DurationExtensionPlus](#-durationextensionplus)\n\t- [Attributes](#-attributes)\n\t\t- [BorderPlus](#-borderplus)\n\t\t- [GradientPlus](#-gradientplus)\n\t\t- [InnerShadowPlus](#-innershadowplus)\n\t\t- [RadiusPlus](#-radiusplus)\n\t\t- [ShadowPlus](#-shadowplus)\n\t\t- [SkeletonPlus](#-skeletonplus)\n\t\t- [TextDecorationPlus](#-textdecorationplus)\n- [Next steps](#-next-steps)\n\n# 👾 FlutterPlus\n\n### Creating apps using Flutter is great, but it can get better!\n\nFlutterPlus is an open-source library created to make Flutter development faster, easier and more intuitive.\n\nCreate **Containers**, **Buttons**, **TextFields**, **Texts** and **RichTexts** customized with few lines.\n\nNavigate between **Screens**, open **BottomSheets**, **Dialogs** and **Snackbars** without context anywhere in your code.\n\nUse extensions to treat **dates**, **strings**, **numbers** and **files**.\n\n\u003e Many of the solutions found here were created for my own use throughout my journey with Flutter.\n\n\u003e I decided to bring everything together in a single place to help my work and that of anyone interested. ;)\n\n\u003e I will always try to keep the documentation up to date but it may happen that I forget to put something or other here.\n\n## 🍬 Demonstration\n\nAn appetizer of the real meaning of the library. Two codes that do the same thing, the first using the library and the second with native widgets.\n\n\u003e A customized Container with centralized text that accepts user interaction.\n\n![FlutterPlus compare](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/comparativo.png)\n\n# 🔩 Installation\n\nAdd the \u003cb\u003eflutter_plus\u003c/b\u003e dependency to your project's \u003cb\u003epubspec.yaml\u003c/b\u003e file.\n\n```yaml\ndependencies:\n  flutter_plus: any\n```\n\nImport a single file to access all components.\n\n```dart\nimport 'package:flutter_plus/flutter_plus.dart';\n```\n\n\u003e **- This library will always be in constant evolution, so:**\n\u003e \n\u003e 1- If you don't want to have problems with names or attributes changing and stopping, I suggest setting the version when you start using it.\n\u003e \n\u003e 2- If you're like me who likes evolution and don't mind a little rework when it is for the best, leave it without a fixed version and stay tuned for updates ;) \n\n_*No extra adjustments are required to work on iOS, Android, Web or Desktop._\n\n# 📚 Examples\n\nThe following are examples of how to use and configure the main features of the library.\n\n_*You can also find an example project showing how to use the library [here](https://github.com/gbmiranda/flutter_plus/tree/master/example)._\n\n## 🛠 Widgets\n\nThe *Widgets* below are evolutions of the native Flutter. They were created to increase productivity and facilitate customization, with more powerful and intuitive attributes.\n\n\u003e **Create more complex widgets with less code.**\n\n### `📌 ContainerPlus`\n\nFor me, the *Container* widget is the basis of Flutter. Our **ContainerPlus** is an evolution of the native, easier to customize and with several properties.\n\n\u003e **Example 1:**\n\n```dart\nContainerPlus(\n  width: 150,\n  height: 150,\n  radius: RadiusPlus.all(20),\n  color: Colors.yellow,\n  shadows: [\n    ShadowPlus(\n      color: Colors.red,\n      moveDown: -10,\n      moveRight: -10,\n      blur: 5,\n      spread: 1,\n      opacity: 0.2,\n    ),\n    ShadowPlus(\n      color: Colors.blue,\n      moveDown: 10,\n      moveRight: 10,\n      blur: 10,\n      spread: 5,\n      opacity: 0.5,\n    ),\n  ],\n  border: BorderPlus(\n    color: Colors.black,\n    width: 2,\n  ),\n  child: TextPlus(\n    'EXAMPLE 1',\n    isCenter: true,\n    color: Colors.white,\n  ),\n);\n```\n\n![ContainerPlus example_1](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/container_plus_1.png)\n\n\u003e **Example 2:**\n\n```dart\nContainerPlus(\n  margin: EdgeInsets.only(top: 48),\n  width: 150,\n  height: 150,\n  isCircle: true,\n  gradient: GradientPlus.linear(\n    colors: [\n      Colors.yellow,\n      Colors.orange,\n      Colors.pink,\n    ],\n    begin: Alignment.topLeft,\n    end: Alignment.centerRight,\n  ),\n  innerShadows: [\n    InnerShadowPlus(\n      color: Colors.green,\n      blur: 10,\n    )\n  ],\n  child: TextPlus(\n    'EXAMPLE 2',\n    isCenter: true,\n    color: Colors.white,\n  ),\n);\n```\n\n![ContainerPlus example_2](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/container_plus_2.png)\n\n\u003e **Example 3:**\n\n```dart\nbool isLoading = false;\n\nContainerPlus(\n  margin: EdgeInsets.only(top: 48),\n  width: 150,\n  height: 150,\n  color: Colors.black,\n  radius: RadiusPlus.only(topLeft: 40, bottomRight: 10),\n  skeleton: SkeletonPlus.automatic(enabled: this.isLoading),\n  onTap: () {\n    setState(() {\n      this.isLoading = !this.isLoading;\n    });\n    Future.delayed(Duration(seconds: 5), () {\n      setState(() {\n        this.isLoading = !this.isLoading;\n      });\n    });\n  },\n  child: TextPlus(\n    'EXAMPLE 3',\n    isCenter: true,\n    color: Colors.white,\n  ),\n);\n```\n\n![ContainerPlus example_3](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/container_plus_3.gif)\n\n### `📌 ButtonPlus`\n\n\u003e **Example 1:**\n\n```dart\nButtonPlus(\n  width: 200,\n  height: 60,\n  radius: RadiusPlus.all(12),\n  color: Colors.blue,\n  enabled: true,\n  splashColor: Colors.red,\n  highlightColor: Colors.yellow,\n  focusColor: Colors.green,\n  hoverColor: Colors.pink,\n  child: TextPlus(\n    'EXAMPLE 1',\n    color: Colors.white,\n  ),\n  onPressed: () {\n    print('EXAMPLE 1');\n  },\n);\n```\n\n![ButtonPlus example_1](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/button_plus_1.png)\n\n\u003e **Example 2:**\n\n```dart\nButtonPlus(\n  margin: EdgeInsets.only(top: 48),\n  width: 200,\n  height: 60,\n  radius: RadiusPlus.bottom(20),\n  color: Colors.yellow,\n  shadows: [\n    ShadowPlus(\n      color: Colors.red,\n      moveDown: -10,\n      moveRight: -10,\n      blur: 5,\n      spread: 1,\n      opacity: 0.2,\n    ),\n    ShadowPlus(\n      color: Colors.blue,\n      moveDown: 10,\n      moveRight: 10,\n      blur: 10,\n      spread: 5,\n      opacity: 0.5,\n    ),\n  ],\n  border: BorderPlus(\n    color: Colors.black,\n    width: 2,\n  ),\n  child: TextPlus(\n    'EXAMPLE 2',\n    color: Colors.white,\n  ),\n  onPressed: () {\n    print('EXAMPLE 2');\n  },\n);\n```\n\n![ButtonPlus example_2](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/button_plus_2.png)\n\n\u003e **Example 3:**\n\n```dart\nButtonPlus(\n  margin: EdgeInsets.only(top: 48),\n  width: 200,\n  height: 60,\n  isCircle: true,\n  gradient: GradientPlus.linear(\n    colors: [\n      Colors.yellow,\n      Colors.orange,\n      Colors.pink,\n    ],\n    begin: Alignment.topLeft,\n    end: Alignment.centerRight,\n  ),\n  innerShadows: [\n    InnerShadowPlus(\n      color: Colors.green,\n      blur: 10,\n    )\n  ],\n  child: TextPlus(\n    'EXAMPLE 3',\n    color: Colors.white,\n  ),\n  onPressed: () {\n    print('EXAMPLE 3');\n  },\n);\n```\n\n![ButtonPlus example_3](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/button_plus_3.png)\n\n\u003e **Example 4:**\n\n```dart\nbool isLoading = false;\n\nButtonPlus(\n  margin: EdgeInsets.only(top: 48),\n  width: 200,\n  height: 60,\n  color: Colors.black,\n  radius: RadiusPlus.only(topLeft: 40, bottomRight: 10),\n  skeleton: SkeletonPlus.automatic(enabled: this.isLoading),\n  child: TextPlus(\n    'EXAMPLE 4',\n    color: Colors.white,\n  ),\n  onPressed: () {\n    print('EXAMPLE 4');\n\n    setState(() {\n      this.isLoading = !this.isLoading;\n    });\n    Future.delayed(Duration(seconds: 5), () {\n      setState(() {\n        this.isLoading = !this.isLoading;\n      });\n    });\n  },\n);\n```\n![ButtonPlus example_4](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/button_plus_4.gif)\n\n### `📌 TextFieldPlus`\n\n\u003e **Example 1:**\n\n```dart\nTextFieldPlus(\n  padding: EdgeInsets.symmetric(horizontal: 8),\n  height: 60,\n  backgroundColor: Colors.black12,\n  cursorColor: Colors.red,\n  enabled: true,\n  textInputType: TextInputType.emailAddress,\n  placeholder: TextPlus(\n    'E-mail',\n    color: Colors.black38,\n  ),\n  prefixWidget: Icon(\n    Icons.alternate_email,\n    color: Colors.redAccent,\n  ),\n  suffixWidget: Icon(\n    Icons.email,\n    color: Colors.redAccent,\n  ),\n);\n```\n\n![TextFieldPlus example_1](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/text_field_plus_1.png)\n\n\u003e **Example 2:**\n\n```dart\nTextFieldPlus(\n  margin: EdgeInsets.only(top: 24),\n  padding: EdgeInsets.symmetric(horizontal: 8),\n  height: 60,\n  backgroundColor: Colors.black12,\n  cursorColor: Colors.red,\n  textInputType: TextInputType.number,\n  mask: '###.###.###-##',\n  placeholder: TextPlus(\n    'CPF',\n    color: Colors.black38,\n  ),\n);\n```\n\n![TextFieldPlus example_2](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/text_field_plus_2.png)\n\n\u003e **Example 3:**\n\n```dart\nTextFieldPlus(\n  margin: EdgeInsets.only(top: 24),\n  padding: EdgeInsets.symmetric(horizontal: 8),\n  height: 60,\n  cursorColor: Colors.white,\n  textCapitalization: TextCapitalization.words,\n  maxLines: 1,\n  letterSpacing: 2,\n  gradient: GradientPlus.linear(\n    colors: [\n      Colors.red,\n      Colors.orange,\n      Colors.yellow,\n    ],\n  ),\n  radius: RadiusPlus.all(12),\n  placeholder: TextPlus(\n    'Name',\n    color: Colors.white70,\n  ),\n  suffixWidget: Icon(\n    Icons.person,\n    color: Colors.white70,\n  ),\n  textColor: Colors.white,\n  fontSize: 16,\n  fontWeight: FontWeight.bold,\n);\n```\n\n![TextFieldPlus example_3](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/text_field_plus_3.png)\n\n### `📌 TextPlus`\n\n\u003e **Example 1:**\n\n```dart\nTextPlus(\n  'Exemplo 1',\n  padding: EdgeInsets.all(16),\n  backgroundColor: Colors.red,\n  color: Colors.white,\n  fontSize: 20,\n  fontWeight: FontWeight.w700,\n  letterSpacing: 2,\n  wordSpacing: 20,\n  maxLines: 1,\n  textOverflow: TextOverflow.ellipsis,\n);\n```\n\n![TextPlus example_1](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/text_plus_1.png)\n\n\u003e **Example 2:**\n\n```dart\nTextPlus(\n  'Exemplo 2',\n  color: Colors.white,\n  fontSize: 20,\n  margin: EdgeInsets.only(top: 24),\n  padding: EdgeInsets.all(16),\n  backgroundGradient: GradientPlus.linear(\n    colors: [\n      Colors.yellow,\n      Colors.orange,\n      Colors.pink,\n    ],\n    begin: Alignment.topLeft,\n    end: Alignment.centerRight,\n  ),\n  backgroundRadius: RadiusPlus.all(10),\n  backgroundBorder: BorderPlus(\n    color: Colors.blue,\n    width: 2,\n  ),\n  textShadows: [\n    ShadowPlus(\n      color: Colors.black45,\n      blur: 10,\n    )\n  ],\n);\n```\n\n![TextPlus example_2](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/text_plus_2.png)\n\n\u003e **Example 3:**\n\n```dart\nTextPlus(\n  '00000000000',\n  margin: EdgeInsets.only(top: 24),\n  padding: EdgeInsets.all(16),\n  backgroundColor: Colors.black,\n  color: Colors.white,\n  fontSize: 20,\n  mask: '###.###.###-##',\n  onTap: () {\n    print('Exemplo 3');\n  },\n);\n```\n![TextPlus example_3](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/text_plus_3.png)\n\n### `📌 RichTextPlus`\n\n```dart\nRichTextPlus(\n  texts: [\n    TextPlus(\n      'Flutter ',\n      color: Colors.black,\n      fontWeight: FontWeight.normal,\n      fontSize: 30,\n    ),\n    TextPlus(\n      'Plus ',\n      color: Colors.red,\n      fontWeight: FontWeight.bold,\n      fontSize: 30,\n    ),\n    TextPlus(\n      '!',\n      color: Colors.blue,\n      fontWeight: FontWeight.bold,\n      fontSize: 30,\n    ),\n    TextPlus(\n      '!',\n      color: Colors.green,\n      fontWeight: FontWeight.bold,\n      fontSize: 30,\n    ),\n    TextPlus(\n      '!',\n      color: Colors.orange,\n      fontWeight: FontWeight.bold,\n      fontSize: 30,\n    ),\n  ],\n);\n```\n![RichTextPlus example](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/rich_text_plus.png)\n\n## 🔧 Utils\n\nIn addition to the standard widgets we have some abstractions that will save you code and time so you can focus on what really matters to your project.\n\n### `📌 NavigatorPlus`\n\nNavigatorPlus makes it possible to navigate between screens from anywhere in your code, without the need for a `context`.\n\n\u003e You need to configure it to work.\n\n**• Navigate to the next screen:**\n\n```dart\n// Navigate to desired screen\nnavigatorPlus.show(NextScreen());\n```\n\n```dart\n// Open desired screen as modal\nnavigatorPlus.showModal(NextScreen());\n```\n\n**• Back or close screen:**\n\n```dart\n// Back or close to previous screen\nnavigatorPlus.back();\n```\n\n```dart\n// Check if there is a previous screen to go back\nif (navigatorPlus.canBack) {\n  navigatorPlus.back();\n}\n```\n\n```dart\n// Back to first stack screen\nnavigatorPlus.backAll();\n```\n\n**• Return data to source screen:**\n\n```dart\n// Call the next screen with await waiting for a return\nvar result = await navigatorPlus.show(NextScreen());\n\n// Return to the previous screen passing the desired data\nnavigatorPlus.back(result: customData);\n```\n\n**• Configuration:**\n\n\u003e Recommended: Replace MaterialApp with FlutterAppPlus.\n\n```dart\nreturn FlutterAppPlus(\n  title: 'Flutter Plus Example',\n  home: HomeScreen(),\n);\n```\n\n\u003e Alternative: Add the keys of the navigatorPlus and snackBarPlus.\n\n```dart\nMaterialApp(\n  title: 'Flutter Plus Example',\n  navigatorKey: navigatorPlus.key,\n  builder: (context, child) {\n    return Scaffold(\n      key: snackBarPlus.scaffoldKey,\n      body: child,\n    );\n  },\n);\n```\n\n**• Context:**\n\n```dart\n// Get current context\nBuildContext context = navigatorPlus.currentContext;\n```\n\n**• Access:**\n\n```dart\nnavigatorPlus.show(NextScreen());\n\nFlutterPlus.navigator.show(NextScreen());\n```\n\n### `📌 BottomSheetPlus`\n\nO BottomSheetPlus possibilita a abertura em qualquer lugar do seu código, sem a necessidade de um `context`.\n\n\u003e You need to configure it to work.\n\n```dart\nbottomSheetPlus.show(\n  child: CustomWidget(),\n  radius: RadiusPlus.top(20),\n  heightPercentScreen: 0.3,\n);\n```\n![BottomSheetPlus example](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/bottom_sheet_plus.png)\n\n**• Access:**\n\n```dart\nbottomSheetPlus.show(...);\n\nFlutterPlus.bottomSheet.show(...);\n```\n\n**• Configuration:**\n\n\u003e Recommended: Replace MaterialApp with FlutterAppPlus.\n\n```dart\nreturn FlutterAppPlus(\n  title: 'Flutter Plus Example',\n  home: HomeScreen(),\n);\n```\n\n\u003e Alternative: Add the keys of the navigatorPlus and snackBarPlus.\n\n```dart\nMaterialApp(\n  title: 'Flutter Plus Example',\n  navigatorKey: navigatorPlus.key,\n  builder: (context, child) {\n    return Scaffold(\n      key: snackBarPlus.scaffoldKey,\n      body: child,\n    );\n  },\n);\n```\n\n### `📌 DialogPlus`\n\nDialogPlus makes it possible to open a dialog with an already defined layout.\n\n\u003e You need to configure it to work.\n\n```dart\n// Opening of customizable default Dialog\n\nconst url = 'https://github.com/gbmiranda/flutter_plus';\n\ndialogPlus.showDefault(\n\ttitle: 'FlutterPlus',\n\tmessage: url,\n\telementsSpacing: 16,\n\tbuttonOneText: 'Close',\n\tbuttonOneColor: Colors.red,\n\tbuttonOneCallback: () {\n\t  navigatorPlus.back();\n\t},\n\tbuttonTwoText: 'Open',\n\tbuttonTwoCallback: () async {\n\t  if (await canLaunch(url)) {\n\t    await launch(url);\n\t  } else {\n\t    throw 'Could not launch $url';\n\t  }\n\t},\n);\n```\n![DialogPlus example](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/dialog_plus_default.png)\n\n```dart\n// Dialog opening with its own layout\n\n  dialogPlus.show(\n    child: CustomWidget(),\n    radius: RadiusPlus.all(20),\n    closeKeyboardWhenOpen: true,\n  );\n```\n\n![DialogPlus example](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/dialog_plus_custom.png)\n\n**• Access:**\n\n```dart\ndialogPlus.show(...);\n\nFlutterPlus.dialog.show(...);\n```\n\n**• Configuration:**\n\n\u003e Recommended: Replace MaterialApp with FlutterAppPlus.\n\n```dart\nreturn FlutterAppPlus(\n  title: 'Flutter Plus Example',\n  home: HomeScreen(),\n);\n```\n\n\u003e Alternative: Add the keys of the navigatorPlus and snackBarPlus.\n\n```dart\nMaterialApp(\n  title: 'Flutter Plus Example',\n  navigatorKey: navigatorPlus.key,\n  builder: (context, child) {\n    return Scaffold(\n      key: snackBarPlus.scaffoldKey,\n      body: child,\n    );\n  },\n);\n```\n\n### `📌 SnackBarPlus`\n\nSnackBarPlus allows you to open your code anywhere, without the need for a scaffold.\n\n\u003e You need to configure it to work.\n\n```dart\n// SnackBar opening with plain text\n\nsnackBarPlus.showText(\n  'FlutterPlus',\n  textColor: Colors.white,\n  fontSize: 18,\n  fontWeight: FontWeight.bold,\n  backgroundColor: Colors.green,\n);\n```\n\n![SnackBarPlus example](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/snack_bar_plus_default.png)\n\n```dart\n// SnackBar opening with custom widget\n\nsnackBarPlus.show(\n\tbackgroundColor: Colors.green,\n\tchild: Row(\n\t  mainAxisAlignment: MainAxisAlignment.center,\n\t  children: [\n\t    Icon(\n\t      Icons.star,\n\t      color: Colors.yellow,\n\t    ),\n\t    SizedBox(\n\t      width: 8,\n\t    ),\n\t    TextPlus(\n\t      'FlutterPlus!',\n\t      color: Colors.white,\n\t      fontSize: 18,\n\t      fontWeight: FontWeight.bold,\n\t    ),\n\t    SizedBox(\n\t      width: 8,\n\t    ),\n\t    Icon(\n\t      Icons.star,\n\t      color: Colors.yellow,\n\t    ),\n\t  ],\n\t),\n);\n```\n![SnackBarPlus example](https://raw.githubusercontent.com/gbmiranda/flutter_plus/master/example/images/snack_bar_plus_custom.png)\n\n**• Configuration:**\n\n\u003e Recommended: Replace MaterialApp with FlutterAppPlus.\n\n```dart\nreturn FlutterAppPlus(\n  title: 'Flutter Plus Example',\n  home: HomeScreen(),\n);\n```\n\n\u003e Alternative: Add the keys of the navigatorPlus and snackBarPlus.\n\n```dart\nMaterialApp(\n  title: 'Flutter Plus Example',\n  navigatorKey: navigatorPlus.key,\n  builder: (context, child) {\n    return Scaffold(\n      key: snackBarPlus.scaffoldKey,\n      body: child,\n    );\n  },\n);\n```\n\n**• Access:**\n\n```dart\nsnackBarPlus.show(...);\n\nFlutterPlus.snackBar.show(...);\n```\n\n### `📌 LocalStoragePlus`\n\nLocalStoragePlus makes it possible to persist and access local data anywhere in your code.\n\n```dart\n// Save local data\nawait localStoragePlus.write('lib_name', 'flutter_plus');\n\n// Read local data\nawait localStoragePlus.read('lib_name');\n\n// Erase local data\nawait localStoragePlus.delete('lib_name');\n\n// Check for local data\nawait localStoragePlus.containsKey('lib_name');\n\n// Clear all local data\nawait localStoragePlus.clear();\n```\n\n**• Access:**\n\n```dart\nlocalStoragePlus...;\n\nFlutterPlus.localStorage...;\n```\n\n\u003e Uses the `shared_preferences` dependency.\n\n### `📌 UtilsPlus`\n\nUtilsPlus provides functions to assist in the development of your application.\n\n```dart\n// Close the keyboard if it is open\nutilsPlus.closeKeyboard();\n\n// Get a Color from a Hex\nColor customColor = utilsPlus.colorHex('FFFFFF');\n```\n\n**• Access:**\n\n```dart\nutilsPlus...;\n\nFlutterPlus.utils...;\n```\n\n## 🧩 ExtensionsPlus\n\nLast but not least, *** Extensions *** are a powerful tool to make certain tasks easier without having to replicate code multiple times.\n\nIn this section you will find various extensions for the types ***String***, ***Date***, ***Num***, ***File***, ***Duration***.\n\n\u003e Sometimes it is difficult to keep everything up to date, so new properties may appear that are not here.\n\n### `📌 StringExtensionPlus`\n\n**• Properties:**\n\n| Property | Example | Result |\n| ---| --- | --- |\n| toDate | `\"11/08/1992\".toDate(format: \"dd/MM/yyyy\");` | DateTime\n| capitalizeFirstWord | `\"flutter plus\".capitalizeFirstWord;` | Flutter plus\n| capitalizeAllWords | `\"flutter plus\".capitalizeAllWords;` | Flutter Plus\n| setMask | `\"00000000000\".setMask(mask: \"###.###.###-##\");` | 000.000.000-00\n| cleanDiacritics ou removerAcentos | `\"fluttér plús\". cleanDiacritics;` | flutter plus\n| firstLetter | `\"flutter plus\".firstLetter;` | f\n| firstWord | `\"flutter plus\".firstWord;` | flutter\n| toBase64 | `\"flutter plus\".toBase64;` | base64Str\n| fromBase64 | `base64Str.fromBase64;` | flutter plus\n| cleanString | `\"* flutter plus *\".cleanString;` | flutter plus\n| cleanStringAndSpaces | `\"* flutter plus *\".cleanStringAndSpaces;` | flutterplus\n| isNotNullOrEmpty | `\"flutter plus\".isNotNullOrEmpty;` | true\n| isEmail | `\"flutter plus\".isEmail;` | false\n| isNum | `\"flutter plus\".isNum;` | false\n| isBool | `\"flutter plus\".isBool;` | false\n| isDateTime | `\"flutter plus\".isDateTime;` | false\n| isURL | `\"flutter plus\".isURL;` | false\n| isCpf | `\"flutter plus\".isCpf;` | false\n| isCelular | `\"flutter plus\".isCelular;` | false\n| isTelefone | `\"flutter plus\".isTelefone;` | false\n\n**• Example:**\n\n```dart\nString dateStr = \"01/01/2020 10:00:00\";\nDateTime date = dateStr.toDate(\"dd/MM/yyyy\");\nprint(date.year); \n// 2020\n```\n\n### `📌 DateExtensionPlus`\n\n**• Properties:**\n\n| Property | Return Type | Result |\n| ---| --- | --- |\n| format | `String` | String with formatted date\n| daysOfMonth | `int` | Number of days of the month\n| daysOfYear | `int` | Number of days in the year (366 when binary year)\n| isToday | `bool` | True or false\n| monthName | `String` | Month name\n| monthNameSort | `String` | Summarized month name\n| weekName | `String` | Day of the week\n| weekNameSort | `String` | Summary day of the week\n\n**• Example:**\n\n```dart\nDateTime.now date = DateTime.now();\nString dateStr = date.format(\"dd/MM/yyyy\");\nprint(dateStr); \n// 01/01/2020\n```\n\n### `📌 NumExtensionPlus`\n\n**• Properties:**\n\n| Property | Return Type | Result |\n| ---| --- | --- |\n| toCurrency | `String` | Formats to local currency\n| toCurrencyCompact | `String` | Formats to summarized local currency\n| toPrecision | `double` | Sets number of decimal places\n| daysToHours | `int` | Days to hours\n| minutesToHours | `int` | Minutes to hours\n| secondsToHours | `int` | Seconds to hours\n| hoursToDays | `int` | Hours to days\n| secondsToMinutes | `int` | Seconds to minutes\n| hoursToMinutes | `int` | Hours to minutes\n| isNullOrZero | `bool` | Checks if it is different from null or zero\n\n**• Example:**\n\n```dart\ndouble value = 13512.98;\nprint(value.toCurrency()); \n// $ 13,512.98\n// R$ 13.512,98\n```\n\n### `📌 FileExtensionPlus`\n\n**• Properties:**\n\n| Property | Return Type | Result |\n| ---| --- | --- |\n| base64Sync | `String` | Converts to base64 sync\n| base64Async | `String` | Converts to base64 async\n\n**• Example:**\n\n```dart\nFile customFile = File(path);\nString base64 = customFile.base64Sync;\n```\n\n### `📌 DurationExtensionPlus`\n\n**• Properties:**\n\n| Property | Return Type | Result |\n| ---| --- | --- |\n| months | `int` | Returns the number of months of Duration\n| days | `int` | Returns the number of days of Duration\n| hours | `int` | Returns the number of hours of Duration\n| hoursStr | `String` | Returns the formatted number of hours of Duration\n| minutes | `int` | Returns the number of minutes of Duration\n| minutesStr | `String` | Returns the formatted number of minutes of Duration\n| seconds | `int` | Returns the number of seconds of Duration\n| secondsStr | `String` | Returns the formatted number of seconds of Duration\n| formattedDuration | `String` | Returns the formatted Duration\n\n**• Example:**\n\n```dart\nDuration customDuration = Duration(hours: 10, minutes: 4, seconds: 55);\nprint(customDuration.days); // 0\nprint(customDuration.hours); // 10\nprint(customDuration.minutesStr); // 04\nprint(customDuration.formattedDuration); // 10:04:55\n```\n\n## ⚙️ Attributes\n\nThe customization attributes below are used in most of the widgets above.\n\n### `📌 BorderPlus`\n\n```dart\nBorderPlus(\n  color: Colors.black,\n  style: BorderStyle.solid,\n  width: 2.0,\n);\n```\n\n### `📌 GradientPlus`\n\n```dart\nGradientPlus.linear(\n  colors: [Colors.black, Colors.white],\n  begin: Alignment.centerLeft,\n  end: Alignment.centerRight,\n  stops: [0.2, 0.8],\n);\n```\n\n```dart\nGradientPlus.radial(\n  colors: [Colors.black, Colors.white],\n  center: Alignment.centerLeft,\n  focal: Alignment.bottomCenter,\n  focalRadius: 1.5,\n  radius: 4.5,\n  stops: [0.3, 0.7],\n);\n```\n\n```dart\nGradientPlus.sweep(\n  colors: [Colors.black, Colors.white],\n  center: Alignment.centerLeft,\n  startAngle: 1.5,\n  endAngle: 3.2,\n  stops: [0.5, 0.8],\n);\n```\n\n### `📌 InnerShadowPlus`\n\n```dart\nInnerShadowPlus(\n  color: Colors.red,\n  blur: 10.0,\n  moveDown: 4.5,\n  moveRight: 2.5,\n  opacity: 0.5,\n);\n```\n### `📌 RadiusPlus`\n\n```dart\nRadiusPlus.all(12.0);\n```\n\n```dart\nRadiusPlus.bottom(12.0);\n```\n\n```dart\nRadiusPlus.top(12.0);\n```\n\n```dart\nRadiusPlus.only(\n  topLeft: 10.0,\n  topRight: 16.0,\n  bottomLeft: 4.0,\n  bottomRight: 8.0,\n);\n```\n\n### `📌 ShadowPlus`\n\n```dart\nShadowPlus(\n  color: Colors.red,\n  blur: 10.0,\n  spread: 2.5,\n  moveDown: 4.5,\n  moveRight: 2.5,\n  opacity: 0.5,\n);\n```\n\n### `📌 SkeletonPlus`\n\n```dart\nbool isLoading = true;\nSkeletonPlus.automatic(enabled: isLoading);\n```\n\n```dart\nbool isLoading = true;\nSkeletonPlus.custom(\n  enabled: isLoading,\n  baseColor: Colors.black87,\n  highlightColor: Colors.black26,\n  duration: Duration(\n    milliseconds: 500,\n  ),\n  showBorders: false,\n  showShadows: false,\n);\n```\n\n### `📌 TextDecorationPlus`\n\n```dart\nTextDecorationPlus(\n  color: Colors.red,\n  decorationStyle: TextDecorationStyle.dashed,\n  decorationThickness: 0.5,\n);\n```\n\n# 🎯 Next Steps\n\n📌 Detailed documentation of the components.\n\n📌 Route Navigation\n\n📌 ScaffoldPlus.\n\n📌 GridViewPlus.\n\n📌 ListViewPlus.\n\n📌 LoadingPlus.\n\n📌 ThemePlus.\n\n📌 TranslatePlus.\n\n📌 ∞\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgbmiranda%2Fflutter_plus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgbmiranda%2Fflutter_plus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgbmiranda%2Fflutter_plus/lists"}