@amsom-habitat/amsom-modal

Composant modal Vue 3 pour AMSOM Habitat.
15,096
Install
npm install @amsom-habitat/amsom-modal
Latest Version:1.5.0
Vue:3
Last Updated:Oct 13, 2026
Links: npm
Maintainer: amsom-habitat

@amsom-habitat/amsom-modal

Composant modal Vue 3 pour AMSOM Habitat.

Installation

npm install @amsom-habitat/amsom-modal

Utilisation

import { AmsomModal } from '@amsom-habitat/amsom-modal'

Props

Prop Type Défaut Description
close-option Boolean false Affiche la croix de fermeture. Émet @close au clic.
title String '' Titre affiché en haut de la modale.
class-title String selon le mode Classe CSS appliquée au titre. Par défaut 'h4 text-center' sur une modale classique, et 'h4 text-start' en mode bandeau (le titre d'un bandeau s'aligne à gauche). Une valeur explicite est toujours prioritaire.
header-class String '' Classes CSS du conteneur d'en-tête. Active le mode bandeau.
header-style Object {} Styles inline de l'en-tête. Active le mode bandeau.
size String 'md' Taille de la modale : xxs, xs, sm, md, lg, xl.
position String 'center' Position verticale : top, center, bottom.
backdrop Boolean true Affiche un overlay grisé derrière la modale.
internalScroll Boolean true Scroll interne : la modale a une hauteur max de 90vh et son contenu défile à l'intérieur. À false, la modale n'a pas de hauteur max et défile avec la page. Reste actif en plein écran et une fois la modale déplacée (position fixe).
border Boolean automatique Affiche la fine bordure autour de la modale. Non renseignée, la bordure est automatique : présente sur une modale classique, absente en mode bandeau (l'en-tête coloré délimite déjà la fenêtre). true ou false force la valeur, en-tête personnalisé compris.
reducible Boolean false Affiche l'icône - pour réduire la modale en onglet (bas droite).
show-reduced-tab Boolean true Affiche ou masque l'onglet intégré. Mettre à false pour gérer la restauration soi-même.
maximizable Boolean false Affiche l'icône plein écran / restauration.
movable Boolean false Affiche l'icône de déplacement par drag & drop.

Emits

Événement Description
close Émis lors d'un clic sur la croix, d'un clic sur le backdrop, ou de la touche Escape.
minimize Émis quand la modale est réduite en onglet.
restore Émis quand la modale est restaurée depuis l'onglet.
maximize Émis quand la modale passe en plein écran.
unmaximize Émis quand la modale quitte le plein écran.

Slots

Slot Description
default Contenu principal de la modale.
header Compose tout le contenu de l'en-tête. Scope : { title: String, titleClass: String, close: Function } — le titre de la prop title est rendu à l'intérieur du slot, vous le placez et le stylez donc en fonction du reste (ex: une icône de retour à sa gauche). Le conteneur devient une ligne flex et réserve à droite la largeur de la barre d'icônes d'action.
title Remplace le titre par défaut, sans mise en page imposée (conteneur bloc). Rendu dans le conteneur d'en-tête (.amsom-modal-header) : c'est le slot à utiliser pour un titre + un sous-titre empilés. Ignoré si #header est fourni.
#reduced-tab Personnalise le contenu de l'onglet réduit (le positionnement reste géré par le composant). Scope : { restore: Function, close: Function, title: String }.

Exemple complet

<amsom-modal
  v-if="showModal"
  title="Ma modale"
  size="md"
  close-option
  reducible
  maximizable
  movable
  @close="showModal = false"
  @minimize="onMinimize"
>
  Contenu de la modale
</amsom-modal>

En-tête personnalisé (bandeau)

Renseigner header-class et/ou header-style active le mode bandeau :

  • l'en-tête occupe toute la largeur de la modale, jusqu'à ses bords, avec 1rem de padding interne ;
  • ses coins hauts épousent l'arrondi de la modale (et se carrent automatiquement en plein écran) ;
  • l'en-tête reste fixe pendant que le corps de la modale défile — la croix de fermeture reste donc toujours accessible ;
  • les utilitaires de couleur de texte (text-white…) sont hérités par le titre et par les icônes d'action, qui sont des SVG dessinés en currentColor.
<amsom-modal
  v-if="showModal"
  size="sm"
  close-option
  header-class="text-white"
  :header-style="{ background: 'linear-gradient(135deg, #3f4257 0%, #5c6378 100%)' }"
  @close="showModal = false"
>
  <template #title>
    <div class="h4 fw-bold mb-1">Découvrez les nouveautés !</div>
    <div class="small opacity-75">De nouvelles fonctionnalités vous attendent</div>
  </template>

  Contenu de la modale
</amsom-modal>

Réglages courants :

Besoin Comment
Couleur de fond Bootstrap header-class="bg-primary text-white"
Dégradé ou couleur hors palette :header-style="{ background: 'linear-gradient(...)' }"
Hauteur / épaisseur du bandeau header-class="py-4" ou :header-style="{ padding: '2rem' }"
Titre simple (sans sous-titre) props title + class-title="h4 fw-bold mb-0"
Titre + sous-titre slot #title
Titre entouré d'autres éléments (icône de retour, bouton d'aide…) slot #header

À savoir :

  • En mode bandeau, le titre est aligné à gauche par défaut (class-title vaut alors 'h4 text-start'). Pour le centrer : class-title="h4 text-center".
  • La classe Bootstrap .h4 ajoute 0.5rem sous le titre : utilisez mb-0 ou mb-1 pour un bandeau visuellement équilibré.
  • header-style est libre, mais évitez position, transform, filter, backdrop-filter, perspective, contain, will-change, opacity, z-index et isolation : ces propriétés feraient de l'en-tête le bloc conteneur (ou le contexte d'empilement) de la barre d'icônes d'action, qui est positionnée en absolu par rapport à la modale.
  • La barre d'icônes reste ancrée en haut à droite de la modale, pas du bandeau : avec un bandeau très épais, la croix ne sera pas centrée verticalement dedans.
  • L'onglet de modale réduite (bas droite) n'est pas affecté par header-class : c'est un élément d'interface distinct, personnalisable via le slot #reduced-tab.
  • Pour revenir à la géométrie d'origine tout en gardant une couleur de titre : :header-style="{ margin: 0, padding: 0 }".

En-tête composé (slot #header)

Le slot #header prend la main sur tout le contenu de l'en-tête, tout en vous fournissant le titre dans son scope : la prop title est rendue à l'intérieur du slot, accompagnée de ses classes par défaut (titleClass, qui reflète class-title). Vous choisissez donc sa position et son style en fonction du reste de votre contenu.

<amsom-modal
  v-if="showModal"
  :title="currentStepTitle"
  size="sm"
  close-option
  header-class="text-white"
  :header-style="{ background: '#3f4257' }"
  @close="showModal = false"
>
  <template #header="{ title, titleClass, close }">
    <!-- Icône de retour à gauche du titre -->
    <font-awesome-icon
      v-if="step > 1"
      icon="fa-solid fa-arrow-left"
      role="button"
      title="Revenir en arrière"
      @click="step--"
    />
    <div :class="titleClass" class="flex-grow-1 text-truncate mb-0">{{ title }}</div>
    <button class="btn btn-sm btn-light" @click="close">Annuler</button>
  </template>

  Contenu de la modale
</amsom-modal>

Scope du slot :

Clé Type Description
title String La prop title, à rendre où vous le souhaitez.
titleClass String Les classes du titre (class-title, ou la valeur par défaut du mode). À appliquer telle quelle pour garder le rendu standard, ou à ignorer pour un style totalement libre.
close Function Émet @close : pratique pour un bouton de fermeture placé dans l'en-tête.

À savoir :

  • Le conteneur du slot est une ligne flex (align-items: center, gouttière de 0.5rem) : icônes et titre s'alignent verticalement sans effort. Ajoutez flex-grow-1 text-truncate sur le titre pour qu'il occupe la place restante et se tronque proprement.
  • La largeur de la barre d'icônes d'action (fermer / réduire / agrandir / déplacer) est réservée automatiquement à droite du slot, en fonction du nombre d'icônes réellement affichées : votre contenu ne passe jamais dessous. Cette réserve est inutile — et donc absente — avec move-handle: 'zone', la barre d'actions étant alors dans la zone de déplacement, au-dessus de l'en-tête.
  • Les icônes Font Awesome utilisées dans le slot doivent être enregistrées dans la librairie Font Awesome de votre projet.
  • #header est prioritaire sur #title et sur le titre par défaut. Sans #header, le rendu reste strictement identique aux versions précédentes.

Onglet réduit personnalisé

<amsom-modal v-if="showModal" title="Ma modale" reducible close-option @close="showModal = false">
  <template #reduced-tab="{ restore, close, title }">
    <span @click="restore">{{ title }}</span>
    <button @click="restore">Restaurer</button>
    <button @click="close">×</button>
  </template>
</amsom-modal>

Contrôle externe de la restauration (show-reduced-tab: false)

<!-- Bouton placé librement dans votre layout -->
<button v-if="isMinimized" @click="$refs.modal.toggleReduced()">Restaurer la modale</button>

<amsom-modal
  ref="modal"
  v-if="showModal"
  title="Ma modale"
  reducible
  :show-reduced-tab="false"
  @minimize="isMinimized = true"
  @restore="isMinimized = false"
  @close="showModal = false"
>
  Contenu
</amsom-modal>

Project Setup

npm install

Compile and Hot-Reload for Development

npm run dev

Compile and Minify for Production

npm run build

Run Headed Component Tests with Cypress Component Testing

npm run test:unit:dev # or `npm run test:unit` for headless testing

Run End-to-End Tests with Cypress

npm run test:e2e:dev

This runs the end-to-end tests against the Vite development server. It is much faster than the production build.

But it's still recommended to test the production build with test:e2e before deploying (e.g. in CI environments):

npm run build
npm run test:e2e

Lint with ESLint

npm run lint

Version History

Version Released Vue License
1.5.0 ^3.5.42
1.4.0 ^3.5.42
1.3.1 ^3.5.0
1.2.0 ^3.5.0
1.1.1 ^3.5.0