accessibility
Audits or remediates Flutter widgets against WCAG 2.2 conformance levels A, AA, or AAA across iOS, Android, Web, macOS, Windows,…
Best practices for Bloc state management in Flutter/Dart, covering Cubit versus Bloc, event and state naming, sealed classes with Equatable, the Page/View split with BlocProvider, BlocBuilder, BlocListener, and BlocSelector. Use when writing, modifying, or reviewing code that
$ npx -y skills add VeryGoodOpenSource/vgv-ai-flutter-plugin --skill bloc --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/blocContext preview
The summary Claude sees to decide when to auto-load this skill.
Best practices for Bloc state management in Flutter/Dart, covering Cubit versus Bloc, event and state naming, sealed classes with Equatable, the Page/View split with BlocProvider, BlocBuilder, BlocListener, and BlocSelector. Use when writing, modifying, or reviewing code that
name: bloc description: > Best practices for Bloc state management in Flutter/Dart, covering Cubit versus Bloc, event and state naming, sealed classes with Equatable, the Page/View split with BlocProvider, BlocBuilder, BlocListener, and BlocSelector. Use when writing, modifying, or reviewing code that uses package:bloc, package:flutter_bloc, or package:bloc_test. Also use for any test of a class that extends Bloc or Cubit, including "write the unit tests for this bloc", "test my cubit", "add tests for LoginBloc", mocking a repository a bloc depends on, and asserting the states an event emits. Bloc and Cubit tests must use blocTest() from package:bloc_test with package:mocktail, so prefer this over the testing skill whenever the class under test is a Bloc or Cubit. Also use when a request pushes against these rules, such as injecting one bloc into another to read its state, calling a repository from a widget or build method, or keeping a Cubit for a feature that needs an event transformer such as debounce. allowed-tools: Read Glob Grep
State management library for Dart and Flutter using the BLoC (Business Logic Component) pattern to separate business logic from the presentation layer.
---
Apply these standards to all Bloc/Cubit work:
---
| Aspect | Cubit | Bloc | | ------------ | ----------------------------- | --------------------------------------- | | API | Functions → `emit(state)` | Events → `on<Event>` → `emit(state)` | | Complexity | Low | Higher | | Traceability | Less (no event log) | Full (events + transitions) | | When to use | Simple state, UI-driven logic | Complex flows, event-driven, transforms | | Testing | Call methods, assert states | Add events, assert states |
class CounterCubit extends Cubit<int> {
CounterCubit() : super(0);
void increment() => emit(state + 1);
void decrement() => emit(state - 1);
}sealed class CounterEvent extends Equatable {
const CounterEvent();
@override
List<Object> get props => [];
}
final class CounterIncrementPressed extends CounterEvent {}
final class CounterDecrementPressed extends CounterEvent {}
class CounterBloc extends Bloc<CounterEvent, int> {
CounterBloc() : super(0) {
on<CounterIncrementPressed>((event, emit) => emit(state + 1));
on<CounterDecrementPressed>((event, emit) => emit(state - 1));
}
}---
**Pattern:** `BlocSubject` + `Noun` + `VerbPastTense`
| Event class name | Meaning | | ------------------------------- | ------------------------------- | | `TodoListSubscriptionRequested` | Subscribing to todo list stream | | `TodoListTodoDeleted` | Deleting a specific todo | | `TodoListUndoDeletionRequested` | Undoing the last deletion | | `LoginFormSubmitted` | Submitting the login form | | `ProfilePageRefreshed` | Refreshing the profile page |
sealed class TodoListEvent extends Equatable {
const TodoListEvent();
@override
List<Object> get props => [];
}
final class TodoListSubscriptionRequested extends TodoListEvent {}
final class const TodoListTodoDeleted({required final Todo todo})
extends TodoListEvent {
@override
List<Object> get props => [todo];
}Use when each state carries different data.
| State class name | Meaning | | ----------------- | ----------------------- | | `LoginInitial` | No action taken yet | | `LoginInProgress` | Login request in flight | | `LoginSuccess` | Login succeeded | | `LoginFailure` | Login failed |
sealed class LoginState extends Equatable {
const LoginState();
@override
List<Object> get props => [];
}
final class LoginInitial extends LoginState {}
final class LoginInProgress extends LoginState {}
final class const LoginSuccess({required final User user}) extends LoginState {
@override
List<Object> get props => [user];
}
final class const LoginFailure({required final String error})
extends LoginState {
@override
List<Object> get props => [error];
}Use when all state
A Claude Code plugin that accelerates Flutter & Dart development with best-practices skills from Very Good Ventures. Developed with 💙 by Very Good Ventures 🦄
Audits or remediates Flutter widgets against WCAG 2.2 conformance levels A, AA, or AAA across iOS, Android, Web, macOS, Windows,…
Best practices for Flutter animations using the built-in animation framework, covering implicit animations, explicit…
Scaffold a new Dart or Flutter project from a Very Good CLI template, covering the flutter_app, dart_package, flutter_package,…
VGV-specific reference for bumping Dart and Flutter SDK constraints across packages, covering pubspec.yaml environment…
Drives a Dart or Flutter package fully green through a verify-fix-rerun loop across four gates: analyze, format, test, coverage.…
Best practices for internationalization (i18n) and localization (l10n) in Flutter, using the built-in `flutter_localizations` and…