Files
web-temp/layers/components/widgets/slide/Fade.vue
2026-01-16 14:55:02 +09:00

108 lines
2.3 KiB
Vue

<script setup lang="ts">
import { Splide, SplideTrack } from '@splidejs/vue-splide'
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 {
drag?: boolean
autoplay?: boolean
interval?: number
arrows?: boolean
arrowsData?: PageDataResourceGroups
pagination?: boolean
paginationData?: PageDataResourceGroups
}
const props = withDefaults(defineProps<Props>(), {
drag: true,
autoplay: false,
interval: 5000,
arrows: true,
pagination: true,
})
const emit = defineEmits(['mounted', 'move'])
const splideIndex = defineModel<number>('index', { required: false })
const splideRef = ref()
const options = computed((): ResponsiveOptions => {
return {
type: 'fade',
rewind: true,
perPage: 1,
perMove: 1,
speed: 600,
easing: 'ease-in-out',
updateOnMove: true,
drag: props.drag,
autoplay: props.autoplay,
interval: props.interval,
pauseOnHover: false,
pauseOnFocus: false,
arrows: props.arrows,
pagination: props.pagination,
flickPower: 300,
lazyLoad: 'nearby',
classes: {
pagination: 'splide-pagination-bullets type-full',
page: 'splide-pagination-bullet',
},
}
})
const handleSplideMounted = (splide: SplideType) => {
emit('mounted', splide)
if (splideIndex.value !== undefined) {
splideIndex.value = splide.index
}
}
const handleMove = (
splide: SplideType,
newIndex: number,
oldIndex: number,
destIndex: number
) => {
emit('move', splide, newIndex, oldIndex, destIndex)
if (splideIndex.value !== undefined) {
splideIndex.value = newIndex
}
}
defineExpose({
splide: computed(() => splideRef.value?.splide),
})
</script>
<template>
<Splide
ref="splideRef"
:options="options"
:has-track="false"
class="h-full"
:style="getPaginationClass(props.paginationData)"
@splide:mounted="handleSplideMounted"
@splide:move="handleMove"
>
<SplideTrack>
<slot />
</SplideTrack>
<BlocksButtonSlideArrows
v-if="props.arrows"
:arrows-data="props.arrowsData"
class="type-full"
/>
</Splide>
</template>
<style scoped>
.splide:deep(.splide__track) {
@apply h-full;
}
</style>