fix. gnb 작업 1차

This commit is contained in:
clkim
2025-10-02 17:34:41 +09:00
parent a70b3c8795
commit 1da6227c46
18 changed files with 413 additions and 448 deletions

View File

@@ -17,11 +17,12 @@ const _breakpoints = useResponsiveBreakpointsReliable()
const { isPassedStoveGnb } = storeToRefs(scrollStore)
const gameData = gameDataStore.gameData as GameDataValue
const gnbList = (gameData?.gnb?.menus ?? {}) as GameDataMenuChildren
const isMenuOpen = ref(false)
const navAreaRef = ref<HTMLElement>()
const startRef = ref<HTMLElement>()
const gameData = gameDataStore.gameData as GameDataValue
const gnbData = gameData?.gnb
const isMenuOpen = ref(false)
const navWidth = ref(0)
const startWidth = ref(0)
const officialItemWidths = ref<number[]>([])
@@ -71,7 +72,8 @@ const calculateNavWidth = () => {
if (!navAreaRef.value) return 0
const navAreaWidth = navAreaRef.value.offsetWidth
return navAreaWidth
const moreWidth = 72
return navAreaWidth + moreWidth
}
// startRef의 넓이를 구하는 함수
@@ -79,7 +81,8 @@ const calculateStartWidth = () => {
if (!startRef.value) return 0
const startWidth = startRef.value.offsetWidth
return startWidth + 40
const headerPadding = 40
return startWidth + headerPadding
}
// official 자식들의 넓이를 구하는 함수 (뒤에서부터 순서대로)
@@ -103,8 +106,6 @@ const calculateOfficialItemWidths = () => {
calculateOverflow()
}
console.log(0, Object.keys(gnbList).length)
// 오버플로우 계산 함수
const calculateOverflow = () => {
if (!navAreaRef.value) return
@@ -112,18 +113,9 @@ const calculateOverflow = () => {
const totalNavWidth = navWidth.value + startWidth.value
const screenWidth = width.value
console.log('calculateOverflow called:', {
screenWidth,
totalNavWidth,
navWidth: navWidth.value,
startWidth: startWidth.value,
officialItemWidths: officialItemWidths.value,
})
// 모바일(1024px 미만)에서는 overflowNam을 0으로 설정
if (screenWidth < 1024) {
overflowNam.value = 0
console.log('Mobile view - overflowNam set to 0')
return
}
@@ -132,12 +124,10 @@ const calculateOverflow = () => {
let removedCount = 0
let currentTotal = totalNavWidth
// officialItemWidths를 하나씩 빼면서 해상도보다 작아지는지 확인
for (let i = 0; i < officialItemWidths.value.length; i++) {
currentTotal -= officialItemWidths.value[i]
removedCount++
// 해상도보다 작아지면 중단
if (currentTotal <= screenWidth) {
break
}
@@ -147,7 +137,6 @@ const calculateOverflow = () => {
console.log('Overflow calculated:', overflowNam.value)
} else {
overflowNam.value = 0
console.log('No overflow needed, setting to 0')
}
}
@@ -155,7 +144,6 @@ const calculateOverflow = () => {
onMounted(() => {
// 초기화
overflowNam.value = 0
console.log('onMounted - overflowNam 초기화:', overflowNam.value)
nextTick(() => {
if (navAreaRef.value && startRef.value) {
@@ -182,7 +170,7 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
<div class="game-wrapper" :class="{ 'is-fixed': isPassedStoveGnb }">
<AtomsLocaleLink to="/brand" class="mx-auto md:hidden">
<img
:src="gameData?.gnb?.bi_path"
:src="gnbData?.bi_path"
:alt="gameData?.game_name"
class="h-[30px]"
/>
@@ -198,31 +186,35 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
<div class="nav-logo">
<AtomsLocaleLink to="/brand">
<img
:src="gameData?.gnb?.bi_path"
:src="gnbData?.bi_path"
:alt="gameData?.game_name"
class="h-[30px]"
/>
</AtomsLocaleLink>
</div>
<nav class="nav-list">
<div v-if="gnbList" class="official">
<div v-if="gnbData?.menus" class="official">
<div
v-for="(gnbItem, key) in gnbList"
v-for="(gnbItem, key) in gnbData?.menus"
:key="key"
class="nav-item"
:class="{
'is-hidden':
overflowNam > 0 &&
Number(key) >= Object.keys(gnbList).length - overflowNam,
Number(key) >=
Object.keys(gnbData?.menus).length - overflowNam,
}"
>
<BlocksHybridLink
:to="gnbItem.url_path"
:target="gnbItem.link_target"
:class="`nav-1depth ${isNavItemActive(gnbItem) ? 'active' : ''}`"
:class="['nav-1depth', { active: isNavItemActive(gnbItem) }]"
>
<span>{{ gnbItem.menu_name }}</span>
<AtomsIconsArrowDown v-if="gnbItem.children" />
<AtomsIconsArrowDown
v-if="gnbItem.children"
class="hidden md:block"
/>
</BlocksHybridLink>
<div v-if="gnbItem.children" class="nav-2depth">
<ul>
@@ -244,44 +236,46 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
</div>
</div>
</div>
<div v-if="gnbList && overflowNam > 0" class="more">
<div v-if="gnbData?.menus && overflowNam > 0" class="more">
<button class="btn-more">
<span class="sr-only">more</span>
</button>
<div class="more-list">
<div
v-for="(gnbItem, key) in gnbList"
:key="key"
:class="{
hidden:
Number(key) < Object.keys(gnbList).length - overflowNam,
}"
>
<BlocksHybridLink
:to="gnbItem.url_path"
:target="gnbItem.link_target"
:class="`${isNavItemActive(gnbItem) ? 'active' : ''}`"
<div class="list-inner">
<div
v-for="(gnbItem, key) in gnbData?.menus"
:key="key"
:class="{
hidden:
Number(key) <
Object.keys(gnbData?.menus).length - overflowNam,
}"
>
<span>{{ gnbItem.menu_name }}</span>
<AtomsIconsArrowDown v-if="gnbItem.children" />
</BlocksHybridLink>
<div v-if="gnbItem.children">
<ul>
<li
v-for="child in gnbItem.children"
:key="child.menu_name"
>
<BlocksHybridLink
:to="child.url_path"
:target="child.link_target"
<BlocksHybridLink
:to="gnbItem.url_path"
:target="gnbItem.link_target"
:class="`${isNavItemActive(gnbItem) ? 'active' : ''}`"
>
<span>{{ gnbItem.menu_name }}</span>
</BlocksHybridLink>
<div v-if="gnbItem.children">
<ul>
<li
v-for="child in gnbItem.children"
:key="child.menu_name"
>
<span>{{ child.menu_name }}</span>
<AtomsIconsLinkOut
v-if="child.link_target === '_blank'"
/>
</BlocksHybridLink>
</li>
</ul>
<BlocksHybridLink
:to="child.url_path"
:target="child.link_target"
>
<span>{{ child.menu_name }}</span>
<AtomsIconsLinkOut
v-if="child.link_target === '_blank'"
/>
</BlocksHybridLink>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -340,9 +334,6 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
.btn-start {
@apply relative mt-2 px-5 md:absolute md:right-0 md:mt-0 md:px-0;
}
.btn-more {
@apply w-[40px] h-[40px] bg-[red];
}
.gnb-game {
@apply absolute top-0 left-0 w-0 md:relative md:w-full md:!h-full;
@@ -355,12 +346,12 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
@apply content-[''] absolute inset-0 w-[100vw] h-full bg-[rgba(0,0,0,0.6)] md:hidden;
}
.gnb-game.is-open .nav-area {
@apply h-full translate-x-0 transition-transform duration-300 md:translate-x-0;
@apply h-full translate-x-0 transition-transform duration-300 md:transform-none;
}
.nav-area {
@apply flex flex-col w-[360px] bg-theme-foreground-10 translate-x-[-100%]
md:inline-flex md:flex-row md:w-auto md:h-full md:pl-[40px] md:items-center md:bg-transparent transform-none;
md:inline-flex md:flex-row md:w-auto md:h-full md:pl-[40px] md:items-center md:bg-transparent md:transform-none;
}
.nav-logo {
@@ -369,7 +360,7 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
.nav-list {
@apply overflow-hidden flex flex-col order-1 h-full mt-2 mb-4 px-2
md:flex-row md:order-none md:h-full md:my-0 md:mx-10 md:px-0 md:overflow-visible;
md:flex-row md:order-none md:h-full md:my-0 md:ml-10 md:mr-6 md:px-0 md:overflow-visible;
}
.nav-item {
@@ -400,15 +391,15 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
}
.nav-2depth {
@apply block text-[15px] md:hidden md:absolute md:top-[64px] md:left-[-28px] md:min-w-[190px] md:pt-1 md:z-50;
@apply text-[15px] md:hidden md:absolute md:top-[64px] md:left-[-28px] md:pt-1;
}
.nav-2depth ul {
@apply bg-theme-foreground-10 rounded-[20px] md:shadow-lg md:p-3;
@apply bg-theme-foreground-10 rounded-[20px] md:min-w-[190px] md:p-3 md:shadow-lg;
}
.nav-2depth a {
@apply flex items-center gap-1 px-5 py-[9px] rounded-[12px] transition-colors
hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10
md:px-4 md:py-[11px];
@apply flex items-center gap-1 py-[9px] px-5 rounded-[12px] transition-colors
md:py-[11px] md:px-4
hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10;
}
.official {
@@ -416,14 +407,30 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
}
.more {
@apply relative hidden md:block;
@apply relative hidden ml-[32px] pt-[11px] md:block;
}
.more:hover .more-list {
@apply md:block;
}
.btn-more {
@apply w-[40px] h-[40px] rounded-[12px] bg-theme-foreground-reversal-6 hover:bg-theme-foreground-reversal-10 active:bg-theme-foreground-reversal-4;
}
.more-list {
@apply absolute;
@apply hidden absolute top-[64px] left-[-20px] pt-1;
}
.list-inner {
@apply min-w-[190px] p-3 rounded-[20px] bg-theme-foreground-10 shadow-lg;
}
.more-list a {
@apply flex items-center gap-1 py-[10px] px-4 rounded-[12px] transition-colors
hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10;
}
.more-list li a {
@apply px-6;
}
.event {
@apply ml-[100px];
@apply relative md:ml-[64px] md:after:content-[''] md:after:absolute md:after:top-[50%] md:after:left-[-32px] md:after:w-[1px] md:after:h-[16px] md:after:bg-theme-foreground-reversal-30 md:after:translate-y-[-50%];
}
.is-hidden {