MIF_E31221407_FE/layouts/main-copy.vue

116 lines
4.6 KiB
Vue

<template>
<div class="w-full h-full min-h-screen">
<header class="fixed top-0 left-0 right-0 flex gap-2 shadow-md bg-white" ref="header" :class="[
isLowerThanMd ? 'z-10' : 'z-20'
]">
<NuxtUiButton icon="i-heroicons-bars-3-16-solid" class="aspect-[1/1] w-11 justify-center" variant="ghost"
color="white" @click="() => asideToggle()" />
<NuxtImg src="/assets/icons/logo-text.png" width="auto" height="44" format="webp" />
</header>
<div>
<div class="fixed z-10 top-0 left-0 right-0 bottom-0 isolate" :class="[
isLowerThanMd ? 'z-20' : 'z-10'
]" v-show="!isLowerThanMd || (asideState === 'shown' || asideState === 'before-shown')">
<div class="bg-black/30 absolute top-0 left-0 right-0 bottom-0 z-[1]"
v-if="isLowerThanMd && (asideState === 'shown' || asideState === 'before-shown')"
@click="() => asideToggle()"></div>
<aside
class="flex-shrink-0 w-full h-full overflow-y-auto overflow-x-hidden z-[2] relative bg-gray-200 bottom-0 flex flex-col"
ref="aside" :class="[
asideTailwindClass
]">
<header class="flex gap-2 sticky top-0 bg-white shadow-md">
<NuxtUiButton icon="i-heroicons-bars-3-16-solid" class="aspect-[1/1] w-11 justify-center"
variant="ghost" color="white" @click="() => asideToggle()" />
<NuxtImg src="/assets/icons/logo-text.png" width="auto" height="44" format="webp" />
</header>
<div class="w-full">
<div class="p-3 flex flex-col ">
<NuxtLink class="flex items-center gap-2">
<NuxtUiIcon name="i-heroicons-home-20-solid" class="flex-shrink-0 w-6 h-6" />
<span>Home</span>
</NuxtLink>
<NuxtLink>
<NuxtUiIcon name="i-heroicons-home-20-solid" />
<span>Stock</span>
</NuxtLink>
<NuxtLink>
<NuxtUiIcon name="i-heroicons-home-20-solid" />
<span>Inventory</span>
</NuxtLink>
</div>
</div>
</aside>
</div>
<main :style="mainContentSafePadding">
<div>
</div>
</main>
</div>
</div>
</template>
<script lang="ts" setup>
import { useElementSize, useWindowSize } from '@vueuse/core'
const windowSize = useWindowSize()
const header = ref<HTMLElement>()
const { height: headerHeight } = useElementSize(header)
const aside = ref<HTMLElement>()
const { width: asideWidth } = useElementSize(aside)
type TAsideState = 'before-shown' | 'shown' | 'hidden'
const asideState = ref<TAsideState>('hidden')
watch(asideState, newVal => {
if (newVal === 'before-shown') {
setTimeout(() => {
asideState.value = 'shown'
}, 50);
}
})
const isLowerThanMd = computed(() => windowSize.width.value < 768)
watch(isLowerThanMd, newVal => {
if (newVal) {
asideState.value = 'hidden'
} else {
asideState.value = 'shown'
}
}, { immediate: true })
const mainContentSafePadding = computed(() => {
if (isLowerThanMd.value) {
return `padding-top:${headerHeight.value}px;`
}
return `padding-top:${headerHeight.value}px;padding-left:${asideWidth.value}px;`
})
function asideToggle(value?: TAsideState) {
if (asideState.value === 'before-shown') {
return
}
if (!!value) {
if (value === 'shown') {
asideState.value = 'before-shown'
} else {
asideState.value = value
}
} else {
if (asideState.value === 'hidden') {
asideState.value = 'before-shown'
} else if (asideState.value === 'shown') {
asideState.value = 'hidden'
}
}
}
const asideTailwindClass = computed(() => {
if (asideState.value === 'shown') {//on
if (isLowerThanMd.value) {//mobile
return 'max-w-[360px]'
} else {//desktop
return 'max-w-[240px]'
}
} else if (asideState.value === 'hidden') {//of
if (isLowerThanMd.value) {//mobile
// return '-translate-x-full'
} else {//desktop
return 'max-w-16'
}
}
})
</script>