All checks were successful
Deploy site (production) / build-and-deploy (push) Successful in 15s
- .htaccess : désactive Google PageSpeed (mod_pagespeed/ngx_pagespeed) qui renvoyait un corps HTML vide sur le vhost Plesk (home en 200 mais 0 octet → page blanche), alors que les assets Vite passaient. Backstop versionné du fix côté serveur. - CopyButton réutilisable (variantes bar/icon, retour ✓ 1,8 s, bilingue, accessible) : ajoute « copier » sur la commande de How-it-works, l'URL localhost et la commande du footer. - URL du dépôt Gitea : johanleroy/git-arboretum → johanleroy/arboretum (centralisée dans lib/links.ts). Le paquet npm @johanleroy/git-arboretum reste inchangé (c'est son nom). - Port affiché corrigé : localhost:7777 → 7317 (port réel du daemon, cf. config.ts).
58 lines
2.2 KiB
Vue
58 lines
2.2 KiB
Vue
<script setup lang="ts">
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useCopy } from '../composables/useCopy';
|
|
import IconCopy from './icons/IconCopy.vue';
|
|
import IconCheck from './icons/IconCheck.vue';
|
|
|
|
// Bouton « copier » réutilisable, avec retour visuel (icône ✓ + label) pendant 1800 ms.
|
|
// Deux variantes :
|
|
// - 'bar' : bouton étiqueté intégré aux barres de commande (hero, CTA final).
|
|
// - 'icon' : bouton compact icône seule, pour les blocs de code (étapes, footer).
|
|
withDefaults(
|
|
defineProps<{
|
|
text: string;
|
|
variant?: 'bar' | 'icon';
|
|
label?: string; // aria-label décrivant ce qui est copié
|
|
barClass?: string; // padding/ajustements de la variante 'bar'
|
|
}>(),
|
|
{ variant: 'bar', label: '', barClass: 'px-[15px]' },
|
|
);
|
|
|
|
const { t } = useI18n();
|
|
const { copied, copy } = useCopy();
|
|
</script>
|
|
|
|
<template>
|
|
<button
|
|
v-if="variant === 'bar'"
|
|
type="button"
|
|
:aria-label="label || t('copy')"
|
|
:class="[
|
|
'inline-flex flex-none items-center gap-[7px] border-l border-zinc-800 bg-zinc-900 font-mono text-[13px] font-semibold transition-colors hover:bg-zinc-800 hover:text-emerald-400 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-emerald-500/70',
|
|
barClass,
|
|
copied ? 'text-emerald-400' : 'text-zinc-300',
|
|
]"
|
|
@click="copy(text)"
|
|
>
|
|
<component :is="copied ? IconCheck : IconCopy" :size="15" />
|
|
<span aria-live="polite">{{ copied ? t('copied') : t('copy') }}</span>
|
|
</button>
|
|
|
|
<button
|
|
v-else
|
|
type="button"
|
|
:aria-label="label || t('copy')"
|
|
:title="copied ? t('copied') : label || t('copy')"
|
|
:class="[
|
|
'inline-flex flex-none items-center justify-center rounded-md border p-1.5 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-emerald-500/70',
|
|
copied
|
|
? 'border-emerald-500/40 bg-zinc-800 text-emerald-400'
|
|
: 'border-zinc-800 bg-zinc-900/80 text-zinc-400 hover:border-emerald-500/40 hover:bg-zinc-800 hover:text-emerald-400',
|
|
]"
|
|
@click="copy(text)"
|
|
>
|
|
<component :is="copied ? IconCheck : IconCopy" :size="14" />
|
|
<span aria-live="polite" class="sr-only">{{ copied ? t('copied') : t('copy') }}</span>
|
|
</button>
|
|
</template>
|