Groupe d’accordéons - DsfrAccordionsGroup
🌟 Introduction
Le composant DsfrAccordionsGroup
permet de regrouper plusieurs accordéons en une seule unité cohérente. Il gère la logique de sélection active entre les accordéons enfants, permettant ainsi d'ouvrir un accordéon tout en fermant les autres. Ce composant est essentiel pour organiser des ensembles d'accordéons liés de manière interactive.
🏅 La documentation sur l’accordéon sur le DSFR
La story sur l’accordéon sur le storybook de VueDsfrLe composant DsfrAccordionsGroup
agit comme un conteneur pour les composants d'accordéons individuels. Il contrôle quel accordéon est actuellement ouvert, garantissant qu'un seul peut être déplié à la fois.
🛠️ Props
Nom de Prop | Type | Par défaut | Description |
---|---|---|---|
modelValue | number | -1 | Index de l'accordéon actuellement actif. Cette prop est utilisée pour le contrôle externe de l'accordéon ouvert (un seul peut être ouvert à la fois). |
📡 Événements
Nom de l'Événement | Payload | Description |
---|---|---|
update:modelValue | number | Émis lorsque l'accordéon actif change. Le payload est l'index du nouvel accordéon ouvert. |
Astuce
Il est donc possible (et recommandé) d’utiliser la directive v-model
sur ce composant.
🧩 Slots
default
: Slot par défaut pour le contenu du groupe d'accordéons. Ce slot contiendra les composantsDsfrAccordion
enfants.
📝 Exemple
vue
<script lang="ts" setup>
import { ref } from 'vue'
import DsfrAccordion from '../DsfrAccordion.vue'
import DsfrAccordionsGroup from '../DsfrAccordionsGroup.vue'
const title1 = ref('Un titre d’accordéon 1')
const title2 = ref('Un titre d’accordéon 2')
const title3 = ref('Un titre d’accordéon 3')
const activeAccordion = ref<number>()
</script>
<template>
<DsfrAccordionsGroup v-model="activeAccordion">
<DsfrAccordion
id="accordion-1"
:title="title1"
>
Contenu de l’accordéon 1
</DsfrAccordion>
<DsfrAccordion
id="accordion-2"
:title="title2"
>
Contenu de l’accordéon 2
</DsfrAccordion>
<DsfrAccordion
id="accordion-3"
:title="title3"
>
Contenu de l’accordéon 3
</DsfrAccordion>
</DsfrAccordionsGroup>
</template>
⚙️ Code source des composants
vue
<script setup lang="ts">
import { computed, onUnmounted, provide, ref, type Ref, watch } from 'vue'
import { registerAccordionKey } from './injection-key'
const props = withDefaults(defineProps<{
modelValue?: number
}>(), {
modelValue: -1,
})
const emit = defineEmits<{
'update:modelValue': [value: number]
}>()
const activeAccordion = computed({
get: () => props.modelValue,
set (accordionId: number) {
emit('update:modelValue', accordionId)
},
})
const accordions = ref(new Map<number, string>())
const currentId = ref(0)
provide(registerAccordionKey, (title: Ref<string>) => {
const myIndex = currentId.value++
accordions.value.set(myIndex, title.value)
const isActive = computed(() => myIndex === activeAccordion.value)
watch(title, () => {
accordions.value.set(myIndex, title.value)
})
function expand (): void {
if (activeAccordion.value === myIndex) {
activeAccordion.value = -1
return
}
activeAccordion.value = myIndex
}
onUnmounted(() => {
accordions.value.delete(myIndex)
})
return { isActive, expand }
})
</script>
<template>
<div
class="fr-accordions-group"
>
<!-- @slot Slot par défaut pour le contenu de la liste. Sera dans `<div class="fr-accordions-group">` -->
<slot />
</div>
</template>
ts
import type { TitleTag } from '@/common-types'
export type DsfrAccordionProps = {
id?: string
selected?: boolean
title?: string
titleTag?: TitleTag
}