Untitled
<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>
Leave a Comment