Skip to content

Interrupteur - DsfrToggleSwitch

🌟 Introduction

Le DsfrToggleSwitch est un composant Vue versatile, conçu pour permettre à l’utilisateur de faire un choix entre deux états opposés (activé / désactivé).

🏅 La documentation sur les interrupteurs sur le DSFR

La story sur la carte sur le storybook de VueDsfr

🛠️ Props

NomTypeDéfautObligatoireDescription
modelValuebooleanValeur booléenne associée à la case à cocher
disabledbooleanValeur booléenne pour désactiver le toggle
hintstringTexte d'information complémentaire affiché en dessous de l'interrupteur
labelstringfalseTexte du label associé à l'interrupteur
labelLeftbooleanfalsePermet d'afficher le label à gauche de l'interrupteur
borderBottombooleanfalseAffiche une bordure sous l'interrupteur et le label
inputIdstringgetRandomId('toggle')Identifiant unique pour le toggle. Utilisé pour l'accessibilité.
activeTextstringActivéTexte à afficher sous l'interrupteur lorsqu'il est activé
inactiveTextstringDésactivéTexte à afficher sous l'interrupteur lorsqu'il est désactivé
notextbooleanfalseDésactive l'affichage de activeText et inactiveText

📡 Évenements

DsfrToggleSwitch émet l'événement suivant :

NomtypeDescription
update:modelValuebooleanEst émis lorsque la valeur de l'interrupteur change

🧩 Slots

Aucun slot n'est prévu dans ce composant. Le contenu est entièrement basé sur les props.

📝 Exemples

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

<template>
  <div
    class="flex flex-col"
  >
    <div>
      <DsfrToggleSwitch label="Label action interrupteur" />
    </div>
    <div>
      <DsfrToggleSwitch
        label="Label action interrupteur"
        label-left
      />
    </div>
    <div>
      <DsfrToggleSwitch
        label="Vitesse lumière ?"
        border-bottom
        active-text="Vers l'infini et au-delà"
        inactive-text="restons terre à terre"
      />
    </div>
  </div>
</template>

⚙️ Code source du composant

vue
<script lang="ts" setup>
import { computed } from 'vue'

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

import type { DsfrToggleSwitchProps } from './DsfrToggleSwitch.types'

export type { DsfrToggleSwitchProps }

const props = withDefaults(defineProps<DsfrToggleSwitchProps>(), {
  inputId: () => getRandomId('toggle'),
  hint: '',
  label: '',
  labelLeft: false,
  borderBottom: false,
  activeText: 'Activé',
  inactiveText: 'Désactivé',
  noText: false,
})

defineEmits<{ (e: 'update:modelValue', payload: boolean): void }>()

const labelId = computed(() => {
  return `${props.inputId}-hint-text`
})
</script>

<template>
  <div
    class="fr-toggle"
    :class="{
      'fr-toggle--label-left': labelLeft,
      'fr-toggle--border-bottom': borderBottom,
    }"
  >
    <input
      :id="inputId"
      :disabled="disabled"
      :aria-disabled="disabled"
      type="checkbox"
      :checked="modelValue"
      :data-testid="inputId"
      class="fr-toggle__input"
      :aria-describedby="labelId"
      @input="$emit('update:modelValue', ($event.target as HTMLInputElement).checked)"
    >
    <label
      :id="labelId"
      class="fr-toggle__label"
      :for="inputId"
      :data-fr-checked-label="noText ? undefined : activeText"
      :data-fr-unchecked-label="noText ? undefined : inactiveText"
      style="--toggle-status-width: 3.55208125rem;"
    >
      {{ label }}
    </label>
    <p
      v-if="hint"
      :id="`${inputId}-hint-text`"
      class="fr-hint-text"
    >
      {{ hint }}
    </p>
  </div>
</template>
ts
export type DsfrToggleSwitchProps = {
  modelValue?: boolean
  inputId?: string
  hint?: string
  label?: string
  disabled?: boolean
  labelLeft?: boolean
  borderBottom?: boolean
  activeText?: string
  inactiveText?: string
  noText?: boolean
}