Skip to content

Groupe d'interrupteurs - DsfrToggleSwitchGroup

🌟 Introduction

Le groupe d’interrupteurs est utilisé pour constituer une liste d’actions de même nature. Les interrupteurs du groupe auront un comportement uniforme pour la bordure basse et pour le texte à afficher sous l'interrupteur lorsqu’il est activé ou désactivé. Le Statut d’erreur est commun pour l’ensemble du groupe

🛠️ Props

Aucune prop n’est obligatoire

NomTypeDéfautDescription
idstringIdentifiant unique pour le groupe. Utilisé pour l’accessibilité.
legendstringLégende pour l’ensemble des éléments
disabledbooleanfalseDésactive tous les interrupteurs du groupe
toggleSwitchesDsfrToggleSwitchProps[]Tableau d’interrupteurs à afficher. Chaque interrupteur est un objet DsfrToggleSwitch borderBottom, activeText, inactiveText, noText sont gérés au niveau du groupe et sont inutiles
bordersbooleanAffiche une bordure sous chaque interrupteur et label.
activeTextstringTexte à afficher sous le groupe d’interrupteurs lorsqu’il est activé
inactiveTextstringTexte à afficher sous le groupe d’interrupteurs lorsqu’il est désactivé
noTextbooleanDésactive l’affichage de activeText et inactiveText
statusundefined | 'valid' | 'error'statut du message du groupe d’interrupteurs
validMessagestringMessage de validité du groupe d’interrupteurs
errorMessagestringMessage d’erreur du groupe d’interrupteurs

📝 Exemples

Groupe d'interrupteurs simple

vue
<script lang="ts" setup>
import DsfrToggleSwitchGroup from '../DsfrToggleSwitchGroup.vue'

const toggleSwitches = [
  {
    modelValue: true,
    label: 'Premier élément du groupe',
  },
  {
    modelValue: false,
    label: 'Deuxième élément du groupe',
  },
  {
    modelValue: true,
    label: 'Troisième élément du groupe',
  },
]
</script>

<template>
  <div
    class="flex flex-col"
  >
    <div>
      <DsfrToggleSwitchGroup
        id="toggle-group-1"
        :toggle-switches="toggleSwitches"
        legend="Légende pour l'ensemble des éléments du groupe"
        borders
        active-text="Oui"
        inactive-text="Non"
      />
    </div>
  </div>
</template>

Groupe d'interrupteurs désactivé

vue
<script lang="ts" setup>
import DsfrToggleSwitchGroup from '../DsfrToggleSwitchGroup.vue'

const toggleSwitches = [
  {
    modelValue: true,
    label: 'Premier élément du groupe',
  },
  {
    modelValue: false,
    label: 'Deuxième élément du groupe',
  },
  {
    modelValue: true,
    label: 'Troisième élément du groupe',
  },
]
</script>

<template>
  <div
    class="flex flex-col"
  >
    <div>
      <DsfrToggleSwitchGroup
        disabled
        :toggle-switches="toggleSwitches"
        legend="Légende pour l'ensemble des éléments du groupe"
        borders
        active-text="Oui"
        inactive-text="Non"
      />
    </div>
  </div>
</template>

Groupe d'interrupteurs en erreur

vue
<script lang="ts" setup>
import DsfrToggleSwitchGroup from '../DsfrToggleSwitchGroup.vue'

const toggleSwitches = [
  {
    modelValue: true,
    label: 'Premier élément du groupe',
  },
  {
    modelValue: false,
    label: 'Deuxième élément du groupe',
  },
  {
    modelValue: true,
    label: 'Troisième élément du groupe',
  },
]
</script>

<template>
  <div
    class="flex flex-col"
  >
    <div>
      <DsfrToggleSwitchGroup
        :toggle-switches="toggleSwitches"
        legend="Légende pour l'ensemble des éléments du groupe"
        borders
        active-text="Oui"
        inactive-text="Non"
        error-message="Il y a une erreur dans ce groupe de boutons"
        status="error"
      />
    </div>
  </div>
</template>

⚙️Code source du composant

vue
<script lang="ts" setup>
import type { DsfrToggleSwitchGroupProps } from './DsfrToggleSwitch.types'

import { computed } from 'vue'

import { useRandomId } from '../../utils/random-utils'

import DsfrToggleSwitch from './DsfrToggleSwitch.vue'

export type { DsfrToggleSwitchGroupProps }

const props = withDefaults(defineProps<DsfrToggleSwitchGroupProps>(), {
  id: () => useRandomId('toggle-group'),
  legend: '',
  disabled: false,
  toggleSwitches: () => [],
})

const message = computed(() => {
  if (props.status === 'valid') {
    return props.validMessage
  }
  if (props.status === 'error') {
    return props.errorMessage
  }
  return undefined
})

const toggleSwitchesWithInputId = computed(() => (
  props.toggleSwitches.map((toggleSwitch, index) => ({
    ...toggleSwitch,
    resolvedInputId: toggleSwitch.inputId
      ? `${props.id}-${toggleSwitch.inputId}`
      : `${props.id}-toggle-${index}`,
  }))
))
</script>

<template>
  <fieldset
    class="fr-fieldset"
    :class="{
      [`fr-fieldset--${status}`]: status,
    }"
    :disabled="disabled"
    role="group"
    :aria-labelledby="`${id}-legend`"
    :aria-describedby="message ? `${id}-message-${status}` : undefined"
  >
    <legend
      :id="`${id}-legend`"
      class="fr-fieldset__legend"
    >
      {{ legend }}
    </legend>
    <div class="fr-fieldset__element">
      <ul class="fr-toggle__list">
        <li
          v-for="(toggleSwitch, index) in toggleSwitchesWithInputId"
          :key="index"
        >
          <DsfrToggleSwitch
            v-bind="toggleSwitch"
            :input-id="toggleSwitch.resolvedInputId"
            :disabled="disabled || toggleSwitch.disabled"
            :border-bottom="borders"
            :active-text="activeText"
            :inactive-text="inactiveText"
            :no-text="noText"
          />
        </li>
      </ul>
    </div>
    <div
      :id="`${id}-messages`"
      class="fr-messages-group"
      aria-live="polite"
    >
      <p
        v-if="message"
        :id="`${id}-message-${status}`"
        class="fr-message"
        :class="{
          'fr-message--error': status === 'error',
          'fr-message--valid': status === 'valid',
        }"
      >
        {{ message }}
      </p>
    </div>
  </fieldset>
</template>
ts
import type { InputHTMLAttributes } from 'vue'

export type DsfrToggleSwitchProps = {
  modelValue?: boolean
  inputId?: string
  hint?: string
  label?: string
  disabled?: boolean
  labelLeft?: boolean
  borderBottom?: boolean
  activeText?: string
  inactiveText?: string
  noText?: boolean
  name?: string
  status?: undefined | 'valid' | 'error'
  validMessage?: string
  errorMessage?: string
}
export type DsfrToggleSwitchGroupProps = {
  id?: string
  legend?: string
  disabled?: boolean
  toggleSwitches?: (DsfrToggleSwitchProps & InputHTMLAttributes)[]
  borders?: boolean
  activeText?: string
  inactiveText?: string
  noText?: boolean
  status?: undefined | 'valid' | 'error'
  validMessage?: string
  errorMessage?: string
}

Et voilà ! Vous êtes prêt à ajouter une touche de sophistication à votre interface avec DsfrToggleSwitchGroup. Bonne création ! 🎨✨