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

105 lines
2.4 KiB
Vue

<script setup lang="ts">
import type { ButtonType } from '#layers/types/components/button'
interface props {
type?: ButtonType
buttonSize?: string
target?: '_self' | '_blank'
href?: string
rel?: string
backgroundColor?: string
textColor?: string
disabled?: boolean
}
const props = withDefaults(defineProps<props>(), {
type: 'action',
buttonSize: 'size-small md:size-large',
backgroundColor: 'var(--primary)',
textColor: 'var(--alternative-02)',
disabled: false,
})
const componentTag = computed((): string => {
switch (props.type) {
case 'link':
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="['btn-base', props.buttonSize]"
:style="{
backgroundColor: props.backgroundColor,
color: props.textColor,
}"
>
<span class="btn-content">
<slot />
<AtomsIconsLongArrowRightLine
v-if="props.type === 'internal'"
class="icon"
/>
<AtomsIconsWebLinkLine
v-if="props.type === 'external'"
color="#ebebeb"
class="icon"
/>
<AtomsIconsDownloadLine v-if="props.type === 'download'" class="icon" />
</span>
</component>
</template>
<style scoped>
.btn-base {
@apply overflow-hidden relative inline-flex items-center justify-center font-medium cursor-pointer
before:content-[''] before:absolute before:top-0 before:left-0 before:w-full before:h-full before:border before:border-white/10
after:content-[''] after:absolute after:top-0 after:left-0 after:w-full after:h-full after:bg-white after:transition-opacity after:duration-300 after:ease-in-out after:opacity-0;
}
.btn-base:hover {
@apply after:opacity-20;
}
.btn-base:disabled {
@apply cursor-default
after:bg-[var(--text-color)] after:opacity-20 after:z-[2];
}
.btn-base .btn-content {
@apply relative flex items-center gap-1 z-[1];
}
.btn-base.size-extra-small .btn-content {
@apply gap-0.5;
}
</style>