diff --git a/docs/config.md b/docs/config.md index e03a596..1a859ce 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2,26 +2,28 @@ ## Available Props -| Prop | Default | Description | -| ---------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `enabled` | true | Controlled weather the carousel is enabled or disabled. | -| `itemsToShow` | 1 | Count of items to showed per view (can be a fraction). Must be between 1 and the total number of slides. If set to a value less than 1, it defaults to 1. If set to a value greater than the total number of slides, it defaults to the total number of slides. | -| `itemsToScroll` | 1 | Number of slides to be scrolled | -| `wrapAround` | false | Enable infinite scrolling mode. | -| `snapAlign` | 'center' | Controls the carousel position alignment, can be 'start', 'end', 'center-[odd\|even]' | -| `transition` | 300 | Sliding transition time in ms. | -| `autoplay` | 0 | Auto play time in ms. | -| `breakpointMode` | 'viewport' | Determines how the carousel breakpoints are calculated. acceptable values: 'viewport', 'carousel' | -| `breakpoints` | null | An object to pass all the breakpoints settings. | -| `modelValue` | 0 | Index number of the initial slide. | -| `mouseDrag` | true | Toggle mouse dragging | -| `touchDrag` | true | Toggle pointer touch dragging | -| `pauseAutoplayOnHover` | false | Toggle if auto play should pause on mouse hover | -| `dir` | 'ltr' | Controls the carousel direction. Available values: 'ltr', 'rtl', 'ttb', 'btt' or use verbose 'left-to-right', 'right-to-left', 'top-to-bottom', 'bottom-to-top' | -| `i18n` | [`{ ariaNextSlide: ...}`](#i18n) | Used to translate and/or change aria labels and additional texts used in the carousel. | -| `gap` | 0 | Used to add gap between the slides. | -| `height` | 'auto' | Carousel track height. | -| `ignoreAnimations` | false | List of animation names to ignore for size calculations. Can be a boolean, string, or array of strings. | +| Prop | Default | Description | +| -------------------------- | -------------------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `enabled` | true | Controlled weather the carousel is enabled or disabled. | +| `itemsToShow` | 1 | Count of items to showed per view (can be a fraction). Must be between 1 and the total number of slides. If set to a value less than 1, it defaults to 1. If set to a value greater than the total number of slides, it defaults to the total number of slides. | +| `itemsToScroll` | 1 | Number of slides to be scrolled | +| `wrapAround` | false | Enable infinite scrolling mode. | +| `snapAlign` | 'center' | Controls the carousel position alignment, can be 'start', 'end', 'center-[odd\|even]' | +| `transition` | 300 | Sliding transition time in ms. | +| `autoplay` | 0 | Auto play time in ms. | +| `breakpointMode` | 'viewport' | Determines how the carousel breakpoints are calculated. acceptable values: 'viewport', 'carousel' | +| `breakpoints` | null | An object to pass all the breakpoints settings. | +| `modelValue` | 0 | Index number of the initial slide. | +| `mouseDrag` | true | Toggle mouse dragging | +| `touchDrag` | true | Toggle pointer touch dragging | +| `pauseAutoplayOnHover` | false | Toggle if auto play should pause on mouse hover | +| `dir` | 'ltr' | Controls the carousel direction. Available values: 'ltr', 'rtl', 'ttb', 'btt' or use verbose 'left-to-right', 'right-to-left', 'top-to-bottom', 'bottom-to-top' | +| `i18n` | [`{ ariaNextSlide: ...}`](#i18n) | Used to translate and/or change aria labels and additional texts used in the carousel. | +| `gap` | 0 | Used to add gap between the slides. | +| `height` | 'auto' | Carousel track height. | +| `ignoreAnimations` | false | List of animation names to ignore for size calculations. Can be a boolean, string, or array of strings. | +| `preventExcessiveDragging` | false | Prevents unwanted dragging behavior when the carousel reaches its first or last slide. | + ## Slots diff --git a/src/components/Carousel/Carousel.ts b/src/components/Carousel/Carousel.ts index cdffca1..c7d8c80 100644 --- a/src/components/Carousel/Carousel.ts +++ b/src/components/Carousel/Carousel.ts @@ -795,8 +795,27 @@ export const Carousel = defineComponent({ // Include user drag interaction offset const dragOffset = isVertical.value ? dragged.y : dragged.x - const totalOffset = scrolledOffset.value + dragOffset - + let totalOffset = scrolledOffset.value + dragOffset + + if (!config.wrapAround && config.preventExcessiveDragging) { + let maxSlidingValue = 0 + if (isAuto.value) { + maxSlidingValue = slidesRect.value.reduce( + (acc, slide) => acc + slide[dimension.value], + 0 + ) + } else { + maxSlidingValue = + (slidesCount.value - Number(config.itemsToShow)) * effectiveSlideSize.value + } + const min = isReversed.value ? 0 : -1 * maxSlidingValue + const max = isReversed.value ? maxSlidingValue : 0 + totalOffset = getNumberInRange({ + val: totalOffset, + min, + max, + }) + } return `translate${translateAxis}(${totalOffset}px)` }) diff --git a/src/components/Carousel/carouselProps.ts b/src/components/Carousel/carouselProps.ts index b67f9fc..f77485c 100644 --- a/src/components/Carousel/carouselProps.ts +++ b/src/components/Carousel/carouselProps.ts @@ -121,4 +121,17 @@ export const carouselProps = { return SLIDE_EFFECTS.includes(value) }, }, + preventExcessiveDragging: { + default: false, + type: Boolean, + validator(value: boolean, props: { wrapAround?: boolean }) { + if (value && props.wrapAround) + console.warn( /* eslint-disable-line no-console */ + '[vue3-carousel warn]: preventExcessiveDragging cannot be used with wrapAround. ' + + 'The preventExcessiveDragging setting will be ignored.' + ); + + return true; + } + } } diff --git a/src/shared/constants.ts b/src/shared/constants.ts index a44e441..f6870fc 100644 --- a/src/shared/constants.ts +++ b/src/shared/constants.ts @@ -61,4 +61,5 @@ export const DEFAULT_CONFIG: CarouselConfig = { i18n: I18N_DEFAULT_CONFIG, ignoreAnimations: false, slideEffect: SLIDE_EFFECTS[0], + preventExcessiveDragging: false } diff --git a/src/shared/types.ts b/src/shared/types.ts index aaa9a9e..0999313 100644 --- a/src/shared/types.ts +++ b/src/shared/types.ts @@ -47,6 +47,7 @@ export interface CarouselConfig { i18n: { [key in I18nKeys]?: string } ignoreAnimations: boolean | string[] | string slideEffect: SlideEffect + preventExcessiveDragging: boolean } export type VueClass = string | Record | VueClass[]