Skip to content

Composant DsfrNewsLetter

🌟 Introduction

Le composant DsfrNewsLetter est conçu pour afficher un formulaire d'inscription à une lettre d'information (newsletter) respectant les standards du Design System de l'État Français (DSFR). Flexible et accessible, il s'adapte à différents cas d'usage grâce à ses props personnalisables.

🏅 La documentation sur la lettre d’information sur le DSFR

La story sur la lettre d’information sur le storybook de VueDsfr

📐 Structure

Le composant offre deux modes :

  • Mode callout : un simple bouton pour l'inscription à la newsletter.
  • Mode formulaire : un formulaire complet avec champ email, bouton de soumission, et gestion des erreurs.

🛠️ Props

NomTypeDéfautDescription
titlestring'Abonnez-vous à notre lettre d’information'Titre affiché en haut de la section newsletter.
descriptionstring''Texte descriptif affiché sous le titre.
emailstring''Valeur initiale du champ email.
errorstring''Message d'erreur à afficher si la saisie est invalide.
labelEmailstring'Votre adresse électronique (ex. : prenom.nom@example.com)'Label du champ email.
placeholderstring'prenom.nom@example.com'Texte de placeholder pour le champ email.
hintTextstring''Texte d'aide affiché sous le champ email.
inputTitlestring'Adresse courriel'Titre de l'input email (pour l'attribut title de l'élément HTML).
buttonTextstring'S’abonner'Texte du bouton de soumission.
buttonTitlestring'S’abonner à notre lettre d’information'Titre du bouton (pour l'attribut title de l'élément HTML).
buttonAction($event: MouseEvent) => void() => undefinedAction personnalisée exécutée au clic du bouton en mode callout.
onlyCalloutbooleanfalseActive le mode "callout" avec un simple bouton au lieu du formulaire complet.

📡 Événements

NomPayloadDescription
update:emailstringÉmis lorsque l'utilisateur modifie le champ email.

🧩 Slots

Aucun slot disponible pour ce composant.

📝 Exemples

Exemple de base (formulaire)

vue
<DsfrNewsLetter
  :title="'Recevez nos actualités !'"
  :description="'Inscrivez-vous pour recevoir notre newsletter.'"
  :buttonText="'Envoyer'"
  :placeholder="'nom@exemple.com'"
  @update:email="(email) => console.log('Email mis à jour :', email)"
/>

📝 Exemples

Exemple de base

vue
<DsfrFollow>
  <DsfrNewsLetter
    :onlyCallout="true"
    :buttonText="'S’inscrire maintenant'"
    :buttonAction="() => console.log('Bouton cliqué !')"
  />
</DsfrFollow>

Exemple complet

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

const networks: DsfrSocialNetwork[] = [
  {
    name: 'Facebook',
    type: 'facebook',
    href: 'https://www.facebook.com',
  },
  {
    name: 'X (anciennement Twitter)',
    type: 'twitter-x',
    href: 'https://www.x.com',
  },
  {
    name: 'Youtube',
    type: 'youtube',
    href: 'https://www.youtube.com',
  },
  {
    name: 'Linkedin',
    type: 'linkedin',
    href: 'https://www.linkedin.com',
  },
  {
    name: 'Instagram',
    type: 'instagram',
    href: 'https://www.instagram.com',
  },
]
const newsletterData = {
  title: 'Titre de la lettre d’informations',
  description: 'Description de la lettre d’informations',
  email: '',
  labelEmail: 'Label du champ adresse électronique',
  placeholder: 'james.bond@mi6.gov.uk',
  hintText: 'Mise en garde concernant l’abonnement à la lettre d’information',
  buttonText: 'S’abonner',
  buttonTitle:
      'Titre du bouton (valeur de l’attribut `title` de la balise `button`)',
  buttonAction: () => undefined,
  onlyCallout: false,
}
</script>

<template>
  <DsfrFollow
    :networks="networks"
    :newsletter-data="newsletterData"
  />
</template>

⚙️ Code source du composant

vue
<script lang="ts" setup>
import { computed } from 'vue'

import DsfrNewsLetter from './DsfrNewsLetter.vue'
import DsfrSocialNetworks from './DsfrSocialNetworks.vue'
import type { DsfrFollowProps } from './DsfrFollow.types'

export type { DsfrFollowProps }

const props = withDefaults(defineProps<DsfrFollowProps>(), {
  // @ts-expect-error this is really undefined
  newsletterData: () => undefined,
  networks: () => [],
})

const hasNetworks = computed(() => {
  return props.networks && props.networks.length
})
const hasNewsletter = computed(() => {
  return typeof props.newsletterData === 'object'
})
</script>

<template>
  <div class="fr-follow">
    <div class="fr-container">
      <div class="fr-grid-row">
        <!-- @slot Slot par défaut pour le contenu. Sera dans `<div class="fr-grid-row">` -->
        <slot>
          <div
            v-if="newsletterData"
            class="fr-col-12"
            :class="{ 'fr-col-md-8': hasNetworks }"
          >
            <DsfrNewsLetter v-bind="newsletterData" />
          </div>
          <div
            v-if="hasNetworks"
            class="fr-col-12"
            :class="{ 'fr-col-md-4': hasNewsletter }"
          >
            <DsfrSocialNetworks :networks="networks" />
          </div>
        </slot>
      </div>
    </div>
  </div>
</template>
ts
export type DsfrSocialNetworkName = 'facebook' | 'twitter-x' | 'instagram' | 'linkedin' | 'youtube'
export type DsfrSocialNetwork = {
  type: DsfrSocialNetworkName
  name: string
  href: string
}

export type DsfrSocialNetworksProps = {
  networks: DsfrSocialNetwork[]
  titleTag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
}

export type DsfrNewsLetterProps = {
  title?: string
  description?: string
  email?: string
  error?: string
  labelEmail?: string
  placeholder?: string
  hintText?: string
  inputTitle?: string
  buttonText?: string
  buttonTitle?: string
  buttonAction?: ($event: MouseEvent) => void
  onlyCallout?: boolean
}

export type DsfrFollowProps = {
  newsletterData: DsfrNewsLetterProps
  networks: DsfrSocialNetwork[]
}