65 lines
2.1 KiB
JavaScript
65 lines
2.1 KiB
JavaScript
/**
|
|
* copy-email.js — Copie de l'adresse e-mail dans le presse-papiers
|
|
* =============================================================================
|
|
* Détail d'ergonomie qui compte sur un site de contact : tout le monde
|
|
* n'a pas de client mail configuré, et un lien mailto: qui ouvre un
|
|
* logiciel inattendu est une impasse. Le bouton de copie offre la voie
|
|
* alternative sans supprimer le lien mailto.
|
|
*
|
|
* Le retour à l'utilisateur passe par deux canaux :
|
|
* - visuel : le libellé du bouton change temporairement
|
|
* - vocal : une région aria-live annonce la copie aux lecteurs d'écran
|
|
*
|
|
* L'API Clipboard exige un contexte sécurisé (HTTPS ou localhost). En cas
|
|
* d'échec, on ne laisse pas l'utilisateur sans réponse : on lui indique
|
|
* de copier manuellement.
|
|
*/
|
|
|
|
/** Durée d'affichage du message de confirmation, en millisecondes. */
|
|
const FEEDBACK_DURATION = 2200;
|
|
|
|
/**
|
|
* Initialise le bouton de copie.
|
|
*
|
|
* @param {object} options
|
|
* @param {HTMLElement} options.button - Bouton portant data-copy="<valeur>".
|
|
* @param {HTMLElement} options.status - Région aria-live pour l'annonce.
|
|
* @returns {void}
|
|
*/
|
|
export function initCopyEmail({ button, status }) {
|
|
if (!button) return;
|
|
|
|
const value = button.dataset.copy;
|
|
if (!value) return;
|
|
|
|
const label = button.querySelector("[data-copy-label]");
|
|
const originalLabel = label?.textContent ?? "";
|
|
let resetTimer;
|
|
|
|
/**
|
|
* Affiche un retour temporaire, visuel et vocal.
|
|
* @param {string} message
|
|
* @returns {void}
|
|
*/
|
|
const announce = (message) => {
|
|
if (label) label.textContent = message;
|
|
if (status) status.textContent = message;
|
|
|
|
clearTimeout(resetTimer);
|
|
resetTimer = setTimeout(() => {
|
|
if (label) label.textContent = originalLabel;
|
|
if (status) status.textContent = "";
|
|
}, FEEDBACK_DURATION);
|
|
};
|
|
|
|
button.addEventListener("click", async () => {
|
|
try {
|
|
await navigator.clipboard.writeText(value);
|
|
announce("Adresse copiée");
|
|
} catch {
|
|
// Contexte non sécurisé, permission refusée ou API absente.
|
|
announce("Copie impossible");
|
|
}
|
|
});
|
|
}
|