Confirmation avant de quitter la trace affichée, pour qu’un clic de travers sur « Nouvelle trace » ne fasse pas perdre l’analyse ni les alternatives appliquées.
stableÀ valider
// Titre : Avec deux alternatives appliquées
import { useState } from 'react';
import LeaveConfirm from '@pathou/components/LeaveConfirm';
export default function Exemple() {
const [open, setOpen] = useState(true);
return (
<div style={{ minHeight: 320 }}>
<button type="button" onClick={() => setOpen(true)}>
Nouvelle trace
</button>
{open && <LeaveConfirm lost={2} onStay={() => setOpen(false)} onLeave={() => setOpen(false)} />}
</div>
);
}
Installation
Copie le fichier dans ton projet, ainsi que les tokens qu’il utilise.
import Modal from './Modal';
/**
* Confirmation avant de quitter la trace : un clic de travers sur « Nouvelle trace » ne fait plus perdre l'analyse.
* Le focus est sur « Rester sur la trace » : Entrée, Échap, ✕ et un clic sur le fond laissent la trace affichée.
*/
export default function LeaveConfirm({ lost, onStay, onLeave }: { lost: number; onStay: () => void; onLeave: () => void }) {
return (
<Modal title="Revenir à l’accueil ?" onClose={onStay} small>
{(close) => (
<>
<p className="modal-lead">La trace affichée sera fermée. Pour la revoir, il faudra la charger à nouveau et attendre son analyse.</p>
{lost > 0 && (
<p className="modal-lead">
<strong>{lost === 1 ? 'L’alternative appliquée sera perdue.' : `Les ${lost} alternatives appliquées seront perdues.`}</strong> Reste sur la trace et télécharge le GPX
avant si tu veux {lost === 1 ? 'la' : 'les'} garder.
</p>
)}
<div className="modal-actions">
<button type="button" className="secondary" onClick={onLeave}>
Revenir à l’accueil
</button>
{/* l'attribut natif `autofocus` désigne le bouton à la showModal() : le prop React ne le pose pas */}
<button type="button" className="primary" onClick={close} ref={(el) => el?.setAttribute('autofocus', '')}>
Rester sur la trace
</button>
</div>
</>
)}
</Modal>
);
}
Tokens : --bg --panel --text --muted --accent --accent-ink --chip --ease-out
Utilisation
import LeaveConfirm from './components/LeaveConfirm';
{confirm && <LeaveConfirm lost={applied.length} onStay={() => setConfirm(false)} onLeave={goHome} />}Exemples
Sans alternative appliquée
// Titre : Sans alternative appliquée
import { useState } from 'react';
import LeaveConfirm from '@pathou/components/LeaveConfirm';
export default function Exemple() {
const [open, setOpen] = useState(true);
return (
<div style={{ minHeight: 280 }}>
<button type="button" onClick={() => setOpen(true)}>
Nouvelle trace
</button>
{open && <LeaveConfirm lost={0} onStay={() => setOpen(false)} onLeave={() => setOpen(false)} />}
</div>
);
}
Anatomie
| # | Élément | Rôle |
|---|---|---|
| 1 | Question | Le titre « Revenir à l’accueil ? », dans une petite fenêtre Modal. |
| 2 | Conséquence | Ce qui sera perdu ; la phrase sur les alternatives n’apparaît que si lost est supérieur à zéro. |
| 3 | Partir | Bouton secondaire « Revenir à l’accueil », qui appelle onLeave. |
| 4 | Rester | Bouton principal « Rester sur la trace », qui a le focus à l’ouverture. |
Guidelines
- MUSTFaire de « rester » l’action par défaut : Entrée, Échap, la croix et un clic sur le fond ne doivent jamais faire perdre la trace.
- SHOULDDire précisément ce qui sera perdu (nombre d’alternatives) et comment le garder (télécharger le GPX).
Clavier
| Touche | Effet |
|---|---|
| Entrée | Reste sur la trace (le focus est sur ce bouton à l’ouverture). |
| Échap | Reste sur la trace. |
Référence de l’API
| Prop | Type | Défaut |
|---|---|---|
lost | number | requis |
onStay | () => void | requis |
onLeave | () => void | requis |