holders 0.1.0 copy "holders: ^0.1.0" to clipboard
holders: ^0.1.0 copied to clipboard

Lightweight reactive value holders for Flutter with linked values, notifications, timing controls, and builder widgets.

holders #

Quality

Lightweight reactive values for Flutter. A holder owns or adapts a value, notifies callbacks when it changes, and can rebuild widgets without requiring a larger state-management framework.

Features #

  • Store values with ValueHolder.
  • Derive and update values through LinkHolder.
  • Adapt ValueNotifier instances with NotifierHolder.
  • Adapt callback-based state with GetterHolder.
  • Ignore equivalent values with a custom comparator.
  • Debounce notifications with stress and throttle them with cooldown.
  • Rebuild widgets with HolderBuilder or HoldersBuilder.

Installation #

Add holders to your pubspec.yaml:

dependencies:
  holders: ^0.1.0

Then import it:

import 'package:holders/holders.dart';

Usage #

Create a holder and subscribe to changes:

final counter = ValueHolder<int>(
  0,
  isEqual: nativeIsEqual,
);

void logValue(int value) => print('Counter: $value');

counter.hold(logValue);
counter.value = 1; // Prints: Counter: 1
counter.value = 1; // Ignored because the value is equal.
counter.unhold(logValue);

Create a two-way derived value with link:

final temperature = ValueHolder<double>(20);
final fahrenheit = temperature.link<double>(
  read: (celsius) => celsius * 9 / 5 + 32,
  write: (fahrenheit) => (fahrenheit - 32) * 5 / 9,
  isEqual: nativeIsEqual,
);

fahrenheit.value = 86;
print(temperature.value); // 30.0

Rebuild a widget when a holder changes:

HolderBuilder(
  holder: counter,
  builder: (context) => Text('${counter.value}'),
)

Create a Flutter listenable when an API requires one, and dispose it when its owner is disposed:

final listenable = counter.buildListener();

// Use listenable with a ValueListenableBuilder.

listenable.dispose();

Holder values update immediately. stress waits until changes stop before notifying callbacks, emitting only the latest value. cooldown emits the first notification immediately and then, at most once per interval, emits the latest value received during that interval. When both are set, stress runs first and cooldown starts after the changes settle:

final query = ValueHolder<String>(
  '',
  isEqual: nativeIsEqual,
  stress: const Duration(milliseconds: 300),
);

Notifications can be disabled until a particular value is observed or a condition is met. These methods also support nullable values:

final selection = ValueHolder<int?>(0);

selection.turnOffUntilValue(null);
selection.value = null; // Turns on and emits null.

selection.turnOffUntil(
  (value) => value != null && value.isEven,
  excludeMatchingCall: true,
);
selection.value = 2; // Turns on without emitting 2.

selection.dispose();

Lifecycle #

Call dispose() when a holder is no longer needed. This cancels its timers, removes callbacks, and disconnects linked or notifier-backed holders from their source. Disposal is permanent: attempts to access the value or reactivate the holder throw StateError. Status and configuration reads, removing a callback with unhold(), and calling dispose() again remain safe.

Linked holders and read-only listeners are disposed automatically with their source. NotifierHolder does not own the supplied ValueNotifier; dispose that notifier separately when appropriate.

Listenables and notifiers created with buildListener() or buildNotifier() are owned by their caller and must be disposed. Disposing the holder disconnects them but does not dispose them.

1
likes
160
points
107
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Lightweight reactive value holders for Flutter with linked values, notifications, timing controls, and builder widgets.

Repository (GitHub)
View/report issues

Topics

#state-management #reactive #value-notifier #value-listenable #flutter

License

MIT (license)

Dependencies

flutter

More

Packages that depend on holders