fix. slideThumbnail 컴포넌트 수정
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { Splide, SplideSlide } from '@splidejs/vue-splide'
|
||||
import type { Splide as SplideType, Options } from '@splidejs/splide'
|
||||
import type { PageDataTemplateComponentSet } from '#layers/types/api/pageData'
|
||||
import type {
|
||||
PageDataTemplateComponentSet,
|
||||
PageDataResourceGroups,
|
||||
} from '#layers/types/api/pageData'
|
||||
|
||||
interface Props {
|
||||
slideData: PageDataTemplateComponentSet[]
|
||||
paginationData?: PageDataResourceGroups
|
||||
variant?: 'default' | 'media'
|
||||
drag?: boolean
|
||||
}
|
||||
@@ -102,6 +106,7 @@ onBeforeUnmount(() => {
|
||||
ref="thumbsRef"
|
||||
:options="thumbOptions"
|
||||
class="thumbnail-splide"
|
||||
:style="getPaginationClass(paginationData, { type: 'thumbnail' })"
|
||||
>
|
||||
<SplideSlide
|
||||
v-for="(item, index) in props.slideData"
|
||||
@@ -129,12 +134,19 @@ onBeforeUnmount(() => {
|
||||
}
|
||||
.thumbnail-slide {
|
||||
@apply overflow-hidden relative mr-[12px] !border-none rounded-[4px] md:mr-[16px]
|
||||
after:content-[''] after:absolute after:top-0 after:left-0 after:w-full after:h-full
|
||||
after:border after:border-white/60 after:rounded-[4px];
|
||||
after:content-[''] after:absolute after:top-0 after:left-0 after:w-full after:h-full after:border after:rounded-[4px];
|
||||
background-color: var(--pagination-disabled);
|
||||
}
|
||||
.thumbnail-slide:hover,
|
||||
.thumbnail-slide.is-active {
|
||||
@apply after:border-[var(--primary)];
|
||||
background-color: var(--pagination-active);
|
||||
}
|
||||
.thumbnail-slide::after {
|
||||
border-color: var(--pagination-disabled);
|
||||
}
|
||||
.thumbnail-slide:hover::after,
|
||||
.thumbnail-slide.is-active::after {
|
||||
border-color: var(--pagination-active);
|
||||
}
|
||||
|
||||
/* 기본 버전 스타일 */
|
||||
@@ -153,14 +165,15 @@ onBeforeUnmount(() => {
|
||||
@apply right-0;
|
||||
}
|
||||
.thumbnail-carousel.thumbnail-default .thumbnail-slide {
|
||||
@apply aspect-[1/1] w-[8px] bg-red-500 md:w-[80px] md:bg-transparent
|
||||
@apply aspect-[1/1] w-[8px] md:w-[80px]
|
||||
after:hidden md:after:block;
|
||||
}
|
||||
.thumbnail-carousel.thumbnail-default .thumbnail-slide.is-active {
|
||||
@apply bg-blue-500 md:bg-transparent;
|
||||
.thumbnail-carousel.thumbnail-default .thumbnail-slide:hover img,
|
||||
.thumbnail-carousel.thumbnail-default .thumbnail-slide.is-active img {
|
||||
@apply md:grayscale-0 md:opacity-100;
|
||||
}
|
||||
.thumbnail-carousel.thumbnail-default .thumbnail-slide img {
|
||||
@apply hidden md:block;
|
||||
@apply hidden md:block md:grayscale md:opacity-60;
|
||||
}
|
||||
|
||||
/* 미디어 버전 스타일 */
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { SplideSlide } from '@splidejs/vue-splide'
|
||||
import { hasComponentGroup, getComponentGroup } from '#layers/utils/dataUtil'
|
||||
import type { PageDataTemplateComponents } from '#layers/types/api/pageData'
|
||||
|
||||
interface Props {
|
||||
@@ -16,6 +15,9 @@ const currentSlide = ref<number | null>(null)
|
||||
const slideData = computed(() => {
|
||||
return getComponentContainer(props.components, 'group_sets', { maxLength: 5 })
|
||||
})
|
||||
const paginationData = computed(() => {
|
||||
return getComponentGroupAry(props.components, 'pagination')
|
||||
})
|
||||
|
||||
const goToSlide = (index: number) => {
|
||||
const splide = splideRef.value?.splide
|
||||
@@ -73,7 +75,11 @@ onMounted(() => {
|
||||
</div>
|
||||
</SplideSlide>
|
||||
</BlocksSlideFade>
|
||||
<div v-if="slideData && slideData.length > 1" class="splide-pagination">
|
||||
<div
|
||||
v-if="slideData && slideData.length > 1"
|
||||
class="splide-pagination"
|
||||
:style="getPaginationClass(paginationData)"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in slideData"
|
||||
:key="index"
|
||||
@@ -113,25 +119,28 @@ onMounted(() => {
|
||||
@apply flex items-center;
|
||||
}
|
||||
.item-bullet {
|
||||
@apply block w-3 h-3 rounded-full bg-white/30 transition-all duration-300;
|
||||
@apply block w-3 h-3 rounded-full transition-all duration-300;
|
||||
background-color: var(--pagination-disabled);
|
||||
}
|
||||
.item-title {
|
||||
@apply hidden absolute -bottom-[46px] left-1/2 -translate-x-1/2 whitespace-nowrap text-sm font-medium text-white/30 md:block;
|
||||
@apply hidden absolute -bottom-[46px] left-1/2 -translate-x-1/2 whitespace-nowrap text-sm font-medium md:block;
|
||||
color: var(--pagination-disabled);
|
||||
}
|
||||
.progress-bar {
|
||||
@apply relative w-[68px] h-0.5 bg-white/30 overflow-hidden md:w-[184px];
|
||||
@apply relative w-[68px] h-0.5 overflow-hidden md:w-[184px];
|
||||
background-color: var(--pagination-disabled);
|
||||
}
|
||||
.progress-fill {
|
||||
@apply absolute inset-y-0 left-0 bg-white;
|
||||
width: 0;
|
||||
@apply absolute inset-y-0 left-0 w-[0];
|
||||
background-color: var(--pagination-active);
|
||||
}
|
||||
|
||||
/* 활성화 상태 (현재 슬라이드) */
|
||||
.is-active .item-bullet {
|
||||
@apply bg-white;
|
||||
background-color: var(--pagination-active);
|
||||
}
|
||||
.is-active .item-title {
|
||||
@apply text-white;
|
||||
color: var(--pagination-active);
|
||||
}
|
||||
.is-active .progress-fill {
|
||||
animation: progressFill 5000ms linear forwards;
|
||||
@@ -139,7 +148,7 @@ onMounted(() => {
|
||||
|
||||
/* 완료 상태 (지나간 슬라이드) */
|
||||
.is-completed .item-bullet {
|
||||
@apply bg-white;
|
||||
background-color: var(--pagination-active);
|
||||
}
|
||||
.is-completed .progress-fill {
|
||||
width: 100%;
|
||||
|
||||
@@ -12,11 +12,17 @@ const props = defineProps<Props>()
|
||||
const slideData = computed(() => {
|
||||
return getComponentContainer(props.components, 'group_sets', { maxLength: 7 })
|
||||
})
|
||||
const paginationData = computed(() => {
|
||||
return getComponentGroupAry(props.components, 'pagination')
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="section-container relative">
|
||||
<BlocksSlideThumbnail ref="slideThumbnailRef" :slide-data="slideData">
|
||||
<BlocksSlideThumbnail
|
||||
:slide-data="slideData"
|
||||
:pagination-data="paginationData"
|
||||
>
|
||||
<SplideSlide v-for="(item, index) in slideData" :key="index">
|
||||
<WidgetsBackground
|
||||
v-if="hasComponentGroup(item, 'background')"
|
||||
|
||||
58
layers/templates/GrDetail03/index.vue
Normal file
58
layers/templates/GrDetail03/index.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<script setup lang="ts">
|
||||
import { SplideSlide } from '@splidejs/vue-splide'
|
||||
import type { PageDataTemplateComponents } from '#layers/types/api/pageData'
|
||||
|
||||
interface Props {
|
||||
components: PageDataTemplateComponents
|
||||
pageVerTmplSeq: string
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const slideData = computed(() => {
|
||||
return getComponentContainer(props.components, 'group_sets', {
|
||||
maxLength: 10,
|
||||
})
|
||||
})
|
||||
const paginationData = computed(() => {
|
||||
return getComponentGroupAry(props.components, 'pagination')
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="section-container relative">
|
||||
<BlocksSlideThumbnail
|
||||
:slide-data="slideData"
|
||||
:pagination-data="paginationData"
|
||||
>
|
||||
<SplideSlide v-for="(item, index) in slideData" :key="index">
|
||||
<WidgetsBackground
|
||||
v-if="hasComponentGroup(item, 'background')"
|
||||
:resources-data="getComponentGroup(item, 'background')"
|
||||
/>
|
||||
<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"
|
||||
/>
|
||||
<WidgetsMainTitle
|
||||
v-if="hasComponentGroup(item, 'mainTitle')"
|
||||
:resources-data="getComponentGroup(item, 'mainTitle')"
|
||||
class="title-md line-clamp-1 text-left"
|
||||
/>
|
||||
<WidgetsSubTitle
|
||||
v-if="hasComponentGroup(item, 'subTitle')"
|
||||
:resources-data="getComponentGroup(item, 'subTitle')"
|
||||
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"
|
||||
/>
|
||||
</div>
|
||||
</SplideSlide>
|
||||
</BlocksSlideThumbnail>
|
||||
</section>
|
||||
</template>
|
||||
@@ -3,7 +3,10 @@
|
||||
* @description 스타일 처리에 필요한 유틸리티 함수를 제공합니다.
|
||||
*/
|
||||
|
||||
import type { PageDataResourceGroupResPath } from '#layers/types/api/pageData'
|
||||
import type {
|
||||
PageDataResourceGroups,
|
||||
PageDataResourceGroupResPath,
|
||||
} from '#layers/types/api/pageData'
|
||||
|
||||
/**
|
||||
* [TODO] 수정 필요
|
||||
@@ -94,3 +97,45 @@ export const getColorCode = ({
|
||||
return colorCode
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pagination 활성화, 비활성화 style을 반환합니다.
|
||||
* @param paginationGroups pagination groups 배열
|
||||
* @param options type: 'thumbnail' | 'bullet' (기본값: 'thumbnail')
|
||||
* @returns Record<string, string> CSS 변수 객체
|
||||
*/
|
||||
export const getPaginationClass = (
|
||||
paginationGroups?: PageDataResourceGroups,
|
||||
{ type }: { type: 'thumbnail' | 'bullet' } = { type: 'bullet' }
|
||||
): 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,
|
||||
}
|
||||
}
|
||||
|
||||
// 색상 추출 또는 기본값 사용
|
||||
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
|
||||
|
||||
return {
|
||||
'--pagination-active': paginationActive,
|
||||
'--pagination-disabled': paginationDisabled,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user