fabrik_utils
fabrik_utils is a lightweight, real-world-first utility package for Flutter apps. It includes the essential extensions and helpers that show up in almost every production app — crafted to improve developer experience and save time.
Installation
Section titled “Installation”Add the package to your pubspec.yaml:
dependencies: fabrik_utils: ^0.1.0Then run:
flutter pub getImport it in your Dart files:
import 'package:fabrik_utils/fabrik_utils.dart';String Extensions
Section titled “String Extensions”10 case conversions and null-safe helpers:
'hello world'.titleCase // "Hello World"'helloWorld'.snakeCase // "hello_world"'user_name'.camelCase // "userName"'http_request'.pascalCase // "HttpRequest"'Hello World'.kebabCase // "hello-world"'Hello World'.constantCase // "HELLO_WORLD"
'hello'.capitalizeFirst // "Hello"
String? value = null;value.isNullOrBlank // true' '.isNullOrBlank // trueDateTime Extensions
Section titled “DateTime Extensions”Checkers, formatters, date math, and relative time:
// CheckersDateTime.now().isToday // trueDateTime.now().isWeekend // false (on a weekday)someDate.isYesterdaysomeDate.isTomorrow
// Relative timesomeDate.timeAgo // "3 hours ago" / "2 days ago" / "1 month ago"
// Formattersdate.isoDate // "2024-06-15"date.dayMonthYear // "15 Jun 2024"date.fullWithWeekday // "Saturday, June 15, 2024"date.time12Hour // "2:30 PM"date.hourMinute24h // "14:30"
// Date mathdate.startOfDay // 2024-06-15 00:00:00.000date.endOfDay // 2024-06-15 23:59:59.999date.startOfWeek // midnight of the most recent Monday
// Range checkdate.isBetween(start, end) // true if start <= date <= endDuration Helpers
Section titled “Duration Helpers”formatDuration(Duration(seconds: 3665)) // "01:01:05"formatDuration(Duration(minutes: 4, seconds: 5)) // "04:05"formatDuration(Duration(seconds: 90), alwaysShowHours: true) // "00:01:30"
final parts = splitDuration(3665);parts.hours // "01"parts.minutes // "01"parts.seconds // "05"Throttle
Section titled “Throttle”Executes a function at most once per duration:
final throttle = Throttle<void>(duration: const Duration(seconds: 1));
throttle.throttle(() { print('Runs at most once per second');});
// Stream-based statusthrottle.listen((status) { print(status); // ThrottleStatus.idle or ThrottleStatus.busy});
throttle.close();Debounce
Section titled “Debounce”Delays execution until a pause in activity:
final debounce = Debounce<void>(duration: const Duration(milliseconds: 300));
// Fires after 300ms of inactivitydebounce.debounce(() => search(query));
// With maxWait — fires after at most 1 second regardless of call frequencyfinal debounce = Debounce<void>( duration: const Duration(milliseconds: 300), maxWait: const Duration(seconds: 1),);
// Cancel a pending call without closing the streamdebounce.cancel();
// Stream-based statusdebounce.listen((status) { print(status); // DebounceStatus.idle or DebounceStatus.waiting});
debounce.close();Scroll Helpers
Section titled “Scroll Helpers”Detect when a list is approaching the bottom — useful for pagination:
scrollController.addListener(() { if (isApproachingScrollEnd(scrollController)) { loadNextPage(); }});
// Custom threshold — trigger at 90% instead of the default 70%isApproachingScrollEnd(controller, scrollOffsetThreshold: 0.9)