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 composants- DsfrAccordionenfants.
📝 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 type { Ref } from 'vue'
import { computed, onUnmounted, provide, 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
}