Example

<div
  x-data="carousel"
  :data-items="['mononoke033.jpg', 'mononoke035.jpg', 'mononoke032.jpg']"
  class="relative flex items-center justify-center overflow-hidden"
>
  <template x-for="(i, index) in getItems">
    <div
      x-bind="item"
      x-alt-transition='{
        "enter": ["opacity-0", "transition ease-in-out duration-300", "opacity-100"],
        "leave": ["opacity-100", "transition ease-in-out duration-300 absolute top-0", "opacity-0"]
      }'
    >
      <img :src="'/images/' + i" alt="" />
      <div
        data-text
        class="absolute bottom-14 left-1/2 -translate-x-1/2 empty:hidden"
      ></div>
    </div>
  </template>
  <button
    class="absolute top-1/2 left-4 -translate-y-1/2 rounded-full bg-gray-200/80 p-3 text-black hover:bg-gray-200"
    x-bind="prevButton"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 320 512"
      fill="currentColor"
      class="h-4 w-4"
    >
      <path
        d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z"
      />
    </svg>
  </button>
  <button
    class="absolute top-1/2 right-4 -translate-y-1/2 rounded-full bg-gray-200/80 p-3 text-black hover:bg-gray-200"
    x-bind="nextButton"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 320 512"
      fill="currentColor"
      class="h-4 w-4"
    >
      <path
        d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"
      />
    </svg>
  </button>
  <div
    class="absolute bottom-4 left-1/2 flex -translate-x-1/2 gap-x-4 bg-transparent px-2 py-2"
  >
    <template x-for="(i, index) in getItems">
      <div
        x-bind="indicator"
        class="h-3 w-3 rounded-full"
        class-default="bg-gray-400 hover:bg-gray-300"
        class-current="bg-white"
      ></div>
    </template>
  </div>
</div>

Usage

<script defer src="https://cdn.jsdelivr.net/npm/litewind-alpine@0.x.x/carousel/dropdown/dist/cdn.min.js"></script>

The data for the component is provided by the carousel function in the x-data directive and the props in the data-* attributes.

Props

data-items
[] Array

Array of items to display in the carousel


data-auto-play
0 Number

This prop enables automatic playing of slides. The value is a time interval in milliseconds.


data-no-first-and-last-button
false Boolean

Hides the previous button on the first slide and the next button on the last slide.

Auto play

Add the data-auto-play prop to automatically transition to the next slide. The prop value is a time interval in milliseconds.

Example

<div
  x-data="carousel"
  :data-items="['mononoke033.jpg', 'mononoke035.jpg', 'mononoke032.jpg']"
  data-auto-play="5000"
  class="relative flex items-center justify-center overflow-hidden"
>
  <template x-for="(i, index) in getItems">
    <div
      x-bind="item"
      x-alt-transition='{
        "enter": ["opacity-0", "transition ease-in-out duration-300", "opacity-100"],
        "leave": ["opacity-100", "transition ease-in-out duration-300 absolute top-0", "opacity-0"]
      }'
    >
      <img :src="'/images/' + i" alt="" />
      <div
        data-text
        class="absolute bottom-14 left-1/2 -translate-x-1/2 empty:hidden"
      ></div>
    </div>
  </template>
  <button
    class="absolute top-1/2 left-4 -translate-y-1/2 rounded-full bg-gray-200/80 p-3 text-black hover:bg-gray-200"
    x-bind="prevButton"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 320 512"
      fill="currentColor"
      class="h-4 w-4"
    >
      <path
        d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z"
      />
    </svg>
  </button>
  <button
    class="absolute top-1/2 right-4 -translate-y-1/2 rounded-full bg-gray-200/80 p-3 text-black hover:bg-gray-200"
    x-bind="nextButton"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 320 512"
      fill="currentColor"
      class="h-4 w-4"
    >
      <path
        d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"
      />
    </svg>
  </button>
  <div
    class="absolute bottom-4 left-1/2 flex -translate-x-1/2 gap-x-4 bg-transparent px-2 py-2"
  >
    <template x-for="(i, index) in getItems">
      <div
        x-bind="indicator"
        class="h-3 w-3 rounded-full"
        class-default="bg-gray-400 hover:bg-gray-300"
        class-current="bg-white"
      ></div>
    </template>
  </div>
</div>

Transition

The next example shows how you can customize the carousel transition. This transition is slightly more advanced than the default one:

  • the transition-none class is added in the first frames to cancel the previous transition and prevent glitches when switching slides too quickly.
  • the data-prev and data-next variants are used to move slides left or right based on the direction
  • the motion-reduce variant is used to prevent transition from playing if the user has prefers-reduced-motion enabled. To add a fallback transition, such as opacity, you can use the motion-safe variant.
Example

<div
  x-data="carousel"
  :data-items="['mononoke033.jpg', 'mononoke035.jpg', 'mononoke032.jpg']"
  class="relative flex items-center justify-center overflow-hidden"
>
  <template x-for="(i, index) in getItems">
    <div
      x-bind="item"
      x-alt-transition='{
        "enter": ["transition-none data-prev:-translate-x-full data-next:translate-x-full", "motion-reduce:transition-none transition ease-in-out duration-300", ""],
        "leave": ["transition-none", "motion-reduce:transition-none transition ease-in-out duration-300 absolute top-0", "data-prev:translate-x-full data-next:-translate-x-full"]
      }'
    >
      <img :src="'/images/' + i" alt="" />
      <div
        data-text
        class="absolute bottom-14 left-1/2 -translate-x-1/2 empty:hidden"
      ></div>
    </div>
  </template>
  <button
    class="absolute top-1/2 left-4 -translate-y-1/2 rounded-full bg-gray-200/80 p-3 text-black hover:bg-gray-200"
    x-bind="prevButton"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 320 512"
      fill="currentColor"
      class="h-4 w-4"
    >
      <path
        d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z"
      />
    </svg>
  </button>
  <button
    class="absolute top-1/2 right-4 -translate-y-1/2 rounded-full bg-gray-200/80 p-3 text-black hover:bg-gray-200"
    x-bind="nextButton"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 320 512"
      fill="currentColor"
      class="h-4 w-4"
    >
      <path
        d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"
      />
    </svg>
  </button>
  <div
    class="absolute bottom-4 left-1/2 flex -translate-x-1/2 gap-x-4 bg-transparent px-2 py-2"
  >
    <template x-for="(i, index) in getItems">
      <div
        x-bind="indicator"
        class="h-3 w-3 rounded-full"
        class-default="bg-gray-400 hover:bg-gray-300"
        class-current="bg-white"
      ></div>
    </template>
  </div>
</div>

Hide controls

If you need to permanently hide navigation controls, simply delete them from the template.

To hide them selectively or based on the component's state, check the following two examples.

You can use data-no-first-and-last-button prop to hide the "previous" button of the first slide and the "next" button of the last slide.

Example

<div
  x-data="carousel"
  :data-items="['mononoke033.jpg', 'mononoke035.jpg', 'mononoke032.jpg']"
  data-no-first-and-last-button
  class="relative flex items-center justify-center overflow-hidden"
>
  <template x-for="(i, index) in getItems">
    <div
      x-bind="item"
      x-alt-transition='{
        "enter": ["opacity-0", "transition ease-in-out duration-300", "opacity-100"],
        "leave": ["opacity-100", "transition ease-in-out duration-300 absolute top-0", "opacity-0"]
      }'
    >
      <img :src="'/images/' + i" alt="" />
      <div
        data-text
        class="absolute bottom-14 left-1/2 -translate-x-1/2 empty:hidden"
      ></div>
    </div>
  </template>
  <button
    class="absolute top-1/2 left-4 -translate-y-1/2 rounded-full bg-gray-200/80 p-3 text-black hover:bg-gray-200"
    x-bind="prevButton"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 320 512"
      fill="currentColor"
      class="h-4 w-4"
    >
      <path
        d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z"
      />
    </svg>
  </button>
  <button
    class="absolute top-1/2 right-4 -translate-y-1/2 rounded-full bg-gray-200/80 p-3 text-black hover:bg-gray-200"
    x-bind="nextButton"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 320 512"
      fill="currentColor"
      class="h-4 w-4"
    >
      <path
        d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"
      />
    </svg>
  </button>
  <div
    class="absolute bottom-4 left-1/2 flex -translate-x-1/2 gap-x-4 bg-transparent px-2 py-2"
  >
    <template x-for="(i, index) in getItems">
      <div
        x-bind="indicator"
        class="h-3 w-3 rounded-full"
        class-default="bg-gray-400 hover:bg-gray-300"
        class-current="bg-white"
      ></div>
    </template>
  </div>
</div>

To hide navigation controls based on the component state, you can use Tailwind's group class. In the next example, the buttons are displayed when the pointer hovers over the carousel.

Example

<div
  x-data="carousel"
  :data-items="['mononoke033.jpg', 'mononoke035.jpg', 'mononoke032.jpg']"
  class="relative flex items-center justify-center overflow-hidden group"
>
  <template x-for="(i, index) in getItems">
    <div
      x-bind="item"
      x-alt-transition='{
        "enter": ["opacity-0", "transition ease-in-out duration-300", "opacity-100"],
        "leave": ["opacity-100", "transition ease-in-out duration-300 absolute top-0", "opacity-0"]
      }'
    >
      <img :src="'/images/' + i" alt="" />
      <div
        data-text
        class="absolute bottom-14 left-1/2 -translate-x-1/2 empty:hidden"
      ></div>
    </div>
  </template>
  <button
    class="absolute top-1/2 left-4 -translate-y-1/2 rounded-full bg-gray-200/80 p-3 text-black hover:bg-gray-200 transition duration-200 opacity-0 group-hover:opacity-100 -translate-x-full group-hover:translate-x-0"
    x-bind="prevButton"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 320 512"
      fill="currentColor"
      class="h-4 w-4"
    >
      <path
        d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z"
      />
    </svg>
  </button>
  <button
    class="absolute top-1/2 right-4 -translate-y-1/2 rounded-full bg-gray-200/80 p-3 text-black hover:bg-gray-200 transition duration-200 opacity-0 group-hover:opacity-100 translate-x-full group-hover:-translate-x-0"
    x-bind="nextButton"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 320 512"
      fill="currentColor"
      class="h-4 w-4"
    >
      <path
        d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"
      />
    </svg>
  </button>
  <div
    class="absolute bottom-4 left-1/2 flex -translate-x-1/2 gap-x-4 bg-transparent px-2 py-2"
  >
    <template x-for="(i, index) in getItems">
      <div
        x-bind="indicator"
        class="h-3 w-3 rounded-full"
        class-default="bg-gray-400 hover:bg-gray-300"
        class-current="bg-white"
      ></div>
    </template>
  </div>
</div>
Litewind-alpine 0.1.0