first commit

This commit is contained in:
sajjadtalkhabi
2026-05-13 01:43:05 +03:30
commit d2a577f254
297 changed files with 36274 additions and 0 deletions
+125
View File
@@ -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>