Modal

La modale permet de concentrer l’attention de l’utilisateur exclusivement sur une tâche ou un élément d’information, sans perdre le contexte de la page en cours. Ce composant nécessite une action de l’utilisateur afin d’être clôturée ou ouverte.

Modale simple

La modale par défaut permet de mettre en évidence une information qui ne nécessite pas d’action de l’utilisateur.

Les modales s’affichent suite à un clic sur un bouton qui possède l’attribut aria-controls correspondant à l’identifiant de la modale ET l’attribut data-fr-opened à false.

Code

= dsfr_modal(title: "Information importante", html_attributes: { id: "modal-1" }) do |component|
  %p Bonjour ceci est important
= dsfr_button(label: "Ouvrir la modale", html_attributes: { "data-fr-opened": false, "aria-controls": "modal-1" })

Résultat

Information importante

Bonjour ceci est important

<dialog class="fr-modal" role="dialog" id="modal-1" aria-labelledby="modal-1-title">
  <div class="fr-container fr-container--fluid fr-container-md">
    <div class="fr-grid-row fr-grid-row--center">
      <div class="fr-col-12 fr-col-md-8 fr-col-lg-6">
        <div class="fr-modal__body">
          <div class="fr-modal__header">
            <button class="fr-link--close fr-link" aria-controls="modal-1" type="button">
              Fermer
            </button>
          </div>
          <div class="fr-modal__content">
            <h1 class="fr-modal__title" id="modal-1-title">
              Information importante
            </h1>
            <p>
              Bonjour ceci est important
            </p>
          </div>
        </div>
      </div>
    </div>
  </div>
</dialog>
<button class="fr-btn" data-fr-opened="false" aria-controls="modal-1">
  Ouvrir la modale
</button>

Modale avec un bouton

La modale avec une zone d’action permet de guider l’utilisateur vers des actions attendues.

Dans ce cas, vous pouvez passer les arguments au composant Button directement.

Code

= dsfr_modal(title: "Information importante", html_attributes: { id: "modal-2" }) do |component|
  - component.with_button do
    = dsfr_button label: "Valider"
  %p Bonjour ceci est très important
= dsfr_button(label: "Ouvrir la modale", html_attributes: { "data-fr-opened": false, "aria-controls": "modal-2" })

Résultat

Information importante

Bonjour ceci est très important

<dialog class="fr-modal" role="dialog" id="modal-2" aria-labelledby="modal-2-title">
  <div class="fr-container fr-container--fluid fr-container-md">
    <div class="fr-grid-row fr-grid-row--center">
      <div class="fr-col-12 fr-col-md-8 fr-col-lg-6">
        <div class="fr-modal__body">
          <div class="fr-modal__header">
            <button class="fr-link--close fr-link" aria-controls="modal-2" type="button">
              Fermer
            </button>
          </div>
          <div class="fr-modal__content">
            <h1 class="fr-modal__title" id="modal-2-title">
              Information importante
            </h1>
            <p>
              Bonjour ceci est très important
            </p>
          </div>
          <div class="fr-modal__footer">
            <ul class="fr-btns-group fr-btns-group--right fr-btns-group--inline-reverse fr-btns-group--inline-lg fr-btns-group--icon-left">
              <p>
                Bonjour ceci est très important
              </p>
              <button class="fr-btn">
                Valider
              </button>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</dialog>
<button class="fr-btn" data-fr-opened="false" aria-controls="modal-2">
  Ouvrir la modale
</button>

Modale avec deux boutons

Il peut aussi y avoir un groupe de boutons hiérarchisé.

Code

= dsfr_modal(title: "Information importante", html_attributes: { id: "modal-3" }) do |component|
  %p Bonjour ceci est extrêmement important
  - component.with_button do
    = dsfr_button label: "Valider"
  - component.with_button do
    = dsfr_button label: "Annuler", level: :secondary, html_attributes: { "aria-controls": "modal-3" }
= dsfr_button(label: "Ouvrir la modale", html_attributes: { "data-fr-opened": false, "aria-controls": "modal-3" })

Résultat

Information importante

Bonjour ceci est extrêmement important

<dialog class="fr-modal" role="dialog" id="modal-3" aria-labelledby="modal-3-title">
  <div class="fr-container fr-container--fluid fr-container-md">
    <div class="fr-grid-row fr-grid-row--center">
      <div class="fr-col-12 fr-col-md-8 fr-col-lg-6">
        <div class="fr-modal__body">
          <div class="fr-modal__header">
            <button class="fr-link--close fr-link" aria-controls="modal-3" type="button">
              Fermer
            </button>
          </div>
          <div class="fr-modal__content">
            <h1 class="fr-modal__title" id="modal-3-title">
              Information importante
            </h1>
            <p>
              Bonjour ceci est extrêmement important
            </p>
          </div>
          <div class="fr-modal__footer">
            <ul class="fr-btns-group fr-btns-group--right fr-btns-group--inline-reverse fr-btns-group--inline-lg fr-btns-group--icon-left">
              <p>
                Bonjour ceci est extrêmement important
              </p>
              <button class="fr-btn">
                Valider
              </button>
              <p>
                Bonjour ceci est extrêmement important
              </p>
              <button class="fr-btn">
                Valider
              </button>
              <button class="fr-btn fr-btn--secondary" aria-controls="modal-3">
                Annuler
              </button>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</dialog>
<button class="fr-btn" data-fr-opened="false" aria-controls="modal-3">
  Ouvrir la modale
</button>

Modale pré-ouverte pour Turbo Drive

La modale peut s’afficher ouverte dès le chargement de la page grace à l’option opened: true. Cela permet notamment de rendre compatible cette modale avec un système comme Turbo Drive et de développer une application progressive, qui marchera avec ou sans JS.

Il faut pour cela bien penser que les boutons de fermetures natifs des modales ne fonctionneront pas dans ce cas (sans JS). On peut donc par exemple utiliser des liens de navigation dsfr_link_to plutôt que des boutons. De la même manière, il faut aussi bien penser à modifier le bouton du header par un lien en utilisant le slot header.

Code

= dsfr_modal(title: "Information importante", opened: true, html_attributes: { id: "modal-4" }) do |component|
  %p Bonjour ceci est crucial
  - component.with_button do
    = dsfr_link_to "Valider", "#", class: "fr-btn"
  - component.with_button do
    = dsfr_link_to  "Annuler", "#", class: "fr-btn fr-btn--secondary"

Résultat

Information importante

Bonjour ceci est crucial

<dialog class="fr-modal fr-modal--opened" role="dialog" id="modal-4" aria-labelledby="modal-4-title">
  <div class="fr-container fr-container--fluid fr-container-md">
    <div class="fr-grid-row fr-grid-row--center">
      <div class="fr-col-12 fr-col-md-8 fr-col-lg-6">
        <div class="fr-modal__body">
          <div class="fr-modal__header">
            <button class="fr-link--close fr-link" aria-controls="modal-4" type="button">
              Fermer
            </button>
          </div>
          <div class="fr-modal__content">
            <h1 class="fr-modal__title" id="modal-4-title">
              Information importante
            </h1>
            <p>
              Bonjour ceci est crucial
            </p>
          </div>
          <div class="fr-modal__footer">
            <ul class="fr-btns-group fr-btns-group--right fr-btns-group--inline-reverse fr-btns-group--inline-lg fr-btns-group--icon-left">
              <p>
                Bonjour ceci est crucial
              </p>
              <a class="fr-link fr-btn" href="#">
                Valider
              </a>
              <p>
                Bonjour ceci est crucial
              </p>
              <a class="fr-link fr-btn" href="#">
                Valider
              </a>
              <a class="fr-link fr-btn fr-btn--secondary" href="#">
                Annuler
              </a>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</dialog>