[#MUI-2] Faire un MCP pour la librairie de composant #20
@@ -7,7 +7,7 @@ description: Use when creating a new UI component in the @malio/layer-ui Nuxt la
|
||||
|
||||
## Overview
|
||||
|
||||
Step-by-step process for creating a component in `@malio/layer-ui`. Each component requires 5 deliverables : le `.vue`, les tests, la page playground, la story Histoire, et la mise à jour du CHANGELOG.
|
||||
Step-by-step process for creating a component in `@malio/layer-ui`. Each component requires 6 deliverables : le `.vue`, les tests, la page playground, la story Histoire, la mise à jour du CHANGELOG, et la mise à jour du `COMPONENTS.md`.
|
||||
|
||||
## When to Use
|
||||
|
||||
@@ -27,6 +27,7 @@ digraph create_component {
|
||||
"Tests OK?" -> "3. Créer les tests .test.ts" [label="non, corriger"];
|
||||
"5. Créer la page playground" -> "6. Créer la story Histoire";
|
||||
"6. Créer la story Histoire" -> "7. Mettre à jour CHANGELOG.md";
|
||||
"7. Mettre à jour CHANGELOG.md" -> "8. Mettre à jour COMPONENTS.md";
|
||||
}
|
||||
```
|
||||
|
||||
@@ -176,6 +177,37 @@ Pour extraire le numéro de ticket depuis la branche courante :
|
||||
git branch --show-current | grep -oP '(MUI-\d+|\d{3,})' | head -1
|
||||
```
|
||||
|
||||
### 8. Mettre à jour COMPONENTS.md
|
||||
|
||||
**Fichier :** `COMPONENTS.md` à la racine du projet.
|
||||
|
||||
Ce fichier sert de documentation de référence pour les projets qui consomment `@malio/layer-ui`. Il est lu par Claude dans les projets consommateurs pour connaître les composants disponibles et leurs props.
|
||||
|
||||
**Ajouter une section pour le nouveau composant** en suivant le format existant :
|
||||
|
||||
```markdown
|
||||
## MalioNomComposant
|
||||
|
||||
Description courte du composant.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| ... | ... | ... | ... |
|
||||
|
||||
**Events :** `update:modelValue(value: string)`
|
||||
|
||||
\`\`\`vue
|
||||
<MalioNomComposant v-model="val" label="Exemple" />
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
**Checklist :**
|
||||
- Toutes les props documentées avec type, défaut et description
|
||||
- Events listés
|
||||
- Slots listés si applicable
|
||||
- 2-5 exemples d'utilisation couvrant les cas courants (simple, avec options, disabled, erreur)
|
||||
- Section placée par ordre logique (inputs ensemble, boutons ensemble, etc.)
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
Cette section est alimentée au fur et à mesure des retours utilisateur et des problèmes rencontrés. **Si un retour ou un bug est identifié lors de la création d'un composant, ajouter une ligne dans ce tableau.**
|
||||
@@ -188,3 +220,4 @@ Cette section est alimentée au fur et à mesure des retours utilisateur et des
|
||||
| Padding input pas ajusté avec icône | Ajouter `!pr-10` (ou équivalent) quand une icône est présente à droite |
|
||||
| Story sans initial state | Toujours initialiser les `ref` avec des valeurs pour que les variantes soient visibles dès le chargement |
|
||||
| CHANGELOG oublié | Toujours ajouter la ligne dans `### Added` avant de commit |
|
||||
| COMPONENTS.md pas mis à jour | Ajouter la doc du composant dans `COMPONENTS.md` — c'est la référence pour les projets consommateurs |
|
||||
|
||||
@@ -22,6 +22,7 @@ Liste des évolutions de la librairie Malio layer UI
|
||||
* [#MUI-20] Création d'un composant sidebar
|
||||
* [#MUI-23] Revoir la config couleur tailwind
|
||||
* [#MUI-10] Création d'un composant bouton
|
||||
* [#MUI-2] Faire un MCP pour la librairie de composant
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
357
COMPONENTS.md
Normal file
357
COMPONENTS.md
Normal file
@@ -0,0 +1,357 @@
|
||||
# @malio/layer-ui — Composants
|
||||
|
||||
Tous les composants sont auto-importés avec le préfixe `Malio`. Utiliser `v-model` pour le binding bidirectionnel sur les composants de formulaire.
|
||||
|
||||
---
|
||||
|
||||
## MalioInputText
|
||||
|
||||
Champ texte avec label, icône optionnelle et support de masque de saisie.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `id` | `string` | auto | Identifiant HTML |
|
||||
| `label` | `string` | `''` | Label du champ |
|
||||
| `modelValue` | `string \| null` | `undefined` | Valeur (v-model) |
|
||||
| `disabled` | `boolean` | `false` | Désactive le champ |
|
||||
| `readonly` | `boolean` | `false` | Lecture seule |
|
||||
| `required` | `boolean` | `false` | Champ requis |
|
||||
| `hint` | `string` | `''` | Message d'aide |
|
||||
| `error` | `string` | `''` | Message d'erreur |
|
||||
| `success` | `string` | `''` | Message de succès |
|
||||
| `iconName` | `string` | `''` | Icône Iconify (ex: `mdi:magnify`) |
|
||||
| `iconPosition` | `'left' \| 'right'` | `'right'` | Position de l'icône |
|
||||
| `iconSize` | `string \| number` | `24` | Taille icône |
|
||||
| `iconColor` | `string` | `'text-m-muted'` | Classe couleur icône |
|
||||
| `mask` | `string \| MaskInputOptions` | — | Masque de saisie (maska) |
|
||||
| `maxLength` | `number \| string` | — | Longueur max |
|
||||
| `minLength` | `number \| string` | — | Longueur min |
|
||||
| `inputClass` | `string` | `''` | Classes CSS input |
|
||||
| `labelClass` | `string` | `''` | Classes CSS label |
|
||||
| `groupClass` | `string` | `''` | Classes CSS conteneur |
|
||||
|
||||
**Events :** `update:modelValue(value: string)`
|
||||
|
||||
```vue
|
||||
<MalioInputText v-model="nom" label="Nom" />
|
||||
<MalioInputText v-model="search" label="Recherche" icon-name="mdi:magnify" />
|
||||
<MalioInputText v-model="tel" label="Téléphone" mask="## ## ## ## ##" />
|
||||
<MalioInputText v-model="email" label="Email" error="Email invalide" />
|
||||
<MalioInputText v-model="info" label="Info" disabled hint="Champ désactivé" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioInputPassword
|
||||
|
||||
Champ mot de passe avec toggle visibilité.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `modelValue` | `string \| null` | `undefined` | Valeur (v-model) |
|
||||
| `label` | `string` | `''` | Label |
|
||||
| `displayIcon` | `boolean` | `true` | Afficher l'icône toggle |
|
||||
| `disabled` | `boolean` | `false` | Désactivé |
|
||||
| `readonly` | `boolean` | `false` | Lecture seule |
|
||||
| `hint` | `string` | `''` | Message d'aide |
|
||||
| `error` | `string` | `''` | Message d'erreur |
|
||||
| `success` | `string` | `''` | Message de succès |
|
||||
|
||||
**Events :** `update:modelValue(value: string)`
|
||||
|
||||
```vue
|
||||
<MalioInputPassword v-model="password" label="Mot de passe" />
|
||||
<MalioInputPassword v-model="password" label="Sans icône" :display-icon="false" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioInputAmount
|
||||
|
||||
Champ montant avec icône devise (euro par défaut).
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `modelValue` | `string \| null` | `undefined` | Valeur (v-model) |
|
||||
| `label` | `string` | `''` | Label |
|
||||
| `iconName` | `string` | `'mdi:currency-eur'` | Icône devise |
|
||||
| `disabled` | `boolean` | `false` | Désactivé |
|
||||
| `error` | `string` | `''` | Message d'erreur |
|
||||
|
||||
**Events :** `update:modelValue(value: string)`
|
||||
|
||||
```vue
|
||||
<MalioInputAmount v-model="montant" label="Montant TTC" />
|
||||
<MalioInputAmount v-model="prix" label="Prix" error="Montant invalide" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioInputNumber
|
||||
|
||||
Champ numérique avec boutons +/-.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `modelValue` | `string \| null` | `undefined` | Valeur (v-model) |
|
||||
| `label` | `string` | `''` | Label |
|
||||
| `min` | `number \| string` | — | Valeur minimum |
|
||||
| `max` | `number \| string` | — | Valeur maximum |
|
||||
| `disabled` | `boolean` | `false` | Désactivé |
|
||||
| `error` | `string` | `''` | Message d'erreur |
|
||||
|
||||
**Events :** `update:modelValue(value: string)`
|
||||
|
||||
```vue
|
||||
<MalioInputNumber v-model="quantite" label="Quantité" min="0" max="100" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioInputTextArea
|
||||
|
||||
Zone de texte multiligne avec compteur et redimensionnement.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `modelValue` | `string \| null` | `undefined` | Valeur (v-model) |
|
||||
| `label` | `string` | `''` | Label |
|
||||
| `size` | `number \| string` | `2` | Nombre de lignes |
|
||||
| `resize` | `'none' \| 'both' \| 'horizontal' \| 'vertical'` | `'both'` | Mode redimensionnement |
|
||||
| `maxLength` | `number` | `800` | Longueur max |
|
||||
| `showCounter` | `boolean` | `false` | Afficher le compteur |
|
||||
| `disabled` | `boolean` | `false` | Désactivé |
|
||||
| `error` | `string` | `''` | Message d'erreur |
|
||||
|
||||
**Events :** `update:modelValue(value: string)`
|
||||
|
||||
```vue
|
||||
<MalioInputTextArea v-model="commentaire" label="Commentaire" :show-counter="true" />
|
||||
<MalioInputTextArea v-model="note" label="Note" resize="vertical" :size="4" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioInputUpload
|
||||
|
||||
Champ d'upload de fichier.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `modelValue` | `string \| null` | `undefined` | Nom du fichier (v-model) |
|
||||
| `label` | `string` | `''` | Label |
|
||||
| `accept` | `string` | `''` | Types de fichiers acceptés |
|
||||
| `displayIcon` | `boolean` | `true` | Afficher l'icône |
|
||||
| `disabled` | `boolean` | `false` | Désactivé |
|
||||
| `error` | `string` | `''` | Message d'erreur |
|
||||
|
||||
**Events :** `update:modelValue(value: string)`, `file-selected(file: File)`
|
||||
|
||||
```vue
|
||||
<MalioInputUpload v-model="fileName" label="Document" accept=".pdf,.doc" @file-selected="onFile" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioSelect
|
||||
|
||||
Liste déroulante.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `modelValue` | `string \| number \| null` | **requis** | Valeur sélectionnée (v-model) |
|
||||
| `options` | `{ value: string \| number, text: string }[]` | `[]` | Options disponibles |
|
||||
| `emptyOptionLabel` | `string` | `''` | Placeholder option vide |
|
||||
| `label` | `string` | `''` | Label |
|
||||
| `disabled` | `boolean` | `false` | Désactivé |
|
||||
| `error` | `string` | `''` | Message d'erreur |
|
||||
|
||||
**Events :** `update:modelValue(value: string | number | null)`
|
||||
**Slots :** `icon` (icône dropdown custom)
|
||||
|
||||
```vue
|
||||
<MalioSelect v-model="pays" label="Pays" :options="[{ value: 'FR', text: 'France' }, { value: 'BE', text: 'Belgique' }]" />
|
||||
<MalioSelect v-model="ville" label="Ville" :options="villes" empty-option-label="Choisir..." />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioSelectCheckbox
|
||||
|
||||
Liste déroulante multi-sélection avec checkboxes.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `modelValue` | `(string \| number)[]` | **requis** | Valeurs sélectionnées (v-model) |
|
||||
| `options` | `{ value: string \| number, text: string }[]` | `[]` | Options |
|
||||
| `displayTag` | `boolean` | `false` | Afficher les tags sélectionnés |
|
||||
| `displaySelectAll` | `boolean` | `false` | Afficher "Tout sélectionner" |
|
||||
| `selectAllLabel` | `string` | `'Tout sélectionner'` | Texte du sélecteur global |
|
||||
| `label` | `string` | `''` | Label |
|
||||
| `disabled` | `boolean` | `false` | Désactivé |
|
||||
|
||||
**Events :** `update:modelValue(value: (string | number)[])`
|
||||
|
||||
```vue
|
||||
<MalioSelectCheckbox v-model="competences" label="Compétences" :options="skills" :display-tag="true" />
|
||||
<MalioSelectCheckbox v-model="sites" label="Sites" :options="sitesList" :display-select-all="true" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioCheckbox
|
||||
|
||||
Case à cocher.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `modelValue` | `boolean \| null` | `undefined` | Valeur (v-model) |
|
||||
| `label` | `string` | `''` | Label |
|
||||
| `disabled` | `boolean` | `false` | Désactivé |
|
||||
| `readonly` | `boolean` | `false` | Lecture seule |
|
||||
| `error` | `string` | `''` | Message d'erreur |
|
||||
|
||||
**Events :** `update:modelValue(value: boolean)`
|
||||
|
||||
```vue
|
||||
<MalioCheckbox v-model="accepte" label="J'accepte les conditions" />
|
||||
<MalioCheckbox v-model="newsletter" label="Newsletter" disabled />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioRadioButton
|
||||
|
||||
Bouton radio (à utiliser en groupe avec le même `name`).
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `modelValue` | `string \| number \| boolean \| null` | `undefined` | Valeur du groupe (v-model) |
|
||||
| `value` | `string \| number \| boolean \| null` | `undefined` | Valeur de cette option |
|
||||
| `label` | `string` | `''` | Label |
|
||||
| `name` | `string` | `''` | Nom du groupe radio |
|
||||
| `disabled` | `boolean` | `false` | Désactivé |
|
||||
| `readonly` | `boolean` | `false` | Lecture seule |
|
||||
|
||||
**Events :** `update:modelValue(value: string | number | boolean | null)`
|
||||
|
||||
```vue
|
||||
<MalioRadioButton v-model="civilite" name="civilite" value="M" label="Monsieur" />
|
||||
<MalioRadioButton v-model="civilite" name="civilite" value="Mme" label="Madame" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioTime
|
||||
|
||||
Sélecteur d'heure.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `modelValue` | `string \| null` | `undefined` | Heure au format HH:mm (v-model) |
|
||||
| `label` | `string` | `''` | Label |
|
||||
| `disabled` | `boolean` | `false` | Désactivé |
|
||||
| `readonly` | `boolean` | `false` | Lecture seule |
|
||||
| `error` | `string` | `''` | Message d'erreur |
|
||||
|
||||
**Events :** `update:modelValue(value: string)`
|
||||
|
||||
```vue
|
||||
<MalioTime v-model="heure" label="Heure de début" />
|
||||
<MalioTime v-model="fin" label="Heure de fin" readonly />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioButton
|
||||
|
||||
Bouton d'action avec 4 variantes visuelles et icône optionnelle.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `label` | `string` | `''` | Texte du bouton (ou slot par défaut) |
|
||||
| `variant` | `'primary' \| 'secondary' \| 'tertiary' \| 'danger'` | `'primary'` | Variante visuelle |
|
||||
| `disabled` | `boolean` | `false` | Désactivé |
|
||||
| `buttonClass` | `string` | `''` | Classes CSS additionnelles (twMerge) |
|
||||
| `iconName` | `string` | `''` | Icône Iconify |
|
||||
| `iconPosition` | `'left' \| 'right'` | `'right'` | Position icône |
|
||||
| `iconSize` | `string \| number` | `16` | Taille icône |
|
||||
|
||||
**Events :** `click(e: MouseEvent)`
|
||||
**Slots :** `default` (contenu du bouton, remplace `label`)
|
||||
|
||||
```vue
|
||||
<MalioButton label="Valider" />
|
||||
<MalioButton label="Modifier" variant="secondary" icon-name="mdi:pencil" icon-position="left" />
|
||||
<MalioButton label="Voir plus" variant="tertiary" />
|
||||
<MalioButton label="Supprimer" variant="danger" icon-name="mdi:trash" icon-position="left" />
|
||||
<MalioButton label="Pleine largeur" button-class="w-full" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioButtonIcon
|
||||
|
||||
Bouton icône seul (sans texte).
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `icon` | `string` | **requis** | Icône Iconify |
|
||||
| `ariaLabel` | `string` | **requis** | Label accessible |
|
||||
| `variant` | `'filled' \| 'ghost'` | `'filled'` | Variante visuelle |
|
||||
| `disabled` | `boolean` | `false` | Désactivé |
|
||||
| `buttonClass` | `string` | `''` | Classes CSS additionnelles |
|
||||
| `iconSize` | `string \| number` | `24` | Taille icône |
|
||||
|
||||
**Events :** `click(e: MouseEvent)`
|
||||
|
||||
```vue
|
||||
<MalioButtonIcon icon="mdi:pencil" aria-label="Modifier" />
|
||||
<MalioButtonIcon icon="mdi:trash" aria-label="Supprimer" variant="ghost" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioTabList
|
||||
|
||||
Navigation par onglets avec contenu dynamique.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `modelValue` | `string` | `undefined` | Onglet actif (v-model) |
|
||||
| `tabs` | `{ key: string, label: string, icon?: string }[]` | **requis** | Liste des onglets |
|
||||
|
||||
**Events :** `update:modelValue(value: string)`
|
||||
**Slots :** Un slot nommé par `tab.key` pour le contenu de chaque onglet
|
||||
|
||||
```vue
|
||||
<MalioTabList v-model="activeTab" :tabs="[{ key: 'infos', label: 'Informations' }, { key: 'docs', label: 'Documents', icon: 'mdi:file' }]">
|
||||
<template #infos>Contenu infos</template>
|
||||
<template #docs>Contenu docs</template>
|
||||
</MalioTabList>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioSidebar
|
||||
|
||||
Barre latérale de navigation rétractable.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `modelValue` | `boolean` | `undefined` | État ouvert/fermé (v-model) |
|
||||
| `sections` | `SidebarSection[]` | **requis** | Sections de navigation |
|
||||
| `sidebarClass` | `string` | `''` | Classes CSS sidebar |
|
||||
| `toggleClass` | `string` | `''` | Classes CSS bouton toggle |
|
||||
|
||||
**Type SidebarSection :** `{ title?: string, items: { label: string, icon?: string, to?: string, href?: string, active?: boolean }[] }`
|
||||
|
||||
**Events :** `update:modelValue(value: boolean)`
|
||||
**Slots :** `logo` (sidebar ouverte), `logo-collapsed` (sidebar fermée)
|
||||
|
||||
```vue
|
||||
<MalioSidebar v-model="isOpen" :sections="menuSections">
|
||||
<template #logo><img src="/logo.png" /></template>
|
||||
<template #logo-collapsed><img src="/logo-small.png" /></template>
|
||||
</MalioSidebar>
|
||||
```
|
||||
Reference in New Issue
Block a user