Site personnel courcellematthi.eu
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* 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");
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user