diff --git a/src/components/Carousel/Carousel.ts b/src/components/Carousel/Carousel.ts index a2dd7dd9..2e3034af 100644 --- a/src/components/Carousel/Carousel.ts +++ b/src/components/Carousel/Carousel.ts @@ -8,7 +8,6 @@ import { computed, h, watch, - cloneVNode, VNode, SetupContext, Ref, @@ -21,7 +20,6 @@ import { } from 'vue' import { ARIA as ARIAComponent } from '@/components/ARIA' -import { Slide } from '@/components/Slide' import { injectCarousel } from '@/injectSymbols' import { CarouselConfig, @@ -38,6 +36,7 @@ import { mapNumberToRange, getScrolledIndex, getTransformValues, + createCloneSlides, } from '@/utils' import { @@ -678,35 +677,12 @@ export const Carousel = defineComponent({ const addonsElements = slotAddons?.(data) || [] if (config.wrapAround) { - // Ensure scoped css tracks properly - pushScopeId(output.length > 0 ? output[0].scopeId : null) + // Ensure scoped CSS tracks properly + const scopeId = output.length > 0 ? output[0].scopeId : null + pushScopeId(scopeId) const toShow = clonedSlidesCount.value - const slidesBefore = [] - for (let i = -toShow; i < 0; i++) { - const props = { - index: i, - isClone: true, - key: `clone-before-${i}`, - } - slidesBefore.push( - slides.length > 0 - ? cloneVNode(slides[(i + slides.length) % slides.length].vnode, props) - : h(Slide, props) - ) - } - const slidesAfter = [] - for (let i = 0; i < toShow; i++) { - const props = { - index: slides.length > 0 ? i + slides.length : i + 99999, - isClone: true, - key: `clone-after-${i}`, - } - slidesAfter.push( - slides.length > 0 - ? cloneVNode(slides[i % slides.length].vnode, props) - : h(Slide, props) - ) - } + const slidesBefore = createCloneSlides({ slides, position: 'before', toShow }) + const slidesAfter = createCloneSlides({ slides, position: 'after', toShow }) popScopeId() output = [...slidesBefore, ...output, ...slidesAfter] } diff --git a/src/utils/createCloneSlides.ts b/src/utils/createCloneSlides.ts new file mode 100644 index 00000000..3b7eaff3 --- /dev/null +++ b/src/utils/createCloneSlides.ts @@ -0,0 +1,32 @@ +import { cloneVNode, ComponentInternalInstance, h } from 'vue' + +import { Slide } from '@/components/Slide' + +type CreateCloneSlidesArgs = { + slides: Array + position: 'before' | 'after' + toShow: number +} + +export function createCloneSlides({ slides, position, toShow }: CreateCloneSlidesArgs) { + const clones = [] + const isBefore = position === 'before' + const start = isBefore ? -toShow : 0 + const end = isBefore ? 0 : toShow + + for (let i = start; i < end; i++) { + const index = isBefore ? i : slides.length > 0 ? i + slides.length : i + 99999 + const props = { + index, + isClone: true, + key: `clone-${position}-${i}`, + } + clones.push( + slides.length > 0 + ? cloneVNode(slides[(i + slides.length) % slides.length].vnode, props) + : h(Slide, props) + ) + } + + return clones +} diff --git a/src/utils/index.ts b/src/utils/index.ts index 35394bc7..d1a098b7 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -6,3 +6,4 @@ export * from './mapNumberToRange' export * from './i18nFormatter' export * from './throttle' export * from './getTransformValues' +export * from './createCloneSlides'