accessibility
Use when working on accessibility, a11y, WCAG, ARIA, screen readers, keyboard nav, focus order, contrast, alt text, captions,…
Use when writing switch statements, refactoring if-else chains, creating data classes, choosing records vs classes, destructuring values, or modernizing pre-Dart-3 code.
Claude Code
$ npx -y skills add evanca/flutter-ai-rules --skill dart-3-updates --agent claude-code
Codex
$ npx skills add evanca/flutter-ai-rules --skill dart-3-updates -a codex -y
Cursor
$ npx skills add evanca/flutter-ai-rules --skill dart-3-updates -a cursor -y
Gemini CLI
$ npx skills add evanca/flutter-ai-rules --skill dart-3-updates -a gemini-cli -y
GitHub Copilot
$ npx skills add evanca/flutter-ai-rules --skill dart-3-updates -a github-copilot -y
OpenCode
$ npx skills add evanca/flutter-ai-rules --skill dart-3-updates -a opencode -y
Windsurf
$ npx skills add evanca/flutter-ai-rules --skill dart-3-updates -a windsurf -y
name: dart-3-updates description: "Use when writing switch statements, refactoring if-else chains, creating data classes, choosing records vs classes, destructuring values, or modernizing pre-Dart-3 code." license: MIT
Apply Dart 3 language features — branches, patterns, pattern types, and records — correctly and idiomatically.
Use this skill when:
---
// Standard if
if (score >= 90) {
grade = 'A';
} else if (score >= 80) {
grade = 'B';
} else {
grade = 'C';
}
// if-case: match and destructure against a single pattern
if (pair case [int x, int y]) {
print('$x, $y');
}switch (command) {
case 'quit':
quit();
case 'start' || 'begin': // logical-or pattern
startGame();
default:
print('Unknown command');
}final color = switch (shape) {
Circle() => 'red',
Square() => 'blue',
_ => 'unknown',
};sealed class Shape {}
class Circle extends Shape {}
class Square extends Shape {}
// Dart knows all subtypes — no default needed:
String describe(Shape s) => switch (s) {
Circle() => 'circle',
Square() => 'square',
};switch (point) {
case (int x, int y) when x == y:
print('Diagonal: $x');
case (int x, int y):
print('$x, $y');
}---
Patterns represent the **shape** of a value for matching and destructuring.
// Variable declaration
var (a, [b, c]) = ('str', [1, 2]);
// Variable assignment (swap)
(b, a) = (a, b);
// for-in loop destructuring
for (final MapEntry(:key, :value) in map.entries) { ... }
// switch / if-case (see Branches section)var Foo(:one, :two) = myFoo;
if (data case {'user': [String name, int age]}) {
print('$name, $age');
}---
| Pattern | Syntax | Description | |---|---|---| | Logical-or | `p1 \|\| p2` | Matches if any branch matches. All branches must bind the same variables. | | Logical-and | `p1 && p2` | Matches if both match. Variable names must not overlap. | | Relational | `== c`, `< c`, `>= c` | Compares value to a constant. Combine with `&&` for ranges. | | Cast | `subpattern as Type` | Asserts type, then matches inner pattern. Throws if type mismatch. | | Null-check | `subpattern?` | Matches non-null; binds non-nullable type. | | Null-assert | `subpattern!` | Matches non-null or throws. Use in declarations to eliminate nulls. | | Constant | `42`, `'str'`, `const Foo()` | Matches if value equals the constant. | | Variable | `var name`, `final Type name` | Binds matched value to a new variable. Typed form only matches the declared type. | | Wildcard | `_`, `Type _` | Matches any value without binding. | | Parenthesized | `(subpattern)` | Controls precedence. | | List | `[p1, p2]` | Matches lists by position. Length must match unless a rest element is used. | | Rest element | `...`, `...rest` | Matches arbitrary-length tails or collects remaining elements. | | Map | `{'key': subpattern}` | Matches maps by key. Missing keys throw `StateError`. | | Record | `(p1, p2)`, `(x: p1, y: p2)` | Matches records by shape; field names can be omitted if inferred. | | Object | `ClassName(field: p)` | Matches by type and destructures via getters. Extra fields ignored. |
---
// Create
var record = ('first', a: 2, b: true, 'last');
// Type annotation
({int a, bool b}) namedRecord;
// Access
print(record.$1); // positional: 'first'
print(record.a); // named: 2(String name, int age) userInfo(Map<String, dynamic> json) {
return (json['name'] as String, json['age'] as int);
}
va36 Flutter and Dart skills your coding agent loads by itself, sourced only from official documentation. A skill is a folder with a SKILL.md file.
Use when working on accessibility, a11y, WCAG, ARIA, screen readers, keyboard nav, focus order, contrast, alt text, captions,…
Use when creating a feature, designing folder structure, adding repositories/services/view models, wiring dependency injection,…
Use when creating a Cubit or Bloc, modeling state with sealed classes or status enums, wiring…
Use when asked to review a PR, MR, branch, or diff, audit changed files, or check code quality.
Use when building AI agents in Dart, implementing Genkit flows or tools, integrating LLMs into Dart or Flutter applications, or…
Use when writing Dart code, reviewing for style, refactoring naming, adding doc comments, structuring imports, or enforcing type…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.