feat. GR_GALLERY_03 템플릿 제작

This commit is contained in:
clkim
2025-09-26 13:58:27 +09:00
parent 201815c5ac
commit 7d38b72d24
8 changed files with 487 additions and 75 deletions

View File

@@ -5,7 +5,7 @@ import type { SlideItemSize } from '#layers/types/components/slide'
interface Props {
slideItemSize: SlideItemSize
type?: 'loop' | 'slide'
slideItemLength?: number
autoplay?: boolean | string
arrows?: boolean
pagination?: boolean
@@ -13,22 +13,27 @@ interface Props {
}
const props = withDefaults(defineProps<Props>(), {
type: 'loop',
autoplay: false,
arrows: true,
pagination: true,
})
const emit = defineEmits(['mounted', 'move', 'moved'])
const isMultipleItems = computed(() => {
return props.slideItemLength > 1
})
const options = computed((): ResponsiveOptions => {
return {
type: props.type,
type: isMultipleItems.value ? 'loop' : 'slide',
focus: 'center',
autoWidth: true,
autoHeight: true,
speed: 400,
updateOnMove: true,
arrows: props.arrows,
pagination: props.pagination,
arrows: props.arrows && isMultipleItems.value,
pagination: props.pagination && isMultipleItems.value,
autoplay: props.autoplay,
classes: {
arrows: 'splide-arrows',
@@ -71,13 +76,37 @@ const style = computed(() => {
})
const handleSplideMounted = (splide: SplideType) => {
emit('mounted', splide)
splide.refresh()
}
const handleMove = (
splide: SplideType,
newIndex: number,
oldIndex: number,
destIndex: number
) => {
emit('move', splide, newIndex, oldIndex, destIndex)
}
const handleMoved = (
splide: SplideType,
newIndex: number,
oldIndex: number,
destIndex: number
) => {
emit('moved', splide, newIndex, oldIndex, destIndex)
}
</script>
<template>
<div :class="`center-highlight ${props.class || ''}`" :style="style">
<Splide :options="options" @splide:mounted="handleSplideMounted">
<Splide
:options="options"
@splide:mounted="handleSplideMounted"
@splide:move="handleMove"
@splide:moved="handleMoved"
>
<slot />
</Splide>
</div>
@@ -93,9 +122,18 @@ const handleSplideMounted = (splide: SplideType) => {
height: var(--banner-height-mo-active);
margin-right: var(--banner-gap-mo);
}
.center-highlight:deep(.splide__slide) .slide-inner {
width: var(--banner-width-mo);
height: var(--banner-height-mo);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.center-highlight:deep(.splide__slide.is-active) {
width: var(--banner-width-mo-container);
}
.center-highlight:deep(.splide__slide.is-active) .slide-inner {
width: var(--banner-width-mo-active);
height: var(--banner-height-mo-active);
}
/* PC 스타일 */
@media (min-width: 1024px) {
@@ -104,9 +142,17 @@ const handleSplideMounted = (splide: SplideType) => {
height: var(--banner-height-pc-active);
margin-right: var(--banner-gap-pc);
}
.center-highlight:deep(.splide__slide) .slide-inner {
width: var(--banner-width-pc);
height: var(--banner-height-pc);
}
.center-highlight:deep(.splide__slide.is-active) {
width: var(--banner-width-pc-container);
}
.center-highlight:deep(.splide__slide.is-active) .slide-inner {
width: var(--banner-width-pc-active);
height: var(--banner-height-pc-active);
}
.center-highlight:deep(.splide-arrow) {
left: 50%;
transform: translate(-50%, -50%);