Untitled
unknown
plain_text
10 months ago
4.9 kB
4
Indexable
<template>
<div
v-if="!displaySmallMode"
class="mb-10 h-[104px] w-full justify-between divide-x divide-slate-300 overflow-hidden rounded-lg border border-gray-300 bg-light-100 dark:divide-slate-800 dark:border-gray-800 dark:bg-dark-100 flex md:h-16 lg:h-[72px]"
>
<button
v-for="(step, index) in steps"
:key="`step-${index}`"
class="flex w-1/3 items-center gap-4 pr-1.5 md:gap-2 lg:gap-4"
:class="{
'bg-light-300 dark:bg-dark-50': step.number === selectedStep,
'dark:bg-emerald-300/10 bg-emerald-300/30':
step.isDone && step.number !== selectedStep && step.number < selectedStep
}"
:disabled="isDisabled(index)"
@click="onStepClick(step.number)"
>
<div class="flex flex-col gap-2 overflow-hidden md:flex-row lg:gap-4 mx-4">
<div
class="flex size-10 flex-none items-center justify-center rounded-full border-2 text-sm leading-4"
:class="{
'dark:border-emerald-600 dark:bg-emerald-600 bg-emerald-300 border-emerald-300':
step.isDone && step.number !== selectedStep && step.number < selectedStep,
'border-rose-500': !!step.error,
'dark:border-gray-700 border-gray-300': !step.isDone && !step.error,
'dark:border-gray-300 border-gray-500': step.isDone && step.number === selectedStep
}"
>
<span v-if="!!step.error" class="text-2xl text-rose-500">!</span>
<mdicon
v-else
:name="
step.isDone && step.number !== selectedStep && step.number < selectedStep
? 'check'
: step.iconName
"
:size="20"
:class="[step.isDone ? 'text-white ' : 'dark:text-white text-gray-500']"
/>
</div>
<div class="flex flex-col items-start text-start">
<span
class="text-xs font-semibold"
:class="{
'text-slate-900 dark:text-slate-200':
(step.isDone && step.number !== selectedStep) ||
(!step.isDone && step.number === selectedStep),
'text-slate-500 dark:text-slate-400': !step.isDone && step.number !== selectedStep,
'text-rose-500 dark:text-rose-400': !!step.error && step.number === selectedStep
}"
>
{{ $t('createPost.step', { count: step.number }) }}
</span>
<span class="line-clamp-1 text-sm text-slate-500 dark:text-slate-400">{{ step.title }}</span>
</div>
</div>
</button>
</div>
<div v-else>
<div class="flex gap-2 text-sm dark:text-slate-300 text-slate-700 w-full mb-1">
{{ $t('createPost.step', { count: selectedStep }) }} / {{ steps.length }}
</div>
<div class="w-full mb-4 bg-slate-300 rounded-full h-2.5 dark:bg-gray-700">
<div class="bg-blue-500 dark:bg-blue-600 h-2.5 rounded-full" :style="progressStyle" />
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, type PropType } from 'vue';
import type { IStepItem } from '@/types/create-post';
export default defineComponent({
name: 'NavigationSteps',
props: {
selectedStep: {
type: Number,
required: true
},
steps: {
type: Array as PropType<IStepItem[]>,
required: true
}
},
emits: ['step-click'],
data() {
return {
windowWidth: window.innerWidth
};
},
computed: {
displaySmallMode() {
return this.windowWidth < 1024;
},
progressStyle() {
return { width: `${(this.selectedStep / this.steps.length) * 100}%` };
}
},
mounted() {
window.addEventListener('resize', this.handleResize);
},
beforeUnmount() {
window.removeEventListener('resize', this.handleResize);
},
methods: {
onStepClick(number: number) {
this.$emit('step-click', number);
},
isDisabled(index: number) {
return index === 0 ? false : !this.steps[index - 1].isDone && !this.steps[index].isDone;
},
handleResize() {
this.windowWidth = window.innerWidth;
}
}
});
</script>
Editor is loading...
Leave a Comment