90 lines
1.9 KiB
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>
|