ismail9k / vue3-carousel

Vue 3 carousel component
https://ismail9k.github.io/vue3-carousel/
MIT License
717 stars 172 forks source link

SSR | wrapAround causes wrong order on page load #201

Open graphicfox opened 2 years ago

graphicfox commented 2 years ago

Describe the bug On ssr page load the second slide will get shown first because of oder: -1. This causes a really sharp skip to the correct first slide when the carousel ist initialized on client side and the css order jumps from -1 to 1.

To Reproduce

<Carousel :settings="settings">
   <Slide v-for='slide in slides' :key="slide">
      <image-wrapper :image="slide"></image-wrapper>
   </Slide>
</Carousel>
const settings = {
  itemsToShow: 1,
  snapAlign: "end",
  transition: 1000,
  autoplay: 6000,
  wrapAround: true
};

Expected behavior On page load the slider should load all slides in the provided order.

Additional context

Renderd html

<section class="carousel" dir="ltr" aria-label="Gallery" data-v-6ac4358c="">
   <div class="carousel__viewport">
      <ol class="carousel__track" style="transform:translateX(0px);transition:0ms;">
         <li style="width:100%;order:0;" class="carousel__slide carousel__slide--active carousel__slide--visible" data-v-6ac4358c="">
            <div class="ImageWrapper Jumbotron__image" data-v-6ac4358c="" data-v-ea13a6f8="">
               <img src="/cms/uploads/IMAGE1.jpg" alt="" data-v-ea13a6f8="">
            </div>
         </li>
         <li style="width: 100%; order: -1;" class="carousel__slide" data-v-6ac4358c="">
            <div class="ImageWrapper Jumbotron__image" data-v-6ac4358c="" data-v-ea13a6f8="">
               <img src="/cms/uploads/IMAGE2.jpg" alt="" data-v-ea13a6f8="">
            </div>
         </li>
      </ol>
   </div>
</section>

Temporarily solution only set wrap around on client side

  <Carousel :settings="settings" :wrap-around="isClient">
blood1shot commented 2 months ago

Also reproduced without SSR

blood1shot commented 2 months ago

I found some workaround for this issue. Here my Carousel component usage:

<template lang="pug">
Carousel(
      ref="carousel",
      @init="handleInit",
      :items-to-show="3",
      :wrap-around="isEnabledWrapAround",
      :mouse-drag="false",
      :touch-drag="false",
      :transition="transitionValue",
      v-model="selectedIndexModel"
    )
</template>
<script lang="ts" setup>
...
const isEnabledWrapAround = ref<boolean>(false);
const transitionValue = ref<number>(0);
const carousel = ref(null);

const handleInit = async () => {
  isEnabledWrapAround.value = true;
  await nextTick();
  transitionValue.value = 300;
};
</script>