micha_core 0.1.0 micha_core: ^0.1.0 copied to clipboard
Extensions and widgets that are missing in Flutter's SDK.
Extensions and widgets that are missing in Flutter's SDK.
Features #
- Declarative extensions to avoid loops and imperative logic.
- Useful widgets, like a
Gap
widget to avoid the use ofPadding
.
Usage #
Separate items of collections #
Need to add some items between existing items of a List
or Iterable
? Use collection.separated(separator)
:
[1, 2, 3].separated(0); // [1, 0, 2, 0, 3]
Are these separators dependent on preceding and succeeding items? Use collection.separatedBy((before, after) => separator)
:
[1, 2, 3].separatedBy((before, after) => before + after); // [1, 3, 2, 5, 3]
Enum values byNameOrNull #
In dart, you can find enum values by their names, like:
enum TestEnum { one, two, three }
TestEnum.values.byName('two');
But what if that value does not exist? Dart will throw an ArgumentError
.
Use byNameOrNull to receive null
instead:
TestEnum.values.byValueOrNull('four');
Gap #
We often require some small space between widgets. Flutter's widget catalog has limited options:
- Flutter's
Spacer
takes up all available space, which is often more than we want. - Flutter's
Padding
unfortunately needs to be wrapped around widgets, adding boilerplate, while also being hard to read inside of lists. - The best that Flutter offers is a
SizedBox
with a specifiedwidth
orheight
.
However, this still has some problems: We need to set eitherwidth
orheight
, depending on whether theSizedBox
is placed inside aRow
orColumn
.
We also need to repeat the same constant pixel size all throughout the application.
Instead, consider using a Gap
:
Column(
children: [
Text('first'),
Gap(),
Text('second'),
],
);
Gap
takes up a fixed space in both directions.
It takes 16 pixels by default, but can be configured using the GapThemeData
theme extension or its constructor parameters.
When you need a little more or less space relative to the configured theme, create a Gap with a scale factor, like Gap(scale: 2)
or Gap(scale: 0.5)
respectivly.
You can also add to, subtract from, multiply or devide a Gap to scale it, e.g. Gap() * 2
.
ThemedText #
Avoid accessing ThemeData
manually to set a themed textStyle
. Use a ThemedText
widget instead:
ThemedText.headlineMedium('Some headline');
AsyncBuilder #
Using Flutter's FutureBuilder
requires a lot of imperative boilerplate.
You need to explicitly catch loading, error and no-data states while also keeping the Future
in state.
If you do this: FutureBuilder(future: load(), builder: ...);
, then FutureBuilder will call load()
whenever your widget rebuilds.
As an alternative, AsyncBuilder
offers a declarative API:
AsyncBuilder(
createFuture: () => Future.delayed(
const Duration(seconds: 1),
() => 'some data',
),
builder: (context, data) => Text(data),
);
AsyncBuilder
only reloads when its key
changes.
You can also customize initialData
and change the look of loading, no-data and error states, which each have sensible defaults.
Spinner #
Spinner
is essentially a slightly improved SpinningProgressIndicator
.
It is always centered, can be given a fixed size
, its strokeWidth
is a bit more narrow and it all can be themed using SpinnerThemeData
.
It is also the default loading indicator used by AsyncBuilder
.