42 lines
1.2 KiB
Vue
42 lines
1.2 KiB
Vue
|
|
<template>
|
||
|
|
<button
|
||
|
|
:type="type"
|
||
|
|
:disabled="disabled"
|
||
|
|
:class="buttonClass"
|
||
|
|
@click="$emit('click', $event)"
|
||
|
|
>
|
||
|
|
<slot />
|
||
|
|
</button>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
interface Props {
|
||
|
|
type?: 'button' | 'submit' | 'reset'
|
||
|
|
variant?: 'primary' | 'secondary' | 'outline'
|
||
|
|
disabled?: boolean
|
||
|
|
}
|
||
|
|
|
||
|
|
const props = withDefaults(defineProps<Props>(), {
|
||
|
|
type: 'button',
|
||
|
|
variant: 'primary',
|
||
|
|
disabled: false
|
||
|
|
})
|
||
|
|
|
||
|
|
defineEmits<{
|
||
|
|
click: [event: MouseEvent]
|
||
|
|
}>()
|
||
|
|
|
||
|
|
const buttonClass = computed(() => {
|
||
|
|
const base = 'px-6 py-3 rounded-xl font-medium transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 active:scale-95'
|
||
|
|
|
||
|
|
const variants = {
|
||
|
|
primary: 'bg-blue-500 text-white hover:bg-blue-600 focus:ring-blue-400 shadow-lg shadow-blue-500/30 disabled:bg-gray-300 disabled:shadow-none disabled:cursor-not-allowed',
|
||
|
|
secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300 focus:ring-gray-400 disabled:bg-gray-100 disabled:cursor-not-allowed',
|
||
|
|
outline: 'border-2 border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-gray-400 disabled:border-gray-200 disabled:text-gray-400 disabled:cursor-not-allowed'
|
||
|
|
}
|
||
|
|
|
||
|
|
return `${base} ${variants[props.variant]}`
|
||
|
|
})
|
||
|
|
</script>
|
||
|
|
|