65 lines
2.4 KiB
Cheetah
65 lines
2.4 KiB
Cheetah
---
|
|
description: "BLoC / Cubit conventions for {{PROJECT_NAME}}"
|
|
alwaysApply: true
|
|
---
|
|
|
|
# BLoC / Cubit Standards — {{PROJECT_NAME}}
|
|
|
|
## When to use BLoC vs Cubit
|
|
- **Cubit**: simple state with no meaningful event history (toggle, counter, pagination)
|
|
- **BLoC**: event-driven flows where event history or transitions matter (auth, checkout, form wizard)
|
|
|
|
## Event and State classes
|
|
```dart
|
|
// Events — sealed class (exhaustive switch)
|
|
sealed class AuthEvent { const AuthEvent(); }
|
|
final class AuthLoginRequested extends AuthEvent {
|
|
final String email, password;
|
|
const AuthLoginRequested({required this.email, required this.password});
|
|
}
|
|
final class AuthLogoutRequested extends AuthEvent { const AuthLogoutRequested(); }
|
|
|
|
// States — sealed class, immutable
|
|
sealed class AuthState { const AuthState(); }
|
|
final class AuthInitial extends AuthState { const AuthInitial(); }
|
|
final class AuthLoading extends AuthState { const AuthLoading(); }
|
|
final class AuthAuthenticated extends AuthState {
|
|
final User user;
|
|
const AuthAuthenticated(this.user);
|
|
}
|
|
final class AuthUnauthenticated extends AuthState { const AuthUnauthenticated(); }
|
|
final class AuthFailure extends AuthState {
|
|
final String message;
|
|
const AuthFailure(this.message);
|
|
}
|
|
```
|
|
|
|
## BlocProvider placement
|
|
- Create `BlocProvider` at the **route level** (in {{ROUTING}} route definitions)
|
|
- `MultiBlocProvider` at route level for screens needing multiple blocs
|
|
- **NEVER** create `BlocProvider` inside a widget's `build()` method
|
|
|
|
## Usage rules
|
|
- **NEVER** call `bloc.add()` inside `build()` — only in gesture callbacks or `initState()`
|
|
- Use `BlocConsumer` only when BOTH `listen` + `build` logic are needed
|
|
- Use `BlocSelector` when only a subset of state triggers a rebuild
|
|
- Every BLoC must override `close()` and cancel `StreamSubscription`s
|
|
|
|
## BlocBuilder patterns
|
|
```dart
|
|
BlocBuilder<AuthBloc, AuthState>(
|
|
builder: (context, state) => switch (state) {
|
|
AuthInitial() => const SizedBox.shrink(),
|
|
AuthLoading() => const LoadingIndicator(),
|
|
AuthAuthenticated(user: final u) => HomeScreen(user: u),
|
|
AuthUnauthenticated() => const LoginScreen(),
|
|
AuthFailure(message: final m) => ErrorScreen(message: m),
|
|
},
|
|
)
|
|
```
|
|
|
|
## File locations in {{PROJECT_NAME}}
|
|
- `lib/features/[feature]/presentation/bloc/[feature]_bloc.dart`
|
|
- `lib/features/[feature]/presentation/bloc/[feature]_event.dart`
|
|
- `lib/features/[feature]/presentation/bloc/[feature]_state.dart`
|