Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: Dot Buttons for Carousel #521

Open
quankhuc opened this issue May 2, 2024 · 5 comments · May be fixed by #527
Open

[Feature]: Dot Buttons for Carousel #521

quankhuc opened this issue May 2, 2024 · 5 comments · May be fixed by #527

Comments

@quankhuc
Copy link

quankhuc commented May 2, 2024

Adding Support for Dot Buttons in Carousel

The current Carousel does not support Dot Buttons. The library Embla Carousel supports the usage of dot buttons, as shown in this React example. Can we add support for dot buttons?

Updates:
I think this setup for the carousel composable would work:

import { createInjectionState } from '@vueuse/core';
import emblaCarouselVue from 'embla-carousel-vue';
import { onMounted, ref } from 'vue';

const [useProvideCarousel, useInjectCarousel] = createInjectionState(({ opts, orientation, plugins }, emits) => {
  const [emblaNode, emblaApi] = emblaCarouselVue(
    {
      ...opts,
      axis: orientation === 'horizontal' ? 'x' : 'y',
    },
    plugins
  );

  function scrollPrev() {
    emblaApi.value?.scrollPrev();
  }
  function scrollNext() {
    emblaApi.value?.scrollNext();
  }
  function scrollTo(index) {
    emblaApi.value?.scrollTo(index)
  }

  const canScrollNext = ref(true);
  const canScrollPrev = ref(true);
  const selectedIndex = ref(0);
  const scrollSnaps = ref([])

  function onSelect(api) {
    canScrollNext.value = api.canScrollNext();
    canScrollPrev.value = api.canScrollPrev();
    selectedIndex.value = api.selectedScrollSnap();
    scrollSnaps.value = api.scrollSnapList();
  }

  onMounted(() => {
    if (!emblaApi.value) return;

    emblaApi.value?.on('init', onSelect);
    emblaApi.value?.on('reInit', onSelect);
    emblaApi.value?.on('select', onSelect);

    emits('init-api', emblaApi.value);
  });

  return {
    carouselRef: emblaNode,
    carouselApi: emblaApi,
    canScrollPrev,
    canScrollNext,
    scrollPrev,
    scrollNext,
    scrollTo,
    scrollSnaps,
    selectedIndex,
    orientation,
  };
});

function useCarousel() {
  const carouselState = useInjectCarousel();

  if (!carouselState) throw new Error('useCarousel must be used within a <Carousel />');

  return carouselState;
}

export { useCarousel, useProvideCarousel };

And here would be my version of the dot "buttons"

<template>
  <div
    v-for="(item, index) in scrollSnaps"
    :key="index"
    class="sm:mt-0 first:ml-0 border-1 w-2 h-2 mt-2 ml-2 border-gray-200 border-solid rounded-full"
    :class="[cn(props.class), index === selectedIndex ? 'border-transparent bg-blue-400' : 'bg-transparent']"
    @click="scrollTo(index)"
  />
</template>
<script setup>
import { useCarousel } from '~/composables/carousel';
import { cn } from '~/lib/utils';

const props = defineProps({
  class: {
    type: String,
    default: '',
  },
});

const { scrollTo, selectedIndex, scrollSnaps } = useCarousel();
</script>
@marcosgomesneto
Copy link

marcosgomesneto commented May 2, 2024

Very good, it worked for me! Waiting for implementation in the next version.

@quankhuc Are you going to make a pull request?

@quankhuc
Copy link
Author

quankhuc commented May 3, 2024

I can make it! Do you have any guidelines to make a PR? @marcosgomesneto

@zernonia
Copy link
Contributor

zernonia commented May 3, 2024

Nice addition @quankhuc ! Do check out contribution section if you are unsure, and don't hesitate to create a PR for this 😁

@quankhuc
Copy link
Author

quankhuc commented May 3, 2024

Nice addition @quankhuc ! Do check out contribution section if you are unsure, and don't hesitate to create a PR for this 😁

I tried to open a PR but I don't have a permission to make PR to merge into radix-vue/shadcn-vue. Do you have a guideline for me to push a commit and open a PR? I am sorry this is my first time contributing into an open source project so I am not good at this

@zernonia
Copy link
Contributor

zernonia commented May 3, 2024

No problem @quankhuc !

  1. Fork the branch
  2. Clone to your local
  3. Push changes to the forked repo
  4. Create a PR here

@zernonia zernonia linked a pull request May 6, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants