Skip to content

Documentation du Composant DsfrSegmented

🌟 Introduction

👋 Bonjour et bienvenue dans la documentation de DsfrSegmented, un composant radio boutonné avec une touche de « je ne sais quoi » à la française! C'est chic, c'est pratique, et en plus, ça supporte des icônes. Alors, allons-y !

Le composant « contrôle segmenté » incite l'utilisateur à choisir entre plusieurs options d'affichage disponibles (vues), mutuellement exclusives avec une valeur sélectionnée par défaut (oui, ça c’est la version sérieuse de l’introduction à ce composant).

🏅 La documentation sur les boutons segmentés sur le DSFR sera ici (n’existe pas encore à l’heure où cette documentation est écrite, on est dans l’turfu, nous, qu’on vous dit !).

La story sur l’alerte sur le storybook de VueDsfr est ici (merci Vincent Lainé !).

🛠️ Props

NomTypeDéfautobligatoireDescription
idstringID aléatoireIdentifiant unique pour le composant.
namestringundefinedNom du groupe de boutons radio.
modelValuestring | number''La valeur actuellement sélectionnée.
valuestring | numberValeur du bouton radio.
labelstring''Texte du label associé au bouton.
disabledbooleanfalseSi true, désactive le bouton radio.
iconstring | InstanceType<typeof VIcon>['$props']undefinedIcône à afficher à côté du label (facultatif). Si la valeur est une string commençant par 'fr-', cette classe sera ajoutée à la balise <label>, sinon c’est une icône OhVueIcon qui sera utilisée

Astuce 1

id: Si non fourni, un ID est généré automatiquement pour éviter les conflits.

Astuce 2

icon: Peut être soit une chaîne représentant le nom de l'icône, soit un objet de props pour VIcon.

📡 Évenements

NomValeurDescription
update:modelValuestring | numberÉmis lorsqu'une nouvelle valeur est sélectionnée.

🧩 Slots

Pas de slots ici ! Ce composant est aussi direct qu'un express Paris-Marseille.

📝 Exemple

vue
<DsfrSegmented
  name="group1"
  label="Option 1"
  value="opt1"
  v-model="selectedOption"
  icon="some-icon-name"
/>

DsfrSegmented s’utilise forcément à l’intérieur d’un DsfrSegmentedSet, ainsi, pour un résultat, consultez la documentation de DsfrSegmentedSet.

⚙️ Code source du composant

vue
<script lang="ts" setup>
import { computed } from 'vue'
import { OhVueIcon as VIcon } from 'oh-vue-icons'

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

import type { DsfrSegmentedProps } from './DsfrSegmented.types'

export type { DsfrSegmentedProps }

const props = withDefaults(defineProps<DsfrSegmentedProps>(), {
  id: () => getRandomId('basic', 'checkbox'),
  hint: '',
  icon: undefined,
  label: '',
  modelValue: '',
  name: undefined,
})

defineEmits<{ (e: 'update:modelValue', payload: string | number): void }>()

const iconProps = computed(() => typeof props.icon === 'string' ? { name: props.icon } : props.icon)

const dsfrIcon = computed(() => {
  return props.icon && typeof props.icon === 'string' && props.icon.startsWith('fr-') ? props.icon : ''
})
</script>

<template>
  <div
    class="fr-segmented__element"
  >
    <input
      :id="id"
      type="radio"
      :name="name"
      :value="value"
      :checked="modelValue === value"
      :disabled="disabled"
      :aria-disabled="disabled"
      v-bind="$attrs"
      @click="$emit('update:modelValue', value)"
    >
    <label
      :for="id"
      class="fr-label"
      :class="{ [dsfrIcon]: dsfrIcon }"
    >
      <VIcon
        v-if="icon && !dsfrIcon"
        v-bind="iconProps"
      />
      <span v-if="icon">&nbsp;</span>
      {{ label }}
    </label>
  </div>
</template>
ts
import type { OhVueIcon as VIcon } from 'oh-vue-icons'

export type DsfrSegmentedProps = {
  id?: string
  name?: string
  modelValue?: string | number
  value: string | number
  label: string
  disabled?: boolean
  icon?: string | InstanceType<typeof VIcon>['$props']
}

export type DsfrSegmentedSetProps = {
  titleId?: string
  disabled?: boolean
  small?: boolean
  inline?: boolean
  name?: string
  hint?: string
  legend?: string
  modelValue: string | number
  options?: DsfrSegmentedProps[]
}