|
| 1 | +# Instructions de codage IA pour VueDsfr |
| 2 | + |
| 3 | +## Vue d'ensemble du projet |
| 4 | +VueDsfr est une bibliothèque de composants Vue 3 qui porte le Système de Design Français (DSFR) vers Vue.js. Elle fournit ~50 composants accessibles et prêts pour la production suivant les normes de design du gouvernement français. |
| 5 | + |
| 6 | +## Pour les tâches que je vais te demander |
| 7 | + |
| 8 | +Voir le fichier `.github/copilot-tasks.instructions.md` pour les instructions spécifiques aux tâches. |
| 9 | + |
| 10 | +## Architecture et structure des fichiers |
| 11 | + |
| 12 | +### Organisation des composants |
| 13 | +- **Emplacement** : `src/components/Dsfr*/` |
| 14 | +- **Fichiers par composant** : |
| 15 | + - `DsfrComponent.vue` - Composant principal |
| 16 | + - `DsfrComponent.types.ts` - Interfaces TypeScript |
| 17 | + - `DsfrComponent.spec.ts` - Tests unitaires (Vitest) |
| 18 | + - `DsfrComponent.stories.ts` - Stories Storybook |
| 19 | + - `DsfrComponent.md` - Documentation du composant |
| 20 | + - `docs-demo/` - Composants de démonstration pour la docs |
| 21 | + |
| 22 | +### Répertoires clés |
| 23 | +- `src/components/` - Tous les composants DSFR (exportés via `index.ts`) |
| 24 | +- `src/composables/` - Composables Vue partagés (useScheme, useTabs, useCollapsable) |
| 25 | +- `src/utils/` - Fonctions utilitaires |
| 26 | +- `meta/` - Outils de build (auto-import, résolveur de composants) |
| 27 | +- `demo-app/` - Application de développement/démonstration |
| 28 | +- `docs/` - Documentation VitePress |
| 29 | +- `tests/unit/` - Utilitaires et configuration des tests |
| 30 | + |
| 31 | +## Workflow de développement |
| 32 | + |
| 33 | +### Commandes de build et exécution |
| 34 | +```bash |
| 35 | +pnpm install # Installer les dépendances (utiliser pnpm, pas npm/yarn) |
| 36 | +pnpm dev # Démarrer le serveur de développement Storybook (:6006) |
| 37 | +pnpm demo # Démarrer l'app de démonstration (:5173) |
| 38 | +pnpm docs:dev # Démarrer la documentation VitePress (:4173) |
| 39 | +pnpm build # Builder la bibliothèque vers dist/ |
| 40 | +pnpm test # Exécuter les tests unitaires Vitest |
| 41 | +pnpm coverage # Exécuter les tests avec couverture |
| 42 | +pnpm lint # Exécuter ESLint |
| 43 | +pnpm format # Corriger automatiquement ESLint |
| 44 | +``` |
| 45 | + |
| 46 | +### Pattern de création de composant |
| 47 | +1. Créer le répertoire `src/components/DsfrNewComponent/` |
| 48 | +2. Ajouter les fichiers : `DsfrNewComponent.vue`, `.types.ts`, `.spec.ts`, `.stories.ts`, `.md` |
| 49 | +3. Exporter depuis `src/components/index.ts` (types et composant) |
| 50 | +4. Ajouter à `src/index.ts` s'il s'agit d'une nouvelle exportation racine |
| 51 | +5. Exécuter `pnpm check-exports` pour vérifier les exportations |
| 52 | + |
| 53 | +### Patterns TypeScript |
| 54 | +- **Interface props** : `DsfrComponentProps` dans `.types.ts` |
| 55 | +- **Ref composant** : Utiliser `InstanceType<typeof Component>['$props']` pour les types complexes |
| 56 | +- **Clés d'injection** : Définir dans `injection-key.ts` pour la communication entre composants |
| 57 | +- **Types composables** : Exporter l'implémentation et les interfaces de types de retour |
| 58 | + |
| 59 | +### Patterns de test |
| 60 | +- **Fichier de test** : `*.spec.ts` colocalisé avec le composant |
| 61 | +- **Configuration** : `tests/unit/vitest-setup.ts` configure Vue Test Utils + jsdom |
| 62 | +- **Mocking** : Utiliser `vi.mock()` pour les dépendances externes |
| 63 | +- **Test de composant** : Monter avec `mount(Component, { props })` |
| 64 | + |
| 65 | +### Intégration du style et DSFR |
| 66 | +- **Imports CSS** : Les composants importent depuis les modules CSS `@gouvfr/dsfr` |
| 67 | +- **Support du thème** : Utiliser le composable `useScheme` pour les modes clair/sombre |
| 68 | +- **Accessibilité** : Tous les composants suivent les standards d'accessibilité DSFR |
| 69 | +- **Icônes** : Utiliser le composant `VIcon` avec @iconify/vue |
| 70 | + |
| 71 | +### Qualité du code et commits |
| 72 | +- **Commits** : Suivre les commits conventionnels (`feat:`, `fix:`, `docs:`, etc.) |
| 73 | +- **Linting** : @antfu/eslint-config avec règles spécifiques à Vue |
| 74 | +- **Pre-commit** : Husky exécute lint-staged sur `*.{vue,ts}` |
| 75 | +- **CI** : GitHub Actions exécute les tests, le linting et la vérification de build |
| 76 | + |
| 77 | +### Points d'intégration clés |
| 78 | +- **Installation plugin** : `app.use(VueDsfr)` enregistre tous les composants mais cette utilisation est obsolète |
| 79 | +- **Auto-import** : Utiliser `meta/component-resolver.js` avec `unplugin-vue-components` |
| 80 | +- **Collections d'icônes** : Le binaire `vue-dsfr-icons` génère des collections d'icônes personnalisées |
| 81 | +- **Initialisation DSFR** : Importer `src/init-dsfr.ts` pour configurer `window.dsfr` |
| 82 | + |
| 83 | +### Patterns courants |
| 84 | +- **Communication composants** : Utiliser `provide`/`inject` avec des clés d'injection |
| 85 | +- **Gestion événements** : Émettre des événements personnalisés en kebab-case |
| 86 | +- **Nommage slots** : Utiliser des noms de slots descriptifs (ex: `header`, `content`, `footer`) |
| 87 | +- **Classes CSS** : Suivre les conventions BEM-like DSFR |
| 88 | +- **Gestion erreurs** : Lever des erreurs descriptives pour les combinaisons de props invalides |
| 89 | + |
| 90 | +### Documentation |
| 91 | +- **Docs composants** : Écrire en français (standard DSFR), inclure des exemples d'usage |
| 92 | +- **Stories** : Utiliser le format Storybook CSF3 avec `args`/`argTypes` |
| 93 | +- **VitePress** : Site de documentation dans `docs/` avec références de composants |
| 94 | + |
| 95 | +## 🎯 Conventions Git & Commits |
| 96 | + |
| 97 | +### Format des commits |
| 98 | + |
| 99 | +Utilise **TOUJOURS** le format : `type(scope): gitmoji description` |
| 100 | + |
| 101 | +**Exemple** : `feat(auth): ✨ ajoute la fonctionnalité de connexion OAuth2` |
| 102 | + |
| 103 | +### Types de commits conventionnels |
| 104 | +- `feat`: ✨ Nouvelles fonctionnalités |
| 105 | +- `fix`: 🐛 Corrections de bugs |
| 106 | +- `docs`: 📚 Documentation |
| 107 | +- `style`: 💄 Formatage, style (pas de changement de logique) |
| 108 | +- `refactor`: ♻️ Refactoring (ni feat ni fix) |
| 109 | +- `perf`: ⚡ Améliorations de performance |
| 110 | +- `test`: ✅ Ajout/modification de tests |
| 111 | +- `chore`: 🔧 Maintenance, configuration, dépendances |
| 112 | +- `ci`: 👷 CI/CD, GitHub Actions |
| 113 | +- `revert`: ⏪ Annulation de commit |
| 114 | + |
| 115 | +### Gitmojis recommandés |
| 116 | +- ✨ `:sparkles:` - Nouvelle fonctionnalité |
| 117 | +- 🐛 `:bug:` - Correction de bug |
| 118 | +- 📝 `:memo:` - Documentation |
| 119 | +- 💄 `:lipstick:` - UI/UX, styles |
| 120 | +- ♻️ `:recycle:` - Refactoring |
| 121 | +- ⚡ `:zap:` - Performance |
| 122 | +- ✅ `:white_check_mark:` - Tests |
| 123 | +- 🔧 `:wrench:` - Configuration |
| 124 | +- 🚀 `:rocket:` - Déploiement |
| 125 | +- 🎨 `:art:` - Structure/format du code |
| 126 | +- 🔒 `:lock:` - Sécurité |
| 127 | +- 🌐 `:globe_with_meridians:` - Internationalisation |
| 128 | +- 💾 `:floppy_disk:` - Base de données |
| 129 | +- 🔄 `:arrows_counterclockwise:` - Réactivité, WebSockets |
| 130 | + |
| 131 | +### Structure des messages de commit |
| 132 | +``` |
| 133 | +type(scope): gitmoji description courte |
| 134 | +
|
| 135 | +## Pourquoi les changements ont été faits : |
| 136 | +- Explication du contexte et des raisons |
| 137 | +- Problème résolu ou besoin adressé |
| 138 | +
|
| 139 | +## Quelles modifications ont été apportées : |
| 140 | +- Description détaillée des modifications |
| 141 | +- Impact sur l'architecture/fonctionnalités |
| 142 | +``` |
| 143 | + |
| 144 | +Pas de majuscule au début de la description courte. |
| 145 | +Utilise la troisième personne du singulier au présent de l'indicatif pour la description courte. |
| 146 | + |
| 147 | +## 🛠️ Conventions Techniques |
| 148 | + |
| 149 | +### Vue.js & Composition API |
| 150 | +- **TOUJOURS** utiliser `<script setup lang="ts">` |
| 151 | +- Préférer les `ref()` et `computed()` aux options API |
| 152 | +- **Props & Emits** : Utiliser TOUJOURS la définition par types TypeScript |
| 153 | +- **Props booléennes** : Ne pas utiliser `withDefaults` si la valeur par défaut est `false` |
| 154 | +- Exposer les références nécessaires avec `defineExpose()` |
| 155 | + |
| 156 | +#### ✅ Props & Emits - Bonnes pratiques |
| 157 | + |
| 158 | +```vue |
| 159 | +<!-- ✅ Correct - Types TypeScript --> |
| 160 | +<script setup lang="ts"> |
| 161 | +// Props simples |
| 162 | +const props = defineProps<{ |
| 163 | + show?: boolean // false par défaut, pas besoin de withDefaults |
| 164 | + title?: string // undefined par défaut |
| 165 | + count?: number // undefined par défaut |
| 166 | +}>() |
| 167 | +
|
| 168 | +// Emits avec types |
| 169 | +const emit = defineEmits<{ |
| 170 | + 'update:modelValue': [value: string] |
| 171 | + close: [] |
| 172 | + submit: [data: FormData] |
| 173 | +}>() |
| 174 | +``` |
| 175 | + |
| 176 | +```vue |
| 177 | +// Props avec defaults personnalisés |
| 178 | +const props = withDefaults(defineProps<{ |
| 179 | + size?: 'sm' | 'md' | 'lg' |
| 180 | + disabled?: boolean |
| 181 | +}>(), { |
| 182 | + size: 'md', // Valeur par défaut custom |
| 183 | + // disabled: false // Pas besoin, false par défaut |
| 184 | +}) |
| 185 | +
|
| 186 | +</script> |
| 187 | +
|
| 188 | +<!-- ❌ Éviter - Syntaxe objet --> |
| 189 | +<script setup> |
| 190 | +const props = defineProps({ |
| 191 | + show: { type: Boolean, default: false }, // Verbeux |
| 192 | + title: { type: String }, |
| 193 | +}) |
| 194 | +const emit = defineEmits(['update:show', 'close']) // Pas de typage |
| 195 | +</script> |
| 196 | +``` |
| 197 | + |
| 198 | +### Structure des composables |
| 199 | +```typescript |
| 200 | +export function useFeatureName () { |
| 201 | + const data = ref() |
| 202 | + const isLoading = ref(false) |
| 203 | + const error = ref() |
| 204 | + |
| 205 | + async function fetchData () { |
| 206 | + // logique |
| 207 | + } |
| 208 | + |
| 209 | + return { |
| 210 | + data: readonly(data), |
| 211 | + isLoading: readonly(isLoading), |
| 212 | + error: readonly(error), |
| 213 | + fetchData, |
| 214 | + } |
| 215 | +} |
| 216 | +``` |
| 217 | + |
| 218 | +### Linting et formatage |
| 219 | +- Respecter TOUTES les règles ESLint configurées |
| 220 | +- Pas de `console.*` |
| 221 | +- Préférer les imports nommés aux imports par défaut |
| 222 | +- Ordre alphabétique des imports |
| 223 | + |
| 224 | +### TypeScript |
| 225 | +- Types explicites pour toutes les props/interfaces |
| 226 | +- Éviter `any`, utiliser `unknown` si nécessaire |
| 227 | +- Utiliser les types génériques pour la réutilisabilité |
| 228 | +- Interfaces plutôt que types pour les objets |
| 229 | + |
| 230 | +### Tâches |
| 231 | + |
| 232 | +Pour les tâches que je vais te demander, voir `.github/copilot-tasks.instructions.md`. |
0 commit comments