[#MUI-27] Création d'un composant sélection de site (#29)
Composant MalioSiteSelector : bande horizontale pour choisir un site (usine ou lieu) parmi une liste. Tuiles flex proportionnelles, couleur du site sélectionné partagée par toutes les tuiles (opacité 1 / 0.4). Expose update:modelValue (id) + change (objet site complet) pour faciliter les appels API côté consommateur. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> | 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é Reviewed-on: #29 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #29.
This commit is contained in:
116
app/story/site/siteSelector.story.vue
Normal file
116
app/story/site/siteSelector.story.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<Story title="Site/Selector">
|
||||
<div class="grid grid-cols-1 gap-6">
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Trois sites</h2>
|
||||
<MalioSiteSelector v-model="threeValue" :sites="sites" />
|
||||
<p class="mt-3 text-sm text-gray-600">Site sélectionné : <code>{{ threeValue }}</code></p>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Deux sites</h2>
|
||||
<MalioSiteSelector v-model="twoValue" :sites="sitesTwo" />
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Cinq sites</h2>
|
||||
<MalioSiteSelector v-model="fiveValue" :sites="sitesFive" />
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Non contrôlé</h2>
|
||||
<MalioSiteSelector :sites="sites" />
|
||||
</div>
|
||||
</div>
|
||||
</Story>
|
||||
</template>
|
||||
|
||||
<docs lang="md">
|
||||
# MalioSiteSelector
|
||||
|
||||
Sélecteur horizontal pour choisir **un site** (usine ou lieu) parmi une liste. Les tuiles occupent une largeur proportionnelle du conteneur. La couleur du site sélectionné est appliquée à toutes les tuiles ; la tuile active est opaque (opacité 1), les autres sont atténuées (opacité 0.4).
|
||||
|
||||
---
|
||||
|
||||
## Props détaillées
|
||||
|
||||
### sites
|
||||
|
||||
- Type : `Array<{ id: string; name: string; color: string }>`
|
||||
- Requis : oui
|
||||
- Description : Liste des sites à afficher. `color` est un hex (ex : `'#0055ff'`). La couleur du site actuellement sélectionné est appliquée à toutes les tuiles.
|
||||
|
||||
### modelValue
|
||||
|
||||
- Type : `string`
|
||||
- Description : `id` du site sélectionné (v-model). Sans `v-model`, le premier site est sélectionné par défaut (mode non contrôlé).
|
||||
|
||||
### id
|
||||
|
||||
- Type : `string`
|
||||
- Description : Identifiant HTML du conteneur. Auto-généré si absent.
|
||||
|
||||
### groupClass / tileClass / labelClass
|
||||
|
||||
- Type : `string`
|
||||
- Description : Classes Tailwind additionnelles fusionnées via `twMerge` sur, respectivement, le conteneur `<div role="radiogroup">`, chaque tuile et le libellé.
|
||||
|
||||
---
|
||||
|
||||
## Comportement
|
||||
|
||||
- **Toujours un site sélectionné.** Re-cliquer sur la tuile active ne la désélectionne pas.
|
||||
- **Couleur partagée.** Le `background-color` de toutes les tuiles suit la couleur du site sélectionné. Changer de site met à jour instantanément la couleur de la bande.
|
||||
- **Pas de gestion d'overflow** : les tuiles se répartissent proportionnellement sur toute la largeur disponible.
|
||||
|
||||
---
|
||||
|
||||
## Accessibilité
|
||||
|
||||
- `role="radiogroup"` sur le conteneur.
|
||||
- `role="radio"` avec `aria-checked` sur chaque tuile.
|
||||
- Roving `tabindex` : la tuile active est focusable (`tabindex="0"`), les autres sont exclues du tab order (`tabindex="-1"`).
|
||||
- Activation par Enter/Space via l'élément `<button>`.
|
||||
|
||||
---
|
||||
|
||||
## Events
|
||||
|
||||
### update:modelValue
|
||||
|
||||
- Émis au clic sur une tuile.
|
||||
- Retourne l'`id` (`string`) du site sélectionné.
|
||||
|
||||
### change
|
||||
|
||||
- Émis au clic sur une tuile, en complément de `update:modelValue`.
|
||||
- Retourne l'objet `Site` complet (`{ id, name, color }`) — utile pour déclencher des actions (appel API, filtrage…) sans avoir à relire le tableau `sites` côté consommateur.
|
||||
</docs>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import MalioSiteSelector from '../../components/malio/site/SiteSelector.vue'
|
||||
|
||||
const sites = [
|
||||
{ id: 'chatellerault', name: 'Châtellerault', color: '#0055ff' },
|
||||
{ id: 'saint-jean', name: 'Saint-Jean', color: '#16a34a' },
|
||||
{ id: 'pommevic', name: 'Pommevic', color: '#dc2626' },
|
||||
]
|
||||
|
||||
const sitesTwo = [
|
||||
{ id: 'nord', name: 'Usine Nord', color: '#7c3aed' },
|
||||
{ id: 'sud', name: 'Usine Sud', color: '#ea580c' },
|
||||
]
|
||||
|
||||
const sitesFive = [
|
||||
{ id: 's1', name: 'Site 1', color: '#0ea5e9' },
|
||||
{ id: 's2', name: 'Site 2', color: '#14b8a6' },
|
||||
{ id: 's3', name: 'Site 3', color: '#f59e0b' },
|
||||
{ id: 's4', name: 'Site 4', color: '#ec4899' },
|
||||
{ id: 's5', name: 'Site 5', color: '#6366f1' },
|
||||
]
|
||||
|
||||
const threeValue = ref('chatellerault')
|
||||
const twoValue = ref('nord')
|
||||
const fiveValue = ref('s3')
|
||||
</script>
|
||||
Reference in New Issue
Block a user