first commit
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<RouterLink v-if="to" :to="to" :class="rootClass">
|
||||
<slot name="prependIcon" />
|
||||
<span :class="['base-button__text', textClass]">{{ text }}</span>
|
||||
<slot name="appendIcon" />
|
||||
</RouterLink>
|
||||
<button
|
||||
v-else
|
||||
:class="rootClass"
|
||||
:type="type"
|
||||
:disabled="disabled || loading"
|
||||
@click="handleClick"
|
||||
>
|
||||
<template v-if="loading">
|
||||
<SvgIcon
|
||||
name="spinner"
|
||||
:size="24"
|
||||
:color="spinnerFill"
|
||||
class="base-button__spinner animate-spin"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<slot name="prependIcon" />
|
||||
<span :class="['base-button__text', textClass]">{{ text }}</span>
|
||||
<slot name="appendIcon" />
|
||||
</template>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { RouterLink } from 'vue-router'
|
||||
|
||||
import SvgIcon from '@/components/icons/SvgIcon.vue'
|
||||
|
||||
const props = defineProps({
|
||||
to: { type: [String, Object], default: null },
|
||||
type: { type: String, default: 'button' },
|
||||
variant: { type: String, default: 'primary' },
|
||||
text: { type: String, default: 'تایید' },
|
||||
textClass: { type: String, default: '' },
|
||||
customClass: { type: String, default: 'base-button--full' },
|
||||
disabled: { type: Boolean, default: false },
|
||||
loading: { type: Boolean, default: false },
|
||||
})
|
||||
|
||||
const emit = defineEmits(['click'])
|
||||
|
||||
const rootClass = computed(() => [
|
||||
'base-button',
|
||||
`base-button--${props.variant}`,
|
||||
props.customClass,
|
||||
{ 'base-button--disabled': props.disabled, 'base-button--loading': props.loading },
|
||||
])
|
||||
|
||||
const spinnerFill = computed(() => (props.variant === 'primary' ? '#fff' : '#2B2B2B'))
|
||||
|
||||
const handleClick = (event) => {
|
||||
if (props.type !== 'submit' && (props.disabled || props.loading)) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
return
|
||||
}
|
||||
if (props.type === 'submit') return
|
||||
emit('click', event)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.base-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 2.35rem;
|
||||
border: none;
|
||||
border-radius: 9999px;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s ease, background-color 0.2s ease;
|
||||
font-family: var(--font-family-fa);
|
||||
text-decoration: none;
|
||||
padding: 0 1rem;
|
||||
|
||||
&__text {
|
||||
line-height: 1.25rem;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
&__spinner {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
&--full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&--primary {
|
||||
background-color: var(--color-primary);
|
||||
color: #fff;
|
||||
|
||||
&:hover:not(.base-button--disabled, .base-button--loading) {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
&--secondary {
|
||||
background-color: var(--color-thd-gray);
|
||||
color: var(--color-sec-gray);
|
||||
|
||||
&:hover:not(.base-button--disabled, .base-button--loading) {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
&--transparent {
|
||||
background-color: transparent;
|
||||
color: var(--color-sec-gray);
|
||||
}
|
||||
|
||||
&--disabled,
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user