Modale
Sur cette page
Une modale est un élément popover. N’importe quel bouton dont le popovertarget correspond à l’id de la modale l’ouvre — sans le moindre script, y compris pour le fond, la fermeture au clic extérieur, Échap et la gestion du focus, dont le navigateur se charge.
C’est pourquoi l’id est obligatoire et que le composant lève une erreur sans lui : l’id est tout le câblage.
Modale de base
Chaque modale de cette page s’ouvre vraiment — essayez.
Reconstruire le site ?
fragment(
button({ popovertarget: 'demo-basic' }, 'Ouvrir la modale'),
modal({ id: 'demo-basic', title: 'Reconstruire le site ?' },
'Cela lance sitelo build et republie dist/.',
),
)Avec un pied
Un bouton de fermeture est n’importe quel bouton pointant vers le même id avec popovertargetaction="hide".
Supprimer cette page ?
fragment(
button({ color: 'danger', popovertarget: 'demo-confirm' }, 'Supprimer la page…'),
modal({
id: 'demo-confirm',
title: 'Supprimer cette page ?',
footer: stack({ direction: 'row', gap: 'sm' },
button({
variant: 'ghost',
color: 'neutral',
popovertarget: 'demo-confirm',
popovertargetaction: 'hide',
}, 'Annuler'),
button({ color: 'danger' }, 'Supprimer'),
),
}, 'C’est irréversible. Le HTML généré disparaît au prochain build.'),
)Tailles
Petite
Moyenne
Grande
fragment(
stack({ direction: 'row', gap: 'sm', wrap: true },
button({ variant: 'outline', color: 'neutral', popovertarget: 'demo-sm' }, 'Petite'),
button({ variant: 'outline', color: 'neutral', popovertarget: 'demo-md' }, 'Moyenne'),
button({ variant: 'outline', color: 'neutral', popovertarget: 'demo-lg' }, 'Grande'),
),
modal({ id: 'demo-sm', size: 'sm', title: 'Petite' }, 'size: sm — environ 24rem.'),
modal({ id: 'demo-md', title: 'Moyenne' }, 'Le défaut — environ 32rem.'),
modal({ id: 'demo-lg', size: 'lg', title: 'Grande' }, 'size: lg — environ 48rem.'),
)Des formulaires dans une modale
Nouvelle page
fragment(
button({ variant: 'soft', popovertarget: 'demo-form' }, 'Nouvelle page…'),
modal({
id: 'demo-form',
title: 'Nouvelle page',
footer: stack({ direction: 'row', gap: 'sm' },
button({ variant: 'ghost', color: 'neutral', popovertarget: 'demo-form', popovertargetaction: 'hide' }, 'Annuler'),
button({ type: 'submit' }, 'Créer'),
),
},
stack({ gap: 'md' },
textField({ label: 'Titre', name: 'modal-title', placeholder: 'À propos' }),
selectField({ label: 'Extension', name: 'modal-ext', options: ['.ht.js', '.ht.ts', '.ht.jsx'] }),
),
),
)Sans bouton de fermeture
closable: false retire le × du coin. Échap et le clic à l’extérieur la ferment toujours — un popover ne peut pas être rendu vraiment bloquant, et c’est de toute façon le bon comportement la plupart du temps.
Appuyez sur Échap
fragment(
button({ variant: 'outline', color: 'neutral', popovertarget: 'demo-bare' }, 'Sans bouton de fermeture'),
modal({ id: 'demo-bare', title: 'Appuyez sur Échap', closable: false },
'Ou cliquez n’importe où en dehors de ce dialogue.',
),
)Contenu long
Le corps défile ; l’en-tête et le pied restent en place.
Notes de version
Changement 1 — quelque chose a été corrigé.
Changement 2 — quelque chose a été corrigé.
Changement 3 — quelque chose a été corrigé.
Changement 4 — quelque chose a été corrigé.
Changement 5 — quelque chose a été corrigé.
Changement 6 — quelque chose a été corrigé.
Changement 7 — quelque chose a été corrigé.
Changement 8 — quelque chose a été corrigé.
Changement 9 — quelque chose a été corrigé.
Changement 10 — quelque chose a été corrigé.
Changement 11 — quelque chose a été corrigé.
Changement 12 — quelque chose a été corrigé.
fragment(
button({ variant: 'outline', color: 'neutral', popovertarget: 'demo-long' }, 'Modale longue'),
modal({
id: 'demo-long',
title: 'Notes de version',
footer: button({ popovertarget: 'demo-long', popovertargetaction: 'hide' }, 'Fermer'),
},
stack({ gap: 'md' },
...Array.from({ length: 12 }, (unused, index) =>
text({ variant: 'small', tone: 'muted' }, 'Changement ' + (index + 1) + ' — quelque chose a été corrigé.'),
),
),
),
)Défilement de l’arrière-plan
La page derrière une modale ouverte ne défile pas. C’est la seule chose que l’API popover vous laisse, et elle est faite en CSS ici — aucun script, rien à initialiser. Passez lockScroll: false pour laisser l’arrière-plan défiler comme d’habitude.
Prise en charge des navigateurs
L’API popover est disponible dans tous les navigateurs actuels. Dans un navigateur trop ancien pour la connaître, la modale se rend en ligne dans la page au lieu de par-dessus : visible et utilisable, simplement pas superposée. Rien ne disparaît.
Props
| Prop | Type | Défaut | Description |
|---|---|---|---|
id | string | — | Obligatoire. Ce que vise le popovertarget d’un déclencheur. |
title | Child | — | Titre, et nom accessible du dialogue. |
size | 'sm' | 'md' | 'lg' | 'md' | Largeur maximale. |
footer | Child | — | Rangée du bas, sur sa propre bande teintée. |
closable | boolean | true | Afficher le × dans l’en-tête. |
closeLabel | string | 'Close' | Nom accessible de ce bouton. |
lockScroll | boolean | true | Empêcher la page derrière de défiler tant qu’elle est ouverte. |
closeButton({ target }) rend ce × tout seul, pour un en-tête que vous construisez vous-même.