35 lines
1.5 KiB
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>
|