85 lines
2.2 KiB
TypeScript
85 lines
2.2 KiB
TypeScript
import { ref, onMounted, onUnmounted } from 'vue'
|
|
|
|
const ENIGMA_ROOT = '.enigma'
|
|
|
|
function getLayoutNodes() {
|
|
const root = document.querySelector(ENIGMA_ROOT)
|
|
if (!root) return null
|
|
|
|
return {
|
|
sideMenu: root.querySelector<HTMLElement>('.side-menu'),
|
|
content: root.querySelector<HTMLElement>('.content'),
|
|
}
|
|
}
|
|
|
|
function isCompactLayout() {
|
|
return getLayoutNodes()?.sideMenu?.classList.contains('side-menu--collapsed') ?? false
|
|
}
|
|
|
|
function applyCompactLayout(collapsed: boolean) {
|
|
const nodes = getLayoutNodes()
|
|
if (!nodes?.sideMenu || !nodes.content) return
|
|
|
|
nodes.sideMenu.classList.toggle('side-menu--collapsed', collapsed)
|
|
nodes.content.classList.toggle('content--compact', collapsed)
|
|
}
|
|
|
|
function persistCompactMenu(collapsed: boolean) {
|
|
queueMicrotask(() => {
|
|
localStorage.setItem('compactMenu', collapsed.toString())
|
|
})
|
|
}
|
|
|
|
export const useSideMenu = () => {
|
|
const mobileMenuOpen = ref(false)
|
|
const scrolled = ref(false)
|
|
|
|
const toggleCompactMenu = (event: MouseEvent) => {
|
|
event.preventDefault()
|
|
const collapsed = !isCompactLayout()
|
|
applyCompactLayout(collapsed)
|
|
persistCompactMenu(collapsed)
|
|
}
|
|
|
|
const openMobileMenu = (event: MouseEvent) => {
|
|
event.preventDefault()
|
|
mobileMenuOpen.value = true
|
|
}
|
|
|
|
const closeMobileMenu = (event: MouseEvent) => {
|
|
event.preventDefault()
|
|
mobileMenuOpen.value = false
|
|
}
|
|
|
|
const onScrollContent = (event: Event) => {
|
|
const target = event.target as HTMLElement
|
|
scrolled.value = target.scrollTop > 0
|
|
}
|
|
|
|
const onResize = () => {
|
|
if (window.innerWidth <= 1600) {
|
|
applyCompactLayout(true)
|
|
persistCompactMenu(true)
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
applyCompactLayout(localStorage.getItem('compactMenu') === 'true')
|
|
window.addEventListener('resize', onResize)
|
|
onResize()
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
window.removeEventListener('resize', onResize)
|
|
})
|
|
|
|
return {
|
|
mobileMenuOpen,
|
|
scrolled,
|
|
toggleCompactMenu,
|
|
openMobileMenu,
|
|
closeMobileMenu,
|
|
onScrollContent,
|
|
}
|
|
}
|