fix. 페이지네이션 스타일 적용
This commit is contained in:
@@ -25,10 +25,6 @@
|
||||
@apply line-clamp-2 text-[16px] font-[500] leading-[24px] drop-shadow-[0_2px_2px_rgba(0,0,0,0.6)] md:line-clamp-1 md:text-[24px] md:leading-[34px];
|
||||
}
|
||||
.title-xs {
|
||||
}
|
||||
|
||||
/* Description Utility Classes */
|
||||
.description-lg {
|
||||
@apply line-clamp-4 text-[15px] font-[400] leading-[24px] drop-shadow-[0_2px_2px_rgba(0,0,0,0.6)] md:line-clamp-3 md:text-[20px] md:leading-[30px];
|
||||
@apply text-[14px] leading-[20px] tracking-[-0.42px] md:text-[18px] md:leading-[26px] md:tracking-[-0.54px];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,13 @@
|
||||
}
|
||||
|
||||
.splide-pagination-bullet {
|
||||
@apply relative w-2 h-2 rounded-full bg-[var(--primary)] opacity-100 md:w-3 md:h-3
|
||||
after:content-[''] after:absolute after:top-0 after:left-0 after:w-full after:h-full after:rounded-full after:bg-[rgba(0,0,0,0.5)] after:transition-opacity after:duration-300 after:ease-in-out after:opacity-100;
|
||||
@apply relative w-2 h-2 rounded-full opacity-100 md:w-3 md:h-3 transition-all duration-300 ease-in-out;
|
||||
background-color: var(--pagination-disabled);
|
||||
}
|
||||
|
||||
.splide-pagination-bullet:hover,
|
||||
.splide-pagination-bullet.is-active {
|
||||
@apply after:opacity-0;
|
||||
background-color: var(--pagination-active);
|
||||
}
|
||||
|
||||
.splide-arrows {
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { Splide } from '@splidejs/vue-splide'
|
||||
import type { Splide as SplideType, ResponsiveOptions } from '@splidejs/splide'
|
||||
import { useSplideArrow } from '#layers/composables/useSplideArrow'
|
||||
import { getPaginationClass } from '#layers/utils/styleUtil'
|
||||
import type { Splide as SplideType, ResponsiveOptions } from '@splidejs/splide'
|
||||
import type { PageDataResourceGroups } from '#layers/types/api/pageData'
|
||||
|
||||
interface Props {
|
||||
autoplay?: boolean | string
|
||||
arrows?: boolean
|
||||
pagination?: boolean
|
||||
paginationData?: PageDataResourceGroups
|
||||
class?: string
|
||||
}
|
||||
|
||||
@@ -52,7 +55,6 @@ defineExpose({
|
||||
|
||||
const handleSplideMounted = (splide: SplideType) => {
|
||||
emit('mounted', splide)
|
||||
splide.refresh()
|
||||
|
||||
// 화살표 버튼 클릭 이벤트 리스너 추가
|
||||
nextTick(() => {
|
||||
@@ -77,6 +79,7 @@ const handleMove = (
|
||||
ref="splideRef"
|
||||
:options="options"
|
||||
class="h-full"
|
||||
:style="getPaginationClass(props.paginationData)"
|
||||
@splide:mounted="handleSplideMounted"
|
||||
@splide:move="handleMove"
|
||||
>
|
||||
|
||||
@@ -137,7 +137,7 @@ onBeforeUnmount(() => {
|
||||
ref="thumbsRef"
|
||||
:options="thumbOptions"
|
||||
class="thumbnail-splide"
|
||||
:style="getPaginationClass(paginationData, { type: 'thumbnail' })"
|
||||
:style="getPaginationClass(paginationData)"
|
||||
>
|
||||
<SplideSlide
|
||||
v-for="(item, index) in props.slideData"
|
||||
|
||||
@@ -4,10 +4,12 @@ import type { PageDataResourceGroup } from '#layers/types/api/pageData'
|
||||
interface Props {
|
||||
resourcesData: PageDataResourceGroup
|
||||
gradient?: string
|
||||
size?: 'contain' | 'cover'
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
gradient: '',
|
||||
size: 'cover',
|
||||
})
|
||||
|
||||
const breakpoints = useResponsiveBreakpointsReliable()
|
||||
@@ -47,8 +49,13 @@ const currentPosterSrc = computed(() => {
|
||||
<!-- 이미지 타입-->
|
||||
<div
|
||||
v-if="isTypeImage(resourcesData?.resource_type)"
|
||||
class="w-full h-full bg-cover bg-center bg-no-repeat"
|
||||
:class="getResponsiveClass()"
|
||||
:class="[
|
||||
'w-full h-full bg-cover bg-center bg-no-repeat',
|
||||
{
|
||||
'object-contain': props.size === 'contain',
|
||||
'object-cover': props.size === 'cover',
|
||||
},
|
||||
]"
|
||||
:style="bgStyles"
|
||||
/>
|
||||
|
||||
|
||||
@@ -7,7 +7,13 @@ const props = defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<p>
|
||||
<p class="description">
|
||||
<BlocksVisualContent :resources-data="props.resourcesData" />
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.description {
|
||||
@apply line-clamp-4 text-[15px] font-[400] leading-[24px] drop-shadow-[0_2px_2px_rgba(0,0,0,0.6)] md:line-clamp-3 md:text-[20px] md:leading-[30px];
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import type { PageDataResourceGroup } from '#layers/types/api/pageData'
|
||||
|
||||
const props = defineProps<{
|
||||
interface Props {
|
||||
resourcesData: PageDataResourceGroup
|
||||
}>()
|
||||
tag?: 'h3' | 'h4' | 'p'
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
tag: 'h3',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h3>
|
||||
<component :is="props.tag">
|
||||
<BlocksVisualContent :resources-data="props.resourcesData" />
|
||||
</h3>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
@@ -15,7 +15,7 @@ interface Props {
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const splideRef = ref<SplideSlide | null>(null)
|
||||
const currentSlide = ref<number | null>(null)
|
||||
const currentSlideIndex = ref<number | null>(null)
|
||||
|
||||
const slideData = computed(() => {
|
||||
return getComponentContainer(props.components, 'group_sets', { maxLength: 5 })
|
||||
@@ -32,11 +32,11 @@ const goToSlide = (index: number) => {
|
||||
}
|
||||
|
||||
const handleSplideMounted = (splide: SplideType) => {
|
||||
currentSlide.value = splide.index
|
||||
currentSlideIndex.value = splide.index
|
||||
}
|
||||
|
||||
const changeCurrentSlide = (_splide: SplideType, newIndex: number) => {
|
||||
currentSlide.value = newIndex
|
||||
const handleSplideMove = (_splide: SplideType, newIndex: number) => {
|
||||
currentSlideIndex.value = newIndex
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -50,8 +50,8 @@ const changeCurrentSlide = (_splide: SplideType, newIndex: number) => {
|
||||
:arrows="false"
|
||||
:pagination="false"
|
||||
class="h-full"
|
||||
@splide:move="changeCurrentSlide"
|
||||
@splide:mounted="handleSplideMounted"
|
||||
@move="handleSplideMove"
|
||||
@mounted="handleSplideMounted"
|
||||
>
|
||||
<SplideSlide v-for="(item, index) in slideData" :key="index">
|
||||
<WidgetsBackground
|
||||
@@ -72,7 +72,7 @@ const changeCurrentSlide = (_splide: SplideType, newIndex: number) => {
|
||||
<WidgetsDescription
|
||||
v-if="hasComponentGroup(item, 'description')"
|
||||
:resources-data="getComponentGroup(item, 'description')"
|
||||
class="description-lg mt-4 md:mt-6"
|
||||
class="mt-4 md:mt-6"
|
||||
/>
|
||||
</div>
|
||||
</SplideSlide>
|
||||
@@ -88,13 +88,16 @@ const changeCurrentSlide = (_splide: SplideType, newIndex: number) => {
|
||||
:class="[
|
||||
'pagination-item',
|
||||
{
|
||||
'is-active': currentSlide === index,
|
||||
'is-completed': index < currentSlide,
|
||||
'is-active': currentSlideIndex === index,
|
||||
'is-completed': index < currentSlideIndex,
|
||||
},
|
||||
]"
|
||||
>
|
||||
<button
|
||||
:class="['btn-pagination', { 'is-active': currentSlide === index }]"
|
||||
:class="[
|
||||
'btn-pagination',
|
||||
{ 'is-active': currentSlideIndex === index },
|
||||
]"
|
||||
@click="goToSlide(index)"
|
||||
>
|
||||
<span class="item-bullet"></span>
|
||||
|
||||
@@ -46,7 +46,7 @@ const paginationData = computed(() => {
|
||||
<WidgetsDescription
|
||||
v-if="hasComponentGroup(item, 'description')"
|
||||
:resources-data="getComponentGroup(item, 'description')"
|
||||
class="description-lg mt-4 md:mt-6"
|
||||
class="mt-4 md:mt-6"
|
||||
/>
|
||||
</div>
|
||||
</SplideSlide>
|
||||
|
||||
@@ -3,8 +3,14 @@ import { SplideSlide } from '@splidejs/vue-splide'
|
||||
import {
|
||||
getComponentContainer,
|
||||
getComponentGroupAry,
|
||||
getComponentGroup,
|
||||
hasComponentGroup,
|
||||
} from '#layers/utils/dataUtil'
|
||||
import type { PageDataTemplateComponents } from '#layers/types/api/pageData'
|
||||
import type { Splide as SplideType } from '@splidejs/splide'
|
||||
import type {
|
||||
PageDataTemplateComponents,
|
||||
PageDataTemplateComponent,
|
||||
} from '#layers/types/api/pageData'
|
||||
|
||||
interface Props {
|
||||
components: PageDataTemplateComponents
|
||||
@@ -13,6 +19,10 @@ interface Props {
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const breakpoints = useResponsiveBreakpointsReliable()
|
||||
|
||||
const currentSlideIndex = ref<number>(0)
|
||||
|
||||
const slideData = computed(() => {
|
||||
return getComponentContainer(props.components, 'group_sets', {
|
||||
maxLength: 10,
|
||||
@@ -21,6 +31,21 @@ const slideData = computed(() => {
|
||||
const paginationData = computed(() => {
|
||||
return getComponentGroupAry(props.components, 'pagination')
|
||||
})
|
||||
|
||||
const currentVideoSrc = (item: PageDataTemplateComponent) => {
|
||||
const videoSrc = getComponentGroup(item, 'video')?.res_path
|
||||
const responsiveSrc = getResponsiveSrc(videoSrc, {
|
||||
resourcesType: 'video',
|
||||
})
|
||||
|
||||
return breakpoints.value.isMobile
|
||||
? responsiveSrc.mobileSrc
|
||||
: responsiveSrc.pcSrc
|
||||
}
|
||||
|
||||
const handleSplideMove = (_splide: SplideType, newIndex: number) => {
|
||||
currentSlideIndex.value = newIndex
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -28,17 +53,23 @@ const paginationData = computed(() => {
|
||||
<BlocksSlideThumbnail
|
||||
:slide-data="slideData"
|
||||
:pagination-data="paginationData"
|
||||
@move="handleSplideMove"
|
||||
>
|
||||
<SplideSlide v-for="(item, index) in slideData" :key="index">
|
||||
<WidgetsBackground
|
||||
v-if="hasComponentGroup(item, 'background')"
|
||||
:resources-data="getComponentGroup(item, 'background')"
|
||||
/>
|
||||
<WidgetsBackground
|
||||
v-if="hasComponentGroup(item, 'foreground')"
|
||||
size="contain"
|
||||
:resources-data="getComponentGroup(item, 'foreground')"
|
||||
/>
|
||||
<div class="section-content max-w-[1024px] mx-auto items-start">
|
||||
<WidgetsSubTitle
|
||||
v-if="hasComponentGroup(item, 'category')"
|
||||
:resources-data="getComponentGroup(item, 'category')"
|
||||
class="title-sm mb-2 line-clamp-1 text-left md:mb-5"
|
||||
class="title-xs mb-2 line-clamp-1 text-left md:mb-5"
|
||||
/>
|
||||
<WidgetsMainTitle
|
||||
v-if="hasComponentGroup(item, 'mainTitle')"
|
||||
@@ -48,12 +79,21 @@ const paginationData = computed(() => {
|
||||
<WidgetsSubTitle
|
||||
v-if="hasComponentGroup(item, 'subTitle')"
|
||||
:resources-data="getComponentGroup(item, 'subTitle')"
|
||||
tag="p"
|
||||
class="title-sm mt-1 line-clamp-1 text-left"
|
||||
/>
|
||||
<WidgetsDescription
|
||||
v-if="hasComponentGroup(item, 'description')"
|
||||
:resources-data="getComponentGroup(item, 'description')"
|
||||
class="description-lg mt-2 text-left md:mt-5"
|
||||
class="mt-2 text-left md:mt-5"
|
||||
/>
|
||||
<video
|
||||
v-if="hasComponentGroup(item, 'video')"
|
||||
:src="currentVideoSrc(item)"
|
||||
:autoplay="currentSlideIndex === index"
|
||||
muted
|
||||
loop
|
||||
playsinline
|
||||
/>
|
||||
</div>
|
||||
</SplideSlide>
|
||||
|
||||
@@ -34,9 +34,9 @@ const mainTitleData = computed(() =>
|
||||
const slideData = computed(() =>
|
||||
getComponentContainer(props.components, 'group_sets')
|
||||
)
|
||||
const _videoPlayData = computed(() =>
|
||||
getComponentGroup(props.components, 'videoPlay')
|
||||
)
|
||||
const paginationData = computed(() => {
|
||||
return getComponentGroupAry(props.components, 'pagination')
|
||||
})
|
||||
|
||||
const getMediaComponent = (item: PageDataTemplateComponentSet) => {
|
||||
return getComponentGroup(item, 'media')
|
||||
@@ -82,7 +82,7 @@ const handleVideoClick = (index: number) => {
|
||||
locale.value,
|
||||
useAnalyticsLogDataDirect(
|
||||
(sendingGroup as any) || getComponentGroup(props.components, 'videoPlay'),
|
||||
1
|
||||
props.pageVerTmplSeq
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -116,6 +116,7 @@ const onArrowClick = (direction, targetIndex) => {
|
||||
variant="media"
|
||||
:drag="false"
|
||||
class="mt-[24px] md:mt-[32px]"
|
||||
:pagination-data="paginationData"
|
||||
@move="stopVideo"
|
||||
@arrow-click="onArrowClick"
|
||||
>
|
||||
|
||||
@@ -43,7 +43,7 @@ const slideItemSize = {
|
||||
},
|
||||
}
|
||||
|
||||
const handleChange = (_splide: SplideType, newIndex: number) => {
|
||||
const handleSplideMove = (_splide: SplideType, newIndex: number) => {
|
||||
buttonListData.value = getComponentGroupAry(
|
||||
slideData.value[newIndex],
|
||||
'buttonList'
|
||||
@@ -73,7 +73,7 @@ const onArrowClick = (direction, targetIndex) => {
|
||||
:slide-item-length="slideData?.length"
|
||||
:pagination="false"
|
||||
class="mt-[24px] md:mt-[48px]"
|
||||
@move="handleChange"
|
||||
@move="handleSplideMove"
|
||||
@arrow-click="onArrowClick"
|
||||
>
|
||||
<SplideSlide v-for="(item, index) in slideData" :key="index">
|
||||
|
||||
@@ -44,7 +44,7 @@ const slideItemSize = {
|
||||
},
|
||||
}
|
||||
|
||||
const handleChange = (
|
||||
const handleSplideMove = (
|
||||
_splide: SplideType,
|
||||
newIndex: number,
|
||||
_oldIndex: number,
|
||||
@@ -84,7 +84,7 @@ const onArrowClick = (direction, targetIndex) => {
|
||||
:slide-item-length="slideData?.length"
|
||||
:pagination="false"
|
||||
class="mt-[24px] md:mt-[48px]"
|
||||
@move="handleChange"
|
||||
@move="handleSplideMove"
|
||||
@arrow-click="onArrowClick"
|
||||
>
|
||||
<SplideSlide v-for="(item, index) in slideData" :key="index">
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
getComponentGroup,
|
||||
hasComponentGroup,
|
||||
} from '#layers/utils/dataUtil'
|
||||
import { getPaginationClass } from '#layers/utils/styleUtil'
|
||||
import type { PageDataTemplateComponents } from '#layers/types/api/pageData'
|
||||
|
||||
interface Props {
|
||||
@@ -21,6 +22,9 @@ const { sendLog, useAnalyticsLogDataDirect } = useAnalytics()
|
||||
const slideData = computed(() => {
|
||||
return getComponentContainer(props.components, 'group_sets')
|
||||
})
|
||||
const paginationData = computed(() => {
|
||||
return getComponentGroupAry(props.components, 'pagination')
|
||||
})
|
||||
|
||||
const onArrowClick = direction => {
|
||||
const arrowGroupAry = getComponentGroupAry(props.components, 'arrow')
|
||||
@@ -36,6 +40,7 @@ const onArrowClick = direction => {
|
||||
:arrows="true"
|
||||
:pagination="true"
|
||||
class="h-full"
|
||||
:pagination-data="paginationData"
|
||||
@arrow-click="onArrowClick"
|
||||
>
|
||||
<SplideSlide v-for="(item, index) in slideData" :key="index">
|
||||
@@ -57,7 +62,6 @@ const onArrowClick = direction => {
|
||||
<WidgetsDescription
|
||||
v-if="hasComponentGroup(item, 'description')"
|
||||
:resources-data="getComponentGroup(item, 'description')"
|
||||
class="description-lg"
|
||||
/>
|
||||
<WidgetsButtonList
|
||||
v-if="hasComponentGroup(item, 'buttonList')"
|
||||
|
||||
@@ -105,35 +105,22 @@ export const getColorCode = ({
|
||||
* @returns Record<string, string> CSS 변수 객체
|
||||
*/
|
||||
export const getPaginationClass = (
|
||||
paginationGroups?: PageDataResourceGroups,
|
||||
{ type }: { type: 'thumbnail' | 'bullet' } = { type: 'bullet' }
|
||||
paginationGroups?: PageDataResourceGroups
|
||||
): Record<string, string> => {
|
||||
// 기본 색상 상수
|
||||
const DEFAULT_ACTIVE = 'var(--primary)'
|
||||
const DEFAULT_DISABLED =
|
||||
type === 'bullet' ? 'rgba(0,0,0,0.5)' : 'rgba(255,255,255,0.1)'
|
||||
|
||||
// Early return: 데이터가 없거나 충분하지 않은 경우
|
||||
if (!paginationGroups || paginationGroups.length < 2) {
|
||||
return {
|
||||
'--pagination-active': DEFAULT_ACTIVE,
|
||||
'--pagination-disabled': DEFAULT_DISABLED,
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
// 색상 추출 또는 기본값 사용
|
||||
const paginationActive =
|
||||
getColorCode({
|
||||
colorName: paginationGroups[0]?.display?.color_name,
|
||||
colorCode: paginationGroups[0]?.display?.color_code,
|
||||
}) || DEFAULT_ACTIVE
|
||||
|
||||
const paginationDisabled =
|
||||
getColorCode({
|
||||
colorName: paginationGroups[1]?.display?.color_name,
|
||||
colorCode: paginationGroups[1]?.display?.color_code,
|
||||
}) || DEFAULT_DISABLED
|
||||
const paginationActive = getColorCode({
|
||||
colorName: paginationGroups[0]?.display?.color_name,
|
||||
colorCode: paginationGroups[0]?.display?.color_code,
|
||||
})
|
||||
|
||||
const paginationDisabled = getColorCode({
|
||||
colorName: paginationGroups[1]?.display?.color_name,
|
||||
colorCode: paginationGroups[1]?.display?.color_code,
|
||||
})
|
||||
return {
|
||||
'--pagination-active': paginationActive,
|
||||
'--pagination-disabled': paginationDisabled,
|
||||
|
||||
Reference in New Issue
Block a user