Groupe de champs de saisie - DsfrInputGroup
🌟 Introduction
Bienvenue dans la documentation du composant DsfrInputGroup
, conçu pour envelopper vos champs de saisie avec une élégance à la française. Que vous composiez un message d'amour ou remplissiez un formulaire administratif, ce composant est là pour apporter de l'ordre et de la clarté à vos interfaces utilisateur.
Ce composant est très utile si vous souhaitez afficher un message d’erreur ou de succès pour un ou plusieurs champs de saisie DsfrInput
.
🛠️ Props
Nom | Type | Défaut | Obligatoire | Description |
---|---|---|---|---|
descriptionId | Function | () => getRandomId(...) | ID unique pour la description du groupe, généré automatiquement si non spécifié. | |
hint | string | '' | Texte d'indice pour guider l'utilisateur dans le groupe de champs. | |
label | string | '' | Le libellé associé au groupe de champs. | |
labelClass | string | '' | Classe CSS personnalisée pour le style du libellé. | |
modelValue | string | '' | La valeur liée au modèle du composant DsfrInput . | |
wrapperClass | string | '' | Classe CSS pour le style du conteneur du groupe. | |
placeholder | string | undefined | Texte de l'espace réservé pour l'input. | |
errorMessage | string | string[] | undefined | Message(s) d'erreur à afficher si une erreur est présente. | |
validMessage | string | string[] | undefined | Message(s) de validation à afficher si l'input est valide. |
Attributs implicitement déclarés
Important
Toutes les props passées à <DsfrInputGroup>
dans une template et qui ne sont pas définies dans les props seront passées à la balise <DsfrInput>
. Si ces props ne sont pas définies non plus en tant que props dans DsfrInput
, elles seront passés à la balise native <input>
, comme par exemple readonly
ou disabled
.
Cf. la note important sur DsfrInput
📡 Événements
Nom | Description |
---|---|
update:modelValue | Événement émis lors de la mise à jour de la valeur de l'input. |
🧩 Slots
Nom | Description |
---|---|
before-input | Slot pour insérer du contenu avant le champ de saisie principal. |
default | Slot par défaut pour le contenu principal du groupe de champ. Utilisé pour insérer des éléments personnalisés. |
📝 Exemples
Voici comment vous pourriez utiliser DsfrInputGroup
:
<script lang="ts" setup>
import { ref } from 'vue'
import DsfrInput from '../DsfrInput.vue'
import DsfrInputGroup from '../DsfrInputGroup.vue'
const type = 'text'
const label = 'Label champ de saisie'
const placeholder = 'Yo'
const modelValue = ref('')
const modelValue2 = ref('')
const validMessage1 = 'Message de validation'
const errorMessage1 = 'Message d’erreur'
const errorMessage2 = 'Message d’erreur 2'
const hint = 'Texte d’indice du champ'
const id = ''
const readonly = ''
</script>
<template>
<div class="fr-container fr-my-2w">
<h2>1. Avec un message de succès</h2>
<DsfrInputGroup
:id="id"
:valid-message="validMessage1"
:placeholder="placeholder"
:readonly="readonly !== ''"
:model-value="modelValue"
:label="label"
:type="type"
:hint="hint"
label-visible
/>
<h2>2. Avec un message d’erreur</h2>
<DsfrInputGroup
:id="id"
:error-message="errorMessage1"
:placeholder="placeholder"
:readonly="readonly !== ''"
:model-value="modelValue"
:label="label"
:type="type"
:hint="hint"
label-visible
/>
<h2>3. Avec plusieurs messages</h2>
<DsfrInputGroup
:id="id"
:error-message="[errorMessage1, errorMessage2]"
:valid-message="[validMessage1]"
:placeholder="placeholder"
:readonly="readonly !== ''"
:model-value="modelValue"
:label="label"
:type="type"
:hint="hint"
label-visible
/>
<h2>4. Avec plusieurs champs de saisie</h2>
<DsfrInputGroup
valid-message="Tout va bien pour ces deux champs"
>
<p>
<DsfrInput
:id="id"
:placeholder="placeholder"
:readonly="readonly !== ''"
:model-value="modelValue"
:label="label"
:type="type"
:hint="hint"
label-visible
/>
</p>
<p>
<DsfrInput
:id="id"
:placeholder="placeholder"
:readonly="readonly !== ''"
:model-value="modelValue2"
:label="label"
:type="type"
:hint="hint"
label-visible
/>
</p>
</DsfrInputGroup>
</div>
</template>
⚙️ Code source du composant
<script lang="ts" setup>
import { getRandomId } from '../../utils/random-utils'
import DsfrInput from './DsfrInput.vue'
import type { DsfrInputGroupProps } from './DsfrInput.types'
export type { DsfrInputGroupProps }
defineOptions({
inheritAttrs: false,
})
withDefaults(defineProps<DsfrInputGroupProps>(), {
descriptionId: () => getRandomId('basic', 'input'),
hint: '',
label: '',
labelClass: '',
modelValue: '',
wrapperClass: '',
placeholder: undefined,
errorMessage: undefined,
validMessage: undefined,
})
defineEmits<{ (e: 'update:modelValue', payload: string): void }>()
</script>
<template>
<div
class="fr-input-group"
:class="[
{
'fr-input-group--error': errorMessage,
'fr-input-group--valid': (validMessage && !errorMessage),
},
wrapperClass,
]"
>
<slot name="before-input" />
<!-- @slot Slot par défaut pour le contenu du groupe de champ -->
<slot />
<DsfrInput
v-if="!$slots.default"
v-bind="$attrs"
:is-valid="!!validMessage"
:is-invalid="!!errorMessage"
:label="label"
:hint="hint"
:description-id="((errorMessage || validMessage) && descriptionId) || undefined"
:label-visible="labelVisible"
:model-value="modelValue"
:placeholder="placeholder"
@update:model-value="$emit('update:modelValue', $event)"
/>
<div
class="fr-messages-group"
role="alert"
aria-live="polite"
>
<template
v-if="Array.isArray(errorMessage)"
>
<p
v-for="message in errorMessage"
:id="descriptionId"
:key="message"
:data-testid="descriptionId"
class="fr-error-text"
>
{{ message }}
</p>
</template>
<p
v-else-if="errorMessage"
:id="descriptionId"
:key="errorMessage"
:data-testid="descriptionId"
class="fr-error-text"
>
{{ errorMessage }}
</p>
<template
v-if="Array.isArray(validMessage)"
>
<p
v-for="message in validMessage"
:id="descriptionId"
:key="message"
:data-testid="descriptionId"
class="fr-valid-text"
>
{{ message }}
</p>
</template>
<p
v-else-if="validMessage"
:id="descriptionId"
:key="validMessage"
:data-testid="descriptionId"
class="fr-valid-text"
>
{{ validMessage }}
</p>
</div>
</div>
</template>
export type DsfrInputProps = {
id?: string
descriptionId?: string
hint?: string
isInvalid?: boolean
isValid?: boolean
isTextarea?: boolean
isWithWrapper?: boolean
labelVisible?: boolean
label?: string
labelClass?: string
modelValue?: string | number | null
wrapperClass?: string
}
export type DsfrInputGroupProps = {
descriptionId?: string
hint?: string
labelVisible?: boolean
label?: string
labelClass?: string
modelValue?: string | number | null
placeholder?: string
errorMessage?: string | string[]
validMessage?: string | string[]
wrapperClass?: string
}