Selaa lähdekoodia

Add the `compact` option.

Naotoshi Fujita 2 vuotta sitten
vanhempi
commit
5b2eb73a1b

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/js/splide-renderer.min.js.map


+ 50 - 26
dist/js/splide.cjs.js

@@ -412,17 +412,18 @@ function EventBinder() {
   };
 }
 
+var ARROWS = "arrows:";
+var PAGINATION = "pagination:";
+var AUTOPLAY = "autoplay:";
 var EVENT_MOUNTED = "mounted";
 var EVENT_READY = "ready";
 var EVENT_MOVE = "move";
 var EVENT_MOVED = "moved";
-var EVENT_SHIFTED = "shifted";
 var EVENT_CLICK = "click";
 var EVENT_ACTIVE = "active";
 var EVENT_INACTIVE = "inactive";
 var EVENT_VISIBLE = "visible";
 var EVENT_HIDDEN = "hidden";
-var EVENT_SLIDE_KEYDOWN = "slide:keydown";
 var EVENT_REFRESH = "refresh";
 var EVENT_UPDATED = "updated";
 var EVENT_RESIZE = "resize";
@@ -433,15 +434,18 @@ var EVENT_DRAGGED = "dragged";
 var EVENT_SCROLL = "scroll";
 var EVENT_SCROLLED = "scrolled";
 var EVENT_DESTROY = "destroy";
-var EVENT_ARROWS_MOUNTED = "arrows:mounted";
-var EVENT_ARROWS_UPDATED = "arrows:updated";
-var EVENT_PAGINATION_MOUNTED = "pagination:mounted";
-var EVENT_PAGINATION_UPDATED = "pagination:updated";
+var EVENT_ARROWS_MOUNTED = ARROWS + "mounted";
+var EVENT_ARROWS_UPDATED = ARROWS + "updated";
+var EVENT_PAGINATION_MOUNTED = PAGINATION + "mounted";
+var EVENT_PAGINATION_UPDATED = PAGINATION + "updated";
 var EVENT_NAVIGATION_MOUNTED = "navigation:mounted";
-var EVENT_AUTOPLAY_PLAY = "autoplay:play";
-var EVENT_AUTOPLAY_PLAYING = "autoplay:playing";
-var EVENT_AUTOPLAY_PAUSE = "autoplay:pause";
+var EVENT_AUTOPLAY_PLAY = AUTOPLAY + "play";
+var EVENT_AUTOPLAY_PLAYING = AUTOPLAY + "playing";
+var EVENT_AUTOPLAY_PAUSE = AUTOPLAY + "pause";
 var EVENT_LAZYLOAD_LOADED = "lazyload:loaded";
+var EVENT_SLIDE_KEYDOWN = "sk";
+var EVENT_SHIFTED = "sh";
+var EVENT_END_INDEX_CHANGED = "ei";
 
 function EventInterface(Splide2) {
   var bus = Splide2 ? Splide2.event.bus : document.createDocumentFragment();
@@ -1553,7 +1557,8 @@ function Move(Splide2, Components2, options) {
 
 function Controller(Splide2, Components2, options) {
   var _EventInterface6 = EventInterface(Splide2),
-      on = _EventInterface6.on;
+      on = _EventInterface6.on,
+      emit = _EventInterface6.emit;
 
   var Move = Components2.Move;
   var getPosition = Move.getPosition,
@@ -1562,11 +1567,13 @@ function Controller(Splide2, Components2, options) {
   var _Components2$Slides = Components2.Slides,
       isEnough = _Components2$Slides.isEnough,
       getLength = _Components2$Slides.getLength;
+  var compact = options.compact;
   var isLoop = Splide2.is(LOOP);
   var isSlide = Splide2.is(SLIDE);
   var getNext = apply(getAdjacent, false);
   var getPrev = apply(getAdjacent, true);
   var currIndex = options.start || 0;
+  var endIndex;
   var prevIndex = currIndex;
   var slideCount;
   var perMove;
@@ -1574,14 +1581,16 @@ function Controller(Splide2, Components2, options) {
 
   function mount() {
     init();
-    on([EVENT_UPDATED, EVENT_REFRESH], init);
+    on([EVENT_UPDATED, EVENT_REFRESH, EVENT_END_INDEX_CHANGED], init);
+    on(EVENT_RESIZED, onResized);
   }
 
   function init() {
     slideCount = getLength(true);
     perMove = options.perMove;
     perPage = options.perPage;
-    var index = clamp(currIndex, 0, slideCount - 1);
+    endIndex = getEnd();
+    var index = clamp(currIndex, 0, compact ? endIndex : slideCount - 1);
 
     if (index !== currIndex) {
       currIndex = index;
@@ -1589,6 +1598,12 @@ function Controller(Splide2, Components2, options) {
     }
   }
 
+  function onResized() {
+    if (endIndex !== getEnd()) {
+      emit(EVENT_END_INDEX_CHANGED);
+    }
+  }
+
   function go(control, allowSameIndex, callback) {
     if (!isBusy()) {
       var dest = parse(control);
@@ -1603,7 +1618,7 @@ function Controller(Splide2, Components2, options) {
 
   function scroll(destination, duration, snap, callback) {
     Components2.Scroll.scroll(destination, duration, snap, function () {
-      setIndex(loop(Move.toIndex(getPosition())));
+      setIndex(min(loop(Move.toIndex(getPosition())), endIndex));
       callback && callback();
     });
   }
@@ -1624,7 +1639,7 @@ function Controller(Splide2, Components2, options) {
         index = getPrev(true);
       }
     } else {
-      index = isLoop ? control : clamp(control, 0, getEnd());
+      index = isLoop ? control : clamp(control, 0, endIndex);
     }
 
     return index;
@@ -1636,7 +1651,7 @@ function Controller(Splide2, Components2, options) {
 
     if (dest === -1 && isSlide) {
       if (!approximatelyEqual(getPosition(), getLimit(!prev), 1)) {
-        return prev ? 0 : getEnd();
+        return prev ? 0 : endIndex;
       }
     }
 
@@ -1645,7 +1660,6 @@ function Controller(Splide2, Components2, options) {
 
   function computeDestIndex(dest, from, snapPage) {
     if (isEnough() || hasFocus()) {
-      var end = getEnd();
       var index = computeMovableDestIndex(dest);
 
       if (index !== dest) {
@@ -1654,14 +1668,14 @@ function Controller(Splide2, Components2, options) {
         snapPage = false;
       }
 
-      if (dest < 0 || dest > end) {
-        if (!perMove && (between(0, dest, from, true) || between(end, from, dest, true))) {
+      if (dest < 0 || dest > endIndex) {
+        if (!perMove && (between(0, dest, from, true) || between(endIndex, from, dest, true))) {
           dest = toIndex(toPage(dest));
         } else {
           if (isLoop) {
             dest = snapPage ? dest < 0 ? -(slideCount % perPage || perPage) : slideCount : dest;
           } else if (options.rewind) {
-            dest = dest < 0 ? end : 0;
+            dest = dest < 0 ? endIndex : 0;
           } else {
             dest = -1;
           }
@@ -1695,20 +1709,29 @@ function Controller(Splide2, Components2, options) {
   }
 
   function getEnd() {
-    return max(slideCount - (hasFocus() || isLoop && perMove ? 1 : perPage), 0);
+    var end = slideCount - (hasFocus() || isLoop && perMove ? 1 : perPage);
+
+    while (compact && --end > 0) {
+      if (toPosition(slideCount - 1, true) !== toPosition(end, true)) {
+        end++;
+        break;
+      }
+    }
+
+    return clamp(end, 0, slideCount - 1);
   }
 
   function toIndex(page) {
-    return clamp(hasFocus() ? page : perPage * page, 0, getEnd());
+    return clamp(hasFocus() ? page : perPage * page, 0, endIndex);
   }
 
   function toPage(index) {
-    return hasFocus() ? index : floor((index >= getEnd() ? slideCount - 1 : index) / perPage);
+    return hasFocus() ? min(index, endIndex) : floor((index >= endIndex ? slideCount - 1 : index) / perPage);
   }
 
   function toDest(destination) {
     var closest = Move.toIndex(destination);
-    return isSlide ? clamp(closest, 0, getEnd()) : closest;
+    return isSlide ? clamp(closest, 0, endIndex) : closest;
   }
 
   function setIndex(index) {
@@ -1817,7 +1840,7 @@ function Arrows(Splide2, Components2, options) {
   }
 
   function listen() {
-    on([EVENT_MOVED, EVENT_REFRESH, EVENT_SCROLLED], update);
+    on([EVENT_MOVED, EVENT_REFRESH, EVENT_SCROLLED, EVENT_END_INDEX_CHANGED], update);
     bind(next, "click", apply(go, ">"));
     bind(prev, "click", apply(go, "<"));
   }
@@ -2506,7 +2529,7 @@ function Pagination(Splide2, Components2, options) {
 
   function mount() {
     destroy();
-    on([EVENT_UPDATED, EVENT_REFRESH], mount);
+    on([EVENT_UPDATED, EVENT_REFRESH, EVENT_END_INDEX_CHANGED], mount);
     var enabled = options.pagination && Slides.isEnough();
     placeholder && display(placeholder, enabled ? "" : "none");
 
@@ -2537,7 +2560,7 @@ function Pagination(Splide2, Components2, options) {
     var classes = options.classes,
         i18n = options.i18n,
         perPage = options.perPage;
-    var max = hasFocus() ? length : ceil(length / perPage);
+    var max = hasFocus() ? Controller.getEnd() + 1 : ceil(length / perPage);
     list = placeholder || create("ul", classes.pagination, Elements.track.parentElement);
     addClass(list, paginationClasses = CLASS_PAGINATION + "--" + getDirection());
     setAttribute(list, ROLE, "tablist");
@@ -3698,6 +3721,7 @@ exports.EVENT_DESTROY = EVENT_DESTROY;
 exports.EVENT_DRAG = EVENT_DRAG;
 exports.EVENT_DRAGGED = EVENT_DRAGGED;
 exports.EVENT_DRAGGING = EVENT_DRAGGING;
+exports.EVENT_END_INDEX_CHANGED = EVENT_END_INDEX_CHANGED;
 exports.EVENT_HIDDEN = EVENT_HIDDEN;
 exports.EVENT_INACTIVE = EVENT_INACTIVE;
 exports.EVENT_LAZYLOAD_LOADED = EVENT_LAZYLOAD_LOADED;

+ 50 - 27
dist/js/splide.esm.js

@@ -407,17 +407,18 @@ function EventBinder() {
   };
 }
 
+var ARROWS = "arrows:";
+var PAGINATION = "pagination:";
+var AUTOPLAY = "autoplay:";
 var EVENT_MOUNTED = "mounted";
 var EVENT_READY = "ready";
 var EVENT_MOVE = "move";
 var EVENT_MOVED = "moved";
-var EVENT_SHIFTED = "shifted";
 var EVENT_CLICK = "click";
 var EVENT_ACTIVE = "active";
 var EVENT_INACTIVE = "inactive";
 var EVENT_VISIBLE = "visible";
 var EVENT_HIDDEN = "hidden";
-var EVENT_SLIDE_KEYDOWN = "slide:keydown";
 var EVENT_REFRESH = "refresh";
 var EVENT_UPDATED = "updated";
 var EVENT_RESIZE = "resize";
@@ -428,15 +429,18 @@ var EVENT_DRAGGED = "dragged";
 var EVENT_SCROLL = "scroll";
 var EVENT_SCROLLED = "scrolled";
 var EVENT_DESTROY = "destroy";
-var EVENT_ARROWS_MOUNTED = "arrows:mounted";
-var EVENT_ARROWS_UPDATED = "arrows:updated";
-var EVENT_PAGINATION_MOUNTED = "pagination:mounted";
-var EVENT_PAGINATION_UPDATED = "pagination:updated";
+var EVENT_ARROWS_MOUNTED = ARROWS + "mounted";
+var EVENT_ARROWS_UPDATED = ARROWS + "updated";
+var EVENT_PAGINATION_MOUNTED = PAGINATION + "mounted";
+var EVENT_PAGINATION_UPDATED = PAGINATION + "updated";
 var EVENT_NAVIGATION_MOUNTED = "navigation:mounted";
-var EVENT_AUTOPLAY_PLAY = "autoplay:play";
-var EVENT_AUTOPLAY_PLAYING = "autoplay:playing";
-var EVENT_AUTOPLAY_PAUSE = "autoplay:pause";
+var EVENT_AUTOPLAY_PLAY = AUTOPLAY + "play";
+var EVENT_AUTOPLAY_PLAYING = AUTOPLAY + "playing";
+var EVENT_AUTOPLAY_PAUSE = AUTOPLAY + "pause";
 var EVENT_LAZYLOAD_LOADED = "lazyload:loaded";
+var EVENT_SLIDE_KEYDOWN = "sk";
+var EVENT_SHIFTED = "sh";
+var EVENT_END_INDEX_CHANGED = "ei";
 
 function EventInterface(Splide2) {
   var bus = Splide2 ? Splide2.event.bus : document.createDocumentFragment();
@@ -1548,7 +1552,8 @@ function Move(Splide2, Components2, options) {
 
 function Controller(Splide2, Components2, options) {
   var _EventInterface6 = EventInterface(Splide2),
-      on = _EventInterface6.on;
+      on = _EventInterface6.on,
+      emit = _EventInterface6.emit;
 
   var Move = Components2.Move;
   var getPosition = Move.getPosition,
@@ -1557,11 +1562,13 @@ function Controller(Splide2, Components2, options) {
   var _Components2$Slides = Components2.Slides,
       isEnough = _Components2$Slides.isEnough,
       getLength = _Components2$Slides.getLength;
+  var compact = options.compact;
   var isLoop = Splide2.is(LOOP);
   var isSlide = Splide2.is(SLIDE);
   var getNext = apply(getAdjacent, false);
   var getPrev = apply(getAdjacent, true);
   var currIndex = options.start || 0;
+  var endIndex;
   var prevIndex = currIndex;
   var slideCount;
   var perMove;
@@ -1569,14 +1576,16 @@ function Controller(Splide2, Components2, options) {
 
   function mount() {
     init();
-    on([EVENT_UPDATED, EVENT_REFRESH], init);
+    on([EVENT_UPDATED, EVENT_REFRESH, EVENT_END_INDEX_CHANGED], init);
+    on(EVENT_RESIZED, onResized);
   }
 
   function init() {
     slideCount = getLength(true);
     perMove = options.perMove;
     perPage = options.perPage;
-    var index = clamp(currIndex, 0, slideCount - 1);
+    endIndex = getEnd();
+    var index = clamp(currIndex, 0, compact ? endIndex : slideCount - 1);
 
     if (index !== currIndex) {
       currIndex = index;
@@ -1584,6 +1593,12 @@ function Controller(Splide2, Components2, options) {
     }
   }
 
+  function onResized() {
+    if (endIndex !== getEnd()) {
+      emit(EVENT_END_INDEX_CHANGED);
+    }
+  }
+
   function go(control, allowSameIndex, callback) {
     if (!isBusy()) {
       var dest = parse(control);
@@ -1598,7 +1613,7 @@ function Controller(Splide2, Components2, options) {
 
   function scroll(destination, duration, snap, callback) {
     Components2.Scroll.scroll(destination, duration, snap, function () {
-      setIndex(loop(Move.toIndex(getPosition())));
+      setIndex(min(loop(Move.toIndex(getPosition())), endIndex));
       callback && callback();
     });
   }
@@ -1619,7 +1634,7 @@ function Controller(Splide2, Components2, options) {
         index = getPrev(true);
       }
     } else {
-      index = isLoop ? control : clamp(control, 0, getEnd());
+      index = isLoop ? control : clamp(control, 0, endIndex);
     }
 
     return index;
@@ -1631,7 +1646,7 @@ function Controller(Splide2, Components2, options) {
 
     if (dest === -1 && isSlide) {
       if (!approximatelyEqual(getPosition(), getLimit(!prev), 1)) {
-        return prev ? 0 : getEnd();
+        return prev ? 0 : endIndex;
       }
     }
 
@@ -1640,7 +1655,6 @@ function Controller(Splide2, Components2, options) {
 
   function computeDestIndex(dest, from, snapPage) {
     if (isEnough() || hasFocus()) {
-      var end = getEnd();
       var index = computeMovableDestIndex(dest);
 
       if (index !== dest) {
@@ -1649,14 +1663,14 @@ function Controller(Splide2, Components2, options) {
         snapPage = false;
       }
 
-      if (dest < 0 || dest > end) {
-        if (!perMove && (between(0, dest, from, true) || between(end, from, dest, true))) {
+      if (dest < 0 || dest > endIndex) {
+        if (!perMove && (between(0, dest, from, true) || between(endIndex, from, dest, true))) {
           dest = toIndex(toPage(dest));
         } else {
           if (isLoop) {
             dest = snapPage ? dest < 0 ? -(slideCount % perPage || perPage) : slideCount : dest;
           } else if (options.rewind) {
-            dest = dest < 0 ? end : 0;
+            dest = dest < 0 ? endIndex : 0;
           } else {
             dest = -1;
           }
@@ -1690,20 +1704,29 @@ function Controller(Splide2, Components2, options) {
   }
 
   function getEnd() {
-    return max(slideCount - (hasFocus() || isLoop && perMove ? 1 : perPage), 0);
+    var end = slideCount - (hasFocus() || isLoop && perMove ? 1 : perPage);
+
+    while (compact && --end > 0) {
+      if (toPosition(slideCount - 1, true) !== toPosition(end, true)) {
+        end++;
+        break;
+      }
+    }
+
+    return clamp(end, 0, slideCount - 1);
   }
 
   function toIndex(page) {
-    return clamp(hasFocus() ? page : perPage * page, 0, getEnd());
+    return clamp(hasFocus() ? page : perPage * page, 0, endIndex);
   }
 
   function toPage(index) {
-    return hasFocus() ? index : floor((index >= getEnd() ? slideCount - 1 : index) / perPage);
+    return hasFocus() ? min(index, endIndex) : floor((index >= endIndex ? slideCount - 1 : index) / perPage);
   }
 
   function toDest(destination) {
     var closest = Move.toIndex(destination);
-    return isSlide ? clamp(closest, 0, getEnd()) : closest;
+    return isSlide ? clamp(closest, 0, endIndex) : closest;
   }
 
   function setIndex(index) {
@@ -1812,7 +1835,7 @@ function Arrows(Splide2, Components2, options) {
   }
 
   function listen() {
-    on([EVENT_MOVED, EVENT_REFRESH, EVENT_SCROLLED], update);
+    on([EVENT_MOVED, EVENT_REFRESH, EVENT_SCROLLED, EVENT_END_INDEX_CHANGED], update);
     bind(next, "click", apply(go, ">"));
     bind(prev, "click", apply(go, "<"));
   }
@@ -2501,7 +2524,7 @@ function Pagination(Splide2, Components2, options) {
 
   function mount() {
     destroy();
-    on([EVENT_UPDATED, EVENT_REFRESH], mount);
+    on([EVENT_UPDATED, EVENT_REFRESH, EVENT_END_INDEX_CHANGED], mount);
     var enabled = options.pagination && Slides.isEnough();
     placeholder && display(placeholder, enabled ? "" : "none");
 
@@ -2532,7 +2555,7 @@ function Pagination(Splide2, Components2, options) {
     var classes = options.classes,
         i18n = options.i18n,
         perPage = options.perPage;
-    var max = hasFocus() ? length : ceil(length / perPage);
+    var max = hasFocus() ? Controller.getEnd() + 1 : ceil(length / perPage);
     list = placeholder || create("ul", classes.pagination, Elements.track.parentElement);
     addClass(list, paginationClasses = CLASS_PAGINATION + "--" + getDirection());
     setAttribute(list, ROLE, "tablist");
@@ -3654,4 +3677,4 @@ var SplideRenderer = /*#__PURE__*/function () {
   return SplideRenderer;
 }();
 
-export { 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_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, DEFAULTS, 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_HIDDEN, EVENT_INACTIVE, EVENT_LAZYLOAD_LOADED, EVENT_MOUNTED, EVENT_MOVE, EVENT_MOVED, EVENT_NAVIGATION_MOUNTED, 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, EventBinder, EventInterface, FADE, LOOP, LTR, RTL, RequestInterval, SLIDE, STATUS_CLASSES, Splide, SplideRenderer, State, TTB, Throttle, Splide as default };
+export { 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_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, DEFAULTS, 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_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, EventBinder, EventInterface, FADE, LOOP, LTR, RTL, RequestInterval, SLIDE, STATUS_CLASSES, Splide, SplideRenderer, State, TTB, Throttle, Splide as default };

+ 49 - 26
dist/js/splide.js

@@ -408,17 +408,18 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     };
   }
 
+  var ARROWS = "arrows:";
+  var PAGINATION = "pagination:";
+  var AUTOPLAY = "autoplay:";
   var EVENT_MOUNTED = "mounted";
   var EVENT_READY = "ready";
   var EVENT_MOVE = "move";
   var EVENT_MOVED = "moved";
-  var EVENT_SHIFTED = "shifted";
   var EVENT_CLICK = "click";
   var EVENT_ACTIVE = "active";
   var EVENT_INACTIVE = "inactive";
   var EVENT_VISIBLE = "visible";
   var EVENT_HIDDEN = "hidden";
-  var EVENT_SLIDE_KEYDOWN = "slide:keydown";
   var EVENT_REFRESH = "refresh";
   var EVENT_UPDATED = "updated";
   var EVENT_RESIZE = "resize";
@@ -429,15 +430,18 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   var EVENT_SCROLL = "scroll";
   var EVENT_SCROLLED = "scrolled";
   var EVENT_DESTROY = "destroy";
-  var EVENT_ARROWS_MOUNTED = "arrows:mounted";
-  var EVENT_ARROWS_UPDATED = "arrows:updated";
-  var EVENT_PAGINATION_MOUNTED = "pagination:mounted";
-  var EVENT_PAGINATION_UPDATED = "pagination:updated";
+  var EVENT_ARROWS_MOUNTED = ARROWS + "mounted";
+  var EVENT_ARROWS_UPDATED = ARROWS + "updated";
+  var EVENT_PAGINATION_MOUNTED = PAGINATION + "mounted";
+  var EVENT_PAGINATION_UPDATED = PAGINATION + "updated";
   var EVENT_NAVIGATION_MOUNTED = "navigation:mounted";
-  var EVENT_AUTOPLAY_PLAY = "autoplay:play";
-  var EVENT_AUTOPLAY_PLAYING = "autoplay:playing";
-  var EVENT_AUTOPLAY_PAUSE = "autoplay:pause";
+  var EVENT_AUTOPLAY_PLAY = AUTOPLAY + "play";
+  var EVENT_AUTOPLAY_PLAYING = AUTOPLAY + "playing";
+  var EVENT_AUTOPLAY_PAUSE = AUTOPLAY + "pause";
   var EVENT_LAZYLOAD_LOADED = "lazyload:loaded";
+  var EVENT_SLIDE_KEYDOWN = "sk";
+  var EVENT_SHIFTED = "sh";
+  var EVENT_END_INDEX_CHANGED = "ei";
 
   function EventInterface(Splide2) {
     var bus = Splide2 ? Splide2.event.bus : document.createDocumentFragment();
@@ -1546,7 +1550,8 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
   function Controller(Splide2, Components2, options) {
     var _EventInterface6 = EventInterface(Splide2),
-        on = _EventInterface6.on;
+        on = _EventInterface6.on,
+        emit = _EventInterface6.emit;
 
     var Move = Components2.Move;
     var getPosition = Move.getPosition,
@@ -1555,11 +1560,13 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     var _Components2$Slides = Components2.Slides,
         isEnough = _Components2$Slides.isEnough,
         getLength = _Components2$Slides.getLength;
+    var compact = options.compact;
     var isLoop = Splide2.is(LOOP);
     var isSlide = Splide2.is(SLIDE);
     var getNext = apply(getAdjacent, false);
     var getPrev = apply(getAdjacent, true);
     var currIndex = options.start || 0;
+    var endIndex;
     var prevIndex = currIndex;
     var slideCount;
     var perMove;
@@ -1567,14 +1574,16 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
     function mount() {
       init();
-      on([EVENT_UPDATED, EVENT_REFRESH], init);
+      on([EVENT_UPDATED, EVENT_REFRESH, EVENT_END_INDEX_CHANGED], init);
+      on(EVENT_RESIZED, onResized);
     }
 
     function init() {
       slideCount = getLength(true);
       perMove = options.perMove;
       perPage = options.perPage;
-      var index = clamp(currIndex, 0, slideCount - 1);
+      endIndex = getEnd();
+      var index = clamp(currIndex, 0, compact ? endIndex : slideCount - 1);
 
       if (index !== currIndex) {
         currIndex = index;
@@ -1582,6 +1591,12 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       }
     }
 
+    function onResized() {
+      if (endIndex !== getEnd()) {
+        emit(EVENT_END_INDEX_CHANGED);
+      }
+    }
+
     function go(control, allowSameIndex, callback) {
       if (!isBusy()) {
         var dest = parse(control);
@@ -1596,7 +1611,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
     function scroll(destination, duration, snap, callback) {
       Components2.Scroll.scroll(destination, duration, snap, function () {
-        setIndex(loop(Move.toIndex(getPosition())));
+        setIndex(min(loop(Move.toIndex(getPosition())), endIndex));
         callback && callback();
       });
     }
@@ -1617,7 +1632,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
           index = getPrev(true);
         }
       } else {
-        index = isLoop ? control : clamp(control, 0, getEnd());
+        index = isLoop ? control : clamp(control, 0, endIndex);
       }
 
       return index;
@@ -1629,7 +1644,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
       if (dest === -1 && isSlide) {
         if (!approximatelyEqual(getPosition(), getLimit(!prev), 1)) {
-          return prev ? 0 : getEnd();
+          return prev ? 0 : endIndex;
         }
       }
 
@@ -1638,7 +1653,6 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
     function computeDestIndex(dest, from, snapPage) {
       if (isEnough() || hasFocus()) {
-        var end = getEnd();
         var index = computeMovableDestIndex(dest);
 
         if (index !== dest) {
@@ -1647,14 +1661,14 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
           snapPage = false;
         }
 
-        if (dest < 0 || dest > end) {
-          if (!perMove && (between(0, dest, from, true) || between(end, from, dest, true))) {
+        if (dest < 0 || dest > endIndex) {
+          if (!perMove && (between(0, dest, from, true) || between(endIndex, from, dest, true))) {
             dest = toIndex(toPage(dest));
           } else {
             if (isLoop) {
               dest = snapPage ? dest < 0 ? -(slideCount % perPage || perPage) : slideCount : dest;
             } else if (options.rewind) {
-              dest = dest < 0 ? end : 0;
+              dest = dest < 0 ? endIndex : 0;
             } else {
               dest = -1;
             }
@@ -1688,20 +1702,29 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function getEnd() {
-      return max(slideCount - (hasFocus() || isLoop && perMove ? 1 : perPage), 0);
+      var end = slideCount - (hasFocus() || isLoop && perMove ? 1 : perPage);
+
+      while (compact && --end > 0) {
+        if (toPosition(slideCount - 1, true) !== toPosition(end, true)) {
+          end++;
+          break;
+        }
+      }
+
+      return clamp(end, 0, slideCount - 1);
     }
 
     function toIndex(page) {
-      return clamp(hasFocus() ? page : perPage * page, 0, getEnd());
+      return clamp(hasFocus() ? page : perPage * page, 0, endIndex);
     }
 
     function toPage(index) {
-      return hasFocus() ? index : floor((index >= getEnd() ? slideCount - 1 : index) / perPage);
+      return hasFocus() ? min(index, endIndex) : floor((index >= endIndex ? slideCount - 1 : index) / perPage);
     }
 
     function toDest(destination) {
       var closest = Move.toIndex(destination);
-      return isSlide ? clamp(closest, 0, getEnd()) : closest;
+      return isSlide ? clamp(closest, 0, endIndex) : closest;
     }
 
     function setIndex(index) {
@@ -1810,7 +1833,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function listen() {
-      on([EVENT_MOVED, EVENT_REFRESH, EVENT_SCROLLED], update);
+      on([EVENT_MOVED, EVENT_REFRESH, EVENT_SCROLLED, EVENT_END_INDEX_CHANGED], update);
       bind(next, "click", apply(go, ">"));
       bind(prev, "click", apply(go, "<"));
     }
@@ -2499,7 +2522,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
     function mount() {
       destroy();
-      on([EVENT_UPDATED, EVENT_REFRESH], mount);
+      on([EVENT_UPDATED, EVENT_REFRESH, EVENT_END_INDEX_CHANGED], mount);
       var enabled = options.pagination && Slides.isEnough();
       placeholder && display(placeholder, enabled ? "" : "none");
 
@@ -2530,7 +2553,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       var classes = options.classes,
           i18n = options.i18n,
           perPage = options.perPage;
-      var max = hasFocus() ? length : ceil(length / perPage);
+      var max = hasFocus() ? Controller.getEnd() + 1 : ceil(length / perPage);
       list = placeholder || create("ul", classes.pagination, Elements.track.parentElement);
       addClass(list, paginationClasses = CLASS_PAGINATION + "--" + getDirection());
       setAttribute(list, ROLE, "tablist");

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/js/splide.min.js


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


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/js/splide.min.js.map


+ 13 - 14
dist/types/index.d.ts

@@ -424,6 +424,7 @@ interface Options extends ResponsiveOptions {
      * If `true`, screen readers will read a content of each slide whenever slide changes.
      */
     live?: boolean;
+    compact?: boolean;
     /**
      * Determines whether to use the Transition component or not.
      */
@@ -734,10 +735,6 @@ interface EventMap {
     'autoplay:playing': (rate: number) => void;
     'autoplay:pause': () => void;
     'lazyload:loaded': (img: HTMLImageElement, Slide: SlideComponent) => void;
-    /** @internal */
-    'shifted': () => void;
-    'slide:keydown': (Slide: SlideComponent, e: KeyboardEvent) => void;
-    'media': (query: MediaQueryList) => void;
 }
 
 /**
@@ -1559,13 +1556,11 @@ declare const EVENT_MOUNTED = "mounted";
 declare const EVENT_READY = "ready";
 declare const EVENT_MOVE = "move";
 declare const EVENT_MOVED = "moved";
-declare const EVENT_SHIFTED = "shifted";
 declare const EVENT_CLICK = "click";
 declare const EVENT_ACTIVE = "active";
 declare const EVENT_INACTIVE = "inactive";
 declare const EVENT_VISIBLE = "visible";
 declare const EVENT_HIDDEN = "hidden";
-declare const EVENT_SLIDE_KEYDOWN = "slide:keydown";
 declare const EVENT_REFRESH = "refresh";
 declare const EVENT_UPDATED = "updated";
 declare const EVENT_RESIZE = "resize";
@@ -1576,15 +1571,19 @@ declare const EVENT_DRAGGED = "dragged";
 declare const EVENT_SCROLL = "scroll";
 declare const EVENT_SCROLLED = "scrolled";
 declare const EVENT_DESTROY = "destroy";
-declare const EVENT_ARROWS_MOUNTED = "arrows:mounted";
-declare const EVENT_ARROWS_UPDATED = "arrows:updated";
-declare const EVENT_PAGINATION_MOUNTED = "pagination:mounted";
-declare const EVENT_PAGINATION_UPDATED = "pagination:updated";
+declare const EVENT_ARROWS_MOUNTED: string;
+declare const EVENT_ARROWS_UPDATED: string;
+declare const EVENT_PAGINATION_MOUNTED: string;
+declare const EVENT_PAGINATION_UPDATED: string;
 declare const EVENT_NAVIGATION_MOUNTED = "navigation:mounted";
-declare const EVENT_AUTOPLAY_PLAY = "autoplay:play";
-declare const EVENT_AUTOPLAY_PLAYING = "autoplay:playing";
-declare const EVENT_AUTOPLAY_PAUSE = "autoplay:pause";
+declare const EVENT_AUTOPLAY_PLAY: string;
+declare const EVENT_AUTOPLAY_PLAYING: string;
+declare const EVENT_AUTOPLAY_PAUSE: string;
 declare const EVENT_LAZYLOAD_LOADED = "lazyload:loaded";
+/** @internal */
+declare const EVENT_SLIDE_KEYDOWN = "sk";
+declare const EVENT_SHIFTED = "sh";
+declare const EVENT_END_INDEX_CHANGED = "ei";
 
 declare const CLASS_ROOT = "splide";
 declare const CLASS_TRACK: string;
@@ -1675,4 +1674,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_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_HIDDEN, EVENT_INACTIVE, EVENT_LAZYLOAD_LOADED, EVENT_MOUNTED, EVENT_MOVE, EVENT_MOVED, EVENT_NAVIGATION_MOUNTED, 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, EventBinder, EventBinderObject, EventInterface, EventInterfaceObject, EventMap, FADE, Head, KeyboardComponent, LOOP, LTR, LayoutComponent, LazyLoadComponent, LiveComponent, MediaComponent, MoveComponent, Options, PaginationComponent, PaginationData, PaginationItem, Push, RTL, RequestInterval, RequestIntervalInterface, Resolve, ResponsiveOptions, SLIDE, STATUS_CLASSES, ScrollComponent, Shift, ShiftN, SlideComponent, SlidesComponent, Splide, SplideRenderer, State, StateObject, SyncComponent, SyncTarget, TTB, Throttle, ThrottleInstance, TransitionComponent, WheelComponent, Splide as default };
+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_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_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, EventBinder, EventBinderObject, EventInterface, EventInterfaceObject, EventMap, FADE, Head, KeyboardComponent, LOOP, LTR, LayoutComponent, LazyLoadComponent, LiveComponent, MediaComponent, MoveComponent, Options, PaginationComponent, PaginationData, PaginationItem, Push, RTL, RequestInterval, RequestIntervalInterface, Resolve, ResponsiveOptions, SLIDE, STATUS_CLASSES, ScrollComponent, Shift, ShiftN, SlideComponent, SlidesComponent, Splide, SplideRenderer, State, StateObject, SyncComponent, SyncTarget, TTB, Throttle, ThrottleInstance, TransitionComponent, WheelComponent, Splide as default };

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

@@ -2,7 +2,7 @@ import { ALL_ATTRIBUTES, ARIA_CONTROLS, ARIA_LABEL } from '../../constants/attri
 import { CLASS_ARROWS } from '../../constants/classes';
 import {
   EVENT_ARROWS_MOUNTED,
-  EVENT_ARROWS_UPDATED,
+  EVENT_ARROWS_UPDATED, EVENT_END_INDEX_CHANGED,
   EVENT_MOVED,
   EVENT_REFRESH,
   EVENT_SCROLLED,
@@ -147,7 +147,7 @@ export function Arrows( Splide: Splide, Components: Components, options: Options
    * Listens to some events.
    */
   function listen(): void {
-    on( [ EVENT_MOVED, EVENT_REFRESH, EVENT_SCROLLED ], update );
+    on( [ EVENT_MOVED, EVENT_REFRESH, EVENT_SCROLLED, EVENT_END_INDEX_CHANGED ], update );
     bind( next, 'click', apply( go, '>' ) );
     bind( prev, 'click', apply( go, '<' ) );
   }

+ 44 - 17
src/js/components/Controller/Controller.ts

@@ -1,10 +1,10 @@
-import { EVENT_REFRESH, EVENT_UPDATED } from '../../constants/events';
+import { EVENT_END_INDEX_CHANGED, EVENT_REFRESH, EVENT_RESIZED, EVENT_UPDATED } from '../../constants/events';
 import { MOVING, SCROLLING } from '../../constants/states';
 import { LOOP, SLIDE } from '../../constants/types';
 import { EventInterface } from '../../constructors';
 import { Splide } from '../../core/Splide/Splide';
 import { AnyFunction, BaseComponent, Components, Options } from '../../types';
-import { apply, approximatelyEqual, between, clamp, floor, isString, isUndefined, max } from '../../utils';
+import { apply, approximatelyEqual, between, clamp, floor, isString, isUndefined, min } from '../../utils';
 
 
 /**
@@ -42,10 +42,11 @@ export interface ControllerComponent extends BaseComponent {
  * @return A Controller component object.
  */
 export function Controller( Splide: Splide, Components: Components, options: Options ): ControllerComponent {
-  const { on } = EventInterface( Splide );
+  const { on, emit } = EventInterface( Splide );
   const { Move } = Components;
   const { getPosition, getLimit, toPosition } = Move;
   const { isEnough, getLength } = Components.Slides;
+  const { compact } = options;
   const isLoop  = Splide.is( LOOP );
   const isSlide = Splide.is( SLIDE );
   const getNext = apply( getAdjacent, false );
@@ -56,6 +57,11 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
    */
   let currIndex = options.start || 0;
 
+  /**
+   * The latest end index.
+   */
+  let endIndex: number;
+
   /**
    * The previous index.
    */
@@ -81,7 +87,8 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
    */
   function mount(): void {
     init();
-    on( [ EVENT_UPDATED, EVENT_REFRESH ], init );
+    on( [ EVENT_UPDATED, EVENT_REFRESH, EVENT_END_INDEX_CHANGED ], init );
+    on( EVENT_RESIZED, onResized );
   }
 
   /**
@@ -93,8 +100,9 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
     slideCount = getLength( true );
     perMove    = options.perMove;
     perPage    = options.perPage;
+    endIndex   = getEnd();
 
-    const index = clamp( currIndex, 0, slideCount - 1 );
+    const index = clamp( currIndex, 0, compact ? endIndex : slideCount - 1 );
 
     if ( index !== currIndex ) {
       currIndex = index;
@@ -102,6 +110,16 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
     }
   }
 
+  /**
+   * Called when the viewport width is changed.
+   * The end index can change if `autoWidth` or `fixedWidth` is enabled.
+   */
+  function onResized(): void {
+    if ( endIndex !== getEnd() ) {
+      emit( EVENT_END_INDEX_CHANGED );
+    }
+  }
+
   /**
    * Moves the slider by the control pattern.
    *
@@ -133,7 +151,7 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
    */
   function scroll( destination: number, duration?: number, snap?: boolean, callback?: AnyFunction ): void {
     Components.Scroll.scroll( destination, duration, snap, () => {
-      setIndex( loop( Move.toIndex( getPosition() ) ) );
+      setIndex( min( loop( Move.toIndex( getPosition() ) ), endIndex ) );
       callback && callback();
     } );
   }
@@ -159,7 +177,7 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
         index = getPrev( true );
       }
     } else {
-      index = isLoop ? control : clamp( control, 0, getEnd() );
+      index = isLoop ? control : clamp( control, 0, endIndex );
     }
 
     return index;
@@ -181,7 +199,7 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
 
     if ( dest === -1 && isSlide ) {
       if ( ! approximatelyEqual( getPosition(), getLimit( ! prev ), 1 ) ) {
-        return prev ? 0 : getEnd();
+        return prev ? 0 : endIndex;
       }
     }
 
@@ -204,7 +222,6 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
    */
   function computeDestIndex( dest: number, from: number, snapPage?: boolean ): number {
     if ( isEnough() || hasFocus() ) {
-      const end   = getEnd();
       const index = computeMovableDestIndex( dest );
 
       if ( index !== dest ) {
@@ -213,8 +230,8 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
         snapPage = false;
       }
 
-      if ( dest < 0 || dest > end ) {
-        if ( ! perMove && ( between( 0, dest, from, true ) || between( end, from, dest, true ) ) ) {
+      if ( dest < 0 || dest > endIndex ) {
+        if ( ! perMove && ( between( 0, dest, from, true ) || between( endIndex, from, dest, true ) ) ) {
           dest = toIndex( toPage( dest ) );
         } else {
           if ( isLoop ) {
@@ -222,7 +239,7 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
               ? dest < 0 ? - ( slideCount % perPage || perPage ) : slideCount
               : dest;
           } else if ( options.rewind ) {
-            dest = dest < 0 ? end : 0;
+            dest = dest < 0 ? endIndex : 0;
           } else {
             dest = -1;
           }
@@ -274,11 +291,21 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
    * Returns the end index where the slider can go.
    * For example, if the slider has 10 slides and the `perPage` option is 3,
    * the slider can go to the slide 8 (the index is 7).
+   * If the `compact` option is available, computes the index from the slide position.
    *
    * @return An end index.
    */
   function getEnd(): number {
-    return max( slideCount - ( hasFocus() || ( isLoop && perMove ) ? 1 : perPage ), 0 );
+    let end = slideCount - ( hasFocus() || ( isLoop && perMove ) ? 1 : perPage );
+
+    while ( compact && --end > 0 ) {
+      if ( toPosition( slideCount - 1, true ) !== toPosition( end, true ) ) {
+        end++;
+        break;
+      }
+    }
+
+    return clamp( end, 0, slideCount - 1 );
   }
 
   /**
@@ -289,7 +316,7 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
    * @return A slide index.
    */
   function toIndex( page: number ): number {
-    return clamp( hasFocus() ? page : perPage * page, 0, getEnd() );
+    return clamp( hasFocus() ? page : perPage * page, 0, endIndex );
   }
 
   /**
@@ -301,8 +328,8 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
    */
   function toPage( index: number ): number {
     return hasFocus()
-      ? index
-      : floor( ( index >= getEnd() ? slideCount - 1 : index ) / perPage );
+      ? min( index, endIndex )
+      : floor( ( index >= endIndex ? slideCount - 1 : index ) / perPage );
   }
 
   /**
@@ -314,7 +341,7 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
    */
   function toDest( destination: number ): number {
     const closest = Move.toIndex( destination );
-    return isSlide ? clamp( closest, 0, getEnd() ) : closest;
+    return isSlide ? clamp( closest, 0, endIndex ) : closest;
   }
 
   /**

+ 3 - 2
src/js/components/Pagination/Pagination.ts

@@ -10,6 +10,7 @@ import {
 import { CLASS_ACTIVE, CLASS_PAGINATION } from '../../constants/classes';
 import { TTB } from '../../constants/directions';
 import {
+  EVENT_END_INDEX_CHANGED,
   EVENT_MOVE,
   EVENT_PAGINATION_MOUNTED,
   EVENT_PAGINATION_UPDATED,
@@ -112,7 +113,7 @@ export function Pagination( Splide: Splide, Components: Components, options: Opt
    */
   function mount(): void {
     destroy();
-    on( [ EVENT_UPDATED, EVENT_REFRESH ], mount );
+    on( [ EVENT_UPDATED, EVENT_REFRESH, EVENT_END_INDEX_CHANGED ], mount );
 
     const enabled = options.pagination && Slides.isEnough();
     placeholder && display( placeholder, enabled ? '' : 'none' );
@@ -145,7 +146,7 @@ export function Pagination( Splide: Splide, Components: Components, options: Opt
   function createPagination(): void {
     const { length } = Splide;
     const { classes, i18n, perPage } = options;
-    const max = hasFocus() ? length : ceil( length / perPage );
+    const max = hasFocus() ? Controller.getEnd() + 1 : ceil( length / perPage );
 
     list = placeholder || create( 'ul', classes.pagination, Elements.track.parentElement );
 

+ 15 - 9
src/js/constants/events.ts

@@ -1,14 +1,16 @@
+const ARROWS     = `arrows:`;
+const PAGINATION = `pagination:`;
+const AUTOPLAY   = `autoplay:`;
+
 export const EVENT_MOUNTED            = 'mounted';
 export const EVENT_READY              = 'ready';
 export const EVENT_MOVE               = 'move';
 export const EVENT_MOVED              = 'moved';
-export const EVENT_SHIFTED            = 'shifted';
 export const EVENT_CLICK              = 'click';
 export const EVENT_ACTIVE             = 'active';
 export const EVENT_INACTIVE           = 'inactive';
 export const EVENT_VISIBLE            = 'visible';
 export const EVENT_HIDDEN             = 'hidden';
-export const EVENT_SLIDE_KEYDOWN      = 'slide:keydown';
 export const EVENT_REFRESH            = 'refresh';
 export const EVENT_UPDATED            = 'updated';
 export const EVENT_RESIZE             = 'resize';
@@ -19,13 +21,17 @@ export const EVENT_DRAGGED            = 'dragged';
 export const EVENT_SCROLL             = 'scroll';
 export const EVENT_SCROLLED           = 'scrolled';
 export const EVENT_DESTROY            = 'destroy';
-export const EVENT_ARROWS_MOUNTED     = 'arrows:mounted';
-export const EVENT_ARROWS_UPDATED     = 'arrows:updated';
-export const EVENT_PAGINATION_MOUNTED = 'pagination:mounted';
-export const EVENT_PAGINATION_UPDATED = 'pagination:updated';
+export const EVENT_ARROWS_MOUNTED     = `${ ARROWS }mounted`;
+export const EVENT_ARROWS_UPDATED     = `${ ARROWS }updated`;
+export const EVENT_PAGINATION_MOUNTED = `${ PAGINATION }mounted`;
+export const EVENT_PAGINATION_UPDATED = `${ PAGINATION }updated`;
 export const EVENT_NAVIGATION_MOUNTED = 'navigation:mounted';
-export const EVENT_AUTOPLAY_PLAY      = 'autoplay:play';
-export const EVENT_AUTOPLAY_PLAYING   = 'autoplay:playing';
-export const EVENT_AUTOPLAY_PAUSE     = 'autoplay:pause';
+export const EVENT_AUTOPLAY_PLAY      = `${ AUTOPLAY }play`;
+export const EVENT_AUTOPLAY_PLAYING   = `${ AUTOPLAY }playing`;
+export const EVENT_AUTOPLAY_PAUSE     = `${ AUTOPLAY }pause`;
 export const EVENT_LAZYLOAD_LOADED    = 'lazyload:loaded';
 
+/** @internal */
+export const EVENT_SLIDE_KEYDOWN     = 'sk';
+export const EVENT_SHIFTED           = 'sh';
+export const EVENT_END_INDEX_CHANGED = 'ei';

+ 5 - 2
src/js/test/php/examples/autoWidth.php

@@ -20,9 +20,10 @@ $settings = get_settings();
         // width     : 1000,
         autoWidth : true,
         gap       : '1rem',
-        trimSpace : false,
-        focus     : 'center',
+        // trimSpace : tr,
+        focus     : 0,
         drag      : 'free',
+        compact   : true,
       } );
 
       splide01.mount();
@@ -34,6 +35,8 @@ $settings = get_settings();
         gap       : '1rem',
         focus     : 'center',
         trimSpace : false,
+        drag      : 'free',
+
       } );
 
       splide02.mount();

+ 6 - 3
src/js/test/php/examples/default.php

@@ -22,18 +22,21 @@ $settings = get_settings();
     document.addEventListener( 'DOMContentLoaded', function () {
       var splide = new Splide( '#splide01', {
         width: 800,
-        type        : 'loop',
+        // type        : 'loop',
         perPage: 2,
+        // perMove: 3,
         // rewind: true,
         // rewindByDrag: true,
         padding: '3rem',
         updateOnMove: true,
         direction: 'ltr',
         height: undefined,
-        paginationDirection: 'ttb',
+        // paginationDirection: 'ttb',
         rewindSpeed: 2000,
         // role: '',
         label: '1',
+        focus: 0,
+        compact: true,
 
         // breakpoints: {
         //   1200: {
@@ -107,7 +110,7 @@ $settings = get_settings();
 </head>
 <body>
 
-<?php render( 'splide01', 10 ); ?>
+<?php render( 'splide01', 5 ); ?>
 
 <pre></pre>
 

+ 3 - 1
src/js/test/php/examples/fixedSize.php

@@ -19,9 +19,11 @@ $settings = get_settings();
   <script>
     document.addEventListener( 'DOMContentLoaded', function () {
       var splide01 = new Splide( '#splide01', {
-        type       : 'loop',
+        // type       : 'loop',
         fixedWidth : '6rem',
         gap        : 10,
+        compact    : true,
+        focus      : 0,
       } );
 
       splide01.mount();

+ 0 - 5
src/js/types/events.ts

@@ -38,9 +38,4 @@ export interface EventMap {
   'autoplay:playing': ( rate: number ) => void;
   'autoplay:pause': () => void;
   'lazyload:loaded': ( img: HTMLImageElement, Slide: SlideComponent ) => void;
-
-  /** @internal */
-  'shifted': () => void;
-  'slide:keydown': ( Slide: SlideComponent, e: KeyboardEvent ) => void;
-  'media': ( query: MediaQueryList ) => void;
 }

+ 2 - 0
src/js/types/options.ts

@@ -183,6 +183,8 @@ export interface Options extends ResponsiveOptions {
    */
   live?: boolean;
 
+  compact?: boolean;
+
   /**
    * Determines whether to use the Transition component or not.
    */

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä