Skip to content

Regroupement de champs - DsfrFieldset

🌟 Introduction

Le regroupement de champs permet à l'utilisateur de lier de façon logique et visuelle des éléments de formulaire appartenant à un même ensemble.

La story du regroupement de champs sur le storybook de VueDsfr

📐 Structure

Le regroupement de champs est constitué des éléments suivants :

  • un slot par défaut pour le contenu du fieldset
  • un slot pour la légende du fieldset appelé legend
  • un id pour la balise <legend> appelé legendId
  • une classe pour la balise <legend> appelée legendClass
  • un slot pour l'indice placé au dessus du contenu du fieldset appelé hint
  • un classe pour l'indice appelée hintClass

🛠️ Props

nomtypedéfautobligatoire
legendIdstring''
legendClassstring''
hintClassstring''

🧩 Slots

  • Un slot par défaut pour laisser la possibilité à l'utilisateur d'ajouter librement les champs contenus dans le fieldset.
  • Un slot pour le contenu de la légende du fieldset (legend).
  • Un slot pour l'indice placé au dessus du contenu du fieldset (hint).

📝 Exemple complet

vue
<script lang="ts" setup>
import { ref } from 'vue'
import DsfrRadioButtonSet from '../../DsfrRadioButton/DsfrRadioButtonSet.vue'
import DsfrFieldset from '../DsfrFieldset.vue'

const options = [
  { label: 'Godzilla', value: 'G' },
  { label: 'La créature de Frankenstein', value: 'F' },
  { label: 'King Kong', value: 'K' },
  { label: 'Le xénomorphe', value: 'X' },
  { label: 'Le prédator', value: 'P' },
  { label: 'Dracula', value: 'D' },
]

const choice = ref('')
</script>

<template>
  <div class="fr-container fr-my-2v">
    <DsfrFieldset>
      <template #legend>
        Quel est votre monstre préféré du cinéma ?
      </template>
      <template #hint>
        Si le vôtre n'est pas cité ici, toutes mes excuses !
      </template>
      <DsfrRadioButtonSet
        :options="options"
        :model-value="choice"
      />
    </DsfrFieldset>
  </div>
</template>

⚙️ Code source du composant

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

export type { DsfrFieldsetProps }

withDefaults(defineProps<DsfrFieldsetProps>(), {
  legend: '',
  legendId: '',
  legendClass: '',
  hint: '',
  hintClass: '',
})
</script>

<template>
  <fieldset class="fr-fieldset">
    <legend
      v-if="legend || $slots.legend?.().length"
      :id="legendId"
      class="fr-fieldset__legend"
      :class="legendClass"
    >
      {{ legend }}
      <!-- @slot Slot pour le contenu du titre du `fieldset` (sera dans `<legend class="fr-fieldset__legend">`). Une props du même nom est utilisable pour du texte simple sans mise en forme. -->
      <slot name="legend" />
    </legend>
    <div
      v-if="hint || $slots.hint?.().length"
      class="fr-fieldset__element"
    >
      <span
        class="fr-hint-text"
        :class="hintClass"
      >
        {{ hint }}
        <!-- @slot Slot pour le contenu de l’indice (sera dans `<span class="fr-hint-text">` qui sera dans `</legend>`). Une **props du même nom est utilisable pour du texte simple** sans mise en forme. -->
        <slot name="hint" />
      </span>
    </div>
    <div class="fr-fieldset__element">
      <!-- @slot Slot par défaut pour le contenu du fieldset (sera dans `<div class="fr-fieldset__element">`) -->
      <slot />
    </div>
  </fieldset>
</template>