diff --git a/packages/embla-carousel-docs/src/content/pages/api/methods.mdx b/packages/embla-carousel-docs/src/content/pages/api/methods.mdx
index 8eb582ec..1946fde6 100644
--- a/packages/embla-carousel-docs/src/content/pages/api/methods.mdx
+++ b/packages/embla-carousel-docs/src/content/pages/api/methods.mdx
@@ -322,10 +322,10 @@ Scroll to the previous scroll snap if possible. When [loop](/api/options/#loop)
### scrollToSnap
-Parameters: `index: number`, `jump?: boolean`
+Parameters: `index: number`, `jump?: boolean`, `direction?: 'forward' | 'backward'`
Returns: `void`
-Scroll to a scroll snap by its unique index. If [loop](/api/options/#loop) is enabled, Embla Carousel will choose the closest way to the target scroll snap. Set the **jump** parameter to `true` when you want to go to the desired scroll snap instantly.
+Scroll to a scroll snap by its unique index. Set the **jump** parameter to `true` when you want to go to the desired scroll snap instantly. If [loop](/api/options/#loop) is enabled and the **direction** parameter is omitted, Embla Carousel will choose the closest way to the target scroll snap.
**Note:** A scroll snap isn't equvialent to a slide. A scroll snap can hold
@@ -339,10 +339,10 @@ Scroll to a scroll snap by its unique index. If [loop](/api/options/#loop) is en
### scrollToSlide
-Parameters: `subject: number | HTMLElement`, `jump?: boolean`
+Parameters: `subject: number | HTMLElement`, `jump?: boolean`, `direction?: 'forward' | 'backward'`
Returns: `void`
-Scroll to a scroll snap by providing a slide index or a slide element. The carousel will scroll to the scroll snap that holds the provided slide. If [loop](/api/options/#loop) is enabled, Embla Carousel will choose the closest way to the target scroll snap. Set the **jump** parameter to `true` when you want to go to the desired scroll snap instantly.
+Scroll to a scroll snap by providing a slide index or a slide element. The carousel will scroll to the scroll snap that holds the provided slide. Set the **jump** parameter to `true` when you want to go to the desired scroll snap instantly. If [loop](/api/options/#loop) is enabled and the **direction** parameter is omitted, Embla Carousel will choose the closest way to the target scroll snap.
---
diff --git a/packages/embla-carousel/src/components/EmblaCarousel.ts b/packages/embla-carousel/src/components/EmblaCarousel.ts
index e28af8e9..320816d2 100644
--- a/packages/embla-carousel/src/components/EmblaCarousel.ts
+++ b/packages/embla-carousel/src/components/EmblaCarousel.ts
@@ -7,6 +7,7 @@ import { OptionsHandler } from './OptionsHandler'
import { PluginsHandler } from './PluginsHandler'
import { EmblaPluginsType, EmblaPluginType } from './Plugins'
import { isNumber, isString, WindowType } from './utils'
+import { ScrollToDirectionType } from './ScrollTo'
export type EmblaCarouselType = {
canScrollNext: () => boolean
@@ -28,12 +29,20 @@ export type EmblaCarouselType = {
scrollPrev: (jump?: boolean) => void
scrollProgress: () => number
snapList: () => number[]
- scrollToSnap: (index: number, jump?: boolean) => void
- scrollToSlide: (subject: number | HTMLElement, jump?: boolean) => void
selectedSnap: () => number
slideNodes: () => HTMLElement[]
slidesInView: () => number[]
slidesNotInView: () => number[]
+ scrollToSnap: (
+ index: number,
+ jump?: boolean,
+ direction?: ScrollToDirectionType
+ ) => void
+ scrollToSlide: (
+ subject: number | HTMLElement,
+ jump?: boolean,
+ direction?: ScrollToDirectionType
+ ) => void
}
function EmblaCarousel(
@@ -168,19 +177,19 @@ function EmblaCarousel(
function scrollToSnap(
index: number,
jump?: boolean,
- direction?: number
+ direction?: ScrollToDirectionType
): void {
if (!options.active || destroyed) return
engine.scrollBody
.useBaseFriction()
.useDuration(jump === true ? 0 : options.duration)
- engine.scrollTo.index(index, direction || 0)
+ engine.scrollTo.index(index, direction)
}
function scrollToSlide(
subject: number | HTMLElement,
jump?: boolean,
- direction?: number
+ direction?: ScrollToDirectionType
): void {
const index = isNumber(subject) ? subject : slides.indexOf(subject)
const snapIndex = engine.slideRegistry.findIndex((g) => g.includes(index))
diff --git a/packages/embla-carousel/src/components/ScrollTarget.ts b/packages/embla-carousel/src/components/ScrollTarget.ts
index 1408b260..6c5dce21 100644
--- a/packages/embla-carousel/src/components/ScrollTarget.ts
+++ b/packages/embla-carousel/src/components/ScrollTarget.ts
@@ -1,4 +1,5 @@
import { LimitType } from './Limit'
+import { DirectionType } from './ScrollTo'
import { Vector1DType } from './Vector1d'
import { arrayLast, mathAbs, mathSign } from './utils'
@@ -8,9 +9,9 @@ export type TargetType = {
}
export type ScrollTargetType = {
- byIndex: (target: number, direction: number) => TargetType
+ byIndex: (target: number, direction: DirectionType) => TargetType
byDistance: (force: number, snap: boolean) => TargetType
- shortcut: (target: number, direction: number) => number
+ shortcut: (target: number, direction: DirectionType) => number
}
export function ScrollTarget(
@@ -36,7 +37,7 @@ export function ScrollTarget(
return { index, distance }
}
- function shortcut(target: number, direction: number): number {
+ function shortcut(target: number, direction: DirectionType): number {
const targets = [target, target + contentSize, target - contentSize]
if (!loop) return target
@@ -47,7 +48,7 @@ export function ScrollTarget(
return arrayLast(targets) - contentSize
}
- function byIndex(index: number, direction: number): TargetType {
+ function byIndex(index: number, direction: DirectionType): TargetType {
const diffToSnap = scrollSnaps[index] - targetVector.get()
const distance = shortcut(diffToSnap, direction)
return { index, distance }
diff --git a/packages/embla-carousel/src/components/ScrollTo.ts b/packages/embla-carousel/src/components/ScrollTo.ts
index 98a17c05..0f444551 100644
--- a/packages/embla-carousel/src/components/ScrollTo.ts
+++ b/packages/embla-carousel/src/components/ScrollTo.ts
@@ -4,10 +4,14 @@ import { EventHandlerType } from './EventHandler'
import { ScrollBodyType } from './ScrollBody'
import { ScrollTargetType, TargetType } from './ScrollTarget'
import { Vector1DType } from './Vector1d'
+import { isNumber } from './utils'
+
+export type DirectionType = 0 | 1 | -1
+export type ScrollToDirectionType = 'forward' | 'backward' | DirectionType
export type ScrollToType = {
distance: (n: number, snap: boolean) => void
- index: (n: number, direction: number) => void
+ index: (n: number, direction?: ScrollToDirectionType) => void
}
export function ScrollTo(
@@ -47,12 +51,18 @@ export function ScrollTo(
scrollTo(target)
}
- function index(n: number, direction: number): void {
- const targetIndex = indexCurrent.clone().set(n)
- const target = scrollTarget.byIndex(targetIndex.get(), direction)
+ function index(n: number, direction?: ScrollToDirectionType): void {
+ const targetIndex = indexCurrent.clone().set(n).get()
+ const target = scrollTarget.byIndex(targetIndex, getDirection(direction))
scrollTo(target)
}
+ function getDirection(direction?: ScrollToDirectionType): DirectionType {
+ if (!direction) return 0
+ if (isNumber(direction)) return direction
+ return direction === 'forward' ? -1 : 1
+ }
+
const self: ScrollToType = {
distance,
index