feat(ui) : MalioDate — markedDates (statut par jour) + event month-change (#MUI-45) (#76)

## MUI-45 — MalioDate : statut par jour (`markedDates`) + event `@month-change`

Étend la famille `date` du layer de façon **générique** (aucune logique métier dans le layer) pour marquer des jours et exposer le mois affiché. **Bloquant** pour le ticket SIRH « Heures (vue Jour) : calendrier avec jours validés en vert ».

### Changements
- **`MonthGrid.vue`** : prop `markedDates?: Record<string /* ISO yyyy-mm-dd */, 'success' | 'danger'>`. Fond tokenisé par jour (`bg-m-success/15` / `bg-m-danger/15`, par opacité — pas de nouveau token). **Précédence** : sélection (primary) > variante marquée ; le jour courant (`today`) **garde sa bordure ET reçoit le fond marqué**.
- **`CalendarField.vue`** : emit `month-change { month: 0-11, year }` à l'ouverture du popover **et** à chaque navigation de mois.
- **`Date.vue`** : expose `markedDates` (passée à `MonthGrid` via le slot) et réémet `month-change`.

> `success` et `danger` suffisent dans un premier temps (pas de `warning`).
> `month` est **0-11** (état brut de `useCalendarView`).

### Tests
- `MonthGrid.test.ts` (nouveau) : variantes success/danger, précédence sélection, today marqué (bordure + fond) / non marqué.
- `Date.test.ts` (+5) : `month-change` à l'ouverture (mois courant / mois de la valeur), à chaque nav, non ré-émis après fermeture, passthrough `markedDates`.
- Suite complète : **998/998** verts, lint clean.

### Doc / démo
- `COMPONENTS.md` (section MalioDate) + `CHANGELOG.md` (`[#MUI-45]`).
- Story `app/story/date/datePicker.story.vue` + playground `.playground/pages/composant/date/date.vue`.

### Reste à faire (hors PR)
- Publier une version du layer **> 1.4.6** incluant la famille `date` (débloque SIRH).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: #76
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #76.
This commit is contained in:
2026-06-16 09:40:28 +00:00
committed by Autin
parent cca15524f4
commit b4841f40ed
9 changed files with 225 additions and 2 deletions
+35 -1
View File
@@ -78,11 +78,29 @@
/>
</div>
</div>
<div class="flex flex-wrap items-start gap-10">
<div class="w-[396px] space-y-3">
<h2 class="font-semibold">markedDates + @month-change</h2>
<MalioDate
v-model="markedValue"
label="Calendrier avec statuts par jour"
hint="Jours verts = validés, rouges = à corriger"
:marked-dates="markedDates"
@month-change="onMonthChange"
/>
<div class="rounded border p-3 text-sm">
<p>Mois affiché : <code>{{ shownMonth }}</code></p>
<p class="mt-1 text-m-success"> success : {{ successDays.join(', ') }}</p>
<p class="text-m-danger"> danger : {{ dangerDays.join(', ') }}</p>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {ref} from 'vue'
import {computed, ref} from 'vue'
const pad = (n: number) => String(n).padStart(2, '0')
const toIso = (d: Date) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`
@@ -95,4 +113,20 @@ const value = ref<string | null>(null)
const erpValue = ref<string | null>(null)
const bounded = ref<string | null>(null)
const editableValue = ref<string | null>(null)
// Démo markedDates : quelques jours du mois courant marqués success / danger.
const ym = `${now.getFullYear()}-${pad(now.getMonth() + 1)}`
const successDays = [`${ym}-05`, `${ym}-06`, `${ym}-12`]
const dangerDays = [`${ym}-09`, `${ym}-20`]
const markedDates = computed<Record<string, 'success' | 'danger'>>(() => ({
...Object.fromEntries(successDays.map(d => [d, 'success' as const])),
...Object.fromEntries(dangerDays.map(d => [d, 'danger' as const])),
}))
const markedValue = ref<string | null>(null)
const monthsLong = ['janvier', 'février', 'mars', 'avril', 'mai', 'juin',
'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre']
const shownMonth = ref('—')
const onMonthChange = ({month, year}: {month: number, year: number}) => {
shownMonth.value = `${monthsLong[month]} ${year} (month=${month})`
}
</script>