diff --git a/packages/0/src/components/Carousel/CarouselViewport.vue b/packages/0/src/components/Carousel/CarouselViewport.vue index 0bd719f3d..9a71e95c6 100644 --- a/packages/0/src/components/Carousel/CarouselViewport.vue +++ b/packages/0/src/components/Carousel/CarouselViewport.vue @@ -68,6 +68,7 @@ } = defineProps() const carousel = useCarouselRoot(namespace) + const isVertical = toRef(() => carousel.orientation.value === 'vertical') const isDragging = shallowRef(false) const syncing = shallowRef(false) @@ -79,15 +80,18 @@ const ticket = carousel.parts.register({ type: 'viewport', el }) onBeforeUnmount(() => ticket.unregister()) - const { width } = useElementSize(el) + const { width, height } = useElementSize(el) const slideStep = toRef(() => { - if (!el.value || width.value === 0) return 0 + if (!el.value) return 0 + if ((isVertical.value ? height.value : width.value) === 0) return 0 + const first = toValue((carousel.seek('first') as CarouselTicket | undefined)?.el) as HTMLElement | undefined const second = toValue((carousel.seek('first', 1) as CarouselTicket | undefined)?.el) as HTMLElement | undefined + if (!first) return 0 - if (!second) return first.offsetWidth - return second.offsetLeft - first.offsetLeft + if (!second) return isVertical.value ? first.offsetHeight : first.offsetWidth + return isVertical.value ? second.offsetTop - first.offsetTop : second.offsetLeft - first.offsetLeft }) if (IN_BROWSER) { @@ -102,8 +106,7 @@ isDragging.value = false - const isVertical = carousel.orientation.value === 'vertical' - const scrollPos = isVertical ? viewport.scrollTop : viewport.scrollLeft + const scrollPos = isVertical.value ? viewport.scrollTop : viewport.scrollLeft const snapIndex = Math.round(scrollPos / slideStep.value) const id = carousel.lookup(snapIndex) @@ -118,18 +121,18 @@ } }) - let lastShiftWheel = 0 + let lastWheel = 0 useEventListener(el, 'wheel', (e: WheelEvent) => { - if (!e.shiftKey) return + if (e.shiftKey === isVertical.value) return const delta = e.deltaY || e.deltaX if (delta === 0) return e.preventDefault() const now = performance.now() - if (now - lastShiftWheel < 300) return - lastShiftWheel = now + if (now - lastWheel < 300) return + lastWheel = now if (delta > 0) carousel.next() else carousel.prev() @@ -144,9 +147,8 @@ if (!viewport) return carousel.pause() - const isVertical = carousel.orientation.value === 'vertical' - dragStart = isVertical ? e.clientY : e.clientX - scrollStart = isVertical ? viewport.scrollTop : viewport.scrollLeft + dragStart = isVertical.value ? e.clientY : e.clientX + scrollStart = isVertical.value ? viewport.scrollTop : viewport.scrollLeft snapDisabled.value = true }) @@ -156,11 +158,10 @@ if (!viewport) return e.preventDefault() - const isVertical = carousel.orientation.value === 'vertical' - const pos = isVertical ? e.clientY : e.clientX + const pos = isVertical.value ? e.clientY : e.clientX const delta = pos - dragStart - if (isVertical) { + if (isVertical.value) { viewport.scrollTop = scrollStart - delta } else { viewport.scrollLeft = scrollStart - delta @@ -177,14 +178,13 @@ return } - const isVertical = carousel.orientation.value === 'vertical' - const scrollPos = isVertical ? viewport.scrollTop : viewport.scrollLeft + const scrollPos = isVertical.value ? viewport.scrollTop : viewport.scrollLeft const snapIndex = Math.round(scrollPos / slideStep.value) const position = snapIndex * slideStep.value syncing.value = true viewport.scrollTo({ - [isVertical ? 'top' : 'left']: position, + [isVertical.value ? 'top' : 'left']: position, behavior: carousel.behavior.value, }) @@ -214,24 +214,21 @@ syncing.value = true - const isVertical = carousel.orientation.value === 'vertical' const position = index * slideStep.value viewport.scrollTo({ - [isVertical ? 'top' : 'left']: position, + [isVertical.value ? 'top' : 'left']: position, behavior: carousel.behavior.value, }) }) const viewportStyle = toRef(() => { - const isVertical = carousel.orientation.value === 'vertical' - return { 'display': 'flex', - 'flex-direction': isVertical ? 'column' : 'row', - [isVertical ? 'overflow-y' : 'overflow-x']: 'auto', - [isVertical ? 'overflow-x' : 'overflow-y']: 'hidden', - 'scroll-snap-type': snapDisabled.value ? 'none' : `${isVertical ? 'y' : 'x'} mandatory`, + 'flex-direction': isVertical.value ? 'column' : 'row', + [isVertical.value ? 'overflow-y' : 'overflow-x']: 'auto', + [isVertical.value ? 'overflow-x' : 'overflow-y']: 'hidden', + 'scroll-snap-type': snapDisabled.value ? 'none' : `${isVertical.value ? 'y' : 'x'} mandatory`, 'scrollbar-width': 'none', ...(snapDisabled.value ? { 'user-select': 'none' } : {}), } as Record