Modal

Organisms

Source Code HTML / SASS

Vous trouverez ici les démos et le code source statiques du composant.

On expose les différentes déclinaisons du composant au format HTML et SASS.

Le composant React a été conçu sur la base de cette structure en y ajoutant les interactions que vous trouverez dans notre storybook.react storybook

Modal

Copied
<div class="af-modal">
    <div class="af-modal__dialog">
        <div class="af-modal__content">
            <div class="af-modal__header">
                <h4 class="af-modal__header-title">Large Modal Title</h4>
                <button class="af-modal__header-close-btn" type="button" aria-label="Close">
                    <svg class="glyphicon glyphicon-close" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
                        <path d="M90.086 0.888l-40.086 40.086-40.086-40.086-9.026 9.026 40.086 40.086-40.086 40.086 9.026 9.026 40.086-40.086 40.086 40.086 9.026-9.026-40.086-40.086 40.086-40.086z"></path>
                    </svg>
                </button>
            </div>
            <div class="af-modal__body">
                <p>Reprehenderit sit quis aute nisi consequat consequat mollit. Commodo in aliquip consectetur nulla sit anim. Pariatur minim commodo enim ea eu laborum culpa laboris. Labore labore irure ipsum consequat enim officia anim ipsum aliqua excepteur qui sint. Duis sint do culpa adipisicing dolor adipisicing ea dolore aute nisi quis ullamco aliquip occaecat. Aute ut mollit amet ut culpa ipsum eiusmod veniam elit aute elit.</p>
            </div>
            <div class="af-modal__footer">
                <button class="btn af-btn af-btn--reverse" type="button">Cancel</button>
                <button class="btn af-btn" type="button">Save</button>
            </div>
        </div>
    </div>
</div>
<div class="af-modal__backdrop show"></div>
Copied
@import '@axa-fr/react-toolkit-core/src/common/scss/core.scss';

// stylelint-disable selector-class-pattern
.ReactModal__Overlay {
    animation: fademodal 0.1s linear;
    z-index: 3;
    overflow: auto;
}

.ReactModal__Body {
    &--open {
        overflow: hidden;
    }
}

// stylelint-enable selector-class-pattern

.af-modal {
    position: absolute;
    left: 50%;
    transform: translate(-50%, 0);
    z-index: 1050;
    outline: 0;
    overflow: auto;

    &--lg {
        max-width: 800px;
    }

    &--sm {
        max-width: 300px;
    }

    &__backdrop {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 1040;
        background-color: $color-axa;

        &.show {
            opacity: 0.5;
        }
    }

    &__dialog {
        position: relative;
        width: auto;
        margin: 10px;
        animation: appeardialog 0.3s cubic-bezier(0.65, 0.05, 0.36, 1);
    }

    &__content {
        position: relative;
        display: flex;
        flex-direction: column;
        background-color: $white;
        background-clip: padding-box;
        border: 1px solid $color-mine-shaft;
        border-radius: 0;
        outline: 0;
    }

    &__header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 15px;
        border-bottom: 1px solid $gray-lighter;

        &-title {
            font-weight: inherit;
            margin-bottom: 0;
        }

        &-close-btn {
            font-size: 1rem;
            line-height: 1rem;
            border: none;
            box-shadow: none;
            background: none;
            padding: 0.5rem;

            &:hover {
                background-color: $gray-lighter;
            }

            .glyphicon-close {
                width: 17px;
            }
        }
    }

    &__body {
        position: relative;
        -webkit-box-flex: 1;
        -ms-flex: 1 1 auto;
        flex: 1 1 auto;
        padding: 15px;
    }

    &__footer {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        padding: 15px;
        border-top: 1px solid $gray-lighter;

        &>.af-btn:not(:last-child) {
            margin-right: 0.25rem;
        }

        &>.af-btn:not(:first-child) {
            margin-left: 0.25rem;
        }
    }
}

@include media-breakpoint-up(sm) {
    .af-modal {
        max-width: 500px;
        margin: 30px auto;

        &--sm {
            max-width: 300px;
        }
    }
}

@include media-breakpoint-up(lg) {
    .af-modal {
        &--lg {
            max-width: 800px;
            margin: 30px auto;
        }
    }
}

@keyframes appeardialog {
    0% {
        top: -100%;
        opacity: 0;
    }

    0% {
        top: -100%;
        opacity: 1;
    }

    100% {
        top: 0;
        opacity: 1;
    }
}

@keyframes fademodal {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

Modal Large

Copied
<div class="af-modal af-modal--lg">
    <div class="af-modal__dialog">
        <div class="af-modal__content">
            <div class="af-modal__header">
                <h4 class="af-modal__header-title">Modal Title</h4>
                <button class="af-modal__header-close-btn" type="button" aria-label="Close">
                    <svg class="glyphicon glyphicon-close" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
                        <path d="M90.086 0.888l-40.086 40.086-40.086-40.086-9.026 9.026 40.086 40.086-40.086 40.086 9.026 9.026 40.086-40.086 40.086 40.086 9.026-9.026-40.086-40.086 40.086-40.086z"></path>
                    </svg>
                </button>
            </div>
            <div class="af-modal__body">
                <p>Reprehenderit sit quis aute nisi consequat consequat mollit. Commodo in aliquip consectetur nulla sit anim. Pariatur minim commodo enim ea eu laborum culpa laboris. Labore labore irure ipsum consequat enim officia anim ipsum aliqua excepteur qui sint. Duis sint do culpa adipisicing dolor adipisicing ea dolore aute nisi quis ullamco aliquip occaecat. Aute ut mollit amet ut culpa ipsum eiusmod veniam elit aute elit.</p>
            </div>
            <div class="af-modal__footer">
                <button class="btn af-btn af-btn--reverse" type="button">Cancel</button>
                <button class="btn af-btn" type="button">Save</button>
            </div>
        </div>
    </div>
</div>
<div class="af-modal__backdrop show"></div>
Copied
@import '@axa-fr/react-toolkit-core/src/common/scss/core.scss';

// stylelint-disable selector-class-pattern
.ReactModal__Overlay {
    animation: fademodal 0.1s linear;
    z-index: 3;
    overflow: auto;
}

.ReactModal__Body {
    &--open {
        overflow: hidden;
    }
}

// stylelint-enable selector-class-pattern

.af-modal {
    position: absolute;
    left: 50%;
    transform: translate(-50%, 0);
    z-index: 1050;
    outline: 0;
    overflow: auto;

    &--lg {
        max-width: 800px;
    }

    &--sm {
        max-width: 300px;
    }

    &__backdrop {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 1040;
        background-color: $color-axa;

        &.show {
            opacity: 0.5;
        }
    }

    &__dialog {
        position: relative;
        width: auto;
        margin: 10px;
        animation: appeardialog 0.3s cubic-bezier(0.65, 0.05, 0.36, 1);
    }

    &__content {
        position: relative;
        display: flex;
        flex-direction: column;
        background-color: $white;
        background-clip: padding-box;
        border: 1px solid $color-mine-shaft;
        border-radius: 0;
        outline: 0;
    }

    &__header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 15px;
        border-bottom: 1px solid $gray-lighter;

        &-title {
            font-weight: inherit;
            margin-bottom: 0;
        }

        &-close-btn {
            font-size: 1rem;
            line-height: 1rem;
            border: none;
            box-shadow: none;
            background: none;
            padding: 0.5rem;

            &:hover {
                background-color: $gray-lighter;
            }

            .glyphicon-close {
                width: 17px;
            }
        }
    }

    &__body {
        position: relative;
        -webkit-box-flex: 1;
        -ms-flex: 1 1 auto;
        flex: 1 1 auto;
        padding: 15px;
    }

    &__footer {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        padding: 15px;
        border-top: 1px solid $gray-lighter;

        &>.af-btn:not(:last-child) {
            margin-right: 0.25rem;
        }

        &>.af-btn:not(:first-child) {
            margin-left: 0.25rem;
        }
    }
}

@include media-breakpoint-up(sm) {
    .af-modal {
        max-width: 500px;
        margin: 30px auto;

        &--sm {
            max-width: 300px;
        }
    }
}

@include media-breakpoint-up(lg) {
    .af-modal {
        &--lg {
            max-width: 800px;
            margin: 30px auto;
        }
    }
}

@keyframes appeardialog {
    0% {
        top: -100%;
        opacity: 0;
    }

    0% {
        top: -100%;
        opacity: 1;
    }

    100% {
        top: 0;
        opacity: 1;
    }
}

@keyframes fademodal {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

Modal Small

Copied
<div class="af-modal af-modal--sm">
    <div class="af-modal__dialog">
        <div class="af-modal__content">
            <div class="af-modal__header">
                <h4 class="af-modal__header-title">Titre de la modal</h4>
                <button class="af-modal__header-close-btn" type="button" aria-label="Close">
                    <svg class="glyphicon glyphicon-close" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
                        <path d="M90.086 0.888l-40.086 40.086-40.086-40.086-9.026 9.026 40.086 40.086-40.086 40.086 9.026 9.026 40.086-40.086 40.086 40.086 9.026-9.026-40.086-40.086 40.086-40.086z"></path>
                    </svg>
                </button>
            </div>
            <div class="af-modal__body">
                <p>Reprehenderit sit quis aute nisi consequat consequat mollit. Commodo in aliquip consectetur nulla sit anim. Pariatur minim commodo enim ea eu laborum culpa laboris. Labore labore irure ipsum consequat enim officia anim ipsum aliqua excepteur qui sint. Duis sint do culpa adipisicing dolor adipisicing ea dolore aute nisi quis ullamco aliquip occaecat. Aute ut mollit amet.</p>
            </div>
            <div class="af-modal__footer">
                <button class="btn af-btn" type="button">Valider</button>
            </div>
        </div>
    </div>
</div>
<div class="af-modal__backdrop show"></div>
Copied
@import '@axa-fr/react-toolkit-core/src/common/scss/core.scss';

// stylelint-disable selector-class-pattern
.ReactModal__Overlay {
    animation: fademodal 0.1s linear;
    z-index: 3;
    overflow: auto;
}

.ReactModal__Body {
    &--open {
        overflow: hidden;
    }
}

// stylelint-enable selector-class-pattern

.af-modal {
    position: absolute;
    left: 50%;
    transform: translate(-50%, 0);
    z-index: 1050;
    outline: 0;
    overflow: auto;

    &--lg {
        max-width: 800px;
    }

    &--sm {
        max-width: 300px;
    }

    &__backdrop {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 1040;
        background-color: $color-axa;

        &.show {
            opacity: 0.5;
        }
    }

    &__dialog {
        position: relative;
        width: auto;
        margin: 10px;
        animation: appeardialog 0.3s cubic-bezier(0.65, 0.05, 0.36, 1);
    }

    &__content {
        position: relative;
        display: flex;
        flex-direction: column;
        background-color: $white;
        background-clip: padding-box;
        border: 1px solid $color-mine-shaft;
        border-radius: 0;
        outline: 0;
    }

    &__header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 15px;
        border-bottom: 1px solid $gray-lighter;

        &-title {
            font-weight: inherit;
            margin-bottom: 0;
        }

        &-close-btn {
            font-size: 1rem;
            line-height: 1rem;
            border: none;
            box-shadow: none;
            background: none;
            padding: 0.5rem;

            &:hover {
                background-color: $gray-lighter;
            }

            .glyphicon-close {
                width: 17px;
            }
        }
    }

    &__body {
        position: relative;
        -webkit-box-flex: 1;
        -ms-flex: 1 1 auto;
        flex: 1 1 auto;
        padding: 15px;
    }

    &__footer {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        padding: 15px;
        border-top: 1px solid $gray-lighter;

        &>.af-btn:not(:last-child) {
            margin-right: 0.25rem;
        }

        &>.af-btn:not(:first-child) {
            margin-left: 0.25rem;
        }
    }
}

@include media-breakpoint-up(sm) {
    .af-modal {
        max-width: 500px;
        margin: 30px auto;

        &--sm {
            max-width: 300px;
        }
    }
}

@include media-breakpoint-up(lg) {
    .af-modal {
        &--lg {
            max-width: 800px;
            margin: 30px auto;
        }
    }
}

@keyframes appeardialog {
    0% {
        top: -100%;
        opacity: 0;
    }

    0% {
        top: -100%;
        opacity: 1;
    }

    100% {
        top: 0;
        opacity: 1;
    }
}

@keyframes fademodal {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

React interactions

Vous trouverez ici les démos Storybook pour visualiser les interactions du composant.

Vous avez la possibilité de jouer avec les propriétés du composant React sur notre storybook.react storybook

Generales Guidelines

Les guidelines permettent de décrire l'ensemble des règles et des éléments graaphiques pour la conception des interfaces.

Elle sont destinées à être respectées par tous les intervenants d'un projet (UX, Développeurs, PO, etc ...), il s'agit donc d'un référentiel commun.

1) Définition

Une modale permet de communiquer une information ou une action dans une fenêtre secondaire tout en permettant à l’utilisateur de rester dans le contexte de la tâche en cours.

2) Use case

  • Une modale interrompt le processus en cours par défaut. Elle sera le plus efficace en définissant une tâche à accomplir pour que l’utilisateur puisse continuer.
  • Les modales doivent être utilisées avec parcimonie afin de limiter les interruptions du parcours utilisateur, facteurs de frustration.
  • Une modale s’affiche de manière permanente — elle peut être fermée en cliquant sur l’icône [X] ou le CTA secondaire d’annulation si il est présent
modal

3) DO/DONT

  • Une modale ne doit pas être utilisée si l’information qu’elle présente est facultative ou secondaire dans le parcours utilisateur.
  • Si l’information est secondaire ou ne nécessite pas d’action immédiate, on utilisera une notification.

4) Anatomie

Une modale est composée d’un header, d’un body et d’un footer.

  • Header: doit contenir le titre de la modale, ferré à gauche, un bouton [x] aligné à droite. Le titre explique succinctement le contexte, qui sera complété par le body.
  • Body: doit contenir un minimum d’information précisant l’action à valider ou l’information à prendre en compte dans le processus.
  • Footer: Doit contenir les boutons, généralement un ou deux (Valider / Annuler).
  • Si un bouton d’aide ou un lien doit être inclus, on le placera dans le body.
modal

5) Utilisation

a) Position

Une modale doit être centré verticalement et horizontalement dans la page.

b) Alignement

Une modale doit être centré verticalement et horizontalement dans la page.

c) Contenu

  • Les titres, et textes sont ferrés à gauche, les boutons CTA respectent leurs règles d’usage.
  • Le bouton [x] est positionné en haut à droite
modal

d) Rédaction

  • Les titres et contenus doivent être le plus clair et concis que possible.
  • Le titre doit rentrer sur une seule ligne préférablement.
  • Les boutons d’actions doivent clairement indiquer l’action opérée.

e) Pictogrammes

Aucun pictogramme ne doit être utilisé dans les textes ou les boutons CTA.

f) Action

La modale peut être fermée de plusieurs façons :

  • En cliquant à l’extérieur de celle-ci.
  • En cliquant sur [x] en haut à droite.
  • En cliquant sur un des boutons CTA.

g) Variations

  • Décision
    • Demande une action pour poursuivre.
  • Saisie
    • Demande une saisie spécifique (Champs de formulaire) pour poursuivre.
  • Passive
    • Donne une information critique, impliquant une action qui ne peut être intégrée.
    • Fortement perturbatrice pour l’utilisateur, cette modale doit être utilisée uniquement dans le cas où l’utilisateur doit opérer une action extérieure immédiatement.

Style

Un style a été défini pour chaque composant, il possible d'importer uniquement le style du composant sur le projet fin optimiser le bundle.

On liste également les codes couleur utilisés, cliquez-ici pour voir l'ensemble des couleurs du Design System

Imports SASS

@import '@axa-fr/react-toolkit-core/src/common/scss/core.scss';
@import '@axa-fr/react-toolkit-modal-default/dist/modal.scss';

Typography

Component text should be set in sentence case, with only the first word in a phrase and any proper nouns capitalized.

Class Font-size (px/rem) Font-weight Font-family
.af-modal 16 / 1 400 Source Sans Pro Regular

Colors

BLEU AXA#00008f$color-axa
BLEU Action#3032c1$color-azur
BLEU Action focus#aaabf9$color-azur-focused
Mercury#e5e5e5$color-mercury
Silver#cccccc $color-silver
Button Disabled#c9c9c9 $color-btn-disabled
Button success #1cc578 $color-btn-success
Button success dark #0d844e $color-btn-success-dark
Button success focuced #bdffe1 $color-btn-success-focused
Button danger #f02849 $color-btn-danger
Button danger dark #8f182c $color-btn-danger-dark
Button danger focuced #ffa0af $color-btn-danger-focused