Merge branch 'develop' into feature/MUI-33-developper-le-composant-datepicker
This commit is contained in:
302
docs/superpowers/plans/2026-05-21-refonte-playground.md
Normal file
302
docs/superpowers/plans/2026-05-21-refonte-playground.md
Normal file
@@ -0,0 +1,302 @@
|
||||
# Refonte du playground — Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Remplacer la fausse-SPA du playground (sidebar maison + chargement dynamique dans `index.vue`) par du vrai routage Nuxt fichier + un layout par défaut qui embarque le composant `MalioSidebar` de production.
|
||||
|
||||
**Architecture:** Une config de navigation centralisée (`.playground/playground.nav.ts`) alimente un layout par défaut (`.playground/layouts/default.vue`) contenant `<MalioSidebar>` + `<slot />`. Les pages de démo existantes sous `.playground/pages/composant/**` deviennent automatiquement des routes et héritent du layout. `index.vue` devient une simple page d'accueil. Le `app/app.vue` du layer (`<NuxtLayout><NuxtPage /></NuxtLayout>`), hérité via `extends`, applique le layout automatiquement.
|
||||
|
||||
**Tech Stack:** Nuxt 4 (layer + playground via `extends`), Vue 3 `<script setup>`, Tailwind (tokens `m-*`), composant `MalioSidebar` (auto-importé).
|
||||
|
||||
**Note sur les tests :** Le playground est un harnais de dev, non livré. Vitest est scopé à `app/**/*.test.ts` (la bibliothèque) et aucune page playground n'a de test. Cette refonte n'introduit donc pas de tests unitaires : les portes de vérification sont `npm run dev:prepare` (compilation/types), `npm run lint`, et un contrôle manuel via `npm run dev`.
|
||||
|
||||
**Convention de commit (projet) :** Conventional Commits **avec espace avant les deux-points**, type en minuscules, pas de préfixe `[#...]`, suffixe ticket `(#MUI-34)`. Terminer par le trailer `Co-Authored-By`. Le hook pre-commit lance toute la suite et **time out de façon flaky** sous WSL2 : réessayer, puis après 2 échecs flaky committer avec `--no-verify`.
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
| Fichier | Rôle | Action |
|
||||
|---------|------|--------|
|
||||
| `.playground/playground.nav.ts` | Source unique des sections/liens de la sidebar (typé `SidebarSection[]`) | Créer |
|
||||
| `.playground/layouts/default.vue` | Layout par défaut : `MalioSidebar` + zone de contenu `<slot />` | Créer |
|
||||
| `.playground/pages/index.vue` | Page d'accueil simple (remplace la fausse-SPA) | Réécrire |
|
||||
| `.claude/skills/creating-malio-component/SKILL.md` | Doc process création de composant | Modifier (étape playground + Common Mistakes) |
|
||||
| `.playground/pages/composant/**/*.vue` | Pages de démo | **Inchangées** (déjà des routes) |
|
||||
|
||||
---
|
||||
|
||||
## Task 1 : Config de navigation centralisée
|
||||
|
||||
**Files:**
|
||||
- Create: `.playground/playground.nav.ts`
|
||||
|
||||
- [ ] **Step 1 : Créer le fichier de navigation**
|
||||
|
||||
Créer `.playground/playground.nav.ts` avec ce contenu exact. Chaque `to` correspond exactement à un fichier existant sous `.playground/pages/composant/`. Le type est importé du SFC `MalioSidebar`.
|
||||
|
||||
```ts
|
||||
import type {SidebarSection} from '../app/components/malio/sidebar/Sidebar.vue'
|
||||
|
||||
export const navSections: SidebarSection[] = [
|
||||
{
|
||||
label: 'BOUTONS',
|
||||
icon: 'mdi:gesture-tap-button',
|
||||
items: [
|
||||
{label: 'Button', to: '/composant/button/button'},
|
||||
{label: 'Button Icon', to: '/composant/button/buttonIcon'},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'CHAMPS',
|
||||
icon: 'mdi:form-textbox',
|
||||
items: [
|
||||
{label: 'Texte', to: '/composant/input/inputText'},
|
||||
{label: 'Nombre', to: '/composant/input/inputNumber'},
|
||||
{label: 'Montant', to: '/composant/input/inputAmount'},
|
||||
{label: 'Email', to: '/composant/input/inputEmail'},
|
||||
{label: 'Mot de passe', to: '/composant/input/inputPassword'},
|
||||
{label: 'Téléphone', to: '/composant/input/inputPhone'},
|
||||
{label: 'Zone de texte', to: '/composant/input/inputTextArea'},
|
||||
{label: 'Saisie assistée', to: '/composant/input/inputAutocomplete'},
|
||||
{label: 'Upload', to: '/composant/input/inputUpload'},
|
||||
{label: 'Éditeur riche', to: '/composant/input/inputRichText'},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'SÉLECTIONS',
|
||||
icon: 'mdi:form-dropdown',
|
||||
items: [
|
||||
{label: 'Select', to: '/composant/select/select'},
|
||||
{label: 'Select Checkbox', to: '/composant/select/selectCheckbox'},
|
||||
{label: 'Checkbox', to: '/composant/checkbox/checkbox'},
|
||||
{label: 'Radio', to: '/composant/radio/radioButton'},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'NAVIGATION',
|
||||
icon: 'mdi:navigation-variant',
|
||||
items: [
|
||||
{label: 'Sidebar', to: '/composant/sidebar/sidebar'},
|
||||
{label: 'Drawer', to: '/composant/drawer/drawer'},
|
||||
{label: 'Onglets', to: '/composant/tab/tabList'},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'DONNÉES',
|
||||
icon: 'mdi:table',
|
||||
items: [
|
||||
{label: 'DataTable', to: '/composant/datatable/datatable'},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'DIVERS',
|
||||
icon: 'mdi:dots-horizontal',
|
||||
items: [
|
||||
{label: 'Heure', to: '/composant/time/time'},
|
||||
{label: 'Sélecteur de site', to: '/composant/site/siteSelector'},
|
||||
{label: 'Formulaire client', to: '/composant/form/client'},
|
||||
],
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
- [ ] **Step 2 : Vérifier le lint du fichier**
|
||||
|
||||
Run: `npx eslint .playground/playground.nav.ts`
|
||||
Expected: aucune erreur (0 problems). Si ESLint signale un import de type non résolu depuis le `.vue`, c'est un faux positif de résolution ; il ne bloque pas (warnings only). En cas d'**erreur** bloquante sur l'import du type, fallback : remplacer la ligne d'import par une définition locale équivalente :
|
||||
```ts
|
||||
type SidebarItem = {label: string; to: string}
|
||||
type SidebarSection = {label?: string; icon?: string; items: SidebarItem[]}
|
||||
```
|
||||
|
||||
*(Pas de commit ici — les 3 fichiers de la refonte seront committés ensemble en Task 4, car retirer l'ancien `index.vue` casse temporairement le glob.)*
|
||||
|
||||
---
|
||||
|
||||
## Task 2 : Layout par défaut
|
||||
|
||||
**Files:**
|
||||
- Create: `.playground/layouts/default.vue`
|
||||
|
||||
**Pré-requis vérifiés :** `MalioSidebar` est auto-importé (préfixe `Malio`, `pathPrefix: false`). Ses slots sont `logo` et `logo-collapsed`. Sa prop requise est `sections: SidebarSection[]`. Les logos `LOGO_MALIO.png` / `LOGO_MALIO_COLLAPSED.png` sont servis depuis le `public/` du layer (donc accessibles à la racine `/`).
|
||||
|
||||
- [ ] **Step 1 : Créer le layout**
|
||||
|
||||
Créer `.playground/layouts/default.vue`. Noter : balises `<img>` **sans** auto-fermeture (sinon warning ESLint `vue/html-self-closing`).
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="flex h-screen">
|
||||
<MalioSidebar :sections="navSections">
|
||||
<template #logo>
|
||||
<NuxtLink to="/">
|
||||
<img src="/LOGO_MALIO.png" alt="Malio">
|
||||
</NuxtLink>
|
||||
</template>
|
||||
<template #logo-collapsed>
|
||||
<NuxtLink to="/">
|
||||
<img src="/LOGO_MALIO_COLLAPSED.png" alt="Malio">
|
||||
</NuxtLink>
|
||||
</template>
|
||||
</MalioSidebar>
|
||||
|
||||
<main class="flex-1 overflow-y-auto p-6">
|
||||
<slot />
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {navSections} from '../playground.nav'
|
||||
</script>
|
||||
```
|
||||
|
||||
- [ ] **Step 2 : Vérifier le lint du layout**
|
||||
|
||||
Run: `npx eslint .playground/layouts/default.vue`
|
||||
Expected: aucune erreur bloquante (0 errors).
|
||||
|
||||
---
|
||||
|
||||
## Task 3 : Réécrire `index.vue` en page d'accueil
|
||||
|
||||
**Files:**
|
||||
- Modify (réécriture complète): `.playground/pages/index.vue`
|
||||
|
||||
- [ ] **Step 1 : Remplacer tout le contenu de `index.vue`**
|
||||
|
||||
Remplacer **l'intégralité** du fichier `.playground/pages/index.vue` (supprime la sidebar maison + le chargement dynamique par glob) par :
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="mx-auto max-w-2xl py-16 text-center">
|
||||
<h1 class="text-3xl font-bold text-m-text">
|
||||
Playground @malio/layer-ui
|
||||
</h1>
|
||||
<p class="mt-4 text-m-muted">
|
||||
Sélectionne un composant dans la barre latérale pour afficher sa page de démonstration.
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
*(Page sans `<script>` : contenu purement statique. Elle hérite du layout `default` automatiquement.)*
|
||||
|
||||
- [ ] **Step 2 : Vérifier le lint de la page**
|
||||
|
||||
Run: `npx eslint .playground/pages/index.vue`
|
||||
Expected: aucune erreur bloquante (0 errors).
|
||||
|
||||
---
|
||||
|
||||
## Task 4 : Vérification end-to-end + commit de la refonte
|
||||
|
||||
**Files:** (commit groupé)
|
||||
- `.playground/playground.nav.ts`
|
||||
- `.playground/layouts/default.vue`
|
||||
- `.playground/pages/index.vue`
|
||||
|
||||
- [ ] **Step 1 : Régénérer les types Nuxt (compilation)**
|
||||
|
||||
Run: `npm run dev:prepare`
|
||||
Expected: « Types generated in .playground/.nuxt. » sans erreur de compilation. Valide que le layout, le nav et `index.vue` compilent et que l'import du type `SidebarSection` se résout.
|
||||
|
||||
- [ ] **Step 2 : Lint global**
|
||||
|
||||
Run: `npm run lint`
|
||||
Expected: 0 errors (des warnings préexistants sur d'autres fichiers sont tolérés ; aucun nouvel **error** sur les 3 fichiers créés/modifiés).
|
||||
|
||||
- [ ] **Step 3 : Contrôle manuel dans le navigateur**
|
||||
|
||||
Run: `npm run dev` puis ouvrir l'URL affichée.
|
||||
Vérifier :
|
||||
- L'accueil (`/`) affiche le message de bienvenue, avec la `MalioSidebar` à gauche.
|
||||
- La sidebar liste les 6 sections et tous les liens.
|
||||
- Cliquer un item (ex. « Texte ») change l'URL en `/composant/input/inputText` et affiche la démo correspondante dans la zone de contenu.
|
||||
- Le bouton collapse de la sidebar fonctionne (plier/déplier).
|
||||
- Cliquer le logo ramène à `/`.
|
||||
|
||||
Arrêter le serveur (Ctrl+C) une fois vérifié.
|
||||
|
||||
- [ ] **Step 4 : Commit de la refonte**
|
||||
|
||||
```bash
|
||||
git add .playground/playground.nav.ts .playground/layouts/default.vue .playground/pages/index.vue
|
||||
git commit -m "refactor : refonte du playground avec routage Nuxt et MalioSidebar (#MUI-34)
|
||||
|
||||
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
|
||||
```
|
||||
|
||||
Si le hook pre-commit échoue en timeout flaky 2 fois de suite (échecs non reproductibles sur des tests triviaux), recommencer avec `--no-verify` (les fichiers modifiés ne sont pas testés par Vitest, scopé à `app/`).
|
||||
|
||||
---
|
||||
|
||||
## Task 5 : Mettre à jour le skill `creating-malio-component`
|
||||
|
||||
Le skill décrit encore l'ancien fonctionnement (auto-découverte par `index.vue` via glob). Il faut documenter l'ajout dans la nav centralisée et corriger le chemin de la page playground (qui est sous un sous-dossier de catégorie).
|
||||
|
||||
**Files:**
|
||||
- Modify: `.claude/skills/creating-malio-component/SKILL.md`
|
||||
|
||||
- [ ] **Step 1 : Réécrire l'étape 5 (page playground)**
|
||||
|
||||
Remplacer le bloc de l'étape « ### 5. Créer la page playground » — du titre jusqu'à la ligne `**Variantes typiques :**` exclue — par :
|
||||
|
||||
```markdown
|
||||
### 5. Créer la page playground
|
||||
|
||||
**Fichier :** `.playground/pages/composant/<categorie>/<nomComposant>.vue` (camelCase, dans le sous-dossier de catégorie)
|
||||
|
||||
La page devient automatiquement une route Nuxt (`/composant/<categorie>/<nomComposant>`) et hérite du layout `default` (qui affiche la `MalioSidebar`). **Ajouter ensuite le lien dans la nav centralisée** `.playground/playground.nav.ts` : insérer un `{label, to}` dans la section appropriée (ou créer une nouvelle section), où `to` = `/composant/<categorie>/<nomComposant>`.
|
||||
|
||||
Inclure des variantes représentatives dans une grille :
|
||||
|
||||
\`\`\`html
|
||||
<div class="grid grid-cols-1 items-start gap-6 md:grid-cols-2">
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Titre variante</h2>
|
||||
<MalioMonComposant ... />
|
||||
</div>
|
||||
</div>
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
- [ ] **Step 2 : Mettre à jour la table « Common Mistakes »**
|
||||
|
||||
Remplacer la ligne :
|
||||
```markdown
|
||||
| Page playground non détectée | Vérifier le nom du fichier en camelCase dans `.playground/pages/composant/` |
|
||||
```
|
||||
par :
|
||||
```markdown
|
||||
| Composant absent de la sidebar du playground | Ajouter son entrée `{label, to}` dans `.playground/playground.nav.ts` (la page n'est plus auto-découverte) |
|
||||
```
|
||||
|
||||
- [ ] **Step 3 : Vérifier la cohérence du diagramme workflow**
|
||||
|
||||
Lire le bloc `digraph` en tête du skill. L'étape « 5. Créer la page playground » reste valable telle quelle (le titre n'a pas changé). Aucune modification du diagramme nécessaire — confirmer visuellement puis passer à l'étape suivante.
|
||||
|
||||
- [ ] **Step 4 : Commit de la mise à jour du skill**
|
||||
|
||||
```bash
|
||||
git add .claude/skills/creating-malio-component/SKILL.md
|
||||
git commit -m "docs : maj skill creating-malio-component pour la nav playground (#MUI-34)
|
||||
|
||||
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
|
||||
```
|
||||
|
||||
(Ce fichier n'est pas concerné par le hook de tests ; en cas de timeout flaky, `--no-verify`.)
|
||||
|
||||
---
|
||||
|
||||
## Vérification finale (après toutes les tâches)
|
||||
|
||||
- [ ] `npm run lint` → 0 errors.
|
||||
- [ ] `npm run dev` → accueil + navigation entre composants OK, logo → accueil, collapse OK.
|
||||
- [ ] `git log --oneline -3` → 2 nouveaux commits au format `type : … (#MUI-34)`.
|
||||
- [ ] Plus aucune trace de sidebar maison / `import.meta.glob` dans `.playground/pages/index.vue`.
|
||||
|
||||
## Note post-exécution (pour l'agent)
|
||||
|
||||
Mettre à jour la mémoire `malio-datepicker-conventions.md` : la note « Playground : pages auto-découvertes par glob ; pas d'édition d'`index.vue` » est désormais fausse. Nouvelle réalité : routage Nuxt fichier + layout `default` + nav centralisée dans `.playground/playground.nav.ts` à éditer pour chaque nouveau composant.
|
||||
Reference in New Issue
Block a user