easix 3.0.0 copy "easix: ^3.0.0" to clipboard
easix: ^3.0.0 copied to clipboard

easix is a helper package that provide multiple handy function and extensions to use in your flutter project.

Easix #

Easix is a Flutter package designed to simplify common tasks related to form field validation and provide helpful extensions for working with dates, times, widgets, and error handling. With Easix, you can streamline the development of your Flutter applications, making your code more efficient and maintainable.

Features #

Useful Extensions #

Easix offers a variety of extensions to make your Flutter development easier and more productive. These extensions include:

  • ✅ Converting a string date to a human-readable date format
  • ✅ Converting a Datetime to a human-readable time
  • Enhanced DateTime formatting with 15+ formats: ISO, US, European, relative time, weekday/month names, ordinal days, and chat timestamps
  • Enhanced TimeOfDay formatting with multiple formats and utilities: 12/24-hour formats, AM/PM checks, time arithmetic, and range checking
  • Adding padding to widgets, allowing customization of height, width, or both DEPRECATED - Use Gap and SliverGap widgets instead
  • ✅ Adding an extension to the String class to get the first letters of a string
  • ✅ Checking if a TimeOfDay is before or after another
  • ✅ Calculating the difference in minutes between two TimeOfDay objects
  • ✅ Checking if a TimeOfDay is between two others
  • ✅ Converting time to 12-hour format with optional meridian display
  • ✅ Get the initials of a string.
  • ✅ Add extensions for theme, textTheme and colorScheme for easy access to theme properties.
  • ✅ Add initial extension to get the first letter of a string.

Useful Functions #

  • ✅ Convert any list with a date property to a sorted list of dates, where it will be sorted by the date property in the list items.
  • ✅ GetTypeList function to get a list of types from a list of objects.

Installation #

To get started with Easix, add it to your pubspec.yaml file:

dependencies:
  easix: ^2.0.0

Usage #

Gap and SliverGap Widgets #

Easix provides Gap and SliverGap widgets for adding spacing between widgets.

Column(
  children: [
    Text('Item 1'),
    Gap(16.0),
    Text('Item 2'),
  ],
);

CustomScrollView(
  slivers: [
    SliverList(
      delegate: SliverChildListDelegate([
        Text('Item 1'),
        SliverGap(16.0),
        Text('Item 2'),
      ]),
    ),
  ],
);

Adaptive Image Widget #

Easix provides an AdaptiveImage widget that supports displaying network images, local SVG files, remote SVG files, local image files, and asset images.

AdaptiveImage(
  'https://example.com/image.png',
  width: 100,
  height: 100,
  fit: BoxFit.cover,
  borderRadius: 8.0,
  placeholder: CircularProgressIndicator(),
  errorWidget: Icon(Icons.error),
  color: Colors.blue,
  alignment: Alignment.center,
  repeat: ImageRepeat.noRepeat,
  borderColor: Colors.black,
  borderWidth: 1.0,
  boxShadow: [BoxShadow(color: Colors.grey, blurRadius: 5.0)],
  overlayColor: Colors.black.withOpacity(0.5),
  gradient: LinearGradient(colors: [Colors.black, Colors.transparent]),
  animationDuration: Duration(milliseconds: 300),
  animationCurve: Curves.easeInOut,
  onTap: () => print('Image tapped'),
  onDoubleTap: () => print('Image double tapped'),
  onLongPress: () => print('Image long pressed'),
);

Easix provides a set of navigation extensions to simplify navigation in your Flutter applications. These extensions include:

Push a new screen as a route onto the stack.

context.pushScreen(MyScreen());

Replace the current screen with a new screen.

context.pushReplacementScreen(MyScreen());

Push a new screen and remove all previous screens until the predicate is satisfied.

context.pushScreenAndRemoveUntil(MyScreen(), (route) => false);

Push a fullscreen dialog screen.

context.pushFullscreenDialog(MyScreen());

Pop the current route off the stack.

context.pop();

Pop routes until the specified condition is met.

context.popUntilCondition((route) => route.isFirst);

Pop the current screen and push a new screen onto the stack.

context.popAndPushScreen(MyScreen());

Check if there are any routes in the navigation stack that can be popped.

bool canPop = context.canPop();

Push a new screen and clear the navigation stack.

context.pushScreenAndClearStack(MyScreen());

Push a screen modally (without adding to the navigation stack).

context.pushModal(MyScreen());

Push a new screen and return the result after the screen is popped.

final result = await context.pushScreenForResult(MyScreen());

Useful Extensions Examples #

Easix offers a variety of extensions to make your Flutter development easier and more productive. These extensions include:

Convert a string date to a human-readable date format

Demo
Demo
"Now (English): ${now.toHumanDate()}\n"
"Before 1 Hour (English): ${now.subtract(Duration(hours: 1)).toHumanDate()}\n"
"Before 1 Day (English): ${now.subtract(Duration(days: 1)).toHumanDate()}\n"
"Before 2 Days (English): ${now.subtract(Duration(days: 2)).toHumanDate()}\n"
"Before 10 Days (English, Short): ${now.subtract(Duration(days: 10)).toHumanDate()}\n"
"Before 10 Days (English, Full): ${now.subtract(Duration(days: 10)).toHumanDate(displayType: DateMode.full)}\n"
"Before 1 Month (English): ${now.subtract(Duration(days: 30)).toHumanDate()}\n"
"Before 1 Year (English, full): ${now.subtract(Duration(days: 365)).toHumanDate(displayType: DateMode.full)}\n"
"-----------------------------------\n"
"Before 1 Hour (Arabic): ${now.subtract(Duration(hours: 1)).toHumanDate(language: DateLang.ar)}\n"
"Before 1 Day (Arabic): ${now.subtract(Duration(days: 1)).toHumanDate(language: DateLang.ar)}\n"
"Before 2 Days (Arabic): ${now.subtract(Duration(days: 2)).toHumanDate(language: DateLang.ar)}\n"
"Before 10 Days (Arabic, Short): ${now.subtract(Duration(days: 10)).toHumanDate(language: DateLang.ar)}\n"
"Before 10 Days (Arabic, Full): ${now.subtract(Duration(days: 10)).toHumanDate(displayType: DateMode.full, language: DateLang.ar)}\n"
"Before 1 Month (Arabic): ${now.subtract(Duration(days: 30)).toHumanDate(language: DateLang.ar)}\n"
"Before 1 Year (Arabic, full): ${now.subtract(Duration(days: 365)).toHumanDate(language: DateLang.ar, displayType: DateMode.full)}\n"
"-----------------------------------\n"
"After 1 Hour (English): ${now.add(Duration(hours: 1)).toHumanDate()}\n"
"After 1 Day (English): ${now.add(Duration(days: 1)).toHumanDate()}\n"
"After 2 Days (English): ${now.add(Duration(days: 2)).toHumanDate()}\n"
"After 10 Days (English, Short): ${now.add(Duration(days: 10)).toHumanDate()}\n"
"After 10 Days (English, Full): ${now.add(Duration(days: 10)).toHumanDate(displayType: DateMode.full)}\n"
"After 1 Month (English): ${now.add(Duration(days: 30)).toHumanDate()}\n"
"After 1 Year (English, full): ${now.add(Duration(days: 365)).toHumanDate()}\n"
"-----------------------------------\n"
"After 1 Hour (Arabic): ${now.add(Duration(hours: 1)).toHumanDate(language: DateLang.ar)}\n"
"After 1 Day (Arabic): ${now.add(Duration(days: 1)).toHumanDate(language: DateLang.ar)}\n"
"After 2 Days (Arabic): ${now.add(Duration(days: 2)).toHumanDate(language: DateLang.ar)}\n"
"After 10 Days (Arabic, Short): ${now.add(Duration(days: 10)).toHumanDate(language: DateLang.ar)}\n"
"After 10 Days (Arabic, Full): ${now.add(Duration(days: 10)).toHumanDate(displayType: DateMode.full, language: DateLang.ar)}\n"
"After 1 Month (Arabic): ${now.add(Duration(days: 30)).toHumanDate(language: DateLang.ar)}\n"
"After 1 Year (Arabic, full): ${now.add(Duration(days: 365)).toHumanDate(language: DateLang.ar, displayType: DateMode.full)}\n"

Checking if a TimeOfDay is before or after another

bool isBefore = currentTime.isBefore(otherTime);
bool isAfter = currentTime.isAfter(otherTime);

Calculating the difference in minutes between two TimeOfDay objects

int minutesDifference = currentTime.differenceInMinutes(otherTime);

Checking if a TimeOfDay is between two others

bool isBetween = currentTime.isBetween(startTime, endTime);

Converting time to 12-hour format with optional meridian display

String formattedTime = '12:55:00'.to12Time(showMeridian: true);

Enhanced DateTime & TimeOfDay Formatting #

Easix now provides comprehensive formatting extensions for both DateTime and TimeOfDay objects with 20+ formatting methods.

DateTime Formatting Examples

final dateTime = DateTime(2025, 9, 8, 14, 30, 45);

// Basic formats
print(dateTime.toYMD());                    // "2025-09-08"
print(dateTime.toYMDWithSlash());           // "2025/09/08"
print(dateTime.toDMY());                    // "08-09-2025"
print(dateTime.toDMYWithSlash());           // "08/09/2025"

// Regional formats
print(dateTime.toUSDate());                 // "09/08/2025"
print(dateTime.toUSDateWithDashes());       // "09-08-2025"
print(dateTime.toEuropeanDate());           // "08.09.2025"

// Time formats
print(dateTime.toHM());                     // "14:30"
print(dateTime.toHMS());                    // "14:30:45"
print(dateTime.to12HourTime());             // "2:30 PM"
print(dateTime.toFullDateTime());           // "2025-09-08 14:30:45"
print(dateTime.toIsoLike());                // "2025-09-08T14:30:45"

// Descriptive formats
print(dateTime.toMonthDayYear());           // "Sep 8, 2025"
print(dateTime.toLongMonthDayYear());       // "September 8, 2025"
print(dateTime.toShortWeekdayMonthDayYear()); // "Mon, Sep 8, 2025"
print(dateTime.toFullWeekdayMonthDayYear()); // "Monday, September 8, 2025"

// Components
print(dateTime.toWeekdayName());            // "Monday"
print(dateTime.toShortWeekdayName());       // "Mon"
print(dateTime.toMonthName());              // "September"
print(dateTime.toShortMonthName());         // "Sep"
print(dateTime.toOrdinalDay());             // "8th"

// Relative time
print(DateTime.now().subtract(Duration(hours: 2)).toRelativeTime()); // "2 hours ago"
print(DateTime.now().add(Duration(days: 3)).toRelativeTime());       // "in 3 days"
print(DateTime.now().subtract(Duration(minutes: 30)).toTimeAgo());   // "30m"

// Chat timestamps (smart formatting for messaging apps)
print(dateTime.toChatTimestamp()); // "14:30" (today), "Yesterday", or "Sep 6"

// Compact formats
print(dateTime.toCompactYMD());             // "20250908"

TimeOfDay Formatting Examples

final time = TimeOfDay(hour: 14, minute: 30);

// Basic formats
print(time.toHM());                         // "14:30"
print(time.toHIS());                        // "14:30:00"
print(time.to12Hour());                     // "2:30 PM"
print(time.to12HourWithSeconds());          // "2:30:00 PM"

// Utilities
print(time.isAM);                           // false
print(time.isPM);                           // true
print(time.period);                         // "PM"
print(time.totalMinutes);                   // 870 (minutes since midnight)

// Time arithmetic
print(time.addMinutes(45).toHM());          // "15:15"
print(time.subtractMinutes(45).toHM());     // "13:45"

// Conversions
DateTime dateTime = time.toDateTime();      // Convert to DateTime with today's date
DateTime specificDate = time.toDateTimeWithDate(DateTime(2025, 12, 25)); // Christmas 2025 at 14:30

// Comparisons
TimeOfDay start = TimeOfDay(hour: 12, minute: 0);
TimeOfDay end = TimeOfDay(hour: 18, minute: 0);
print(time.isBetween(start, end));          // true

// Time remaining
TimeOfDay target = TimeOfDay(hour: 18, minute: 0);
print(target.toTimeRemaining());            // "3h 30m" (if current time is 14:30)

// Custom formats
print(time.toCompactHM());                  // "1430"
print(time.toOClock());                     // "14:30 o'clock"

Get the first letters of a string

// you can use it like this
final _firstLetters = 'Mustafa Ibrahim'.initials;
// it will return 'MI'

Get the first letter of a string

// you can use it like this
final _firstLetter = 'Mustafa Ibrahim'.initial;
// it will return 'M'

Add extensions for theme, textTheme, and colorScheme for easy access to theme properties

// you can use it like this
final _theme = context.theme;
final _textTheme = context.textTheme;
final _colorScheme = context.colorScheme;

Add padding to widgets, allowing customization of height, width, or both DEPRECATED

⚠️ DEPRECATED: The EmptyPadding extension getters (ph, pw, p) are deprecated. Use Gap and SliverGap widgets instead.

Old way (deprecated):

8.ph // DEPRECATED - for vertical padding with 8.0 height
8.pw // DEPRECATED - for horizontal padding with 8.0 width  
8.p  // DEPRECATED - for both vertical and horizontal padding

New recommended way:

// Use Gap widget for spacing
Column(
  children: [
    Text('Item 1'),
    Gap(8.0), // Replaces 8.ph
    Text('Item 2'),
  ],
)

Row(
  children: [
    Text('Item 1'),
    Gap(8.0), // Replaces 8.pw  
    Text('Item 2'),
  ],
)

// For slivers, use SliverGap
CustomScrollView(
  slivers: [
    SliverToBoxAdapter(child: Text('Item 1')),
    SliverGap(8.0), // Better performance in slivers
    SliverToBoxAdapter(child: Text('Item 2')),
  ],
)

Useful Functions Example #

Convert any list with a date property to a sorted list of dates, where it will be sorted by the date property in the list items.

List<ExampleModel> _exampleList = [
  ExampleModel(
    id: 1,
    name: 'Example 1',
    date: DateTime.now().subtract(Duration(days: 1)),
  ),
  ExampleModel(
    id: 2,
    name: 'Example 2',
    date: DateTime.now().subtract(Duration(days: 2)),
  ),
  ExampleModel(
    id: 3,
    name: 'Example 3',
    date: DateTime.now().subtract(Duration(days: 3)),
  ),
  ExampleModel(
    id: 4,
    name: 'Example 4',
    date: DateTime.now().subtract(Duration(days: 4)),
  ),
  ExampleModel(
    id: 5,
    name: 'Example 5',
    date: DateTime.now().subtract(Duration(days: 5)),
  ),
  ExampleModel(
    id: 6,
    name: 'Example 6',
    date: DateTime.now().subtract(Duration(days: 6)),
  ),
];

// you can use it like this
final _sortedDateList = convertToSortedDateList(
  existingList: [],
  newList: _exampleList,
  dateProperty: (item) => item.date,
);

// it will return a list of dates sorted by the date property in the list items.

SortedDateList is a list of SortedDate where SortedDate is a class that has two properties date and list where date is the date property in the list items and list is a list of items that have the same date property.

GetTypeList function to get a list of types from a list of objects.

// you can use it like this
final examples = getTypeList<ExampleModel>(
  _exampleList,
  ExampleModel.fromJson,
);

License #

Easix is licensed under the MIT License.

MIT License

Copyright (c) 2023 Mustafa Ibrahim.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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.

Author #

Contributors #

All contributions are welcome. If you are interested in contributing to this project, please open a pull request.

4
likes
160
points
55
downloads

Publisher

verified publishermustafaix.live

Weekly Downloads

easix is a helper package that provide multiple handy function and extensions to use in your flutter project.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

cached_network_image, flutter, flutter_svg, intl

More

Packages that depend on easix