Alertes - DsfrAlert
🌟 Introduction
Les alertes permettent d’attirer l’attention de l’utilisateur sur une information sans interrompre sa tâche en cours.
L’alerte est disponible en deux tailles :
- taille médium (MD, par défaut, si la prop
smallest absente ou àfalse) et - petite taille ‘SM’ si la prop
smallest àtrue.
🏅 La documentation sur l’alerte sur le DSFR
La story sur l’alerte sur le storybook de VueDsfr📐 Structure
L’alerte est composée des éléments suivants :
- un titre (prop
title, de typestring) :- obligatoire sur la version MD (si la prop
smallest absente ou àfalse), - optionnel sur la version SM (si la prop
smallest àtrue).
- obligatoire sur la version MD (si la prop
- un pictogramme et une couleur déterminés par la prop
typequi peut valoir une des chaînes suivantes :'info'(valeur par défaut si la proptypeest absente)'success''warning''error'
- un texte de description (avec la prop
description, de typestring) :- optionnel sur la version MD
- obligatoire sur la version SM
- le
slotpar défaut peut être utilisé
- une croix de fermeture si la prop
closeableest àtrue
Autres props :
closedsert à indiquer si l’alerte doit être présente (false) ou non (true) dans le DOM.titleTagpermet d’indiquer la balise à utiliser pour letitle: il s’agit deh3par défaut, cependant, pour passer les tests RGAA, il faut que les niveaux de titres se suivent et soient cohérents (par exemple, si sur la page il n’y a pas de<h2>, il faut passer'h2'comme valeur à la proptitleTagpour que le titre de la modal soit un<h2>).closeButtonLabelpermet d'indiquer le libellé et l'aria-label du bouton de fermeture de l’alerte. Par défaut, la valeur estFermer.
🛠️ Props
| nom | type | défaut | obligatoire |
|---|---|---|---|
id | string | random string | |
type | 'info' | 'success' | 'warning' | 'error' | 'info' | |
title | string | '' | ✅ |
description | string | ||
titleTag | TitleTag | 'h3' | |
small | boolean | false | |
closed | boolean | false | |
closeable | boolean | false | |
closeButtonLabel | string | Fermer |
📡 Évenements
DsfrAlert déclenche l’événement 'close' lors du clic sur le bouton pour fermer l’alerte, sans données (sans payload).
| nom | donnée (payload) |
|---|---|
'close' | aucune |
🧩 Slots
DsfrAlert possède un slot par défaut pour la description de l'alerte.
📝 Toutes les variantes 🌈 d’Alertes
vue
<script lang="ts" setup>
import type { TitleTag } from '../../../common-types'
import type { DsfrAlertType } from '../DsfrAlert.vue'
import { ref } from 'vue'
import DsfrAlert from '../DsfrAlert.vue'
const defaultAlerts: {
[key: string]: {
id: string
type: DsfrAlertType
title?: string
small?: true
description: string
titleTag: TitleTag
closed?: boolean
closeable?: true
}[]
} = {
'Grandes non fermables': [
{
id: '1',
type: 'error',
title: 'Titre de l’erreur',
description: 'Description de l’erreur',
titleTag: 'h2',
},
{
id: '2',
type: 'info',
title: 'Titre de l’info',
description: 'Description de l’info',
titleTag: 'h3',
},
{
id: '3',
type: 'warning',
title: 'Titre de l’avertissement',
description: 'Description de l’avertissement',
titleTag: 'h4',
},
{
id: '4',
type: 'success',
title: 'Titre du succès',
description: 'Description du succès',
titleTag: 'h5',
},
],
'Grandes fermables': [
{
id: '5',
type: 'error',
title: 'Titre de l’erreur',
description: 'Description de l’erreur',
titleTag: 'h2',
closeable: true,
closed: false,
},
{
id: '6',
type: 'info',
title: 'Titre de l’info',
description: 'Description de l’info',
titleTag: 'h3',
closeable: true,
closed: false,
},
{
id: '7',
type: 'warning',
title: 'Titre de l’avertissement',
description: 'Description de l’avertissement',
titleTag: 'h4',
closeable: true,
closed: false,
},
{
id: '8',
type: 'success',
title: 'Titre du succès',
description: 'Description du succès',
titleTag: 'h5',
closeable: true,
closed: false,
},
],
'Petites non fermables': [
{
id: '9',
type: 'error',
small: true,
description: 'Description de l’erreur',
titleTag: 'h2',
},
{
id: '10',
type: 'info',
small: true,
description: 'Description de l’info',
titleTag: 'h3',
},
{
id: '11',
type: 'warning',
small: true,
description: 'Description de l’avertissement',
titleTag: 'h4',
},
{
id: '12',
type: 'success',
small: true,
description: 'Description du succès',
titleTag: 'h5',
},
],
'Petites fermables': [
{
id: '13',
type: 'error',
small: true,
description: 'Description de l’erreur',
titleTag: 'h2',
closeable: true,
closed: false,
},
{
id: '14',
type: 'info',
small: true,
description: 'Description de l’info',
titleTag: 'h3',
closeable: true,
closed: false,
},
{
id: '15',
type: 'warning',
small: true,
description: 'Description de l’avertissement',
titleTag: 'h4',
closeable: true,
closed: false,
},
{
id: '16',
type: 'success',
small: true,
description: 'Description du succès',
titleTag: 'h5',
closeable: true,
closed: false,
},
],
}
const alertGroups = ref(defaultAlerts)
const onClose = (id: string) => {
Object.values(alertGroups.value)
.flat()
.forEach((alert) => {
if (alert.id === id) {
alert.closed = true // mettre la propriété closed à true pour cette alerte
setTimeout(() => { alert.closed = false }, 3000) // la remettre à false au bout de 3 secondes
}
})
}
</script>
<template>
<div class="fr-container fr-p-2w">
<div
v-for="(alerts, title, i) in alertGroups"
:key="`alert-group-${i}`"
:class="i > 0 ? 'fr-mt-6w' : ''"
>
<h2>{{ title }}</h2>
<DsfrAlert
v-for="alert in alerts"
:key="`alert-${alert.id}`"
:type="alert.type"
:title="alert.title"
:description="alert.description"
:title-tag="alert.titleTag"
:small="alert.small"
:closed="alert.closed"
:closeable="alert.closeable"
@close="onClose(alert.id)"
/>
</div>
</div>
</template>⚙️ Code source du composant
vue
<script setup lang="ts">
import type { DsfrAlertProps } from './DsfrAlert.types.js'
import { computed } from 'vue'
import { useRandomId } from '@/utils/random-utils'
export type { DsfrAlertProps, DsfrAlertType } from './DsfrAlert.types.js'
const props = withDefaults(defineProps<DsfrAlertProps>(), {
id: () => useRandomId('basic', 'alert'),
title: '',
titleTag: 'h3',
type: 'info',
closeButtonLabel: 'Fermer le message',
})
const emit = defineEmits<{ (e: 'close'): void }>()
const onClick = () => emit('close')
const classes = computed(
() => ([
`fr-alert--${props.type}`,
{
'fr-alert--sm': props.small,
},
]),
)
const idTitle = computed(() => useRandomId('alert', 'title'))
const idDescription = computed(() => useRandomId('alert', 'description'))
const idListDescribedby = computed(() => {
if (props.description && !props.title) {
return idDescription.value
}
if (!props.description && props.title) {
return idTitle.value
}
return `${idTitle.value} ${idDescription.value}`
})
</script>
<template>
<div
v-if="!closed"
:id="id"
class="fr-alert"
:class="classes"
:role="alert ? 'alert' : undefined"
>
<component
:is="titleTag"
v-if="!small"
:id="idTitle"
class="fr-alert__title"
>
{{ title }}
</component>
<p
v-if="description"
:id="idDescription"
>
{{ description }}
</p>
<slot v-else />
<button
v-if="closeable"
:aria-describedby="idListDescribedby"
:title="closeButtonLabel"
class="fr-btn fr-btn--close"
@click="onClick"
>
<span class="fr-sr-only">{{ closeButtonLabel }}</span>
</button>
</div>
</template>
<style scoped>
p {
padding: 0;
margin: 0;
}
.fr-alert--sm {
padding: .5rem 2.25rem .5rem 3rem;
}
</style>ts
import type { TitleTag } from '../../common-types'
export type DsfrAlertType = 'error' | 'success' | 'warning' | 'info'
export type DsfrAlertProps = {
alert?: boolean
closed?: boolean
closeable?: boolean
id?: string
title?: string
description?: string
small?: boolean
titleTag?: TitleTag
type?: DsfrAlertType
closeButtonLabel?: string
}