feat: Ajout des composants modal, accordeon, datetime avec selecteur d'heure à la molette (#56)
Release / release (push) Successful in 2m38s
Release / release (push) Successful in 2m38s
| Numéro du ticket | Titre du ticket | |------------------|-----------------| | | | ## Description de la PR ## Modification du .env ## Check list - [ ] Pas de régression - [ ] TU/TI/TF rédigée - [ ] TU/TI/TF OK - [ ] CHANGELOG modifié --------- Co-authored-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr> Co-authored-by: matthieu <matthieu@yuno.malio.fr> Reviewed-on: #56 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #56.
This commit is contained in:
+160
-1
@@ -563,11 +563,40 @@ Sélecteur d'heure.
|
||||
|
||||
---
|
||||
|
||||
## MalioTimePicker
|
||||
|
||||
Sélecteur d'heure à **molettes style iOS** (champ + popover). Deux colonnes infinies (heures `00–23`, minutes `00–59`, pas de 1) avec une bande de sélection centrale ; la valeur centrée est sélectionnée. Défilement, clic sur une valeur (recentrage) ou flèches clavier (`role="spinbutton"`). Pour une saisie clavier directe au format texte, voir plutôt `MalioTime`.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `id` | `string` | auto | Identifiant HTML |
|
||||
| `name` | `string` | `''` | Attribut name |
|
||||
| `label` | `string` | `''` | Label flottant |
|
||||
| `modelValue` | `string \| null` | `undefined` | Heure au format `"HH:MM"` (v-model) |
|
||||
| `placeholder` | `string` | `'HH:MM'` | Placeholder |
|
||||
| `required` | `boolean` | `false` | Champ requis |
|
||||
| `disabled` | `boolean` | `false` | Désactive le champ |
|
||||
| `readonly` | `boolean` | `false` | Lecture seule |
|
||||
| `clearable` | `boolean` | `true` | Affiche la croix d'effacement |
|
||||
| `hint` | `string` | `''` | Message d'aide |
|
||||
| `error` | `string` | `''` | Message d'erreur |
|
||||
| `success` | `string` | `''` | Message de succès |
|
||||
| `inputClass` / `labelClass` / `groupClass` | `string` | `''` | Override des classes |
|
||||
|
||||
**Events :** `update:modelValue(value: string | null)`
|
||||
|
||||
```vue
|
||||
<MalioTimePicker v-model="heure" label="Heure" />
|
||||
<MalioTimePicker v-model="heure" label="Départ" hint="Format HH:MM" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioDateTime
|
||||
|
||||
Champ unique combinant **date et heure** dans un popover (grille de calendrier + sélecteur d'heure sous la grille).
|
||||
|
||||
> ⚠️ **Version intérimaire** : le sélecteur d'heure est un `<input type="time">` natif, en attendant la maquette d'un sélecteur d'heure dédié. Le bloc heure est isolé pour être remplacé sans impact sur le reste.
|
||||
> Depuis MUI-39, le réglage de l'heure utilise le sélecteur à molettes (cf. `MalioTimePicker`), qui remplace l'ancien `<input type="time">` natif intérimaire.
|
||||
|
||||
La valeur est une chaîne **ISO naïve sans fuseau** au format `"YYYY-MM-DDTHH:MM:00"` (heure murale locale). Symfony (`DateTimeNormalizer`) parse ce format et applique son fuseau configuré côté back — pas de gestion de fuseau côté front.
|
||||
|
||||
@@ -694,6 +723,54 @@ const tabs = computed(() => [
|
||||
|
||||
---
|
||||
|
||||
## MalioAccordion
|
||||
|
||||
Accordéon compositionnel : `<MalioAccordion>` enveloppe des `<MalioAccordionItem>`. Plusieurs panneaux ouverts (`multiple`, défaut) ou un seul (`single`). Pensé pour les filtres en drawer et les FAQ.
|
||||
|
||||
### MalioAccordion
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `mode` | `'single' \| 'multiple'` | `'multiple'` | Un seul ou plusieurs panneaux ouverts |
|
||||
| `modelValue` | `string \| string[]` | `undefined` | Clés ouvertes (v-model). `string[]` en `multiple`, `string` en `single` |
|
||||
| `id` | `string` | auto | Préfixe des IDs d'accessibilité |
|
||||
| `groupClass` | `string` | `''` | Classes du conteneur (twMerge) |
|
||||
|
||||
**Events :** `update:modelValue(value: string | string[])`
|
||||
|
||||
### MalioAccordionItem
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `title` | `string` | — | Texte de l'en-tête |
|
||||
| `value` | `string` | auto | Clé unique de la section |
|
||||
| `defaultOpen` | `boolean` | `false` | Ouvert au montage (mode non contrôlé) |
|
||||
| `disabled` | `boolean` | `false` | En-tête non cliquable |
|
||||
| `headerClass` | `string` | `''` | Override classes en-tête (twMerge) |
|
||||
| `panelClass` | `string` | `''` | Override classes panneau (twMerge) |
|
||||
|
||||
**Slot :** par défaut = contenu du panneau.
|
||||
|
||||
```vue
|
||||
<!-- Filtres : plusieurs sections ouvertes -->
|
||||
<MalioAccordion v-model="ouverts">
|
||||
<MalioAccordionItem title="Prix" value="prix">
|
||||
<MalioInputAmount v-model="prix" />
|
||||
</MalioAccordionItem>
|
||||
<MalioAccordionItem title="Catégorie" value="cat">
|
||||
<MalioCheckbox v-model="cats" />
|
||||
</MalioAccordionItem>
|
||||
</MalioAccordion>
|
||||
|
||||
<!-- FAQ : une seule section ouverte -->
|
||||
<MalioAccordion mode="single">
|
||||
<MalioAccordionItem title="Question 1" value="q1">Réponse 1</MalioAccordionItem>
|
||||
<MalioAccordionItem title="Question 2" value="q2">Réponse 2</MalioAccordionItem>
|
||||
</MalioAccordion>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioSidebar
|
||||
|
||||
Barre latérale de navigation rétractable.
|
||||
@@ -779,6 +856,58 @@ Panneau latéral (drawer) qui s'ouvre depuis la droite ou la gauche avec backdro
|
||||
|
||||
---
|
||||
|
||||
## MalioModal
|
||||
|
||||
Boîte de dialogue modale centrée avec backdrop semi-transparent. Gère l'accessibilité (focus-trap, restitution du focus, `Échap`), le verrouillage du scroll de la page et un empilement correct de plusieurs modals. Structure : header fixe, body scrollable (`max-h-[85vh]`), footer fixe.
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `id` | `string` | auto | Identifiant HTML |
|
||||
| `modelValue` | `boolean` | `undefined` | État ouvert/fermé (v-model) |
|
||||
| `showClose` | `boolean` | `true` | Afficher le bouton de fermeture (croix) |
|
||||
| `dismissable` | `boolean` | `true` | Fermer au clic sur le backdrop |
|
||||
| `closeOnEscape` | `boolean` | `true` | Fermer avec la touche `Échap` |
|
||||
| `ariaLabel` | `string` | `''` | Nom accessible de secours quand le slot `#header` est absent |
|
||||
| `modalClass` | `string` | `''` | Classes CSS panneau, ex. largeur `max-w-lg` (twMerge) |
|
||||
| `overlayClass` | `string` | `''` | Classes CSS backdrop (twMerge) |
|
||||
| `headerClass` | `string` | `''` | Classes CSS barre header (twMerge) |
|
||||
| `bodyClass` | `string` | `''` | Classes CSS zone scrollable (twMerge) |
|
||||
| `footerClass` | `string` | `''` | Classes CSS footer fixe (twMerge) |
|
||||
|
||||
**Events :** `update:modelValue(value: boolean)`, `close()`
|
||||
|
||||
**Slots :**
|
||||
- `header` — en-tête (titre, etc.). S'il est absent et que `showClose` est `true`, seule la croix est affichée.
|
||||
- `default` — contenu (zone scrollable).
|
||||
- `footer` — actions (boutons). Rendu en bas, fixe, séparé par une bordure. N'apparaît que si le slot est fourni.
|
||||
|
||||
```vue
|
||||
<MalioModal v-model="isOpen">
|
||||
<template #header>
|
||||
<h2 class="text-[24px] font-bold">Détails</h2>
|
||||
</template>
|
||||
<p>Contenu de la modal</p>
|
||||
</MalioModal>
|
||||
|
||||
<!-- Largeur custom + footer d'actions -->
|
||||
<MalioModal v-model="isOpen" modal-class="max-w-lg">
|
||||
<template #header><h2>Nouveau contact</h2></template>
|
||||
<MalioInputText label="Nom" />
|
||||
<template #footer>
|
||||
<MalioButton label="Annuler" variant="secondary" button-class="flex-1" @click="isOpen = false" />
|
||||
<MalioButton label="Enregistrer" button-class="flex-1" @click="isOpen = false" />
|
||||
</template>
|
||||
</MalioModal>
|
||||
|
||||
<!-- Non fermable au backdrop / Échap (croix uniquement) -->
|
||||
<MalioModal v-model="isOpen" :dismissable="false" :close-on-escape="false">
|
||||
<template #header><h2>Action requise</h2></template>
|
||||
<p>Fermeture via la croix uniquement</p>
|
||||
</MalioModal>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioDataTable
|
||||
|
||||
Tableau de données presentational avec pagination, filtres par slots et lignes cliquables.
|
||||
@@ -832,3 +961,33 @@ Tableau de données presentational avec pagination, filtres par slots et lignes
|
||||
v-model:per-page="perPage"
|
||||
/>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MalioSiteSelector
|
||||
|
||||
Sélecteur de site sous forme de tuiles segmentées (`role="radiogroup"`). Chaque site occupe une tuile de largeur égale ; la tuile active s'affiche pleine opacité dans sa couleur (`site.color`), les autres sont atténuées. Pattern contrôlé (`v-model`) ou non contrôlé (premier site sélectionné par défaut).
|
||||
|
||||
| Prop | Type | Défaut | Description |
|
||||
|------|------|--------|-------------|
|
||||
| `sites` | `{ id: string, name: string, color: string }[]` | **requis** | Liste des sites (la `color` colore la tuile active) |
|
||||
| `modelValue` | `string` | `undefined` | `id` du site sélectionné (v-model) |
|
||||
| `id` | `string` | auto | Identifiant HTML du conteneur |
|
||||
| `groupClass` | `string` | `''` | Classes CSS du conteneur (twMerge) |
|
||||
| `tileClass` | `string` | `''` | Classes CSS de chaque tuile (twMerge) |
|
||||
| `labelClass` | `string` | `''` | Classes CSS du label de tuile (twMerge) |
|
||||
|
||||
**Events :**
|
||||
- `update:modelValue(value: string)` — `id` du site sélectionné (v-model)
|
||||
- `change(site: Site)` — émis avec l'objet site complet sélectionné
|
||||
|
||||
```vue
|
||||
<MalioSiteSelector
|
||||
v-model="siteId"
|
||||
:sites="[
|
||||
{ id: 'paris', name: 'Paris', color: '#2563eb' },
|
||||
{ id: 'lyon', name: 'Lyon', color: '#16a34a' },
|
||||
]"
|
||||
@change="onSiteChange"
|
||||
/>
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user