fluiver 3.1.0
fluiver: ^3.1.0 copied to clipboard
Flutter utility library — debounce/throttle, observers, FlexGrid, DateTime predicates, and SDK gap-fillers.
Changelog #
3.1.0 #
Added #
| Category | API | Notes |
|---|---|---|
| Color | Color.darken([amount]), Color.lighten([amount]), Color.contrastText |
HSL-based; contrastText picks black/white via luminance |
| ScrollController | .atTop, .atBottom, .animateToTop({duration, curve}), .animateToBottom({duration, curve}) |
hasClients-safe |
| Future | Future<T>.timeoutOrNull(Duration) → Future<T?> |
Null on timeout, errors still propagate |
| Iterable | Iterable<E>.windowed(int size, {int step = 1}) |
Stepped sliding window; drops partial trailing window |
| TextEditingController | .setTextAndCaret(String, {int? caret}) |
Avoids the controller.text = ... caret-reset papercut |
Removed #
| Removed | Replacement |
|---|---|
PaddedFlex / PaddedRow / PaddedColumn widgets |
Padding(padding: ..., child: Column(children: [...])) / Row — LLMs reach for this natively |
IterableEnum.byNameOrElse(name, orElse: ...) |
Enum.values.byNameOrNull(name) ?? .fallback — Dart shorthand handles the fallback |
Changed #
- LLM artifact moved from
rules/fluiver.mdtorules/flutter-fluiver.md. Renamed with theflutter-prefix to namespace it against other rule collections.
3.0.0 #
Breaking — utility-library pivot.
The "single-dot shortcut" framing collided with LLM-assisted development: agents do not know the extensions exist, default to stdlib forms, and teaching the API costs input tokens on every turn. The sugar layer had to go. What remains is substance — things the SDK is genuinely missing.
Ships a compact rule file at rules/fluiver.md for consumer projects to
load into their LLM agent.
Removed #
| Removed | Replacement |
|---|---|
extensions/build_context.dart (all context.primaryColor, context.titleLargeTextStyle, context.screenWidth, context.isThemeDark, etc.) |
Theme.of(context).colorScheme.primary, Theme.of(context).textTheme.titleLarge, MediaQuery.sizeOf(context).width, Theme.of(context).brightness == Brightness.dark |
extensions/text_style.dart (withColor, withWeight400, withSize, withUnderline, ...) |
style.copyWith(color: ..., fontWeight: FontWeight.w400, fontSize: ...) |
extensions/edge_insets.dart (addLeft, onlyTop, setRight, withStatusBarMargin, ...) |
EdgeInsets.only(...), .copyWith(...), MediaQuery.viewPaddingOf(context).top |
extensions/border_radius.dart (addAll, onlyTopLeft, setBottomRight, ...) |
BorderRadius.only(...), .copyWith(...) |
extensions/bool.dart (toInt) |
b ? 1 : 0 |
extensions/date_time.dart arithmetic (addYears, addMonths, addWeeks, addDays, addHours, addMinutes, addSeconds) |
dt.add(Duration(days: N)) / DateTime(y + n, m, d) |
extensions/key.dart (validateAndSave on GlobalKey<FormFieldState<T>>) |
if (k.currentState!.validate()) k.currentState!.save(); |
extensions/flutter_enums.dart (Axis.reverse, TextDirection.reverse, Brightness.reverse, Orientation.reverse) |
inline ternary |
extensions/string.dart (capitalize, capitalizeAll, initials, safeSubstring) |
inline |
Renamed / Refactored #
| Before | After | Why |
|---|---|---|
top-level fastHash(s) |
FastHash.fnv1a(s) |
namespace, algorithm-named, future-proof for other hashes |
top-level hasDeviceConnection() |
NetworkProbe.hasConnection({timeout}) |
namespaced, timeout is now configurable |
top-level platformSpecific<T>(...) |
top-level platformDispatch<T>(...) |
clearer name; matches compute/dispatch mental model |
top-level disabledInputCounterBuilder |
TextFieldBuilders.disabledCounter |
namespaced; room for more TextField helpers |
TimeOfDay.todayAt() |
TimeOfDay.onDate(DateTime date) |
takes the calendar day explicitly — testable, no hidden DateTime.now() |
Fixed #
Map.entryOf(k)distinguishes "key absent" from "key present with null value"; previously returnednullfor both.{'a': null}.entryOf('a')now returnsMapEntry('a', null).DateTime.isTomorrow/isYesterdayusedDuration(days: 1)(24h), which crosses DST fall-back days incorrectly. Now uses calendar-day arithmetic (DateTime(y, m, d ± 1)).NetworkProbe.hasConnectionnow short-circuits totrueon web (previousdart:io.Socketcall would have thrown at runtime), narrows its catch toSocketException/TimeoutException(no more swallowing programming bugs), and exposes the timeout as a parameter.PaddedFlex.textDirection/textBaselinedefault tonull—Flexresolves from ambientDirectionality. Previously hardcodedTextDirection.ltrbroke RTL layouts.TickerBuilder.initStatecallssuper.initState()before starting the ticker.ThrottleLast._lastinitialized to a no-op closure instead oflate VoidCallback.Let<T>extension is now bounded toT extends Object, so.letno longer pollutes autocomplete on nullable receivers. Use?.let(...)for null-aware chaining.
Added #
LRUCache<K, V>(maxEntries: N)— bounded least-recently-used cache; O(1) reads/writes/eviction; reads/writes promote.DisposableBag— collectdispose/cancel/closeclosures and flush in registration order with a singledispose(). Idempotent; adding after dispose runs the closure immediately.rules/fluiver.md— compact rule file for LLM agents; documents the surviving API surface and steers away from removed identifiers.
Kept #
- Widgets:
FlexGrid,TickerBuilder,PaddedFlex/PaddedRow/PaddedColumn - Reactive:
Debounce,ThrottleLatest,ThrottleFirst,ThrottleLast - Observers:
LocaleObserver,BrightnessObserver,AppLifecycleObserver - DateTime predicates + merge:
isToday,isTomorrow,isYesterday,inThisYear,isWithinFromNow,age(),truncateTime,withTimeOfDay,toTimeOfDay - Enum:
EnumIndexComparablemixin,byNameOrNull,byNameOrElse - Iterable:
separated - Map:
any,every,firstWhereOrNull,where,whereKeyType,whereValueType,entryOf - Object:
let
2.4.3 #
- Removed
StreamWhereType(duplicatesdart:async). - Renamed
inToday→todayAt, fixedBuildContextsColorSchemetypo. - Doc fixes.
2.4.2 #
- Removed
is*enum getters; use shorthand comparisons (x == .ltr). - Improved
hasDeviceConnection(socket + timeout). - Added
disabledInputCounterBuilder.
2.4.1 #
- Broadened SDK constraint to
>=3.10.0 <4.0.0.
2.4.0 #
- Added
platformSpecificutility. - Modernized observers to use
PlatformDispatcher. - Adopted shorthand enum values throughout.
- Fixed
ThrottleLasttask execution.
2.3.0 #
- Added
indexparameter toIterable.separated. - Added
letscope extension onObject. - Renamed
deviceHasConnection→hasDeviceConnection. - Added
fastHash.
2.2.0 #
- Removed
Iterableextensions that duplicatepackage:collection. - Renamed
Iterable.separate→Iterable.separated.
2.1.0 #
- Added
PaddedFlex,PaddedRow,PaddedColumn.
2.0.0 #
- Breaking:
FlexGridrewritten asMultiChildRenderObjectWidget. - Added
FlexGrid.padding, all M3ColorSchemecontext getters. - Removed
BezierSquircleBorder. Min SDK Dart 3.0.0.
1.2.0 #
- Added
ColorSchemecontext getters,BezierSquircleBorder,StreamWhereType.
1.1.1 #
- Added
TickerBuilder.onTick.
1.1.0 #
- Added
TickerBuilder.
1.0.1 #
- Updated
MediaQuerylookups; removedelementAtOrNull,singleOrNull(now in core).
1.0.0 #
- Initial release.