feat. lnb컴포넌트

This commit is contained in:
clkim
2025-11-11 16:53:46 +09:00
parent 208a907e91
commit 4b034ec009
17 changed files with 486 additions and 122 deletions

View File

@@ -2,7 +2,6 @@
import { onClickOutside, useWindowSize } from '@vueuse/core'
import { useGameDataStore } from '#layers/stores/useGameDataStore'
import type {
GameDataValue,
GameDataMenu,
GameDataMenuChildren,
GameDataResourceGroup,
@@ -12,12 +11,15 @@ import type {
const route = useRoute()
const { width } = useWindowSize()
const gameDataStore = useGameDataStore()
const scrollStore = useScrollStore()
const { gameData } = storeToRefs(gameDataStore)
const { isPassedStoveGnb } = storeToRefs(scrollStore)
const navAreaRef = ref<HTMLElement>()
const startRef = ref<HTMLElement>()
const gameData = gameDataStore.gameData as GameDataValue
const gnbData = gameData?.gnb
const gnbData = gameData.value?.gnb
const isMenuOpen = ref(false)
const navWidth = ref(0)
const startWidth = ref(0)
@@ -57,9 +59,6 @@ const isNavItemActive = (gnbItem: GameDataMenu): boolean => {
return selfActive || hasActiveChild(gnbItem.children)
}
const handleMenuOpen = () => (isMenuOpen.value = true)
const handleMenuClose = () => (isMenuOpen.value = false)
// navAreaRef의 넓이를 구하는 함수
const calculateNavWidth = () => {
if (!navAreaRef.value || !gnbData) return 0
@@ -132,15 +131,26 @@ const calculateOverflow = () => {
}
}
const stopClickOutside = onClickOutside(
navAreaRef,
() => (isMenuOpen.value = false)
)
const handleMenuOpen = () => {
isMenuOpen.value = true
scrollStore.controlScrollLock(true)
}
const handleMenuClose = () => {
isMenuOpen.value = false
scrollStore.controlScrollLock(false)
}
const isNotClickable = (gnbItem: GameDataMenu) => {
return gnbItem.click_action_type === 0
}
const has2depthButton = (gnbItem: GameDataMenu) => {
return gnbItem.children && Object.keys(gnbItem.children).length > 0
}
const stopClickOutside = onClickOutside(navAreaRef, () => handleMenuClose())
// 화면 크기 변경 시 오버플로우 재계산
watch(width, () => {
calculateOverflow()
@@ -168,7 +178,7 @@ onBeforeUnmount(() => {
<template>
<header class="header">
<BlocksStoveGnbNew class="h-[48px]" />
<div class="game-wrap">
<div :class="['game-wrap', { 'is-fixed': isPassedStoveGnb }]">
<AtomsLocaleLink to="/brand" class="mx-auto md:hidden">
<img
:src="getImageHost(gnbData?.bi_path)"
@@ -205,11 +215,11 @@ onBeforeUnmount(() => {
}"
>
<AtomsLocaleLink
:to="gnbItem.url_path"
:to="isNotClickable(gnbItem) ? '#' : gnbItem.url_path"
:target="gnbItem.link_target"
:class="[
'nav-1depth',
{ 'has-link': !!gnbItem.url_path },
{ 'has-link': !isNotClickable(gnbItem) },
{ active: isNavItemActive(gnbItem) },
]"
>
@@ -354,9 +364,13 @@ onBeforeUnmount(() => {
@apply bg-theme-foreground text-theme-foreground-reversal relative z-[110];
}
.game-wrap {
@apply fixed top-0 flex w-full h-[48px] items-center whitespace-nowrap mt-[var(--scroll-position,48px)] px-[52px] bg-theme-foreground sm:px-[72px] md:h-16 md:pl-0 md:pr-[40px]
@apply absolute flex w-full h-[48px] items-center whitespace-nowrap px-[52px] bg-theme-foreground sm:px-[72px] md:h-16 md:pl-0 md:pr-[40px]
before:content-[''] before:absolute before:top-0 before:left-0 before:right-0 before:h-px before:bg-theme-foreground-reversal-6;
}
.game-wrap.is-fixed {
@apply fixed top-0;
}
.game-logo {
@apply mx-auto shrink-0 md:mx-0;
}
@@ -426,7 +440,7 @@ onBeforeUnmount(() => {
@apply bg-theme-foreground-reversal-8 md:bg-transparent;
}
.nav-1depth.has-link {
@apply hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10 md:hover:bg-transparent md:active:bg-transparent;
@apply cursor-pointer hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10 md:hover:bg-transparent md:active:bg-transparent;
}
.nav-2depth {