Value Notifier Tools
Helpful lightweight tools for working with ValueNotifier
s
Installation ๐ป
โ In order to start using History Value Notifier you must have the dart_install_link
installed on your machine.
Install via dart pub add
:
dart pub add value_notifier_tools
Features
This package adds helpful tools for working with ValueNotifier
s. Currently, it offers the following:
- ๐ HistoryValueNotifier allows you to undo and redo changes to the state of the notifier. This is useful for implementing undo/redo functionality in your app.
- ๐ฏ SelectValueNotifier allows you to select a subset of the state of a
ValueNotifier
. This is useful for when you only want to listen to a specific part of the state of and rebuild a widget when that changes. - ๐ WhereValueNotifier allows you to provide a custom predicate to determine whether a state change should be propagated to listeners. This is useful for when only certain state transitions should cause a rebuild.
- ๐ชถ No dependencies on any other packages and super lightweight.
- ๐งฉ Easy to use and integrate into your existing projects.
- ๐งช 100% test coverage
HistoryValueNotifier
- โฉ๏ธ Add
undo()
andredo()
toValueNotifier
- ๐ Limit the size of your history
- ๐ Offers both a mixin that can be added to your existing
ValueNotifier
s and a class that you can extend - ๐ Choose which states get stored to the history
- ๐ Transform states before applying them from the history
Usage
Getting started is easy! There are three main ways in which you can add HistoryValueNotifier
to your project:
Use it as-is
If you don't need any extra functionality, you can use HistoryValueNotifier
as-is.
import 'package:history_value_notifier/history_value_notifier.dart';
final notifier = HistoryValueNotifier<int>(0);
notifier.value = 1;
notifier.undo(); // 0
notifier.redo(); // 1
Upgrade an existing ValueNotifier
class CounterNotifier extends ValueNotifier<int>
with HistoryValueNotifierMixin<int> {
CounterNotifier() : super(0) {
// This is how you limit the size of your history.
// Set it to null to keep all state (default)
maxHistoryLength = 30;
}
void increment() => ++state;
void decrement() => --state;
// By using temporaryState setter, the change won't be stored in history
void reset() => temporaryState = 0;
// You can override this function to apply a transformation to a state
// from the history before it gets applied.
@override
int transformHistoryState(int newState, int currentState) {
return newState;
}
}
Create a HistoryValueNotifier
If you prefer to create a HistoryValueNotifier
directly, you can do this instead:
class CounterNotifier extends HistoryValueNotifier<int> {
// ... Same as above
}
Use It!
You can now use the full functionality of the HistoryValueNotifier
!
// Obtain a reference however you wish (Provider, GetIt, etc.)
final CounterNotifier notifier = context.read(counterNotifier);
notifier.increment(); // 1
notifier.undo(); // 0
notifier.redo(); // 1
notifier.decrement(); // 0
notifier.undo(); // 1
notifier.canRedo // true
notifier.increment // 2
notifier.canRedo // false
// ...
SelectValueNotifier
- ๐ฏ Select a subset of the state of a
ValueNotifier
- ๐งฉ Only listen to the parts of the state that you care about
- ๐ Micromanage rebuilds for maximum performance
Usage
Using SelectValueNotifier
is super easy:
Use the convenient select
extension method
This allows you to select a subset of the state of a ValueNotifier
by providing a selector function anywhere you need.
final notifier = ValueNotifier({'a': 1, 'b': 2});
return ValueListenableBuilder<int>(
valueListenable: notifier.select((value) => value['a']),
builder: (context, value, child) {
return Text(value.toString());
},
);
Your selectNotifier
will now only notify listeners when the value of 'a'
changes.
WhereValueNotifier
- ๐ Provide a custom predicate to determine whether a state change should be propagated to listeners
- ๐งฉ Only listen to the state changes that you care about
Usage
There are two main ways to use WhereValueNotifier
:
Use the where
extension method
This allows you to dynamically filter the state changes that you care about from another notifier.
final notifier = ValueNotifier(0);
return ValueListenableBuilder<int>(
valueListenable: notifier.where((oldState, newState) => newState > oldState),
builder: (context, value, child) {
return Text(value.toString());
},
);
Now, your widget will only rebuild when the new state is greater than the old state.
Extend it for your own custom classes
You can also extend it and provide your own updateShouldNotify
function.
class IncreasingValueNotifier<int> extends WhereValueNotifier<int> {
IncreasingValueNotifier(super.value);
@override
bool updateShouldNotify(T oldState, T newState) {
return oldState < newState;
}
}
Libraries
- value_notifier_tools
- Helpful lightweight tools for working with ValueNotifiers