Skip to content

Suivre (lettre d’information et réseaux sociaux) - DsfrFollow

🌟 Introduction

Le composant DsfrFollow est un conteneur pratique permettant d'afficher une section combinée pour une inscription à une newsletter et une liste de réseaux sociaux. Idéal pour renforcer l'engagement des utilisateurs sur votre site, ce composant combine flexibilité et respect des standards de la Design System de l'État Français (DSFR).

🏅 La documentation sur « Suivre » sur le DSFR

La story sur « Suivre » sur le storybook de VueDsfr

📐 Structure

Le composant affiche une grille responsive contenant :

  • Une section newsletter, propulsée par le composant enfant DsfrNewsLetter.
  • Une section réseaux sociaux, utilisant le composant DsfrSocialNetworks.
  • Un slot par défaut, permettant d'insérer un contenu personnalisé.

🛠️ Props

NomTypeDéfautDescription
newsletterDataDsfrNewsLetterPropsundefinedDonnées pour configurer la section newsletter.
networksDsfrSocialNetwork[][]Liste des réseaux sociaux à afficher avec leurs détails (type, name, href).
onlyCalloutboolean (hérité de DsfrNewsLetterProps)falseIndique si seule une version "callout" de la newsletter doit être utilisée.

Props de DsfrNewsLetter

Voici les principales options de configuration pour newsletterData :

NomTypeDéfautDescription
titlestringundefinedTitre de la section newsletter.
descriptionstringundefinedTexte descriptif au-dessus du champ email.
emailstringundefinedAdresse email pré-remplie (si applicable).
errorstringundefinedMessage d'erreur à afficher en cas de problème.
placeholderstringundefinedPlaceholder du champ email.
buttonTextstringundefinedTexte du bouton d'action.
buttonAction($event: MouseEvent) => voidundefinedFonction déclenchée au clic du bouton.

Props de DsfrSocialNetworks

Les réseaux sociaux (networks) sont des objets de type :

NomTypeDescription
type`'facebook''twitter-x'
namestringNom à afficher pour le réseau social.
hrefstringURL vers le profil ou la page sociale.

📡 Événements

Aucun événement spécifique n'est émis par ce composant. Les événements doivent être gérés via les props des sous-composants DsfrNewsLetter et DsfrSocialNetworks.

🧩 Slots

NomContenu
defaultPermet d'insérer du contenu personnalisé dans le conteneur global du composant.

📝 Exemples

Exemple de base

vue
<DsfrFollow
  :newsletterData="{
    title: 'Abonnez-vous à notre newsletter !',
    description: 'Restez informé(e) de nos actualités et nouveautés.',
    buttonText: 'S\'inscrire',
    placeholder: 'Votre email'
  }"
  :networks="[
    { type: 'facebook', name: 'Facebook', href: 'https://facebook.com' },
    { type: 'twitter-x', name: 'Twitter', href: 'https://twitter.com' },
    { type: 'linkedin', name: 'LinkedIn', href: 'https://linkedin.com' }
  ]"
/>

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[]
}