|
| 1 | +# OUDS Flutter - GitHub Copilot Instructions |
| 2 | + |
| 3 | +This file provides guidance to GitHub Copilot when working on this repository. |
| 4 | +It covers contributor and maintainer guidelines: code formatting, architecture, build process, best practices, accessibility, development requirements, build commands and review guidelines. |
| 5 | + |
| 6 | +## Skills |
| 7 | + |
| 8 | +Load the appropriate skill before acting on the related task: |
| 9 | + |
| 10 | +| Task | Skill to load | |
| 11 | +|------|---------------| |
| 12 | +| Ask about or explain OUDS-specific terms (Tokenator, token, raw token, semantic token, component token, theme, …) | `ouds-flutter-vocabulary` | |
| 13 | +| Write or review Dart / Flutter code that uses OUDS components, themes or tokens | `ouds-flutter-framework-usage` | |
| 14 | +| Translate a Figma token name or token family into its Dart equivalent | `ouds-flutter-figma-to-dart` | |
| 15 | +| Migrate code between OUDS Flutter versions, adopt OUDS from native or custom Flutter components, or remove deprecated APIs | `ouds-flutter-migration-guide` | |
| 16 | +| Implement or review accessibility (Semantics, screen readers, text scale, high-contrast, orientation) | `ouds-flutter-accessibility` | |
| 17 | + |
| 18 | +Skills are located in `skills/<name>/SKILL.md` (treat this folder as the source of truth; keep the copies under `.claude/skills/` and `.opencode/skills/` in sync). |
| 19 | +## 1. Code formatting |
| 20 | + |
| 21 | +The source code is written in Dart and formatted with `dart format`. Linting is configured via `analysis_options.yaml` in each package using `package:flutter_lints/flutter.yaml`. |
| 22 | + |
| 23 | +Before any commit, run: |
| 24 | +```bash |
| 25 | +dart format . |
| 26 | +flutter analyze --no-pub |
| 27 | +``` |
| 28 | + |
| 29 | +No `// ignore:` suppression is allowed unless strictly justified with an explanatory comment on the same line. |
| 30 | + |
| 31 | +## 2. Architecture details |
| 32 | + |
| 33 | +The repository is a multi-package Flutter workspace managed with `pub` (native Dart workspace, `pubspec.yaml` at root). |
| 34 | + |
| 35 | +### 2.1 Packages |
| 36 | + |
| 37 | +#### `ouds_core` |
| 38 | + |
| 39 | +Contains all reusable UI components (widgets) provided by OUDS Flutter: buttons, switches, checkboxes, chips, tags, links, badges, navigation bars, top bars, form inputs, etc. |
| 40 | + |
| 41 | +- Components are located in `ouds_core/lib/components/<name>/` |
| 42 | +- Each component class is prefixed with `Ouds` (e.g. `OudsButton`, `OudsTag`) |
| 43 | +- Every component reads visual values exclusively through the active theme tokens |
| 44 | +- Current component areas also include `alert/`, `bottom_sheet/`, `country_selector/`, `divider/`, `link/`, `navigation/`, `pin_code_input/`, `top_bar/`, and form inputs such as `ouds_phone_number_input.dart` and `password_input/ouds_password_input.dart` |
| 45 | +- `ouds_core` also contains reusable module screens under `ouds_core/lib/modules/` (currently `module-about/` and `module-more/`) |
| 46 | + |
| 47 | +#### `ouds_theme_contract` |
| 48 | + |
| 49 | +Defines the `OudsThemeContract` abstract interface, the `OudsTheme` `InheritedModel` widget, semantic token abstractions and component token interfaces. |
| 50 | + |
| 51 | +> ⚠️ Token interface files in this package are **generated by Tokenator** (Figma → Dart). Do not edit them manually. |
| 52 | +
|
| 53 | +#### `ouds_theme_orange` |
| 54 | + |
| 55 | +Implements `OudsThemeContract` for all Orange brand products. Provides `OrangeTheme`. |
| 56 | + |
| 57 | +#### `ouds_theme_orange_compact` |
| 58 | + |
| 59 | +Implements `OudsThemeContract` for Orange products with tighter space and size constraints. Provides `OrangeCompactTheme`. |
| 60 | + |
| 61 | +#### `ouds_theme_sosh` |
| 62 | + |
| 63 | +Implements `OudsThemeContract` for all Sosh brand products. Provides `SoshTheme`. |
| 64 | + |
| 65 | +#### `ouds_theme_wireframe` |
| 66 | + |
| 67 | +Implements `OudsThemeContract` for prototyping and mockups. Provides `WireframeTheme`. |
| 68 | + |
| 69 | +#### `ouds_global_raw_tokens` |
| 70 | + |
| 71 | +Contains raw design token values (colors as hex, spacing as floats, typography sizes, etc.). |
| 72 | + |
| 73 | +> ⚠️ All files in this package are **generated by Tokenator** (Figma → Dart). Never edit them manually. |
| 74 | +
|
| 75 | +#### `ouds_accessibility_plugin` |
| 76 | + |
| 77 | +Native plugin (Android + iOS) providing platform-level accessibility features: high-contrast detection, system font scale. Used internally by `OudsCheckbox`, `OudsSwitch`, `OudsRadioButton`. |
| 78 | + |
| 79 | +#### `app` |
| 80 | + |
| 81 | +Demo application "Design System Toolbox" showcasing all components and tokens interactively. Every component must have a corresponding demo screen registered in `app/lib/ui/components/components.dart`. |
| 82 | + |
| 83 | +### 2.2 Architecture guidelines |
| 84 | + |
| 85 | +- Flutter / Material 3 is the default UI paradigm — embrace its declarative and reactive nature |
| 86 | +- When creating a new component, try to match the equivalent Material 3 widget API as closely as possible |
| 87 | +- Avoid unnecessary abstractions and over-engineering |
| 88 | +- Focus on simplicity, clarity, and idiomatic Dart |
| 89 | +- Organize by component — keep related code together |
| 90 | +- Use extensions to organise large files |
| 91 | +- Follow [Effective Dart](https://dart.dev/guides/language/effective-dart) naming conventions consistently |
| 92 | +- Use `sealed class` for exhaustive type modelling (e.g. `OudsIconStatus`) |
| 93 | +- Prefer `StatelessWidget` unless state is strictly necessary |
| 94 | +- Use `const` constructors wherever possible |
| 95 | + |
| 96 | +## 3. Build verification process ⚠️ CRITICAL |
| 97 | + |
| 98 | +**IMPORTANT**: When editing code, you MUST: |
| 99 | +1. Format the sources: `dart format .` |
| 100 | +2. Run static analysis: `flutter analyze --no-pub` |
| 101 | +3. Fix **all** errors and warnings before proceeding |
| 102 | +4. Run tests in every modified package: `flutter test` |
| 103 | +5. Check for dead code and remove unused imports, variables and methods |
| 104 | + |
| 105 | +## 4. Best practices |
| 106 | + |
| 107 | +### 4.1 DO |
| 108 | + |
| 109 | +- Write documentation in dartdoc format (`///`) for all public APIs, with at least one minimal code example |
| 110 | +- Use Dart's type system for safety — prefer strong types, avoid `dynamic` |
| 111 | +- Use `public` only when truly needed — prefer private (`_`) visibility |
| 112 | +- Apply **Clean Code, DRY, SOLID** and **TDD** principles |
| 113 | +- Use `const` constructors everywhere possible |
| 114 | +- Use `StatelessWidget` when state is not needed |
| 115 | +- Use `sealed class` / `enum` for exhaustive type modelling |
| 116 | +- Split large widgets into smaller private sub-widgets or methods |
| 117 | +- Use `final` fields in all widget classes |
| 118 | +- Use `static` for utility methods that do not need instance context |
| 119 | +- If a third-party dependency is added or updated, document it in `THIRD_PARTY.md` |
| 120 | +- Use `OudsTheme.of(context)` to read all colors, spacing, typography and component tokens |
| 121 | +- Use `OudsLocalizations.of(context)` or app localizations for user-facing strings |
| 122 | + - When introducing breaking changes or API modifications, update `MIGRATION.md` at the root of the repository and `skills/ouds-flutter-migration-guide/SKILL.md` accordingly |
| 123 | + |
| 124 | +### 4.2 DON'T |
| 125 | + |
| 126 | +- Add abstraction layers without clear benefit |
| 127 | +- Use `dynamic` or `Object` unless strictly necessary |
| 128 | +- Perform heavy computation inside `build()` — move it to `initState`, a provider, or `compute()` |
| 129 | +- Call `setState` from `initState` — use `addPostFrameCallback` if needed |
| 130 | +- Mix business logic with UI code |
| 131 | +- Use `print()` — use `debugPrint` or a proper logging package |
| 132 | +- Hardcode colors, dimensions, or strings — always use tokens and localizations |
| 133 | +- Edit or create token files in `ouds_global_raw_tokens`, `ouds_theme_contract`, `ouds_theme_orange`, `ouds_theme_orange_compact`, `ouds_theme_sosh`, or `ouds_theme_wireframe` |
| 134 | +- Create a root barrel file for `ouds_core` — this repository imports components directly from `package:ouds_core/components/...` |
| 135 | + |
| 136 | +## 5. Accessibility basics 🔴 MANDATORY |
| 137 | + |
| 138 | +Everything is available on [Orange accessibility guidelines](https://a11y-guidelines.orange.com/fr/mobile/). |
| 139 | + |
| 140 | +> Load the **`ouds-flutter-accessibility`** skill for the full reference with code examples, Semantics patterns, high-contrast, TalkBack/VoiceOver and the complete testing checklist. |
| 141 | +
|
| 142 | +### 5.1 Components |
| 143 | + |
| 144 | +- Wrap the root interactive element in a `Semantics` widget with appropriate flags (`button`, `checked`, `toggled`, `label`, `hint`, `value`) |
| 145 | +- Use `ExcludeSemantics` on purely decorative children |
| 146 | +- Use `MergeSemantics` to group related elements into a single focusable node when needed |
| 147 | +- Always provide a `semanticsLabel` parameter on components whose meaning is conveyed by color alone (e.g. `OudsBadge`) |
| 148 | +- Use `OudsLocalizations.of(context)` for all default accessibility strings — never hardcode them |
| 149 | + |
| 150 | +### 5.2 Display |
| 151 | + |
| 152 | +- Never lock text size — use OUDS typography tokens; never override `MediaQuery.textScalerOf` |
| 153 | +- Do not lock the app in portrait mode — support landscape orientation |
| 154 | +- Support high-contrast mode via `ouds_accessibility_plugin` |
| 155 | +- Test with TalkBack (Android) and VoiceOver (iOS) |
| 156 | + |
| 157 | +## 6. Development requirements |
| 158 | + |
| 159 | +- **Flutter**: `>= 3.35.0` |
| 160 | +- **Dart**: `>= 3.9.0` |
| 161 | +- **Minimum Android SDK**: API 21 (Android 5.0) |
| 162 | +- **Minimum iOS**: 13.0 |
| 163 | +- **Android Studio** or **Xcode** for platform builds |
| 164 | +- A physical device or simulator/emulator for full accessibility testing (TalkBack on Android, VoiceOver on iOS) |
| 165 | + |
| 166 | +## 7. Building commands |
| 167 | + |
| 168 | +### 7.1 Install dependencies |
| 169 | + |
| 170 | +```bash |
| 171 | +flutter pub get |
| 172 | +(cd ouds_core && dart pub get) |
| 173 | +(cd app && flutter pub get) |
| 174 | +``` |
| 175 | + |
| 176 | +If you modify ARB files in `app/lib/l10n/` or `ouds_core/lib/l10n/`, regenerate the generated localization files in the corresponding package: |
| 177 | + |
| 178 | +```bash |
| 179 | +(cd app && flutter gen-l10n) |
| 180 | +(cd ouds_core && flutter gen-l10n) |
| 181 | +``` |
| 182 | + |
| 183 | +### 7.2 Run tests |
| 184 | + |
| 185 | +Run tests in each modified package that currently has a `test/` directory: |
| 186 | + |
| 187 | +```bash |
| 188 | +(cd app && flutter test) |
| 189 | +(cd ouds_core && flutter test) |
| 190 | +(cd ouds_global_raw_tokens && flutter test) |
| 191 | +(cd ouds_theme_contract && flutter test) |
| 192 | +(cd ouds_theme_orange && flutter test) |
| 193 | +(cd ouds_theme_sosh && flutter test) |
| 194 | +(cd ouds_theme_wireframe && flutter test) |
| 195 | +``` |
| 196 | + |
| 197 | +At the time of writing, `ouds_theme_orange_compact` and `ouds_accessibility_plugin` do not contain a `test/` directory. |
| 198 | + |
| 199 | +### 7.3 Run static analysis |
| 200 | + |
| 201 | +```bash |
| 202 | +flutter analyze --no-pub |
| 203 | +``` |
| 204 | + |
| 205 | +### 7.4 Format the sources |
| 206 | + |
| 207 | +```bash |
| 208 | +dart format . |
| 209 | +``` |
| 210 | + |
| 211 | +### 7.5 Build documentation |
| 212 | + |
| 213 | +```bash |
| 214 | +cd ouds_core && dart doc |
| 215 | +``` |
| 216 | + |
| 217 | +## 8. Review guidelines |
| 218 | + |
| 219 | +- [ ] Sources are formatted — `dart format .` produces no diff |
| 220 | +- [ ] `flutter analyze --no-pub` passes with zero errors and warnings |
| 221 | +- [ ] All tests pass — `flutter test` in every modified package |
| 222 | +- [ ] No dead code — leave a comment identifying any element that seems unused |
| 223 | +- [ ] Documentation builds without error — `dart doc` in `ouds_core` produces no error |
| 224 | +- [ ] No secrets or credentials committed (Gitleaks scan via `.github/workflows/gitleaks.yml`) |
| 225 | +- [ ] No function is too long or too complex — keep cyclomatic complexity low, split if needed |
| 226 | +- [ ] All commits are signed-off (DCO applied) by their authors |
| 227 | +- [ ] All new public APIs have dartdoc comments (`///`) with at least one code example |
| 228 | +- [ ] All new interactive widgets use `Semantics` with appropriate flags |
| 229 | +- [ ] No hardcoded colors, dimensions, or strings — tokens and localizations are used |
| 230 | +- [ ] Component tested visually with all 4 themes (Orange, Orange Compact, Sosh, Wireframe) |
| 231 | +- [ ] Component tested in light **and** dark mode |
| 232 | +- [ ] Demo screen added or updated in `app/lib/ui/components/<name>/` |
| 233 | +- [ ] Demo screen registered in `app/lib/ui/components/components.dart` |
| 234 | +- [ ] Commit message follows [Conventional Commits](https://www.conventionalcommits.org/) (`feat:`, `fix:`, `doc:`, `chore:`, `test:`) |
| 235 | +- [ ] `MIGRATION.md` updated if any public API has changed or been deprecated |
| 236 | +- [ ] `skills/ouds-flutter-migration-guide/SKILL.md` updated to reflect any new migration steps |
| 237 | + |
| 238 | +## 9. Agent response optimization 🚀 |
| 239 | + |
| 240 | +When using GitHub Copilot for code reviews, refactoring, or documentation updates, minimize token consumption: |
| 241 | + |
| 242 | +### Key principles |
| 243 | + |
| 244 | +- **Batch operations**: Combine multiple file edits into single calls; parallelize `grep_search` and `file_search` |
| 245 | +- **Skip verbose narrative**: Avoid acknowledgments and filler ("Sounds good!", "Let me now..."); use single-line summaries |
| 246 | +- **Compress output**: Use tables/checklists instead of prose; reference line numbers instead of repeating content |
| 247 | +- **Front-load context**: Gather all research upfront before proposing changes; use `run_subagent` for large searches |
| 248 | +- **Minimize reads**: Read files once with adequate ranges; use search filters to avoid irrelevant files |
| 249 | + |
| 250 | +### Response template (optimized) |
| 251 | + |
| 252 | +``` |
| 253 | +**[Action summary — 1 line]** |
| 254 | +
|
| 255 | +### Changes |
| 256 | +[Table or checklist of modifications] |
| 257 | +
|
| 258 | +### Verification |
| 259 | +[Brief grep/status check results] |
| 260 | +``` |
| 261 | + |
| 262 | +**Target**: 150–300 tokens per response (50–60% reduction vs. standard approach). |
| 263 | + |
| 264 | +### When to delegate to subagent |
| 265 | + |
| 266 | +Use `run_subagent` when: |
| 267 | +- Search scope involves 50+ files |
| 268 | +- Result set would exceed 500 tokens |
| 269 | +- Task requires multiple sequential searches |
| 270 | + |
0 commit comments