190 lines
4.7 KiB
Vue
190 lines
4.7 KiB
Vue
<template>
|
|
<Transition>
|
|
<nav v-if="visible" class="mega-menu" @click.self="visible = false">
|
|
<TransitionGroup name="list" tag="section">
|
|
<template v-for="(list, i) in menu" :key="i">
|
|
<ul v-if="list?.length">
|
|
<li v-for="(item, j) in list" :key="j" @mouseover="open(item, i)">
|
|
<router-link :to="{ path: '/search', query: { category: item.link } }">
|
|
<Button v-bind="getProps(item, i)" />
|
|
</router-link>
|
|
</li>
|
|
</ul>
|
|
</template>
|
|
</TransitionGroup>
|
|
</nav>
|
|
</Transition>
|
|
</template>
|
|
|
|
<script setup>
|
|
const visible = defineModel()
|
|
const store = useCategoriesStore()
|
|
const menu = reactive([])
|
|
|
|
const getProps = (item, i) => {
|
|
const temp = { label: item.name, link: true }
|
|
if (i === 0) {
|
|
temp.iconPos = 'right'
|
|
temp.icon = 'isax ' + item.icon
|
|
// temp.disabled = menu[1] == item.sub
|
|
} else if (i === 1 && item.sub?.length > 0) {
|
|
temp.icon = 'isax isax-arrow-left-2'
|
|
// temp.disabled = menu[2] == item.sub
|
|
}
|
|
return temp
|
|
}
|
|
|
|
const open = (item, i) => {
|
|
if (i < 2) {
|
|
delete menu[i + 2]
|
|
menu[i + 1] = item.sub
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
let cat = store.items
|
|
while (true) {
|
|
menu.push(cat)
|
|
if (cat[0]?.sub) cat = cat[0].sub
|
|
else break
|
|
}
|
|
})
|
|
const route = useRoute()
|
|
watch(() => route.query, () => visible.value = false)
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.mega-menu {
|
|
@apply fixed inset-x-0 z-[1] bottom-0 top-24 bg-black/40;
|
|
|
|
&>section {
|
|
@apply flex h-[32.4rem] w-full bg-white shadow-inner;
|
|
|
|
ul:nth-of-type(1) {
|
|
@apply flex flex-col gap-2 py-3 px-4 w-[16.5rem] h-[26.8rem] z-[10];
|
|
|
|
li {
|
|
button {
|
|
@apply w-full h-12 justify-end;
|
|
|
|
.p-button-label {
|
|
@apply text-[#292D32] text-lg font-medium font-vazir grow-0;
|
|
}
|
|
|
|
.p-button-icon {
|
|
@apply text-[#292D32] text-2xl ml-4;
|
|
}
|
|
|
|
&:hover * {
|
|
@apply text-primary-600;
|
|
}
|
|
|
|
&:disabled {
|
|
@apply opacity-100;
|
|
|
|
* {
|
|
@apply text-primary-600;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ul:nth-of-type(2) {
|
|
@apply border-x-2 border-[#E5E5E5] w-[16.5rem] h-[32.4rem] flex flex-col;
|
|
|
|
li {
|
|
@apply border-b border-[#E5E5E5];
|
|
|
|
button {
|
|
@apply w-full h-[3.7rem] justify-between px-2.5;
|
|
|
|
.p-button-label {
|
|
@apply text-[#292D32] text-lg font-vazir grow-0 ml-auto;
|
|
}
|
|
|
|
.p-button-icon {
|
|
@apply text-[#292D32] text-sm transition-transform;
|
|
}
|
|
|
|
&:hover * {
|
|
@apply text-primary-600;
|
|
}
|
|
|
|
&:disabled {
|
|
@apply opacity-100 bg-[#FAFAFA];
|
|
|
|
.p-button-label {
|
|
@apply text-[#333333] font-medium;
|
|
}
|
|
|
|
.p-button-icon {
|
|
@apply text-[#333333] -rotate-90;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ul:nth-of-type(3) {
|
|
@apply flex flex-col;
|
|
|
|
li {
|
|
@apply px-4;
|
|
|
|
button {
|
|
@apply w-full h-[3.8rem] justify-end;
|
|
|
|
.p-button-label {
|
|
@apply text-[#333333] text-lg font-normal font-vazir grow-0;
|
|
}
|
|
|
|
&:hover * {
|
|
@apply text-primary-600;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.list-enter-active,
|
|
.list-leave-active {
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.list-enter-from,
|
|
.list-leave-to {
|
|
opacity: 0;
|
|
transform: translateX(30px);
|
|
}
|
|
|
|
.menu-enter-active,
|
|
.menu-leave-active {
|
|
transition: all 0.3s ease;
|
|
|
|
div {
|
|
transition: all 0.3s ease;
|
|
}
|
|
}
|
|
|
|
.menu-enter-from,
|
|
.menu-leave-to {
|
|
opacity: 0;
|
|
|
|
div {
|
|
transform: translateX(30px);
|
|
}
|
|
}
|
|
}
|
|
|
|
.v-enter-active,
|
|
.v-leave-active {
|
|
transition: opacity 0.1s ease;
|
|
}
|
|
|
|
.v-enter-from,
|
|
.v-leave-to {
|
|
opacity: 0;
|
|
}
|
|
</style>
|