Browse Source

Add the jump method to Controller. Rename Media to Breakpoints.

Naotoshi Fujita 2 years ago
parent
commit
fa747225f7

+ 57 - 41
dist/js/splide.cjs.js

@@ -377,17 +377,24 @@ const EVENT_SLIDE_KEYDOWN = "sk";
 const EVENT_SHIFTED = "sh";
 const EVENT_END_INDEX_CHANGED = "ei";
 
-function Media(Splide2, Components2, options) {
+const NOT_OVERFLOW_KEY = "!overflow";
+function Breakpoints(Splide2, Components2, options, event) {
   const { state } = Splide2;
   const breakpoints = options.breakpoints || {};
   const reducedMotion = options.reducedMotion || {};
   const binder = b();
-  const queries = [];
+  const entries = [];
   function setup() {
     const isMin = options.mediaQuery === "min";
     A(breakpoints).sort((n, m) => isMin ? +n - +m : +m - +n).forEach((key) => {
-      register(breakpoints[key], `(${isMin ? "min" : "max"}-width:${key}px)`);
+      if (key !== NOT_OVERFLOW_KEY) {
+        register(breakpoints[key], `(${isMin ? "min" : "max"}-width:${key}px)`);
+      }
     });
+    if (breakpoints[NOT_OVERFLOW_KEY]) {
+      entries.push([breakpoints[NOT_OVERFLOW_KEY], () => Components2.Layout && !Components2.Layout.isOverflow()]);
+      event.on(EVENT_OVERFLOW, update);
+    }
     register(reducedMotion, MEDIA_PREFERS_REDUCED_MOTION);
     update();
   }
@@ -399,13 +406,13 @@ function Media(Splide2, Components2, options) {
   function register(options2, query) {
     const queryList = matchMedia(query);
     binder.bind(queryList, "change", update);
-    queries.push([options2, queryList]);
+    entries.push([options2, () => queryList.matches]);
   }
   function update() {
     const destroyed = state.is(DESTROYED);
     const direction = options.direction;
-    const merged = queries.reduce((merged2, entry) => {
-      return k(merged2, entry[1].matches ? entry[0] : {});
+    const merged = entries.reduce((merged2, entry) => {
+      return k(merged2, entry[1]() ? entry[0] : {});
     }, {});
     gn(options);
     set(merged);
@@ -782,8 +789,9 @@ function Slide$1(Splide2, index, slideIndex, slide) {
     return diff <= distance;
   }
   function pos() {
+    const first = Components.Slides.get()[0];
     const left = resolve("left");
-    return un(tn(slide)[left] - tn(Elements.list)[left]);
+    return first ? un(tn(slide)[left] - tn(first.slide)[left]) : 0;
   }
   function size() {
     return tn(slide)[resolve("width")];
@@ -1025,7 +1033,7 @@ function Layout(Splide2, Components2, options, event) {
 const MULTIPLIER = 2;
 function Clones(Splide2, Components2, options, event) {
   const { on } = event;
-  const { Elements, Slides } = Components2;
+  const { Elements, Slides, Layout: { resize } } = Components2;
   const { resolve } = Components2.Direction;
   const clones = [];
   let cloneCount;
@@ -1034,12 +1042,13 @@ function Clones(Splide2, Components2, options, event) {
     on([EVENT_UPDATED, EVENT_RESIZE], observe);
     if (cloneCount = computeCloneCount()) {
       generate(cloneCount);
-      Components2.Layout.resize(true);
+      resize(true);
     }
   }
   function remount() {
     destroy();
     mount();
+    resize(true);
   }
   function destroy() {
     en(clones);
@@ -1050,6 +1059,7 @@ function Clones(Splide2, Components2, options, event) {
     const count = computeCloneCount();
     if (cloneCount !== count) {
       if (cloneCount < count || !count) {
+        !count && Splide2.go(0);
         event.emit(EVENT_REFRESH);
       }
     }
@@ -1097,7 +1107,7 @@ function Move(Splide2, Components2, options, event) {
   const { on, emit } = event;
   const { set } = Splide2.state;
   const { Slides } = Components2;
-  const { slideSize, getPadding, listSize, sliderSize } = Components2.Layout;
+  const { slideSize, getPadding, listSize, sliderSize, totalSize } = Components2.Layout;
   const { resolve, orient } = Components2.Direction;
   const { list, track } = Components2.Elements;
   let Transition;
@@ -1173,8 +1183,7 @@ function Move(Splide2, Components2, options, event) {
     return index;
   }
   function toPosition(index, trimming) {
-    const Slide = Slides.getAt(index);
-    const position = Slide ? orient(Slide.pos() - offset(index)) : 0;
+    const position = orient(totalSize(index - 1) - offset(index));
     return trimming ? trim(position) : position;
   }
   function getPosition() {
@@ -1248,7 +1257,7 @@ function Controller(Splide2, Components2, options, event) {
     endIndex = getEnd();
     const end = omitEnd ? endIndex : slideCount - 1;
     const index = bn(currIndex, 0, end);
-    prevIndex = bn(currIndex, 0, end);
+    prevIndex = index;
     if (index !== currIndex) {
       currIndex = index;
       Move.reposition();
@@ -1269,6 +1278,10 @@ function Controller(Splide2, Components2, options, event) {
       }
     }
   }
+  function jump(index) {
+    Move.cancel();
+    scroll(toPosition(index), 0);
+  }
   function scroll(destination, duration, snap, callback) {
     Components2.Scroll.scroll(destination, duration, snap, () => {
       const index = loop(Move.toIndex(getPosition()));
@@ -1382,6 +1395,7 @@ function Controller(Splide2, Components2, options, event) {
   return {
     mount,
     go,
+    jump,
     scroll,
     getNext,
     getPrev,
@@ -1601,9 +1615,9 @@ function Scroll(Splide2, Components2, options, event) {
       const offset = In(destination) * size * Dn(un(destination) / size) || 0;
       destination = Move.toPosition(Components2.Controller.toDest(destination % size)) + offset;
     }
-    const noDistance = Mn(from, destination, 1);
+    const immediately = Mn(from, destination, 1) || duration === 0;
     friction = 1;
-    duration = noDistance ? 0 : duration || $(un(destination - from) / BASE_VELOCITY, MIN_DURATION);
+    duration = immediately ? 0 : duration || $(un(destination - from) / BASE_VELOCITY, MIN_DURATION);
     callback = onScrolled;
     interval = sn(duration, onEnd, a(update, from, destination, noConstrain), 1);
     set(SCROLLING);
@@ -1656,7 +1670,7 @@ function Drag(Splide2, Components2, options, event) {
   const { on, emit, bind } = event;
   const binder = event.create();
   const { state } = Splide2;
-  const { Move, Scroll, Controller, Elements: { track }, Media: { reduce } } = Components2;
+  const { Move, Scroll, Controller, Elements: { track }, Breakpoints: { reduce } } = Components2;
   const { resolve, orient } = Components2.Direction;
   const { getPosition, exceededLimit } = Move;
   let basePosition;
@@ -2116,7 +2130,7 @@ function Sync(Splide2, Components2, options, event) {
   }
   return {
     setup: a(
-      Components2.Media.set,
+      Components2.Breakpoints.set,
       { slideFocus: Z(slideFocus) ? isNavigation : slideFocus },
       true
     ),
@@ -2155,6 +2169,8 @@ function Wheel(Splide2, Components2, options, event) {
   };
 }
 
+const VISUALLY_HIDDEN = `border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px`;
+
 const SR_REMOVAL_DELAY = 90;
 function Live(Splide2, Components2, options, event) {
   const { on } = event;
@@ -2167,7 +2183,7 @@ function Live(Splide2, Components2, options, event) {
       disable(!Components2.Autoplay.isPaused());
       M(track, ARIA_ATOMIC, true);
       sr.textContent = "\u2026";
-      sr.style.cssText = "border: 0; clip: rect(0,0,0,0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px";
+      sr.style.cssText = VISUALLY_HIDDEN;
       on(EVENT_AUTOPLAY_PLAY, a(disable, true));
       on(EVENT_AUTOPLAY_PAUSE, a(disable, false));
       on([EVENT_MOVED, EVENT_SCROLLED], a(toggle, true));
@@ -2179,6 +2195,7 @@ function Live(Splide2, Components2, options, event) {
       Q(track, sr);
       interval.start();
     } else {
+      en(sr);
       interval.cancel();
     }
   }
@@ -2198,27 +2215,26 @@ function Live(Splide2, Components2, options, event) {
   };
 }
 
-var ComponentConstructors = /*#__PURE__*/Object.freeze({
-  __proto__: null,
-  Media: Media,
-  Direction: Direction,
-  Elements: Elements,
-  Slides: Slides,
-  Layout: Layout,
-  Clones: Clones,
-  Move: Move,
-  Controller: Controller,
-  Arrows: Arrows,
-  Autoplay: Autoplay,
-  Scroll: Scroll,
-  Drag: Drag,
-  Keyboard: Keyboard,
-  LazyLoad: LazyLoad,
-  Pagination: Pagination,
-  Sync: Sync,
-  Wheel: Wheel,
-  Live: Live
-});
+const COMPONENTS = {
+  Breakpoints,
+  Direction,
+  Elements,
+  Slides,
+  Layout,
+  Clones,
+  Move,
+  Controller,
+  Arrows,
+  Autoplay,
+  Scroll,
+  Drag,
+  Keyboard,
+  LazyLoad,
+  Pagination,
+  Sync,
+  Wheel,
+  Live
+};
 
 const I18N = {
   prev: "Previous slide",
@@ -2370,7 +2386,7 @@ class Splide {
     this._C = Components2;
     this._T = Transition || (this.is(FADE) ? Fade : Slide);
     this._E = Extensions;
-    const Constructors = v({}, ComponentConstructors, this._E, { Transition: this._T });
+    const Constructors = v({}, COMPONENTS, this._E, { Transition: this._T });
     L(Constructors, (Component, key) => {
       const component = Component(this, Components2, this._o, this.event.create());
       Components2[key] = component;
@@ -2444,7 +2460,7 @@ class Splide {
     return this._o;
   }
   set options(options) {
-    this._C.Media.set(options, true, true);
+    this._C.Breakpoints.set(options, true, true);
   }
   get length() {
     return this._C.Slides.getLength(true);

+ 57 - 41
dist/js/splide.esm.js

@@ -373,17 +373,24 @@ const EVENT_SLIDE_KEYDOWN = "sk";
 const EVENT_SHIFTED = "sh";
 const EVENT_END_INDEX_CHANGED = "ei";
 
-function Media(Splide2, Components2, options) {
+const NOT_OVERFLOW_KEY = "!overflow";
+function Breakpoints(Splide2, Components2, options, event) {
   const { state } = Splide2;
   const breakpoints = options.breakpoints || {};
   const reducedMotion = options.reducedMotion || {};
   const binder = b();
-  const queries = [];
+  const entries = [];
   function setup() {
     const isMin = options.mediaQuery === "min";
     A(breakpoints).sort((n, m) => isMin ? +n - +m : +m - +n).forEach((key) => {
-      register(breakpoints[key], `(${isMin ? "min" : "max"}-width:${key}px)`);
+      if (key !== NOT_OVERFLOW_KEY) {
+        register(breakpoints[key], `(${isMin ? "min" : "max"}-width:${key}px)`);
+      }
     });
+    if (breakpoints[NOT_OVERFLOW_KEY]) {
+      entries.push([breakpoints[NOT_OVERFLOW_KEY], () => Components2.Layout && !Components2.Layout.isOverflow()]);
+      event.on(EVENT_OVERFLOW, update);
+    }
     register(reducedMotion, MEDIA_PREFERS_REDUCED_MOTION);
     update();
   }
@@ -395,13 +402,13 @@ function Media(Splide2, Components2, options) {
   function register(options2, query) {
     const queryList = matchMedia(query);
     binder.bind(queryList, "change", update);
-    queries.push([options2, queryList]);
+    entries.push([options2, () => queryList.matches]);
   }
   function update() {
     const destroyed = state.is(DESTROYED);
     const direction = options.direction;
-    const merged = queries.reduce((merged2, entry) => {
-      return k(merged2, entry[1].matches ? entry[0] : {});
+    const merged = entries.reduce((merged2, entry) => {
+      return k(merged2, entry[1]() ? entry[0] : {});
     }, {});
     gn(options);
     set(merged);
@@ -778,8 +785,9 @@ function Slide$1(Splide2, index, slideIndex, slide) {
     return diff <= distance;
   }
   function pos() {
+    const first = Components.Slides.get()[0];
     const left = resolve("left");
-    return un(tn(slide)[left] - tn(Elements.list)[left]);
+    return first ? un(tn(slide)[left] - tn(first.slide)[left]) : 0;
   }
   function size() {
     return tn(slide)[resolve("width")];
@@ -1021,7 +1029,7 @@ function Layout(Splide2, Components2, options, event) {
 const MULTIPLIER = 2;
 function Clones(Splide2, Components2, options, event) {
   const { on } = event;
-  const { Elements, Slides } = Components2;
+  const { Elements, Slides, Layout: { resize } } = Components2;
   const { resolve } = Components2.Direction;
   const clones = [];
   let cloneCount;
@@ -1030,12 +1038,13 @@ function Clones(Splide2, Components2, options, event) {
     on([EVENT_UPDATED, EVENT_RESIZE], observe);
     if (cloneCount = computeCloneCount()) {
       generate(cloneCount);
-      Components2.Layout.resize(true);
+      resize(true);
     }
   }
   function remount() {
     destroy();
     mount();
+    resize(true);
   }
   function destroy() {
     en(clones);
@@ -1046,6 +1055,7 @@ function Clones(Splide2, Components2, options, event) {
     const count = computeCloneCount();
     if (cloneCount !== count) {
       if (cloneCount < count || !count) {
+        !count && Splide2.go(0);
         event.emit(EVENT_REFRESH);
       }
     }
@@ -1093,7 +1103,7 @@ function Move(Splide2, Components2, options, event) {
   const { on, emit } = event;
   const { set } = Splide2.state;
   const { Slides } = Components2;
-  const { slideSize, getPadding, listSize, sliderSize } = Components2.Layout;
+  const { slideSize, getPadding, listSize, sliderSize, totalSize } = Components2.Layout;
   const { resolve, orient } = Components2.Direction;
   const { list, track } = Components2.Elements;
   let Transition;
@@ -1169,8 +1179,7 @@ function Move(Splide2, Components2, options, event) {
     return index;
   }
   function toPosition(index, trimming) {
-    const Slide = Slides.getAt(index);
-    const position = Slide ? orient(Slide.pos() - offset(index)) : 0;
+    const position = orient(totalSize(index - 1) - offset(index));
     return trimming ? trim(position) : position;
   }
   function getPosition() {
@@ -1244,7 +1253,7 @@ function Controller(Splide2, Components2, options, event) {
     endIndex = getEnd();
     const end = omitEnd ? endIndex : slideCount - 1;
     const index = bn(currIndex, 0, end);
-    prevIndex = bn(currIndex, 0, end);
+    prevIndex = index;
     if (index !== currIndex) {
       currIndex = index;
       Move.reposition();
@@ -1265,6 +1274,10 @@ function Controller(Splide2, Components2, options, event) {
       }
     }
   }
+  function jump(index) {
+    Move.cancel();
+    scroll(toPosition(index), 0);
+  }
   function scroll(destination, duration, snap, callback) {
     Components2.Scroll.scroll(destination, duration, snap, () => {
       const index = loop(Move.toIndex(getPosition()));
@@ -1378,6 +1391,7 @@ function Controller(Splide2, Components2, options, event) {
   return {
     mount,
     go,
+    jump,
     scroll,
     getNext,
     getPrev,
@@ -1597,9 +1611,9 @@ function Scroll(Splide2, Components2, options, event) {
       const offset = In(destination) * size * Dn(un(destination) / size) || 0;
       destination = Move.toPosition(Components2.Controller.toDest(destination % size)) + offset;
     }
-    const noDistance = Mn(from, destination, 1);
+    const immediately = Mn(from, destination, 1) || duration === 0;
     friction = 1;
-    duration = noDistance ? 0 : duration || $(un(destination - from) / BASE_VELOCITY, MIN_DURATION);
+    duration = immediately ? 0 : duration || $(un(destination - from) / BASE_VELOCITY, MIN_DURATION);
     callback = onScrolled;
     interval = sn(duration, onEnd, a(update, from, destination, noConstrain), 1);
     set(SCROLLING);
@@ -1652,7 +1666,7 @@ function Drag(Splide2, Components2, options, event) {
   const { on, emit, bind } = event;
   const binder = event.create();
   const { state } = Splide2;
-  const { Move, Scroll, Controller, Elements: { track }, Media: { reduce } } = Components2;
+  const { Move, Scroll, Controller, Elements: { track }, Breakpoints: { reduce } } = Components2;
   const { resolve, orient } = Components2.Direction;
   const { getPosition, exceededLimit } = Move;
   let basePosition;
@@ -2112,7 +2126,7 @@ function Sync(Splide2, Components2, options, event) {
   }
   return {
     setup: a(
-      Components2.Media.set,
+      Components2.Breakpoints.set,
       { slideFocus: Z(slideFocus) ? isNavigation : slideFocus },
       true
     ),
@@ -2151,6 +2165,8 @@ function Wheel(Splide2, Components2, options, event) {
   };
 }
 
+const VISUALLY_HIDDEN = `border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px`;
+
 const SR_REMOVAL_DELAY = 90;
 function Live(Splide2, Components2, options, event) {
   const { on } = event;
@@ -2163,7 +2179,7 @@ function Live(Splide2, Components2, options, event) {
       disable(!Components2.Autoplay.isPaused());
       M(track, ARIA_ATOMIC, true);
       sr.textContent = "\u2026";
-      sr.style.cssText = "border: 0; clip: rect(0,0,0,0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px";
+      sr.style.cssText = VISUALLY_HIDDEN;
       on(EVENT_AUTOPLAY_PLAY, a(disable, true));
       on(EVENT_AUTOPLAY_PAUSE, a(disable, false));
       on([EVENT_MOVED, EVENT_SCROLLED], a(toggle, true));
@@ -2175,6 +2191,7 @@ function Live(Splide2, Components2, options, event) {
       Q(track, sr);
       interval.start();
     } else {
+      en(sr);
       interval.cancel();
     }
   }
@@ -2194,27 +2211,26 @@ function Live(Splide2, Components2, options, event) {
   };
 }
 
-var ComponentConstructors = /*#__PURE__*/Object.freeze({
-  __proto__: null,
-  Media: Media,
-  Direction: Direction,
-  Elements: Elements,
-  Slides: Slides,
-  Layout: Layout,
-  Clones: Clones,
-  Move: Move,
-  Controller: Controller,
-  Arrows: Arrows,
-  Autoplay: Autoplay,
-  Scroll: Scroll,
-  Drag: Drag,
-  Keyboard: Keyboard,
-  LazyLoad: LazyLoad,
-  Pagination: Pagination,
-  Sync: Sync,
-  Wheel: Wheel,
-  Live: Live
-});
+const COMPONENTS = {
+  Breakpoints,
+  Direction,
+  Elements,
+  Slides,
+  Layout,
+  Clones,
+  Move,
+  Controller,
+  Arrows,
+  Autoplay,
+  Scroll,
+  Drag,
+  Keyboard,
+  LazyLoad,
+  Pagination,
+  Sync,
+  Wheel,
+  Live
+};
 
 const I18N = {
   prev: "Previous slide",
@@ -2366,7 +2382,7 @@ class Splide {
     this._C = Components2;
     this._T = Transition || (this.is(FADE) ? Fade : Slide);
     this._E = Extensions;
-    const Constructors = v({}, ComponentConstructors, this._E, { Transition: this._T });
+    const Constructors = v({}, COMPONENTS, this._E, { Transition: this._T });
     L(Constructors, (Component, key) => {
       const component = Component(this, Components2, this._o, this.event.create());
       Components2[key] = component;
@@ -2440,7 +2456,7 @@ class Splide {
     return this._o;
   }
   set options(options) {
-    this._C.Media.set(options, true, true);
+    this._C.Breakpoints.set(options, true, true);
   }
   get length() {
     return this._C.Slides.getLength(true);

+ 13 - 8
dist/js/splide.js

@@ -377,7 +377,7 @@
   const EVENT_END_INDEX_CHANGED = "ei";
 
   const NOT_OVERFLOW_KEY = "!overflow";
-  function Media(Splide2, Components2, options, event) {
+  function Breakpoints(Splide2, Components2, options, event) {
     const { state } = Splide2;
     const breakpoints = options.breakpoints || {};
     const reducedMotion = options.reducedMotion || {};
@@ -1253,7 +1253,7 @@
       endIndex = getEnd();
       const end = omitEnd ? endIndex : slideCount - 1;
       const index = bn(currIndex, 0, end);
-      prevIndex = bn(currIndex, 0, end);
+      prevIndex = index;
       if (index !== currIndex) {
         currIndex = index;
         Move.reposition();
@@ -1274,6 +1274,10 @@
         }
       }
     }
+    function jump(index) {
+      Move.cancel();
+      scroll(toPosition(index), 0);
+    }
     function scroll(destination, duration, snap, callback) {
       Components2.Scroll.scroll(destination, duration, snap, () => {
         const index = loop(Move.toIndex(getPosition()));
@@ -1387,6 +1391,7 @@
     return {
       mount,
       go,
+      jump,
       scroll,
       getNext,
       getPrev,
@@ -1606,9 +1611,9 @@
         const offset = In(destination) * size * Dn(un(destination) / size) || 0;
         destination = Move.toPosition(Components2.Controller.toDest(destination % size)) + offset;
       }
-      const noDistance = Mn(from, destination, 1);
+      const immediately = Mn(from, destination, 1) || duration === 0;
       friction = 1;
-      duration = noDistance ? 0 : duration || $(un(destination - from) / BASE_VELOCITY, MIN_DURATION);
+      duration = immediately ? 0 : duration || $(un(destination - from) / BASE_VELOCITY, MIN_DURATION);
       callback = onScrolled;
       interval = sn(duration, onEnd, a(update, from, destination, noConstrain), 1);
       set(SCROLLING);
@@ -1661,7 +1666,7 @@
     const { on, emit, bind } = event;
     const binder = event.create();
     const { state } = Splide2;
-    const { Move, Scroll, Controller, Elements: { track }, Media: { reduce } } = Components2;
+    const { Move, Scroll, Controller, Elements: { track }, Breakpoints: { reduce } } = Components2;
     const { resolve, orient } = Components2.Direction;
     const { getPosition, exceededLimit } = Move;
     let basePosition;
@@ -2121,7 +2126,7 @@
     }
     return {
       setup: a(
-        Components2.Media.set,
+        Components2.Breakpoints.set,
         { slideFocus: Z(slideFocus) ? isNavigation : slideFocus },
         true
       ),
@@ -2207,7 +2212,7 @@
   }
 
   const COMPONENTS = {
-    Media,
+    Breakpoints,
     Direction,
     Elements,
     Slides,
@@ -2451,7 +2456,7 @@
       return this._o;
     }
     set options(options) {
-      this._C.Media.set(options, true, true);
+      this._C.Breakpoints.set(options, true, true);
     }
     get length() {
       return this._C.Slides.getLength(true);

File diff suppressed because it is too large
+ 0 - 0
dist/js/splide.min.js


BIN
dist/js/splide.min.js.gz


File diff suppressed because it is too large
+ 0 - 0
dist/js/splide.min.js.map


+ 10 - 23
dist/types/index.d.ts

@@ -120,7 +120,7 @@ declare function State(initialState: number): State;
  *
  * @since 4.0.0
  */
-interface MediaComponent extends BaseComponent {
+interface BreakpointsComponent extends BaseComponent {
     /** @internal */
     reduce(reduced: boolean): void;
     set(options: Options, base?: boolean, notify?: boolean): void;
@@ -167,13 +167,13 @@ interface ElementsComponent extends BaseComponent, ElementCollection {
  * @since 3.0.0
  */
 interface SlideComponent extends BaseComponent {
-    index: number;
-    slideIndex: number;
-    slide: HTMLElement;
-    container: HTMLElement;
-    isClone: boolean;
+    readonly index: number;
+    readonly slideIndex: number;
+    readonly slide: HTMLElement;
+    readonly container: HTMLElement;
+    readonly isClone: boolean;
     update(): void;
-    position(): number;
+    pos(): number;
     size(): number;
     style(prop: CSSProperties, value: string | number, useContainer?: boolean): void;
     isWithin(from: number, distance: number): boolean;
@@ -230,6 +230,7 @@ interface MoveComponent extends BaseComponent {
  */
 interface ControllerComponent extends BaseComponent {
     go(control: number | string, allowSameIndex?: boolean, callback?: AnyFunction): void;
+    jump(index: number): void;
     scroll(destination: number, duration?: number, snap?: boolean, callback?: AnyFunction): void;
     getNext(destination?: boolean): number;
     getPrev(destination?: boolean): number;
@@ -270,14 +271,6 @@ interface AutoplayComponent extends BaseComponent {
     isPaused(): boolean;
 }
 
-/**
- * The interface for the Cover component.
- *
- * @since 3.0.0
- */
-interface CoverComponent extends BaseComponent {
-}
-
 /**
  * The interface for the Scroll component.
  *
@@ -504,11 +497,6 @@ interface Options extends ResponsiveOptions {
      * - 'ttb': Top to bottom
      */
     direction?: 'ltr' | 'rtl' | 'ttb';
-    /**
-     * Converts the image `src` to the css `background-image` URL of the parent element.
-     * This requires `fixedHeight` or `heightRatio` option.
-     */
-    cover?: boolean;
     /**
      * Determines whether to add `tabindex="0"` to visible slides or not.
      */
@@ -806,7 +794,7 @@ interface SyncTarget {
  */
 interface Components {
     [key: string]: BaseComponent | undefined;
-    Media: MediaComponent;
+    Breakpoints: BreakpointsComponent;
     Direction: DirectionComponent;
     Elements: ElementsComponent;
     Slides: SlidesComponent;
@@ -816,7 +804,6 @@ interface Components {
     Controller: ControllerComponent;
     Arrows: ArrowsComponent;
     Autoplay: AutoplayComponent;
-    Cover: CoverComponent;
     Scroll: ScrollComponent;
     Drag: DragComponent;
     Keyboard: KeyboardComponent;
@@ -1696,4 +1683,4 @@ declare const LOOP = "loop";
  */
 declare const FADE = "fade";
 
-export { AnyFunction, ArrowsComponent, AutoplayComponent, BaseComponent, CLASSES, CLASS_ACTIVE, CLASS_ARROW, CLASS_ARROWS, CLASS_ARROW_NEXT, CLASS_ARROW_PREV, CLASS_CLONE, CLASS_CONTAINER, CLASS_FOCUS_IN, CLASS_INITIALIZED, CLASS_LIST, CLASS_LOADING, CLASS_NEXT, CLASS_OVERFLOW, CLASS_PAGINATION, CLASS_PAGINATION_PAGE, CLASS_PREV, CLASS_PROGRESS, CLASS_PROGRESS_BAR, CLASS_ROOT, CLASS_SLIDE, CLASS_SPINNER, CLASS_SR, CLASS_TOGGLE, CLASS_TOGGLE_PAUSE, CLASS_TOGGLE_PLAY, CLASS_TRACK, CLASS_VISIBLE, Cast, ClonesComponent, ComponentConstructor, Components, ControllerComponent, CoverComponent, DEFAULTS, DirectionComponent, DragComponent, EVENT_ACTIVE, EVENT_ARROWS_MOUNTED, EVENT_ARROWS_UPDATED, EVENT_AUTOPLAY_PAUSE, EVENT_AUTOPLAY_PLAY, EVENT_AUTOPLAY_PLAYING, EVENT_CLICK, EVENT_DESTROY, EVENT_DRAG, EVENT_DRAGGED, EVENT_DRAGGING, EVENT_END_INDEX_CHANGED, EVENT_HIDDEN, EVENT_INACTIVE, EVENT_LAZYLOAD_LOADED, EVENT_MOUNTED, EVENT_MOVE, EVENT_MOVED, EVENT_NAVIGATION_MOUNTED, EVENT_OVERFLOW, EVENT_PAGINATION_MOUNTED, EVENT_PAGINATION_UPDATED, EVENT_READY, EVENT_REFRESH, EVENT_RESIZE, EVENT_RESIZED, EVENT_SCROLL, EVENT_SCROLLED, EVENT_SHIFTED, EVENT_SLIDE_KEYDOWN, EVENT_UPDATED, EVENT_VISIBLE, ElementsComponent, EventMap, FADE, Head, KeyboardComponent, LOOP, LTR, LayoutComponent, LazyLoadComponent, LiveComponent, MediaComponent, MoveComponent, Options, PaginationComponent, PaginationData, PaginationItem, Push, RTL, Resolve, ResponsiveOptions, SLIDE, STATUS_CLASSES, ScrollComponent, Shift, ShiftN, SlideComponent, SlidesComponent, Splide, SplideRenderer, SyncComponent, SyncTarget, TTB, TransitionComponent, WheelComponent, Splide as default };
+export { AnyFunction, ArrowsComponent, AutoplayComponent, BaseComponent, BreakpointsComponent, CLASSES, CLASS_ACTIVE, CLASS_ARROW, CLASS_ARROWS, CLASS_ARROW_NEXT, CLASS_ARROW_PREV, CLASS_CLONE, CLASS_CONTAINER, CLASS_FOCUS_IN, CLASS_INITIALIZED, CLASS_LIST, CLASS_LOADING, CLASS_NEXT, CLASS_OVERFLOW, CLASS_PAGINATION, CLASS_PAGINATION_PAGE, CLASS_PREV, CLASS_PROGRESS, CLASS_PROGRESS_BAR, CLASS_ROOT, CLASS_SLIDE, CLASS_SPINNER, CLASS_SR, CLASS_TOGGLE, CLASS_TOGGLE_PAUSE, CLASS_TOGGLE_PLAY, CLASS_TRACK, CLASS_VISIBLE, Cast, ClonesComponent, ComponentConstructor, Components, ControllerComponent, DEFAULTS, DirectionComponent, DragComponent, EVENT_ACTIVE, EVENT_ARROWS_MOUNTED, EVENT_ARROWS_UPDATED, EVENT_AUTOPLAY_PAUSE, EVENT_AUTOPLAY_PLAY, EVENT_AUTOPLAY_PLAYING, EVENT_CLICK, EVENT_DESTROY, EVENT_DRAG, EVENT_DRAGGED, EVENT_DRAGGING, EVENT_END_INDEX_CHANGED, EVENT_HIDDEN, EVENT_INACTIVE, EVENT_LAZYLOAD_LOADED, EVENT_MOUNTED, EVENT_MOVE, EVENT_MOVED, EVENT_NAVIGATION_MOUNTED, EVENT_OVERFLOW, EVENT_PAGINATION_MOUNTED, EVENT_PAGINATION_UPDATED, EVENT_READY, EVENT_REFRESH, EVENT_RESIZE, EVENT_RESIZED, EVENT_SCROLL, EVENT_SCROLLED, EVENT_SHIFTED, EVENT_SLIDE_KEYDOWN, EVENT_UPDATED, EVENT_VISIBLE, ElementsComponent, EventMap, FADE, Head, KeyboardComponent, LOOP, LTR, LayoutComponent, LazyLoadComponent, LiveComponent, MoveComponent, Options, PaginationComponent, PaginationData, PaginationItem, Push, RTL, Resolve, ResponsiveOptions, SLIDE, STATUS_CLASSES, ScrollComponent, Shift, ShiftN, SlideComponent, SlidesComponent, Splide, SplideRenderer, SyncComponent, SyncTarget, TTB, TransitionComponent, WheelComponent, Splide as default };

+ 8 - 3
src/js/components/Media/Media.ts → src/js/components/Breakpoints/Breakpoints.ts

@@ -11,7 +11,7 @@ import { EVENT_OVERFLOW, EVENT_UPDATED } from '../../constants/events';
  *
  * @since 4.0.0
  */
-export interface MediaComponent extends BaseComponent {
+export interface BreakpointsComponent extends BaseComponent {
   /** @internal */
   reduce( reduced: boolean ): void;
   set( options: Options, base?: boolean, notify?: boolean ): void;
@@ -33,10 +33,16 @@ const NOT_OVERFLOW_KEY = '!overflow';
  * @param Splide     - A Splide instance.
  * @param Components - A collection of components.
  * @param options    - Options.
+ * @param event      - An EventInterface instance.
  *
  * @return A Media component object.
  */
-export function Media( Splide: Splide, Components: Components, options: Options, event: EventInterface ): MediaComponent {
+export function Breakpoints(
+  Splide: Splide,
+  Components: Components,
+  options: Options,
+  event: EventInterface
+): BreakpointsComponent {
   const { state } = Splide;
   const breakpoints   = options.breakpoints || {};
   const reducedMotion = options.reducedMotion || {};
@@ -151,7 +157,6 @@ export function Media( Splide: Splide, Components: Components, options: Options,
 
   return {
     setup,
-    // mount,
     destroy,
     reduce,
     set,

+ 2 - 2
src/js/components/Media/test/general.test.ts → src/js/components/Breakpoints/test/general.test.ts

@@ -2,7 +2,7 @@ import { DESTROYED } from '../../../constants/states';
 import { init } from '../../../test';
 
 
-describe( 'Media', () => {
+describe( 'Breakpoints', () => {
   beforeAll( () => {
     window.matchMedia = () => ( {
       matches            : true, // All queries match the media string.
@@ -35,7 +35,7 @@ describe( 'Media', () => {
 
   test( 'can enable or disable `reducedMotion` option by `reduce()`.', () => {
     const splide = init( { speed: 1000, rewindSpeed: 2000, autoplay: true } );
-    const { reduce } = splide.Components.Media;
+    const { reduce } = splide.Components.Breakpoints;
 
     expect( splide.options.speed ).toBe( 0 );
     expect( splide.options.rewindSpeed ).toBe( 0 );

+ 13 - 1
src/js/components/Controller/Controller.ts

@@ -23,6 +23,7 @@ import {
  */
 export interface ControllerComponent extends BaseComponent {
   go( control: number | string, allowSameIndex?: boolean, callback?: AnyFunction ): void;
+  jump( index: number ): void;
   scroll( destination: number, duration?: number, snap?: boolean, callback?: AnyFunction ): void;
   getNext( destination?: boolean ): number;
   getPrev( destination?: boolean ): number;
@@ -120,7 +121,7 @@ export function Controller(
     const end   = omitEnd ? endIndex : slideCount - 1;
     const index = clamp( currIndex, 0, end );
 
-    prevIndex = clamp( currIndex, 0, end );
+    prevIndex = index;
 
     if ( index !== currIndex ) {
       currIndex = index;
@@ -159,6 +160,16 @@ export function Controller(
     }
   }
 
+  /**
+   * Immediately jumps to the specified index.
+   *
+   * @param index - An index where to jump.
+   */
+  function jump( index: number ): void {
+    Move.cancel();
+    scroll( toPosition( index ), 0 );
+  }
+
   /**
    * Scrolls the slider to the specified destination with updating indices.
    *
@@ -405,6 +416,7 @@ export function Controller(
   return {
     mount,
     go,
+    jump,
     scroll,
     getNext,
     getPrev,

+ 1 - 1
src/js/components/Drag/Drag.ts

@@ -40,7 +40,7 @@ export function Drag(
   const { on, emit, bind } = event;
   const binder = event.create();
   const { state } = Splide;
-  const { Move, Scroll, Controller, Elements: { track }, Media: { reduce } } = Components;
+  const { Move, Scroll, Controller, Elements: { track }, Breakpoints: { reduce } } = Components;
   const { resolve, orient } = Components.Direction;
   const { getPosition, exceededLimit } = Move;
 

+ 2 - 2
src/js/components/Scroll/Scroll.ts

@@ -90,10 +90,10 @@ export function Scroll(
       destination = Move.toPosition( Components.Controller.toDest( destination % size ) ) + offset;
     }
 
-    const noDistance = approximatelyEqual( from, destination, 1 );
+    const immediately = approximatelyEqual( from, destination, 1 ) || duration === 0;
 
     friction = 1;
-    duration = noDistance ? 0 : duration || max( abs( destination - from ) / BASE_VELOCITY, MIN_DURATION );
+    duration = immediately ? 0 : duration || max( abs( destination - from ) / BASE_VELOCITY, MIN_DURATION );
     callback = onScrolled;
     interval = RequestInterval( duration, onEnd, apply( update, from, destination, noConstrain ), 1 );
 

+ 2 - 2
src/js/components/Sync/Sync.ts

@@ -54,7 +54,7 @@ export function Sync(
   /**
    * Stores event objects.
    */
-  const events: EventInterface[] = []; // todo
+  const events: EventInterface[] = [];
 
   /**
    * Called when the component is mounted.
@@ -157,7 +157,7 @@ export function Sync(
 
   return {
     setup: apply(
-      Components.Media.set,
+      Components.Breakpoints.set,
       { slideFocus: isUndefined( slideFocus ) ? isNavigation : slideFocus },
       true
     ),

+ 37 - 37
src/js/components/index.ts

@@ -1,42 +1,42 @@
 import { ComponentConstructor } from '../types';
 
-import { Media }      from './Media/Media';
-import { Direction }  from './Direction/Direction';
-import { Elements }   from './Elements/Elements';
-import { Slides }     from './Slides/Slides';
-import { Layout }     from './Layout/Layout';
-import { Clones }     from './Clones/Clones';
-import { Move }       from './Move/Move';
-import { Controller } from './Controller/Controller';
-import { Arrows }     from './Arrows/Arrows';
-import { Autoplay }   from './Autoplay/Autoplay';
-import { Scroll }     from './Scroll/Scroll';
-import { Drag }       from './Drag/Drag';
-import { Keyboard }   from './Keyboard/Keyboard';
-import { LazyLoad }   from './LazyLoad/LazyLoad';
-import { Pagination } from './Pagination/Pagination';
-import { Sync }       from './Sync/Sync';
-import { Wheel }      from './Wheel/Wheel';
-import { Live }       from './Live/Live';
+import { Breakpoints } from './Breakpoints/Breakpoints';
+import { Direction }   from './Direction/Direction';
+import { Elements }    from './Elements/Elements';
+import { Slides }      from './Slides/Slides';
+import { Layout }      from './Layout/Layout';
+import { Clones }      from './Clones/Clones';
+import { Move }        from './Move/Move';
+import { Controller }  from './Controller/Controller';
+import { Arrows }      from './Arrows/Arrows';
+import { Autoplay }    from './Autoplay/Autoplay';
+import { Scroll }      from './Scroll/Scroll';
+import { Drag }        from './Drag/Drag';
+import { Keyboard }    from './Keyboard/Keyboard';
+import { LazyLoad }    from './LazyLoad/LazyLoad';
+import { Pagination }  from './Pagination/Pagination';
+import { Sync }        from './Sync/Sync';
+import { Wheel }       from './Wheel/Wheel';
+import { Live }        from './Live/Live';
 
-export { Media }      from './Media/Media';
-export { Direction }  from './Direction/Direction';
-export { Elements }   from './Elements/Elements';
-export { Slides }     from './Slides/Slides';
-export { Layout }     from './Layout/Layout';
-export { Clones }     from './Clones/Clones';
-export { Move }       from './Move/Move';
-export { Controller } from './Controller/Controller';
-export { Arrows }     from './Arrows/Arrows';
-export { Autoplay }   from './Autoplay/Autoplay';
-export { Scroll }     from './Scroll/Scroll';
-export { Drag }       from './Drag/Drag';
-export { Keyboard }   from './Keyboard/Keyboard';
-export { LazyLoad }   from './LazyLoad/LazyLoad';
-export { Pagination } from './Pagination/Pagination';
-export { Sync }       from './Sync/Sync';
-export { Wheel }      from './Wheel/Wheel';
-export { Live }       from './Live/Live';
+export { Breakpoints } from './Breakpoints/Breakpoints';
+export { Direction }   from './Direction/Direction';
+export { Elements }    from './Elements/Elements';
+export { Slides }      from './Slides/Slides';
+export { Layout }      from './Layout/Layout';
+export { Clones }      from './Clones/Clones';
+export { Move }        from './Move/Move';
+export { Controller }  from './Controller/Controller';
+export { Arrows }      from './Arrows/Arrows';
+export { Autoplay }    from './Autoplay/Autoplay';
+export { Scroll }      from './Scroll/Scroll';
+export { Drag }        from './Drag/Drag';
+export { Keyboard }    from './Keyboard/Keyboard';
+export { LazyLoad }    from './LazyLoad/LazyLoad';
+export { Pagination }  from './Pagination/Pagination';
+export { Sync }        from './Sync/Sync';
+export { Wheel }       from './Wheel/Wheel';
+export { Live }        from './Live/Live';
 
 
 /**
@@ -45,7 +45,7 @@ export { Live }       from './Live/Live';
  * @since 5.0.0
  */
 export const COMPONENTS: Record<string, ComponentConstructor> = {
-  Media,
+  Breakpoints,
   Direction,
   Elements,
   Slides,

+ 19 - 19
src/js/components/types.ts

@@ -1,21 +1,21 @@
-export type { MediaComponent }      from './Media/Media';
-export type { DirectionComponent }  from './Direction/Direction';
-export type { ElementsComponent }   from './Elements/Elements';
-export type { SlidesComponent }     from './Slides/Slides';
-export type { SlideComponent }      from './Slides/Slide';
-export type { LayoutComponent }     from './Layout/Layout';
-export type { ClonesComponent }     from './Clones/Clones';
-export type { MoveComponent }       from './Move/Move';
-export type { ControllerComponent } from './Controller/Controller';
-export type { ArrowsComponent }     from './Arrows/Arrows';
-export type { AutoplayComponent }   from './Autoplay/Autoplay';
-export type { ScrollComponent }     from './Scroll/Scroll';
-export type { DragComponent }       from './Drag/Drag';
-export type { KeyboardComponent }   from './Keyboard/Keyboard';
-export type { LazyLoadComponent }   from './LazyLoad/LazyLoad';
-export type { PaginationComponent } from './Pagination/Pagination';
-export type { SyncComponent }       from './Sync/Sync';
-export type { WheelComponent }      from './Wheel/Wheel';
-export type { LiveComponent }       from './Live/Live';
+export type { BreakpointsComponent } from './Breakpoints/Breakpoints';
+export type { DirectionComponent }   from './Direction/Direction';
+export type { ElementsComponent }    from './Elements/Elements';
+export type { SlidesComponent }      from './Slides/Slides';
+export type { SlideComponent }       from './Slides/Slide';
+export type { LayoutComponent }      from './Layout/Layout';
+export type { ClonesComponent }      from './Clones/Clones';
+export type { MoveComponent }        from './Move/Move';
+export type { ControllerComponent }  from './Controller/Controller';
+export type { ArrowsComponent }      from './Arrows/Arrows';
+export type { AutoplayComponent }    from './Autoplay/Autoplay';
+export type { ScrollComponent }      from './Scroll/Scroll';
+export type { DragComponent }        from './Drag/Drag';
+export type { KeyboardComponent }    from './Keyboard/Keyboard';
+export type { LazyLoadComponent }    from './LazyLoad/LazyLoad';
+export type { PaginationComponent }  from './Pagination/Pagination';
+export type { SyncComponent }        from './Sync/Sync';
+export type { WheelComponent }       from './Wheel/Wheel';
+export type { LiveComponent }        from './Live/Live';
 
 export type { PaginationData, PaginationItem } from './Pagination/Pagination';

+ 1 - 1
src/js/core/Splide/Splide.ts

@@ -390,7 +390,7 @@ export class Splide {
    * @param options - An object with new options.
    */
   set options( options: Options ) {
-    this._C.Media.set( options, true, true );
+    this._C.Breakpoints.set( options, true, true );
   }
 
   /**

+ 9 - 1
src/js/test/php/examples/default.php

@@ -22,7 +22,6 @@ $settings = get_settings();
     document.addEventListener( 'DOMContentLoaded', function () {
       var splide = new Splide( '#splide01', {
         width: 800,
-        start: 1,
         // type        : 'loop',
         perPage: 3,
         // perMove: 3,
@@ -93,6 +92,11 @@ $settings = get_settings();
 
 	    const pre = document.querySelector( 'pre' );
 
+
+      document.querySelector( '#jump' ).addEventListener( 'click', () => {
+        splide.Components.Controller.jump( 5 )
+      } );
+
 	    // Array.from( document.getElementsByTagName( 'button' ) ).forEach( button => {
 			// 	button.addEventListener( 'click', function () {
 			// 		alert( 'click' );
@@ -115,6 +119,10 @@ $settings = get_settings();
 
 <?php render( 'splide01', 10 ); ?>
 
+<button id="jump">
+  jump
+</button>
+
 <div>
   <div style="margin-right: 1rem">a</div>
 </div>

+ 1 - 2
src/js/types/components.ts

@@ -9,7 +9,7 @@ import { BaseComponent, TransitionComponent } from './general';
  */
 export interface Components {
   [ key: string ]: BaseComponent | undefined;
-  Media: Types.MediaComponent;
+  Breakpoints: Types.BreakpointsComponent;
   Direction: Types.DirectionComponent;
   Elements: Types.ElementsComponent;
   Slides: Types.SlidesComponent;
@@ -19,7 +19,6 @@ export interface Components {
   Controller: Types.ControllerComponent;
   Arrows: Types.ArrowsComponent;
   Autoplay: Types.AutoplayComponent;
-  Cover: Types.CoverComponent;
   Scroll: Types.ScrollComponent;
   Drag: Types.DragComponent;
   Keyboard: Types.KeyboardComponent;

Some files were not shown because too many files changed in this diff