Booked Utils
A set of practical utilities for building Flutter apps faster: typed builders, wrappers for common patterns (ValueNotifier, StreamController), stream extensions, and chunked transformations.
Features
- Typed Widget Builders (
CallbackWidgetBuilder) - Reactive Wrappers & Listeners for
ValueNotifierandStreamController - Stream Extensions (e.g., doOnFirst)
- Chunked List Stream Transformer
- Navigation & Route Guards (
BlocPopBuilder)
Installation
Add to your pubspec.yaml:
dependencies:
booked_utils: ^<latest_version>
Import in your Dart files:
import 'package:booked_utils/booked_utils.dart';
Note:
BlocPopBuilderrequiresflutter_blocin your app. Add it to yourpubspec.yamlif you don't already use it.
dependencies:
flutter_bloc: ^<latest_version>
Contents
1. CallbackWidgetBuilder<T>
typedef CallbackWidgetBuilder<T> = Widget Function(T value);
A generic typedef for widget builders that take a value of type T.
2. ValueNotifierWrapper<T>
ValueNotifierWrapper<int>(
initialValue: 0,
onChange: (value) => print('Value changed: $value'),
child: (notifier) => ValueListenableBuilder<int>(
valueListenable: notifier,
builder: (context, value, _) => Text('Value: $value'),
),
)
Wraps a ValueNotifier for local, reactive state. Automatically disposes the notifier and can notify about changes.
3. ValueNotifierListener<T>
final counter = ValueNotifier<int>(0);
ValueNotifierListener<int>(
notifier: counter,
onChange: (value) => debugPrint('Counter: $value'),
child: const Text('Static child'),
)
Listens to a ValueNotifier and calls a callback on changes without rebuilding the child. Ideal for side effects such as snackbars, animations, or logging.
4. StreamControllerWrapper<T>
StreamControllerWrapper<String>(
child: (controller) => StreamBuilder<String>(
stream: controller.stream,
builder: (context, snapshot) => Text(snapshot.data ?? ''),
),
)
Manages the lifecycle of a StreamController and exposes it to a widget subtree.
5. ChunkTransformer<T>
final chunkedStream = Stream.value(List.generate(10000, (i) => i))
.transform(const ChunkTransformer<int>(chunkSize: 1024));
await for (final chunk in chunkedStream) {
print('Chunk size: ${chunk.length}');
}
A StreamTransformer that splits large incoming lists into fixed-size chunks. Useful for chunked uploads, network transfers, or file operations.
6. DoOnFirstEvent<T> Extension
Stream<int>.fromIterable([1, 2, 3])
.doOnFirst((first) async => print('First event: $first'))
.listen(print); // Prints: First event: 1, then 1, 2, 3
Allows performing an action (sync or async) on the first event of a stream, for initialization or logging.
7. BlocPopBuilder<B, S>
BlocPopBuilder<MyBloc, MyState>(
bloc: context.read<MyBloc>(),
// Return `true` to BLOCK pop, `false` to ALLOW pop
blockWhen: (state) => state is SavingState,
child: const MyFormScreen(),
)
A widget that controls back navigation based on BLoC/Cubit state using a blockWhen predicate. Internally it listens to the provided bloc and feeds a computed canPop value into PopScope, so system back gestures and buttons respect your rule.
Why use booked_utils?
- Reduces boilerplate: No need to manually manage controllers or notifiers for simple scenarios.
- Composable patterns: Designed for local state and micro-architecture without global dependencies.
- Production-ready: Null-safe, thoroughly tested in real Flutter apps.
API Reference
Each class and extension is documented with code samples in the source. See
ValueNotifierWrapperValueNotifierListenerStreamControllerWrapperChunkTransformerDoOnFirstEventCallbackWidgetBuilderBlocPopBuilder
License
MIT
Libraries
- booked_utils
- builders/bloc_pop_builder
- builders/builders
- extensions/do_on_first_event
- extensions/extensions
- transformers/chunk_transformer
- transformers/transformers
- typedefs/callback_widget_builder
- typedefs/typedefs
- widgets/value_notifier_listener
- widgets/widgets
- wrappers/stream_controller_wrapper
- wrappers/value_notifier_wrapper
- wrappers/wrappers