Merge branch 'feature/20250910-all' into feature/20251001-gil

This commit is contained in:
“hyeonggkim”
2025-10-16 19:04:36 +09:00
37 changed files with 759 additions and 350 deletions

View File

@@ -7,7 +7,7 @@ interface Props {
withDefaults(defineProps<Props>(), {
size: 12,
color: '#7F7F7F',
color: 'var(--foreground-gray-500)',
className: '',
})
</script>
@@ -23,7 +23,7 @@ withDefaults(defineProps<Props>(), {
>
<path
d="M5.29499 7.715L2.39999 4.875C2.07499 4.555 2.29999 4 2.75999 4L9.23499 4C9.69499 4 9.91999 4.555 9.59499 4.875L6.69999 7.715C6.30999 8.095 5.68999 8.095 5.29999 7.715H5.29499Z"
fill="#7F7F7F"
:fill="color"
/>
</svg>
</template>

View File

@@ -1,29 +0,0 @@
<script setup lang="ts">
interface Props {
size?: number | string
color?: string
className?: string
}
withDefaults(defineProps<Props>(), {
size: 32,
color: '#EBEBEB',
className: '',
})
</script>
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
:width="size"
:height="size"
viewBox="0 0 32 33"
fill="none"
:class="className"
>
<path
d="M26.2768 8.10939C26.7975 7.5887 26.7975 6.74448 26.2768 6.22378C25.7561 5.70308 24.9119 5.70308 24.3912 6.22378L16.0007 14.6143L7.61013 6.22378C7.08943 5.70308 6.24521 5.70308 5.72451 6.22378C5.20381 6.74448 5.20381 7.5887 5.72451 8.10939L14.115 16.4999L5.72451 24.8904C5.20381 25.4111 5.20381 26.2554 5.72451 26.7761C6.24521 27.2968 7.08943 27.2968 7.61013 26.7761L16.0007 18.3855L24.3912 26.7761C24.9119 27.2968 25.7561 27.2968 26.2768 26.7761C26.7975 26.2554 26.7975 25.4111 26.2768 24.8904L17.8863 16.4999L26.2768 8.10939Z"
:fill="color"
/>
</svg>
</template>

View File

@@ -0,0 +1,29 @@
<script setup lang="ts">
interface Props {
size?: number | string
color?: string
className?: string
}
withDefaults(defineProps<Props>(), {
size: 32,
color: '#EBEBEB',
className: '',
})
</script>
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
:width="size"
:height="size"
viewBox="0 0 32 32"
fill="none"
:class="className"
>
<path
d="M26.2768 8.10947C26.7975 7.58877 26.7975 6.74455 26.2768 6.22385C25.7561 5.70315 24.9119 5.70315 24.3912 6.22385L16.0007 14.6144L7.61013 6.22385C7.08943 5.70315 6.24521 5.70315 5.72451 6.22385C5.20381 6.74455 5.20381 7.58877 5.72451 8.10947L14.115 16.5L5.72451 24.8905C5.20381 25.4112 5.20381 26.2554 5.72451 26.7761C6.24521 27.2968 7.08943 27.2968 7.61013 26.7761L16.0007 18.3856L24.3912 26.7761C24.9119 27.2968 25.7561 27.2968 26.2768 26.7761C26.7975 26.2554 26.7975 25.4112 26.2768 24.8905L17.8863 16.5L26.2768 8.10947Z"
:fill="color"
/>
</svg>
</template>

View File

@@ -0,0 +1,29 @@
<script setup lang="ts">
interface Props {
size?: number | string
color?: string
className?: string
}
withDefaults(defineProps<Props>(), {
size: 24,
color: 'var(--foreground-reversal)',
className: '',
})
</script>
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
:width="size"
:height="size"
viewBox="0 0 24 24"
fill="none"
:class="className"
>
<path
d="M20 16C20.7594 16 21.375 16.6156 21.375 17.375C21.375 18.1344 20.7594 18.75 20 18.75H4C3.24061 18.75 2.625 18.1344 2.625 17.375C2.625 16.6156 3.24061 16 4 16H20ZM20 10.5C20.7594 10.5 21.375 11.1156 21.375 11.875C21.375 12.6344 20.7594 13.25 20 13.25H4C3.24061 13.25 2.625 12.6344 2.625 11.875C2.625 11.1156 3.24061 10.5 4 10.5H20ZM20 5C20.7594 5 21.375 5.61561 21.375 6.375C21.375 7.13439 20.7594 7.75 20 7.75H4C3.24061 7.75 2.625 7.13439 2.625 6.375C2.625 5.61561 3.24061 5 4 5H20Z"
:fill="color"
/>
</svg>
</template>

View File

@@ -0,0 +1,29 @@
<script setup lang="ts">
interface Props {
size?: number | string
color?: string
className?: string
}
withDefaults(defineProps<Props>(), {
size: 16,
color: 'var(--foreground-reversal)',
className: '',
})
</script>
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
:width="size"
:height="size"
viewBox="0 0 16 16"
fill="none"
:class="className"
>
<path
d="M15.7071 1.70711C16.0976 1.31658 16.0976 0.683417 15.7071 0.292893C15.3166 -0.0976311 14.6834 -0.0976311 14.2929 0.292893L8 6.58579L1.70711 0.292893C1.31658 -0.0976311 0.683417 -0.0976311 0.292894 0.292893C-0.0976304 0.683417 -0.0976304 1.31658 0.292894 1.70711L6.58579 8L0.292893 14.2929C-0.0976311 14.6834 -0.0976311 15.3166 0.292893 15.7071C0.683417 16.0976 1.31658 16.0976 1.70711 15.7071L8 9.41421L14.2929 15.7071C14.6834 16.0976 15.3166 16.0976 15.7071 15.7071C16.0976 15.3166 16.0976 14.6834 15.7071 14.2929L9.41421 8L15.7071 1.70711Z"
:fill="color"
/>
</svg>
</template>

View File

@@ -0,0 +1,29 @@
<script setup lang="ts">
interface Props {
size?: number | string
color?: string
className?: string
}
withDefaults(defineProps<Props>(), {
size: 24,
color: 'var(--foreground-reversal)',
className: '',
})
</script>
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
:width="size"
:height="size"
viewBox="0 0 24 24"
fill="none"
:class="className"
>
<path
d="M4.5 10.5C3.675 10.5 3 11.175 3 12C3 12.825 3.675 13.5 4.5 13.5C5.325 13.5 6 12.825 6 12C6 11.175 5.325 10.5 4.5 10.5ZM19.5 10.5C18.675 10.5 18 11.175 18 12C18 12.825 18.675 13.5 19.5 13.5C20.325 13.5 21 12.825 21 12C21 11.175 20.325 10.5 19.5 10.5ZM12 10.5C11.175 10.5 10.5 11.175 10.5 12C10.5 12.825 11.175 13.5 12 13.5C12.825 13.5 13.5 12.825 13.5 12C13.5 11.175 12.825 10.5 12 10.5Z"
:fill="color"
/>
</svg>
</template>

View File

@@ -7,7 +7,7 @@ interface Props {
withDefaults(defineProps<Props>(), {
size: 16,
color: '#B2B2B2',
color: 'var(--foreground-gray-500)',
className: '',
})
</script>
@@ -18,16 +18,16 @@ withDefaults(defineProps<Props>(), {
:width="size"
:height="size"
viewBox="0 0 16 16"
:fill="color"
fill="none"
:class="className"
>
<path
d="M3.63636 3.33333C3.469 3.33333 3.33333 3.469 3.33333 3.63636L3.33333 12.3636C3.33333 12.531 3.469 12.6667 3.63636 12.6667H12.3636C12.531 12.6667 12.6667 12.531 12.6667 12.3636V9.93939C12.6667 9.5712 12.9651 9.27273 13.3333 9.27273C13.7015 9.27273 14 9.5712 14 9.93939V12.3636C14 13.2674 13.2674 14 12.3636 14H3.63636C2.73262 14 2 13.2674 2 12.3636L2 3.63636C2 2.73263 2.73262 2 3.63636 2L6.06061 2C6.4288 2 6.72727 2.29848 6.72727 2.66667C6.72727 3.03486 6.4288 3.33333 6.06061 3.33333H3.63636Z"
fill="#B2B2B2"
:fill="color"
/>
<path
d="M12.6667 4.27614V6.54545C12.6667 6.91364 12.9651 7.21212 13.3333 7.21212C13.7015 7.21212 14 6.91364 14 6.54545V2.66667C14 2.29848 13.7015 2 13.3333 2L9.45455 2C9.08636 2 8.78788 2.29848 8.78788 2.66667C8.78788 3.03486 9.08636 3.33333 9.45455 3.33333L11.7239 3.33333L7.28616 7.77103C7.02581 8.03138 7.02581 8.45349 7.28616 8.71384C7.54651 8.97419 7.96862 8.97419 8.22897 8.71384L12.6667 4.27614Z"
fill="#B2B2B2"
:fill="color"
/>
</svg>
</template>

View File

@@ -1,8 +1,10 @@
<script setup lang="ts">
import type { ClassType } from '#layers/types/Common'
interface Props {
to: string
target?: string
class?: string
class?: ClassType
}
const props = withDefaults(defineProps<Props>(), {

View File

@@ -27,6 +27,7 @@ const colorCode = computed(() => {
})
const currentImageSrc = computed(() => {
if (!imageSrc.value) return ''
return breakpoints.value.isMobile
? imageSrc.value.mobileSrc || ''
: imageSrc.value.pcSrc || ''
@@ -36,25 +37,20 @@ const currentImageSrc = computed(() => {
const sanitizedContent = computed(() => {
return displayText.value?.replace(/\n/g, '<br/>') || ''
})
// 이미지가 있는지 확인
const hasImage = computed(() => {
return imageSrc.value && (imageSrc.value.mobileSrc || imageSrc.value.pcSrc)
})
</script>
<template>
<!-- 이미지 -->
<img
v-if="hasImage && currentImageSrc"
v-if="isTypeImage(resourcesData?.resource_type) && currentImageSrc"
:src="currentImageSrc"
:alt="alt || displayText"
:class="`w-full h-full object-${objectFit}`"
loading="lazy"
/>
<!-- 텍스트 -->
<span
v-else-if="displayText"
v-else-if="isTypeText(resourcesData?.resource_type)"
v-dompurify-html="sanitizedContent"
:style="{ color: getColorCode({ colorName, colorCode }) }"
class="block"

View File

@@ -22,13 +22,13 @@
@click.stop
>
<!-- 헤더 -->
<div class="flex justify-end">
<div class="flex justify-end mb-3 md:mb-4">
<button
class="p-1 text-white rounded-full transition-colors"
class="text-white rounded-full transition-colors"
aria-label="모달 닫기"
@click="closeModal"
>
<AtomsIconsClose />
<AtomsIconsCloseLine />
</button>
</div>

View File

@@ -1,10 +1,15 @@
<script setup lang="ts">
import { Splide, SplideSlide } from '@splidejs/vue-splide'
import { getFirstGroup, isTypeVideo } from '#layers/utils/dataUtil'
import { getMediaSrc, getYouTubeEmbedUrl } from '#layers/utils/youtube'
import type { Splide as SplideType, Options } from '@splidejs/splide'
import type { PageDataResourceGroup } from '#layers/types/api/pageData'
import type {
PageDataResourceGroups,
PageDataResourceGroup,
} from '#layers/types/api/pageData'
interface Props {
slideData: { media: any; set_order: number }[]
slideData: { media: PageDataResourceGroups; set_order: number }[]
videoPlay?: PageDataResourceGroup
arrows?: boolean
pagination?: boolean
@@ -46,10 +51,27 @@ const thumbOptions = computed<Options>(() => ({
},
}))
const isPassVideo = (groups: PageDataResourceGroups, index: number) => {
const firstGroup = getFirstGroup(groups)
return (
firstGroup &&
isTypeVideo(firstGroup?.resource_type) &&
index !== playingSlideIndex.value
)
}
const handleVideoClick = (index: number) => {
playingSlideIndex.value = index
}
const getYouTubeEmbedUrlFromMedia = (
resourceGroups: PageDataResourceGroup[]
) => {
const resourceGroup = getFirstGroup(resourceGroups)
const mediaSrc = getMediaSrc(resourceGroup)
return mediaSrc ? getYouTubeEmbedUrl(mediaSrc, true) : ''
}
let mainInst: SplideType | null = null
let thumbsInst: SplideType | null = null
@@ -87,16 +109,14 @@ onBeforeUnmount(() => {
:class="{ 'opacity-0': playingSlideIndex === index }"
/>
<AtomsButtonPlay
v-if="
getMediaType(item.media) === 'video' && playingSlideIndex !== index
"
v-if="isPassVideo(item.media, index)"
:resources-data="videoPlay"
class="btn-play"
@click="handleVideoClick(index)"
/>
<iframe
v-if="playingSlideIndex === index"
:src="getYouTubeEmbedUrl(getMediaText(item.media), true)"
:src="getYouTubeEmbedUrlFromMedia(item.media)"
class="absolute top-0 left-0 w-full h-full"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { useGameDataStore } from '#layers/stores/useGameDataStore'
import { useScrollStore } from '#layers/stores/useScrollStore'
import { useWindowScroll, onClickOutside, useWindowSize } from '@vueuse/core'
import { onClickOutside, useWindowSize } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import type {
GameDataValue,
@@ -10,18 +10,18 @@ import type {
} from '#layers/types/api/gameData'
const route = useRoute()
const { y: windowY } = useWindowScroll()
const { width } = useWindowSize()
const gameDataStore = useGameDataStore()
const scrollStore = useScrollStore()
const _breakpoints = useResponsiveBreakpointsReliable()
const { isPassedStoveGnb } = storeToRefs(scrollStore)
const { isPassedStoveGnb, scrollGnbPosition } = 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[]>([])
@@ -34,15 +34,6 @@ const pathMatches = (base: string, current: string) => {
return current === base || current.startsWith(base + '/')
}
/** header overlay 높이 계산 (re-compute 최소화) */
const scrollPositionHeight = computed(() => {
const gnbHeight = scrollStore.stoveGnbHeight
const y = windowY.value
if (y === 0) return `${gnbHeight}px`
if (y >= gnbHeight) return '0px'
return `${gnbHeight - y}`
})
/** 자식 중 활성 링크 존재 여부 */
const hasActiveChild = (children?: GameDataMenuChildren) => {
const cur = currentPath.value
@@ -71,7 +62,8 @@ const calculateNavWidth = () => {
if (!navAreaRef.value) return 0
const navAreaWidth = navAreaRef.value.offsetWidth
return navAreaWidth
const moreWidth = 72 // 더보기 버튼 넓이 + 마진
return navAreaWidth + moreWidth
}
// startRef의 넓이를 구하는 함수
@@ -79,10 +71,11 @@ const calculateStartWidth = () => {
if (!startRef.value) return 0
const startWidth = startRef.value.offsetWidth
return startWidth + 40
const headerRightPadding = 40 // 헤더 오른쪽 마진
return startWidth + headerRightPadding
}
// official 자식들의 넓이를 구하는 함수 (뒤에서부터 순서대로)
// official 자식들의 넓이를 구하는 함수
const calculateOfficialItemWidths = () => {
if (!navAreaRef.value) return
@@ -103,8 +96,6 @@ const calculateOfficialItemWidths = () => {
calculateOverflow()
}
console.log(0, Object.keys(gnbList).length)
// 오버플로우 계산 함수
const calculateOverflow = () => {
if (!navAreaRef.value) return
@@ -112,18 +103,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,30 +114,30 @@ 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
}
}
overflowNam.value = removedCount
console.log('Overflow calculated:', overflowNam.value)
} else {
overflowNam.value = 0
console.log('No overflow needed, setting to 0')
}
}
// 컴포넌트 마운트 후 한 번만 계산
onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
// 화면 크기 변경 시 오버플로우 재계산
watch(width, () => {
calculateOverflow()
})
onMounted(() => {
// 초기화
overflowNam.value = 0
console.log('onMounted - overflowNam 초기화:', overflowNam.value)
nextTick(() => {
if (navAreaRef.value && startRef.value) {
@@ -165,14 +147,6 @@ onMounted(() => {
}
})
})
// 화면 크기 변경 시 오버플로우 재계산
const { width } = useWindowSize()
watch(width, () => {
calculateOverflow()
})
onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
</script>
<template>
@@ -182,47 +156,52 @@ 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]"
/>
</AtomsLocaleLink>
<button class="btn-open" @click="handleMenuOpen">
<AtomsIconsMenuBoldLine class="mx-auto" />
<span class="sr-only">menu open</span>
</button>
<div
:class="['gnb-game', { 'is-open': isMenuOpen }]"
:style="{ '--scroll-position': scrollPositionHeight }"
:style="{ '--scroll-position': scrollGnbPosition + 'px' }"
>
<div ref="navAreaRef" class="nav-area">
<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" />
<AtomsIconsArrowDownFill
v-if="gnbItem.children"
class="hidden md:block"
/>
</BlocksHybridLink>
<div v-if="gnbItem.children" class="nav-2depth">
<ul>
@@ -235,7 +214,7 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
:target="child.link_target"
>
<span>{{ child.menu_name }}</span>
<AtomsIconsLinkOut
<AtomsIconsWebLinkLine
v-if="child.link_target === '_blank'"
/>
</BlocksHybridLink>
@@ -244,44 +223,47 @@ 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">
<AtomsIconsOptionHorizontalFill class="mx-auto" />
<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>
<AtomsIconsWebLinkLine
v-if="child.link_target === '_blank'"
/>
</BlocksHybridLink>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -293,7 +275,9 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
:target="'_self'"
class="nav-1depth text-gradient-pink"
>
<AtomsIconsStarFill />
<span>이벤트</span>
<AtomsIconsStarFill />
</BlocksHybridLink>
</div>
</div>
@@ -304,6 +288,7 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
</AtomsButton>
</div>
<button class="btn-close" @click="handleMenuClose">
<AtomsIconsMenuCloseLine class="mx-auto" />
<span class="sr-only">menu close</span>
</button>
</div>
@@ -317,7 +302,7 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
@apply bg-theme-foreground text-theme-foreground-reversal relative z-50;
}
.game-wrapper {
@apply absolute flex w-full h-[48px] items-center whitespace-nowrap px-[64px] bg-theme-foreground 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-wrapper.is-fixed {
@@ -329,10 +314,10 @@ onClickOutside(navAreaRef, () => (isMenuOpen.value = false))
.btn-open,
.btn-close {
@apply absolute w-[40px] h-[40px] md:hidden bg-[red];
@apply absolute w-[40px] h-[40px] md:hidden;
}
.btn-open {
@apply top-[4px] left-[12px];
@apply top-[4px] left-[12px] sm:left-[32px];
}
.btn-close {
@apply top-[11px] left-[12px];
@@ -340,9 +325,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 +337,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 +351,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 +382,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 +398,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-gray-750 md:after:translate-y-[-50%];
}
.is-hidden {

View File

@@ -46,7 +46,7 @@ const currentPosterSrc = computed(() => {
<div class="absolute inset-0 w-full h-full">
<!-- 이미지 타입-->
<div
v-if="resourcesData?.group_type === 'image'"
v-if="isTypeImage(resourcesData?.resource_type)"
class="w-full h-full bg-cover bg-center bg-no-repeat"
:class="getResponsiveClass()"
:style="bgStyles"
@@ -54,7 +54,7 @@ const currentPosterSrc = computed(() => {
<!-- 비디오 타입 -->
<video
v-else-if="resourcesData?.group_type === 'video' && currentVideoSrc"
v-else-if="isTypeVideo(resourcesData?.resource_type) && currentVideoSrc"
class="w-full h-full object-cover"
:poster="currentPosterSrc"
autoplay

View File

@@ -68,7 +68,7 @@ console.log("🚀 11111~ getButtonProps ~ props.resourcesData:", getButtonProps(
>
<AtomsButton
v-for="(button, index) in props.resourcesData"
:key="`${button.group_code}-${index}`"
:key="index"
v-bind="getButtonProps(button)"
v-analytics="useAnalyticsLogDataDirect(getButtonProps(button), props.pageVerTmplSeq)"
class="size-extra-small md:size-medium"