idconvert/frontend/app/components/common/BaseButton.vue

35 lines
1.5 KiB
Vue

<script setup>
defineProps({
variant: { type: String, default: 'primary' }, // primary | ghost | success | danger
size: { type: String, default: 'md' }, // sm | md | lg
loading: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
fullWidth: { type: Boolean, default: false },
type: { type: String, default: 'button' },
})
</script>
<template>
<button
:type="type"
:disabled="disabled || loading"
:class="[
'inline-flex items-center justify-center gap-2 font-medium transition-colors rounded-md cursor-pointer border',
fullWidth && 'w-full',
size === 'sm' && 'px-4 py-1.5 text-xs',
size === 'md' && 'px-5 py-2 text-sm',
size === 'lg' && 'px-8 py-3 text-base',
variant === 'primary' && 'bg-[#1a56db] text-white border-[#1a56db] hover:bg-[#1648c0] disabled:opacity-50 disabled:cursor-not-allowed',
variant === 'ghost' && 'bg-transparent text-gray-600 border-gray-200 hover:bg-gray-100 disabled:opacity-50',
variant === 'success' && 'bg-green-500 text-white border-green-500 hover:bg-green-600 disabled:opacity-50',
variant === 'danger' && 'bg-red-500 text-white border-red-500 hover:bg-red-600 disabled:opacity-50',
]"
>
<svg v-if="loading" class="animate-spin h-4 w-4 flex-shrink-0" 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-8v8H4z" />
</svg>
<slot />
</button>
</template>