Files
web-temp/layers/components/atoms/Button/index.vue

90 lines
1.9 KiB
Vue

<script setup lang="ts">
import type { ButtonType } from '#layers/types/components/button'
interface ButtonProps {
type?: ButtonType
icon?: string
target?: '_self' | '_blank'
href?: string
rel?: string
backgroundColor?: string
backgroundImage?: string
textColor?: string
disabled?: boolean
class?: string
}
const props = withDefaults(defineProps<ButtonProps>(), {
type: 'action',
backgroundColor: 'var(--primary)',
textColor: 'var(--alternative-02)',
disabled: false,
})
const buttonClasses = computed(() =>
['btn-base group', props.class].filter(Boolean)
)
const buttonStyles = computed(() => {
const styles: Record<string, string> = {
backgroundColor: props.backgroundColor,
color: props.textColor,
'--text-color': props.textColor,
}
if (props.backgroundImage) {
styles.backgroundImage = `url(${props.backgroundImage})`
styles.backgroundSize = 'contain'
styles.backgroundPosition = 'center'
styles.backgroundRepeat = 'no-repeat'
}
return styles
})
const componentTag = computed((): string => {
switch (props.type) {
case 'download':
case 'external':
return 'a'
case 'internal':
return 'AtomsLocaleLink'
default:
return 'button'
}
})
const componentProps = computed(() => {
const baseProps = { disabled: props.disabled }
if (props.type === 'external') {
return {
...baseProps,
href: props.href,
target: props.target,
rel: props.rel,
}
}
if (props.type === 'internal') {
return {
...baseProps,
to: props.href,
}
}
return baseProps
})
</script>
<template>
<component
:is="componentTag"
v-bind="componentProps"
:class="buttonClasses"
:style="buttonStyles"
>
<span class="relative flex items-center gap-2 z-[1]">
<slot />
<span v-if="props.icon" class="flex-shrink-0" v-html="props.icon" />
</span>
</component>
</template>