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