Contrôle segmenté - DsfrSegmentedSet
🌟 Bienvenue dans l'univers de DsfrSegmentedSet
, le chef d'orchestre de vos composants radio boutonnés DsfrSegmented
. Ce composant est là pour vous aider à organiser et afficher un ensemble de choix avec élégance et fonctionnalité. Préparez-vous, ça va être aussi sympa qu'une balade sur la Seine !
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 (Il faut toujours ramener un peu de sérieux dans l’affaire...).
🏅 La documentation sur les boutons segmentés sur le DSFR sera ici (n’existe pas non plus à l’heure où cette documentation est écrite, on est trop en avance, nous !).
La story sur l’alerte sur le storybook de VueDsfr est ici (oui parce que nous on fait rien à moitié, nous 😏, merci Vincent Lainé !).🛠️ Props
Nom | Type | Défaut | Obligatoire | Description |
---|---|---|---|---|
titleId | string | ID aléatoire | Identifiant unique pour le titre du groupe. | |
disabled | boolean | false | Si true , désactive tous les boutons radio du groupe. | |
small | boolean | false | Si true , Utilise la version réduite des contrôles segmentés. | |
inline | boolean | false | Si true , la légende sera alignée avec les boutons, sinon, ils seront chacun sur une ligne (false , défaut). | |
name | string | 'no-name' | Nom par défaut pour le groupe de boutons radio. | |
hint | string | undefined | Texte d'indice affiché sous la légende (facultatif). | |
legend | string | '' | Texte de la légende pour le groupe de boutons radio. | |
modelValue | string | number | ✅ | La valeur actuellement sélectionnée. | |
options | DsfrSegmentedProps[] | [] | Tableau d’objets : chaque objet contient les props à passer à DsfrSegmented . |
Notes
titleId
: Généré automatiquement si non spécifié.options
: Chaque élément représente un bouton radio avec ses props spécifiques.
📡 Événements
Nom | Valeur | Description |
---|---|---|
update:modelValue | string | number | Émis lorsqu'une nouvelle valeur est sélectionnée dans le groupe. |
🧩 Slots
- slot par défaut: Permet de personnaliser les boutons radio individuellement.
- Slot
legend
: Permet de personnaliser la légende avec du contenu riche.
📝 Exemple
<DsfrSegmentedSet
legend="Votre Choix"
:options="[
{
label: 'Croissant',
value: 'croissant',
},
{
label: 'Pain au chocolat (noooon ! Cho-co-la-tine ! C’est pas compliqué, pourtant !)',
value: 'chocolatine',
disabled: true,
}
]"
v-model="selectedOption"
/>
Assurez-vous d'importer DsfrSegmentedSet
ainsi que DsfrSegmented
dans votre projet. Puis, utilisez-le dans votre template en fournissant les props et les options nécessaires.
<script lang="ts" setup>
import { ref } from 'vue'
import DsfrSegmented from '../DsfrSegmented.vue'
import DsfrSegmentedSet from '../DsfrSegmentedSet.vue'
const region = ref<string | number>('')
const viennoiserie = ref<string | number>('')
const options = [
{ label: 'Sud-ouest', value: 'Chocolatine' },
{ label: 'Ailleurs', value: 'Pain au chocolat' },
]
</script>
<template>
<div class="fr-container">
<div>
<DsfrSegmentedSet
name="region"
label="Région"
:options="options"
@update:model-value="region = $event"
/>
</div>
<div
v-if="region"
class="fr-mt-4w"
>
<DsfrSegmentedSet
name="viennoiserie"
label="Viennoiserie"
>
<DsfrSegmented
icon="fr-icon-moon-line"
label="Croissant"
value="croissant"
:model-value="viennoiserie"
@update:model-value="viennoiserie = $event"
/>
<DsfrSegmented
:label="region.toString()"
value="chocolatine"
:icon="{ name: 'gi-chocolate-bar' }"
:model-value="viennoiserie"
@update:model-value="viennoiserie = $event"
/>
</DsfrSegmentedSet>
<p>
Vrai nom : {{ viennoiserie }}
</p>
</div>
</div>
</template>
⚙️ Code source du composant
<script lang="ts" setup>
import { getRandomId } from '../../utils/random-utils'
import DsfrSegmented from './DsfrSegmented.vue'
import type { DsfrSegmentedSetProps } from './DsfrSegmented.types'
export type { DsfrSegmentedSetProps }
const props = withDefaults(defineProps<DsfrSegmentedSetProps>(), {
titleId: () => getRandomId('radio-button', 'group'),
legend: '',
name: 'no-name',
options: () => [],
})
const emit = defineEmits<{ (e: 'update:modelValue', payload: string | number): void }>()
const onChange = ($event: string) => {
if ($event === props.modelValue) {
return
}
emit('update:modelValue', $event)
}
</script>
<template>
<div class="fr-form-group">
<fieldset
class="fr-segmented"
:class="{
'fr-segmented--sm': small,
'fr-segmented--no-legend': !legend,
}"
:disabled="disabled"
>
<legend
v-if="legend"
:id="titleId"
class="fr-segmented__legend"
:class="{
'fr-segmented__legend--inline': inline,
}"
>
<!-- @slot Slot pour personnaliser tout le contenu de la balise <legend> cf. [DsfrInput](/?path=/story/composants-champ-de-saisie-champ-simple-dsfrinput--champ-avec-label-personnalise). Une **props porte le même nom pour une légende simple** (texte sans mise en forme) -->
<slot name="legend">
{{ legend }}
</slot>
<span
v-if="hint"
class="fr-hint-text"
>
{{ hint }}
</span>
</legend>
<div class="fr-segmented__elements">
<slot>
<DsfrSegmented
v-for="(option, i) of options"
:key="option.value || i"
:name="name || option.name"
v-bind="{ ...option, disabled: disabled || option.disabled }"
:model-value="modelValue"
@update:model-value="onChange($event as string)"
/>
</slot>
</div>
</fieldset>
</div>
</template>
import type VIcon from '../VIcon/VIcon.vue'
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[]
}