Files
RecruIT/resources/js/Components/Rq/RqButton.vue

46 lines
2.2 KiB
Vue

<script setup>
/**
* RqButton.vue — Bouton principal RecruitQuizz
*
* @prop variant 'primary' | 'ghost' | 'danger' | 'outline'
* @prop size 'sm' | 'md' | 'lg'
* @prop disabled Boolean
* @prop loading Boolean — affiche un spinner
* @prop icon SVG path string optionnel (gauche du label)
*/
defineProps({
variant: { type: String, default: 'primary' },
size: { type: String, default: 'md' },
disabled: { type: Boolean, default: false },
loading: { type: Boolean, default: false },
});
</script>
<template>
<button
v-bind="$attrs"
:disabled="disabled || loading"
:class="[
// Base
'inline-flex items-center justify-center gap-1.5 font-sans font-extrabold uppercase tracking-[0.08em] transition-all duration-150 select-none focus:outline-none focus:ring-2 focus:ring-offset-2 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed',
// Size
size === 'sm' && 'text-2xs px-3.5 py-2 rounded-lg',
size === 'md' && 'text-xs px-5 py-2.5 rounded-[10px]',
size === 'lg' && 'text-sm px-7 py-3.5 rounded-[10px]',
// Variant
variant === 'primary' && 'bg-highlight text-highlight-dark shadow-gold hover:brightness-105 hover:-translate-y-px hover:shadow-lg focus:ring-highlight/50',
variant === 'ghost' && 'bg-transparent text-ink border border-ink/10 hover:bg-primary/5 hover:border-primary hover:text-primary focus:ring-primary/30',
variant === 'outline' && 'bg-transparent text-primary border-2 border-primary hover:bg-primary hover:text-white focus:ring-primary/30',
variant === 'danger' && 'bg-accent/10 text-accent border border-accent/20 hover:bg-accent hover:text-white focus:ring-accent/30',
]"
>
<!-- Spinner -->
<svg v-if="loading" class="animate-spin h-4 w-4 opacity-70" viewBox="0 0 24 24" fill="none">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"/>
</svg>
<slot />
</button>
</template>