a9e586cda1
- nuxt.config: extends ['../../yvv-nuxt-base'] - useMood.ts: délègue à useMood(moods) du layer, exporté useLibreMood (évite la collision avec l'auto-import du layer) - MoodSwitcher.vue + app.vue: appellent useLibreMood() - moods.css inchangé (couleurs = identité projet) Mécanisme partagé (application DOM, persistance, sync color-mode) mutualisé sans toucher le contrat CSS. Vérifié headless (Playwright) : 4 moods × light/dark × desktop/mobile OK, persistance au reload OK, zéro erreur JS, zéro régression. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
54 lines
1.1 KiB
Vue
54 lines
1.1 KiB
Vue
<script setup lang="ts">
|
|
const { currentMood, moods, setMood } = useLibreMood()
|
|
</script>
|
|
|
|
<template>
|
|
<div class="mood-switcher" role="radiogroup" aria-label="Ambiance visuelle">
|
|
<UTooltip
|
|
v-for="mood in moods"
|
|
:key="mood.id"
|
|
:text="mood.label"
|
|
>
|
|
<button
|
|
type="button"
|
|
role="radio"
|
|
:aria-checked="currentMood === mood.id"
|
|
:aria-label="`Ambiance ${mood.label}`"
|
|
class="mood-dot"
|
|
:class="{ 'mood-dot--active': currentMood === mood.id }"
|
|
:style="{ '--dot-color': mood.color }"
|
|
@click="setMood(mood.id)"
|
|
/>
|
|
</UTooltip>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.mood-switcher {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.375rem;
|
|
}
|
|
|
|
.mood-dot {
|
|
width: 1rem;
|
|
height: 1rem;
|
|
border-radius: 50%;
|
|
border: 2px solid transparent;
|
|
background: var(--dot-color, var(--mood-text-muted));
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
padding: 0;
|
|
}
|
|
|
|
.mood-dot:hover {
|
|
transform: scale(1.25);
|
|
}
|
|
|
|
.mood-dot--active {
|
|
border-color: var(--mood-text);
|
|
box-shadow: 0 0 0 2px var(--mood-bg), 0 0 0 3px var(--mood-text-muted);
|
|
transform: scale(1.15);
|
|
}
|
|
</style>
|