An essential and powerful library of dart extensions to remove the boilerplate and speed up the development process.
- Go to
pubspec.yaml
- Add extensions_kit and replace
[version]
with the latest version:
dependencies:
extensions_kit: ^[version]
- Click on get packages button or run flutter pub get
- Import
import 'package:extensions_kit/extensions_kit.dart';
Available Extensions & Methods 🔥
- String Extensions
- Media Query Extensions
- Theme Extensions
- Date Extensions
- Navigation Extensions
- Number Extensions
- Widget Extensions
- Colors
- Gap Widget
- Text Style Extensions
- Url Strategy
- Avatar Image
- Distance Between Coordinates
- Snackbar
- Support
- Acknowledgments and References
- Bugs or Feature Requests
// Validate an email
"example@mail.com".isEmailAddress; // true
// Capitalizes each word in the string
"hello world".capitalize; // Hello World
// Capitalizes the first word in the string
"hello world".capitalizeFirst; // Hello world
// Mocks a string that needs to be translated or changed later
"Hello world".mock; //Hello world 🧨
// Check if a string is boolean
// If `caseSensitive` is `true`, which is the default,
//The only accepted inputs are the strings `"true"` and `"false"`,
"true".isBool(); // true
"TRUE".isBool(); // false
"TRUE".isBool(caseSensitive: false); // true
// Convert a string into a boolean
// Throws error if the string is not a Boolean.
// If `caseSensitive` is `true`, which is the default,
//The only accepted inputs are the strings `"true"` and `"false"`,
"true".toBool(); // true
"TRUE".toBool(); // throws error
"TRUE".toBool(caseSensitive: false); // true
// Check if the string is a number
"123".isNum; // true
"12fh".isNum; // false
// Convert a string into a number
"123".toNum; // 123
// Check if a string is a double number
"123.45".isDouble; // true
// Convert a string into a double
"123.12".toDouble; // 123.12
// Check if a string is an integer
"123".isInt; // true
// Convert a string into an integer
"123".toInt; // 123
// Remove all the whitespace from the string
"This is a test string".removeAllWhitespace; // Thisisateststring
// Check if the String matches the Regular expression
"username_10".hasMatch("r'[abcdefghijklmnopqrstuvwxyz1234567890._]"); // true
// Copy a string to Clipboard
Ext.copy("Hello World"); // `Hello World` copied to clipboard
From the MediaQuery
Access properties right in the context
instance.
// Before
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
),
// Now
Container(
width: context.screenWidth, // 100% of screen width
height: context.screenHeight, // 100% of screen height
),
Container(
width: context.w(50), // 50% of screen width
height: context.h(40.5), // 40.5% of screen height
),
// Returns boolean
context.isDarkMode; // true/false
context.isLightMode; // true/false
To format DateTime
// Formats `DateTime` into readable form according to the given format
DateTime.now().format("dd/MM/yyyy - hh:mm a") // 20/12/2023 - 08:00 PM
// Get Date only
DateTime(2023,12,16,11,40,00,0,0).dateOnly; // DateTime(2023,12,16) *time set to midnight
// Check if [DateTime] is on the same day as today
DateTime.now().isToday; // true
// Check if [DateTime] was on the same day as yesterday
DateTime.now().isYesterday; // false
// Check if [DateTime] will be on the same day as tomorrow
DateTime.now().isTomorrow; // false
// Add a certain number of DAYS to [DateTime]
DateTime(2023,12,16).addDays(5); // DateTime(2023,12,21)
// Add a certain number of HOURS to [DateTime]
DateTime(2023,12,16,11,50,0).addHours(10); // DateTime(2023,12,16,21,50,0)
/// The day After this [DateTime]
DateTime(2017, 3, 5).nextDay; // DateTime(2017, 3, 6)
/// The day previous this [DateTime]
DateTime(2017, 3, 5).previousDay; // DateTime(2017, 3, 4)
// First day of the month
DateTime(2018, 9, 30).firstDayOfMonth; // DateTime(2018, 9, 1)
// Last day of the month
DateTime(2017, 3).lastDayOfMonth; // DateTime(2017, 3, 31)
// All days in a month, [DateTime] Array
DateTime(2017, 3).daysInMonth; // [DateTime(2017, 3, 1), DateTime(2017, 3, 2), ...]
// Whether or not two times are on the same day.
DateTime.now().isSameDay(DateTime.now()); // true
// Whether or not two times are on the same week.
DateTime(2017, 3, 5).isSameWeek(DateTime(2017, 3, 6)); // true
// Difference between two `DateTime` in years, month and days
DateTime(2015, 1, 1).diffYearsMonthsDays(DateTime.now()) // 8 years 11 months 24 days
DateTime(2015, 1, 1).diffYearsMonthsDays(DateTime.now(), abbr: true) // 8 y 11 m 24 d
// Difference in Days
DateTime(2017, 3, 5).diffDays(DateTime(2017, 3, 6)); // 1
// Difference in Days
DateTime(2017, 3, 5).diffHours(DateTime(2017, 3, 6)); // 24
Similar other available DateTime difference extensions are:
diffDays()
Difference in Days.diffHours()
Difference in Hours.diffMinutes()
Difference in Minutes.diffSeconds()
Difference in Seconds.
From the Navigator
Access properties right in the context
instance.
// Before
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
// Now
// for push
context.push(SecondScreen());
context.pushNamed('/home');
// For back, you can also add back result data
context.pop();
// for push replacement
context.pushReplacement(SecondScreen());
context.pushReplacementNamed('/home');
// popUntil
context.popUntil('/login');
// with rootNavigator
context.push(SecondScreen(), rootNavigator: true);
context.pushReplacement(SecondScreen(), rootNavigator: true);
context.popUntil('/login', rootNavigator: true);
// Get number into its English ordinal representation
1.ordinal; // 1st
3.ordinal; // 3rd
234.ordinal; // 234th
// Get string representation of the number abbreviated to a compact form
999.abbreviated; // "999"
1000.abbreviated; // "1k"
1100.abbreviated; // "1.1k"
// Check if the number is between the given numbers
45.between(40,60); // true
23.between(10,20); // false
// Check if the number is outside the given numbers
60.outside(40,65); // false
23.outside(10,20); // true
An easy way to specify a border radius
// Before
Container(
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
),
)
// Now
Container(
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: 25.circular(),
),
)
An easy way to specify padding to a Padding
widget
// Before
Padding(
padding: EdgetInsets.all(15),
child: Text("Text"),
)
// Now
Padding(
padding: 15.padAll(),
child: Text("Text"),
)
Similar available padding extensions to numbers are:
padAll()
Creates insets from offsets from all sides.padHrz()
Creates insets from offsets from horizontal sides.padVert()
Creates insets from offsets from vertical sides.padTop()
Creates insets from offsets from the top side.padBottom()
Creates insets from offsets from the bottom side.padLeft()
Creates insets from offsets from the left side.padRight()
Creates insets from offsets from the right side.padOnly()
Creates insets from offsets from the given sides only.
These widget extensions will help you to reduce boilerplate code and increase your productivity
// Before
SizedBox(
height : 20
)
// Now
// makes space of 20 height
20.heightBox;
// for width
20.widthBox
// Before
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("text"),
);
// Now
Text("text").padAll(8.0),
Similar available padding extensions to widgets are:
padAll()
Creates insets from offsets from all sides.padHrz()
Creates insets from offsets from horizontal sides.padVert()
Creates insets from offsets from vertical sides.padTop()
Creates insets from offsets from the top side.padBottom()
Creates insets from offsets from the bottom side.padLeft()
Creates insets from offsets from the left side.padRight()
Creates insets from offsets from the right side.padOnly()
Creates insets from offsets from the given sides only.
// Before
Align(
alignment: Alignment.centerLeft,
child: Text("text"),
);
// Now
Text("text").leftAlign,
Similar available Alignment extensions are:
center
Aligns the widget to the center.leftAlign
Aligns the widget to the center left.rightAlign
Aligns the widget to the center right.topAlign
Aligns the widget to the top center.topLeftAlign
Aligns the widget to the top left.topRightAlign
Aligns the widget to the top right.bottomAlign
Aligns the widget to the bottom center.bottomLeftAlign
Aligns the widget to the bottom left.bottomRightAlign
Aligns the widget to the bottom right.
/// Before
Flexible(
child: Text("text"),
)
// Now
Text("text").flexible
Similar available widget extensions are:
unfocus
Will [Unfocus] focused text field, It's better to use it on the main parent widget of the screen e.g.Scaffold
tooltip()
Will wrap the widget with a Tooltip widgetflexible()
Will wrap the widget with a Flexible widgetexpanded()
Will wrap the widget with an Expanded widgetwithOpacity()
Will wrap the widget with an Opacity widgetonDoubleTap()
Will wrap the widget with a GestureDetector and accept an onDoubleTap functiononTap()
Will wrap the widget with a GestureDetector and accept an onTap functiononLongPress()
Will wrap the widget with a GestureDetector and accept an onLongPress functionpositionTop()
Will wrap the widget with a Positioned widget and accept top positionpositionBottom()
Will wrap the widget with a Positioned widget and accept bottom positionpositionTB()
Will wrap the widget with a Positioned widget and accept top & bottom positionpositionLT()
Will wrap the widget with a Positioned widget and accept left & right positionpositionLRTB()
Will wrap the widget with a Positioned widget and accept left,right,top & bottom positionsizedBox(width,height)
Will wrap the widget with a SizedBox of given height and widthheightBox(height)
Will wrap the widget with a SizedBox of a given heightwidthBox(height)
Will wrap the widget with a SizedBox of a given width
Now we can just add round corners, shadows, align, and add gestures to our Widgets.
Container(
height: 100,
width: 100,)
.withRoundCorners(backgroundColor: Colors.grey)
.withShadow()
Container(height: 50,width: 50,).applyShimmer();
You can also change the color of the shimmer using baseColor
& highlightColor
.
Automatically detect Platform and show Material and Cupertino dialog
context.showAlertDialog(title: 'title', message: 'message',)
Sometimes, according to a condition, we need to display nothing. Usually, when we can't return null, we would return something like const SizedBox()
.
This is good, but it has some performance impacts since SizedBox
creates a RenderObject
. The RenderObject
lives in the render tree and some computations are performed on it, even if it paints nothing on the screen.
We can do better, we can have a widget that does not create a RenderObject
while being still valid. The Nil
widget is the minimal implementation for this use case. It only creates an Element
and does nothing while it's building. Because the optimal way to use it, is to call const Nil()
, it also comes with a nil
constant that you can use everywhere (which is a const Nil()
).
// Before
text != null ? Text(text) : const SizedBox()
// Now
text != null ? Text(text) : nil
or
text != null ? Text(text) : const Nil()
This package includes a comprehensive collection of predefined colors and methods, empowering you to effortlessly enhance the visual appeal of your Flutter applications.
Ext.black; // Color(0xFF000000)
Ext.transparent; // Colors.transparent;
Ext.red500; // Color(0xFFEF4444);
Ext.redHex500; // #EF4444
// Convert a hex color string to a [Color]
Ext.hexToColor("EF4444"); // Color(0xFFEF4444)
// Get [MaterialColor] from [Color]
Ext.getMaterialColor(Ext.red800); // Red Material Color
// Get Random Colors
Ext.randomOpaqueColor; // Random Opaque Color
Ext.randomPrimaryColor; // Random Primary Color
Ext.randomColor; // Random Color
When it comes to add empty space between widgets inside a Column
or a Row
, we have multiple options:
- We can either add a
Padding
around these widgets but it's very verbose - Or we can add
SizedBox
widgets between them.
Gap
is another option. It's like SizedBox
but you don't have to know if it's inside a Row
or a Column
. So that it's less verbose than using a SizedBox
.
You just have to add a Gap
inside a Column
or a Row
with the specified extent. The Gap
widget also works inside Scrollable
widgets such as ListViews
. In these cases, it will occupy the space in the same direction as the Scrollable
.
return Column(
children: <Widget>[
Container(color: Colors.red, height: 20),
const Gap(20), // Adds an empty space of 20 pixels.
Container(color: Colors.red, height: 20),
],
);
From the TextStyle
Access properties right in the context
instance.
// Before
Text('Hello World',style: Theme.of(context).textTheme.labelSmall),
Text('Hello World', style: TextStyle(color: Colors.grey, fontWeight: FontWeight.bold, fontSize: 40))
// After
Text('Hello World',style: context.textStyles.labelSmall),
// OR
Text('Hello World',style: context.textStyles.displaySmall),
// If you want to bold text then
Text('Hello World',style: context.textStyles.labelSmall.bold),
Similar fontWeights are:
thick
The most thick - FontWeight.w900extraBold
Extra-bold - FontWeight.w800bold
Bold - FontWeight.bold - FontWeight.w700semiBold
Semi-bold - FontWeight.w600medium
Medium - FontWeight.w500regular
Regular - FontWeight.w400light
Light - FontWeight.w300extraLight
Extra-light - FontWeight.w200thin
Thin, the least thick - FontWeight.w100
Similar TextStyles are:
context.textStyles.displayLarge
context.textStyles.displayMedium
context.textStyles.displaySmall
context.textStyles.headlineLarge
context.textStyles.headlineMedium
context.textStyles.headlineSmall
context.textStyles.titleLarge
context.textStyles.titleMedium
context.textStyles.titleSmall
context.textStyles.bodyLarge
context.textStyles.bodyMedium
context.textStyles.bodySmall
context.textStyles.labelLarge
context.textStyles.labelMedium
context.textStyles.labelSmall
If you do not want use theme textsyles, then there are methods that you can use on a Text
widget
Text('Hello World')
.bold()
.fontSize(25)
.italic();
Similar methods are:
textScale()
TextScalebold()
Bold Textitalic()
Italic TextfontWeight()
Specific FontWeightfontSize()
Specific FontSizeletterSpacing()
Specific LetterSpacingwordSpacing()
Specific WordSpacingfontFamily()
Specific FontFamilytextShadow()
Specific TextShadowtextColor()
TextColortextAlignment()
Specific TextAlignmentwithUnderLine()
TextUnderLine
With a simple call of setPathUrlStrategy
, your Flutter web app does not have a leading #
in the URL anymore 🚀
void main() {
// Here we set the URL strategy for our web app.
// It is safe to call this function when running on mobile or desktop as well.
setPathUrlStrategy();
runApp(MyApp());
}
AvatarImage(
backgroundImage: NetworkImage(
'https://mdbootstrap.com/img/Photos/Avatars/img%20%281%29.jpg'),
shape: AvatarImageShape.standard,
size: ImageSize.LARGE,
child: Text('Lucky'),
backgroundColor: Colors.red,
),
AvatarImage(
shape: AvatarImageShape.circle,
child: Text('JP'),
backgroundColor: Colors.red,
),
Properties | Description |
---|---|
child | type of [Widget], which can have text , icon etc |
backgroundColor | Color to fill the background of avatar |
foregroundColor | Color to change the textColor inside the avatar |
radius | size of the avatar |
minRadius | minimum size of the avatar |
maxRadius | maximun size of the avatar |
size | size of the avatar i.e ImageSize.large , ImageSize.medium , ImageSize.small |
shape | shape of the avatar i.e, AvatarImageShape.standard , AvatarImageShape.circle , AvatarImageShape.square |
borderRadius | extra radius to avatar shapes, not applicable to circular avatar |
Calculates the great-circle distance in Kilometers between two geographic coordinates using the Haversine formula.
double distance = Ext.getDistanceFromCoordinates(37.7749, -122.4194, 34.0522, -118.2437);
Utility methods for showing a Snackbar with customizable options.
Ext.showMessageSnackbar("This is a message Snackbar", context); // Message Snackbar
Ext.showErrorSnackbar("This is an Error Snackbar", context); // Error Snackbar
Ext.showInfoSnackbar("This is an info Snackbar", context); // Info Snackbar
If this package helped you please leave a like and share it with your friends.
- A lot of extension from Awesome Extensions By Jayesh Pansheriya
- Gap By Romain Rastel
- top_snackbar_flutter by Lanars
If you encounter any problems feel free to open an issue. If you feel the library is missing a feature, please raise a ticket. Pull requests are also welcomed.