opnform/resources/js/components/common/Button.vue

116 lines
2.9 KiB
Vue

<template>
<button v-if="!to" :type="nativeType" :disabled="loading" :class="btnClasses"
@click="$emit('click',$event)"
>
<template v-if="!loading">
<span class="no-underline">
<slot/>
</span>
<svg v-if="arrow" class="ml-2 w-3 h-3 inline" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 11L11 1M11 1H1M11 1V11" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"/>
</svg>
</template>
<loader v-else class="h-6 w-6 mx-auto" :class="`text-${colorShades['text']}`"/>
</button>
<router-link v-else :class="btnClasses" :to="to" :target="target"
>
<span class="no-underline">
<slot/>
</span>
<svg v-if="arrow" class="ml-2 w-3 h-3 inline" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 11L11 1M11 1H1M11 1V11" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"/>
</svg>
</router-link>
</template>
<script>
export default {
name: 'VButton',
props: {
color: {
type: String,
default: 'blue'
},
size: {
type: String,
default: 'medium'
},
nativeType: {
type: String,
default: null
},
loading: {
type: Boolean,
default: false
},
arrow: {
type: Boolean,
default: false
},
to: {
type: Object,
default: null
},
target: {
type: String,
default: '_self'
},
},
computed: {
btnClasses() {
const sizes = this.sizes
const colorShades = this.colorShades
return `${sizes['p-y']} ${sizes['p-x']}
${colorShades['main']} ${colorShades['hover']} ${colorShades['ring']} ${colorShades['ring-offset']}
${colorShades['text']} transition ease-in duration-200 text-center text-${sizes['font']} font-medium focus:outline-none focus:ring-2
focus:ring-offset-2 rounded-lg flex items-center hover:no-underline`
},
colorShades() {
if (this.color === 'blue') {
return {
main: 'bg-blue-600',
hover: 'hover:bg-blue-700',
ring: 'focus:ring-blue-500',
'ring-offset': 'focus:ring-offset-blue-200',
text: 'text-white',
}
} else if (this.color === 'outline-blue') {
return {
main: 'bg-transparent border-2 border-blue-600',
hover: 'hover:bg-blue-600',
ring: 'focus:ring-blue-500',
'ring-offset': 'focus:ring-offset-blue-200',
text: 'text-blue-600 hover:text-white',
}
}
console.error('Unknown color')
},
sizes() {
if (this.size === 'small') {
return {
font: 'sm',
'p-y': 'py-1',
'p-x': 'px-2'
}
}
return {
font: 'base',
'p-y': 'py-2',
'p-x': 'px-4'
}
}
}
}
</script>