|
⚡ bloc_signals_flutter"With the rigor of BLoC and the flex and speed of Signals" Flutter extensions, UI widgets, dependency injection providers, and reactive bindings for the bloc_signals state management library. |
This companion package provides BlocSignalProvider, MultiBlocSignalProvider, BlocSignalBuilder, BlocSignalListener, BlocSignalConsumer, BlocSignalSelector, BuildContext extensions (read(), watch()), and Flutter Listenable interop helpers.
🌐 Ecosystem Packages
The BlocSignal monorepo consists of 10 modular packages:
⚡ Key Features
- 📦
BlocSignalProvider: Dependency injectionInheritedWidgetwith automatic container disposal on unmount. - 🔗
MultiBlocSignalProvider: Nesting-free multi-bloc provider wrapper. - ⚡
BlocSignalBuilder: Fine-grained reactive UI widget triggered synchronously on state changes. - 👂
BlocSignalListener: Side-effect listener widget for snackbars, dialogs, and navigation. - 🔀
BlocSignalConsumer: Combines builder and listener into a single widget. - 🔍
BlocSignalSelector: Rebuilds ONLY when a derived state slice changes.
🚀 Getting Started
Add bloc_signals_flutter to your pubspec.yaml:
dependencies:
flutter:
sdk: flutter
bloc_signals_flutter: ^1.0.0
💡 Quick Examples
1. Providing & Building (BlocSignalProvider & BlocSignalBuilder)
import 'package:flutter/material.dart';
import 'package:bloc_signals_flutter/bloc_signals_flutter.dart';
void main() {
runApp(
MaterialApp(
home: BlocSignalProvider(
create: (context) => CounterBloc(),
child: const CounterScreen(),
),
),
);
}
class CounterScreen extends StatelessWidget {
const CounterScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('BlocSignal Counter')),
body: Center(
child: BlocSignalBuilder<CounterBloc, int>(
builder: (context, state) => Text('Count: $state'),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<CounterBloc>().add(Increment()),
child: const Icon(Icons.add),
),
);
}
}
2. Side-Effect Listener (BlocSignalListener)
BlocSignalListener<AuthBloc, AuthState>(
listener: (context, state) {
if (state is AuthFailure) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(state.error)),
);
}
},
child: const LoginForm(),
)
3. Combined Consumer (BlocSignalConsumer)
BlocSignalConsumer<CartBloc, CartState>(
listener: (context, state) {
if (state.itemAdded) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Item added to cart!')),
);
}
},
builder: (context, state) {
return Text('Cart items: ${state.items.length}');
},
)
4. Selective Rebuilds (BlocSignalSelector & context.select)
BlocSignalSelector<UserBloc, UserState, String>(
selector: (state) => state.username, // Rebuilds ONLY if username changes
options: ComputedOptions(name: 'UsernameSelector'), // Optional debug name
builder: (context, username) {
return Text('Hello, $username!');
},
)
Or directly via BuildContext:
final canSubmit = context.select<FormCubit, bool>(
(cubit) => cubit.stateValue.canSubmit,
);
Tip
Generic Type Parameters for context.select:
Unlike Riverpod's 3-parameter context.select or package:flutter_bloc, BlocSignal's context.select takes 2 generic type parameters:
B: TheBlocSignalBasecontainer type (e.g.,UserCubitorCounterBloc)R: The selected return value type (e.g.,Stringorbool)
The callback receives the bloc instance directly: context.select<FormCubit, bool>((cubit) => cubit.stateValue.canSubmit).
5. MultiBlocSignalProvider
MultiBlocSignalProvider(
providers: [
BlocSignalProvider<AuthBloc>(create: (context) => AuthBloc()),
BlocSignalProvider<ThemeBloc>(create: (context) => ThemeBloc()),
],
child: const AppShell(),
)
6. Flutter Listenable & ChangeNotifier Interop
// Convert any ChangeNotifier into a CubitSignal
final ChangeNotifier notifier = MyChangeNotifier();
final cubit = notifier.toBlocSignal(initialState: 0);
// Convert any CubitSignal into a Flutter ValueListenable
final ValueListenable<int> listenable = cubit.toValueListenable();
🤖 AI Coding Assistant Skill & Guides
This package is supported by official pre-packaged AI Coding Skills and architectural documentation guides representing Flutter widget lifecycle patterns, UI binding rules, and migration paths for BlocSignal:
- 🔄 Migration Guide: Transitioning from classic
package:flutter_bloc/package:bloctoBlocSignal. - 🌁 Universal Interoperability Guide: Bridging state containers across BLoC, Riverpod, Provider, and Listenable primitives.
- 📦 AI Skill Bundle: Load the pre-packaged
bloc-signalsskill bundle for AI coding assistants (such as Claude Code, Antigravity, Gemini, Cursor, or Codex) to guide code generation and analysis.
📜 Credits & Acknowledgements
Inspired by flutter_bloc by Felix Angelov and signals_flutter by Rody Davis.
Libraries
- bloc_signals_flutter
- Flutter bindings and UI integrations for the reactive
BlocSignallibrary.