Explorar o código

Arrows and pagination can be placed anywhere in the slider.

NaotoshiFujita %!s(int64=3) %!d(string=hai) anos
pai
achega
2130350d05

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/css/splide.min.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/css/themes/splide-default.min.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/css/themes/splide-sea-green.min.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/css/themes/splide-skyblue.min.css


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/js/splide-renderer.min.js


+ 103 - 71
dist/js/splide.cjs.js

@@ -1,6 +1,6 @@
 /*!
  * Splide.js
- * Version  : 3.6.14
+ * Version  : 4.0.0
  * License  : MIT
  * Copyright: 2022 Naotoshi Fujita
  */
@@ -157,9 +157,10 @@ function matches(elm, selector) {
 }
 
 function children(parent, selector) {
-  return parent ? slice(parent.children).filter(function (child) {
+  var children2 = parent ? slice(parent.children) : [];
+  return selector ? children2.filter(function (child) {
     return matches(child, selector);
-  }) : [];
+  }) : children2;
 }
 
 function child(parent, selector) {
@@ -739,6 +740,24 @@ var CLASSES = {
   spinner: CLASS_SPINNER
 };
 
+function closest(from, selector) {
+  if (isFunction(from.closest)) {
+    return from.closest(selector);
+  }
+
+  var elm = from;
+
+  while (elm && elm.nodeType === 1) {
+    if (matches(elm, selector)) {
+      break;
+    }
+
+    elm = elm.parentElement;
+  }
+
+  return elm;
+}
+
 function Elements(Splide2, Components2, options) {
   var _EventInterface = EventInterface(Splide2),
       on = _EventInterface.on;
@@ -748,7 +767,6 @@ function Elements(Splide2, Components2, options) {
   var elements = {};
   var slides = [];
   var classes;
-  var slider;
   var track;
   var list;
 
@@ -776,26 +794,27 @@ function Elements(Splide2, Components2, options) {
   }
 
   function collect() {
-    slider = child(root, "." + CLASS_SLIDER);
-    track = query(root, "." + CLASS_TRACK);
+    track = find("." + CLASS_TRACK);
     list = child(track, "." + CLASS_LIST);
     assert(track && list, "A track/list element is missing.");
     push(slides, children(list, "." + CLASS_SLIDE + ":not(." + CLASS_CLONE + ")"));
-    var autoplay = find("." + CLASS_AUTOPLAY);
-    var arrows = find("." + CLASS_ARROWS);
+    forOwn({
+      arrows: CLASS_ARROWS,
+      pagination: CLASS_PAGINATION,
+      autoplay: CLASS_AUTOPLAY,
+      prev: CLASS_ARROW_PREV,
+      next: CLASS_ARROW_NEXT,
+      bar: CLASS_PROGRESS_BAR,
+      play: CLASS_PLAY,
+      pause: CLASS_PAUSE
+    }, function (className, key) {
+      elements[key] = find("." + className);
+    });
     assign(elements, {
       root: root,
-      slider: slider,
       track: track,
       list: list,
-      slides: slides,
-      arrows: arrows,
-      autoplay: autoplay,
-      prev: query(arrows, "." + CLASS_ARROW_PREV),
-      next: query(arrows, "." + CLASS_ARROW_NEXT),
-      bar: query(find("." + CLASS_PROGRESS), "." + CLASS_PROGRESS_BAR),
-      play: query(autoplay, "." + CLASS_PLAY),
-      pause: query(autoplay, "." + CLASS_PAUSE)
+      slides: slides
     });
   }
 
@@ -810,7 +829,8 @@ function Elements(Splide2, Components2, options) {
   }
 
   function find(selector) {
-    return child(root, selector) || child(slider, selector);
+    var elm = query(root, selector);
+    return elm && closest(elm, "." + CLASS_ROOT) === root ? elm : null;
   }
 
   function getClasses() {
@@ -862,8 +882,8 @@ function Slide$1(Splide2, index, slideIndex, slide) {
   function listen() {
     bind(slide, "click", apply(emit, EVENT_CLICK, self));
     bind(slide, "keydown", apply(emit, EVENT_SLIDE_KEYDOWN, self));
-    on([EVENT_REFRESH, EVENT_REPOSITIONED, EVENT_MOVED, EVENT_SCROLLED], apply(update, true));
-    on(EVENT_SHIFTED, apply(update, false));
+    on([EVENT_REFRESH, EVENT_REPOSITIONED, EVENT_MOVED, EVENT_SCROLLED], apply(update, false));
+    on(EVENT_SHIFTED, apply(update, true));
     on(EVENT_NAVIGATION_MOUNTED, initNavigation);
 
     if (updateOnMove) {
@@ -891,18 +911,18 @@ function Slide$1(Splide2, index, slideIndex, slide) {
 
   function onMove() {
     if (!destroyed) {
-      update();
+      update(true);
     }
   }
 
-  function update(attributes) {
+  function update(excludeAttributes) {
     if (!destroyed) {
       var curr = Splide2.index;
       updateActivity();
       updateVisibility();
       toggleClass(slide, CLASS_PREV, index === curr - 1);
       toggleClass(slide, CLASS_NEXT, index === curr + 1);
-      attributes && updateAttributes();
+      !excludeAttributes && updateAttributes();
     }
   }
 
@@ -1707,13 +1727,15 @@ function Arrows(Splide2, Components2, options) {
   var _EventInterface8 = EventInterface(Splide2),
       on = _EventInterface8.on,
       bind = _EventInterface8.bind,
-      emit = _EventInterface8.emit;
+      emit = _EventInterface8.emit,
+      destroyEvents = _EventInterface8.destroy;
 
   var classes = options.classes,
       i18n = options.i18n;
   var Elements = Components2.Elements,
       Controller = Components2.Controller;
-  var wrapper = Elements.arrows;
+  var userArrows = Elements.arrows;
+  var wrapper = userArrows;
   var prev = Elements.prev;
   var next = Elements.next;
   var created;
@@ -1721,51 +1743,65 @@ function Arrows(Splide2, Components2, options) {
 
   function mount() {
     init();
-    on(EVENT_UPDATED, init);
+    on(EVENT_UPDATED, remount);
+  }
+
+  function remount() {
+    destroy();
+    mount();
   }
 
   function init() {
-    if (options.arrows) {
-      if (!prev || !next) {
-        createArrows();
-      }
+    var enabled = options.arrows;
+
+    if (enabled && !(prev && next)) {
+      createArrows();
     }
 
     if (prev && next) {
-      if (!arrows.prev) {
-        setAttribute([prev, next], ARIA_CONTROLS, Elements.list.id);
-        arrows.prev = prev;
-        arrows.next = next;
+      assign(arrows, {
+        prev: prev,
+        next: next
+      });
+      display(wrapper, enabled ? "" : "none");
+
+      if (enabled) {
         listen();
+        update();
+        setAttribute([prev, next], ARIA_CONTROLS, Elements.list.id);
         emit(EVENT_ARROWS_MOUNTED, prev, next);
       }
-
-      display(wrapper, options.arrows === false ? "none" : "");
     }
   }
 
   function destroy() {
+    destroyEvents();
+
     if (created) {
-      remove(wrapper);
+      remove(userArrows ? [prev, next] : wrapper);
+      prev = next = null;
     } else {
       removeAttribute([prev, next], ALL_ATTRIBUTES);
     }
   }
 
   function listen() {
-    var go = Controller.go;
-    on([EVENT_MOUNTED, EVENT_MOVED, EVENT_UPDATED, EVENT_REFRESH, EVENT_SCROLLED], update);
-    bind(next, "click", apply(go, ">", true, void 0));
-    bind(prev, "click", apply(go, "<", true, void 0));
+    on([EVENT_MOVED, EVENT_REFRESH, EVENT_SCROLLED], update);
+    bind(next, "click", apply(go, ">"));
+    bind(prev, "click", apply(go, "<"));
+  }
+
+  function go(control) {
+    Controller.go(control, true);
   }
 
   function createArrows() {
-    wrapper = create("div", classes.arrows);
+    wrapper = userArrows || create("div", classes.arrows);
     prev = createArrow(true);
     next = createArrow(false);
     created = true;
     append(wrapper, [prev, next]);
-    before(wrapper, child(options.arrows === "slider" && Elements.slider || Splide2.root));
+    !userArrows && before(wrapper, Elements.track);
   }
 
   function createArrow(prev2) {
@@ -2083,11 +2119,9 @@ function Drag(Splide2, Components2, options) {
     clickPrevented = false;
 
     if (!disabled) {
-      var noDrag = options.noDrag;
       var isTouch = isTouchEvent(e);
-      var isDraggable = !noDrag || !matches(e.target, noDrag);
 
-      if (isDraggable && (isTouch || !e.button)) {
+      if (isDraggable(e.target) && (isTouch || !e.button)) {
         if (!Controller.isBusy()) {
           target = isTouch ? track : window;
           dragging = state.is([MOVING, SCROLLING]);
@@ -2162,15 +2196,16 @@ function Drag(Splide2, Components2, options) {
     var velocity = computeVelocity(e);
     var destination = computeDestination(velocity);
     var rewind = options.rewind && options.rewindByDrag;
+    var go = Controller.go;
 
     if (isFree) {
       Controller.scroll(destination, 0, options.snap);
     } else if (Splide2.is(FADE)) {
-      Controller.go(orient(sign(velocity)) < 0 ? rewind ? "<" : "-" : rewind ? ">" : "+");
+      go(orient(sign(velocity)) < 0 ? rewind ? "<" : "-" : rewind ? ">" : "+");
     } else if (Splide2.is(SLIDE) && exceeded && rewind) {
-      Controller.go(exceededLimit(true) ? ">" : "<");
+      go(exceededLimit(true) ? ">" : "<");
     } else {
-      Controller.go(Controller.toDest(destination), true);
+      go(Controller.toDest(destination), true);
     }
   }
 
@@ -2222,6 +2257,10 @@ function Drag(Splide2, Components2, options) {
     return diff / (exceeded && Splide2.is(SLIDE) ? FRICTION : 1);
   }
 
+  function isDraggable(target2) {
+    return !matches(target2, push((options.noDrag || "").split(",").filter(Boolean), ["." + CLASS_PAGINATION_PAGE, "." + CLASS_ARROW]).join(","));
+  }
+
   function isTouchEvent(e) {
     return typeof TouchEvent !== "undefined" && e instanceof TouchEvent;
   }
@@ -2449,7 +2488,7 @@ function Pagination(Splide2, Components2, options) {
       on = _EventInterface15.on,
       emit = _EventInterface15.emit,
       bind = _EventInterface15.bind,
-      unbind = _EventInterface15.unbind;
+      destroyEvents = _EventInterface15.destroy;
 
   var Slides = Components2.Slides,
       Elements = Components2.Elements,
@@ -2459,21 +2498,17 @@ function Pagination(Splide2, Components2, options) {
       go = Controller.go;
   var resolve = Components2.Direction.resolve;
   var items = [];
-  var list;
+  var pagination;
 
   function mount() {
-    init();
-    on([EVENT_UPDATED, EVENT_REFRESH], init);
-    on([EVENT_MOVE, EVENT_SCROLL, EVENT_SCROLLED], update);
-  }
-
-  function init() {
     destroy();
+    on([EVENT_UPDATED, EVENT_REFRESH], mount);
 
     if (options.pagination && Slides.isEnough()) {
+      on([EVENT_MOVE, EVENT_SCROLL, EVENT_SCROLLED], update);
       createPagination();
       emit(EVENT_PAGINATION_MOUNTED, {
-        list: list,
+        list: pagination,
         items: items
       }, getAt(Splide2.index));
       update();
@@ -2481,13 +2516,11 @@ function Pagination(Splide2, Components2, options) {
   }
 
   function destroy() {
-    if (list) {
-      remove(list);
-      items.forEach(function (item) {
-        unbind(item.button, "click keydown focus");
-      });
+    if (pagination) {
+      destroyEvents();
+      remove(Elements.pagination ? slice(pagination.children) : pagination);
       empty(items);
-      list = null;
+      pagination = null;
     }
   }
 
@@ -2496,15 +2529,14 @@ function Pagination(Splide2, Components2, options) {
     var classes = options.classes,
         i18n = options.i18n,
         perPage = options.perPage;
-    var parent = options.pagination === "slider" && Elements.slider || Elements.root;
     var max = hasFocus() ? length : ceil(length / perPage);
-    list = create("ul", classes.pagination, parent);
-    setAttribute(list, ROLE, "tablist");
-    setAttribute(list, ARIA_LABEL, i18n.select);
-    setAttribute(list, ARIA_ORIENTATION, options.direction === TTB ? "vertical" : "");
+    pagination = Elements.pagination || create("ul", classes.pagination, Elements.root);
+    setAttribute(pagination, ROLE, "tablist");
+    setAttribute(pagination, ARIA_LABEL, i18n.select);
+    setAttribute(pagination, ARIA_ORIENTATION, options.direction === TTB ? "vertical" : "");
 
     for (var i = 0; i < max; i++) {
-      var li = create("li", null, list);
+      var li = create("li", null, pagination);
       var button = create("button", {
         class: classes.page,
         type: "button"
@@ -2583,7 +2615,7 @@ function Pagination(Splide2, Components2, options) {
     }
 
     emit(EVENT_PAGINATION_UPDATED, {
-      list: list,
+      list: pagination,
       items: items
     }, prev, curr);
   }

+ 103 - 71
dist/js/splide.esm.js

@@ -4,7 +4,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
 /*!
  * Splide.js
- * Version  : 3.6.14
+ * Version  : 4.0.0
  * License  : MIT
  * Copyright: 2022 Naotoshi Fujita
  */
@@ -152,9 +152,10 @@ function matches(elm, selector) {
 }
 
 function children(parent, selector) {
-  return parent ? slice(parent.children).filter(function (child) {
+  var children2 = parent ? slice(parent.children) : [];
+  return selector ? children2.filter(function (child) {
     return matches(child, selector);
-  }) : [];
+  }) : children2;
 }
 
 function child(parent, selector) {
@@ -734,6 +735,24 @@ var CLASSES = {
   spinner: CLASS_SPINNER
 };
 
+function closest(from, selector) {
+  if (isFunction(from.closest)) {
+    return from.closest(selector);
+  }
+
+  var elm = from;
+
+  while (elm && elm.nodeType === 1) {
+    if (matches(elm, selector)) {
+      break;
+    }
+
+    elm = elm.parentElement;
+  }
+
+  return elm;
+}
+
 function Elements(Splide2, Components2, options) {
   var _EventInterface = EventInterface(Splide2),
       on = _EventInterface.on;
@@ -743,7 +762,6 @@ function Elements(Splide2, Components2, options) {
   var elements = {};
   var slides = [];
   var classes;
-  var slider;
   var track;
   var list;
 
@@ -771,26 +789,27 @@ function Elements(Splide2, Components2, options) {
   }
 
   function collect() {
-    slider = child(root, "." + CLASS_SLIDER);
-    track = query(root, "." + CLASS_TRACK);
+    track = find("." + CLASS_TRACK);
     list = child(track, "." + CLASS_LIST);
     assert(track && list, "A track/list element is missing.");
     push(slides, children(list, "." + CLASS_SLIDE + ":not(." + CLASS_CLONE + ")"));
-    var autoplay = find("." + CLASS_AUTOPLAY);
-    var arrows = find("." + CLASS_ARROWS);
+    forOwn({
+      arrows: CLASS_ARROWS,
+      pagination: CLASS_PAGINATION,
+      autoplay: CLASS_AUTOPLAY,
+      prev: CLASS_ARROW_PREV,
+      next: CLASS_ARROW_NEXT,
+      bar: CLASS_PROGRESS_BAR,
+      play: CLASS_PLAY,
+      pause: CLASS_PAUSE
+    }, function (className, key) {
+      elements[key] = find("." + className);
+    });
     assign(elements, {
       root: root,
-      slider: slider,
       track: track,
       list: list,
-      slides: slides,
-      arrows: arrows,
-      autoplay: autoplay,
-      prev: query(arrows, "." + CLASS_ARROW_PREV),
-      next: query(arrows, "." + CLASS_ARROW_NEXT),
-      bar: query(find("." + CLASS_PROGRESS), "." + CLASS_PROGRESS_BAR),
-      play: query(autoplay, "." + CLASS_PLAY),
-      pause: query(autoplay, "." + CLASS_PAUSE)
+      slides: slides
     });
   }
 
@@ -805,7 +824,8 @@ function Elements(Splide2, Components2, options) {
   }
 
   function find(selector) {
-    return child(root, selector) || child(slider, selector);
+    var elm = query(root, selector);
+    return elm && closest(elm, "." + CLASS_ROOT) === root ? elm : null;
   }
 
   function getClasses() {
@@ -857,8 +877,8 @@ function Slide$1(Splide2, index, slideIndex, slide) {
   function listen() {
     bind(slide, "click", apply(emit, EVENT_CLICK, self));
     bind(slide, "keydown", apply(emit, EVENT_SLIDE_KEYDOWN, self));
-    on([EVENT_REFRESH, EVENT_REPOSITIONED, EVENT_MOVED, EVENT_SCROLLED], apply(update, true));
-    on(EVENT_SHIFTED, apply(update, false));
+    on([EVENT_REFRESH, EVENT_REPOSITIONED, EVENT_MOVED, EVENT_SCROLLED], apply(update, false));
+    on(EVENT_SHIFTED, apply(update, true));
     on(EVENT_NAVIGATION_MOUNTED, initNavigation);
 
     if (updateOnMove) {
@@ -886,18 +906,18 @@ function Slide$1(Splide2, index, slideIndex, slide) {
 
   function onMove() {
     if (!destroyed) {
-      update();
+      update(true);
     }
   }
 
-  function update(attributes) {
+  function update(excludeAttributes) {
     if (!destroyed) {
       var curr = Splide2.index;
       updateActivity();
       updateVisibility();
       toggleClass(slide, CLASS_PREV, index === curr - 1);
       toggleClass(slide, CLASS_NEXT, index === curr + 1);
-      attributes && updateAttributes();
+      !excludeAttributes && updateAttributes();
     }
   }
 
@@ -1702,13 +1722,15 @@ function Arrows(Splide2, Components2, options) {
   var _EventInterface8 = EventInterface(Splide2),
       on = _EventInterface8.on,
       bind = _EventInterface8.bind,
-      emit = _EventInterface8.emit;
+      emit = _EventInterface8.emit,
+      destroyEvents = _EventInterface8.destroy;
 
   var classes = options.classes,
       i18n = options.i18n;
   var Elements = Components2.Elements,
       Controller = Components2.Controller;
-  var wrapper = Elements.arrows;
+  var userArrows = Elements.arrows;
+  var wrapper = userArrows;
   var prev = Elements.prev;
   var next = Elements.next;
   var created;
@@ -1716,51 +1738,65 @@ function Arrows(Splide2, Components2, options) {
 
   function mount() {
     init();
-    on(EVENT_UPDATED, init);
+    on(EVENT_UPDATED, remount);
+  }
+
+  function remount() {
+    destroy();
+    mount();
   }
 
   function init() {
-    if (options.arrows) {
-      if (!prev || !next) {
-        createArrows();
-      }
+    var enabled = options.arrows;
+
+    if (enabled && !(prev && next)) {
+      createArrows();
     }
 
     if (prev && next) {
-      if (!arrows.prev) {
-        setAttribute([prev, next], ARIA_CONTROLS, Elements.list.id);
-        arrows.prev = prev;
-        arrows.next = next;
+      assign(arrows, {
+        prev: prev,
+        next: next
+      });
+      display(wrapper, enabled ? "" : "none");
+
+      if (enabled) {
         listen();
+        update();
+        setAttribute([prev, next], ARIA_CONTROLS, Elements.list.id);
         emit(EVENT_ARROWS_MOUNTED, prev, next);
       }
-
-      display(wrapper, options.arrows === false ? "none" : "");
     }
   }
 
   function destroy() {
+    destroyEvents();
+
     if (created) {
-      remove(wrapper);
+      remove(userArrows ? [prev, next] : wrapper);
+      prev = next = null;
     } else {
       removeAttribute([prev, next], ALL_ATTRIBUTES);
     }
   }
 
   function listen() {
-    var go = Controller.go;
-    on([EVENT_MOUNTED, EVENT_MOVED, EVENT_UPDATED, EVENT_REFRESH, EVENT_SCROLLED], update);
-    bind(next, "click", apply(go, ">", true, void 0));
-    bind(prev, "click", apply(go, "<", true, void 0));
+    on([EVENT_MOVED, EVENT_REFRESH, EVENT_SCROLLED], update);
+    bind(next, "click", apply(go, ">"));
+    bind(prev, "click", apply(go, "<"));
+  }
+
+  function go(control) {
+    Controller.go(control, true);
   }
 
   function createArrows() {
-    wrapper = create("div", classes.arrows);
+    wrapper = userArrows || create("div", classes.arrows);
     prev = createArrow(true);
     next = createArrow(false);
     created = true;
     append(wrapper, [prev, next]);
-    before(wrapper, child(options.arrows === "slider" && Elements.slider || Splide2.root));
+    !userArrows && before(wrapper, Elements.track);
   }
 
   function createArrow(prev2) {
@@ -2078,11 +2114,9 @@ function Drag(Splide2, Components2, options) {
     clickPrevented = false;
 
     if (!disabled) {
-      var noDrag = options.noDrag;
       var isTouch = isTouchEvent(e);
-      var isDraggable = !noDrag || !matches(e.target, noDrag);
 
-      if (isDraggable && (isTouch || !e.button)) {
+      if (isDraggable(e.target) && (isTouch || !e.button)) {
         if (!Controller.isBusy()) {
           target = isTouch ? track : window;
           dragging = state.is([MOVING, SCROLLING]);
@@ -2157,15 +2191,16 @@ function Drag(Splide2, Components2, options) {
     var velocity = computeVelocity(e);
     var destination = computeDestination(velocity);
     var rewind = options.rewind && options.rewindByDrag;
+    var go = Controller.go;
 
     if (isFree) {
       Controller.scroll(destination, 0, options.snap);
     } else if (Splide2.is(FADE)) {
-      Controller.go(orient(sign(velocity)) < 0 ? rewind ? "<" : "-" : rewind ? ">" : "+");
+      go(orient(sign(velocity)) < 0 ? rewind ? "<" : "-" : rewind ? ">" : "+");
     } else if (Splide2.is(SLIDE) && exceeded && rewind) {
-      Controller.go(exceededLimit(true) ? ">" : "<");
+      go(exceededLimit(true) ? ">" : "<");
     } else {
-      Controller.go(Controller.toDest(destination), true);
+      go(Controller.toDest(destination), true);
     }
   }
 
@@ -2217,6 +2252,10 @@ function Drag(Splide2, Components2, options) {
     return diff / (exceeded && Splide2.is(SLIDE) ? FRICTION : 1);
   }
 
+  function isDraggable(target2) {
+    return !matches(target2, push((options.noDrag || "").split(",").filter(Boolean), ["." + CLASS_PAGINATION_PAGE, "." + CLASS_ARROW]).join(","));
+  }
+
   function isTouchEvent(e) {
     return typeof TouchEvent !== "undefined" && e instanceof TouchEvent;
   }
@@ -2444,7 +2483,7 @@ function Pagination(Splide2, Components2, options) {
       on = _EventInterface15.on,
       emit = _EventInterface15.emit,
       bind = _EventInterface15.bind,
-      unbind = _EventInterface15.unbind;
+      destroyEvents = _EventInterface15.destroy;
 
   var Slides = Components2.Slides,
       Elements = Components2.Elements,
@@ -2454,21 +2493,17 @@ function Pagination(Splide2, Components2, options) {
       go = Controller.go;
   var resolve = Components2.Direction.resolve;
   var items = [];
-  var list;
+  var pagination;
 
   function mount() {
-    init();
-    on([EVENT_UPDATED, EVENT_REFRESH], init);
-    on([EVENT_MOVE, EVENT_SCROLL, EVENT_SCROLLED], update);
-  }
-
-  function init() {
     destroy();
+    on([EVENT_UPDATED, EVENT_REFRESH], mount);
 
     if (options.pagination && Slides.isEnough()) {
+      on([EVENT_MOVE, EVENT_SCROLL, EVENT_SCROLLED], update);
       createPagination();
       emit(EVENT_PAGINATION_MOUNTED, {
-        list: list,
+        list: pagination,
         items: items
       }, getAt(Splide2.index));
       update();
@@ -2476,13 +2511,11 @@ function Pagination(Splide2, Components2, options) {
   }
 
   function destroy() {
-    if (list) {
-      remove(list);
-      items.forEach(function (item) {
-        unbind(item.button, "click keydown focus");
-      });
+    if (pagination) {
+      destroyEvents();
+      remove(Elements.pagination ? slice(pagination.children) : pagination);
       empty(items);
-      list = null;
+      pagination = null;
     }
   }
 
@@ -2491,15 +2524,14 @@ function Pagination(Splide2, Components2, options) {
     var classes = options.classes,
         i18n = options.i18n,
         perPage = options.perPage;
-    var parent = options.pagination === "slider" && Elements.slider || Elements.root;
     var max = hasFocus() ? length : ceil(length / perPage);
-    list = create("ul", classes.pagination, parent);
-    setAttribute(list, ROLE, "tablist");
-    setAttribute(list, ARIA_LABEL, i18n.select);
-    setAttribute(list, ARIA_ORIENTATION, options.direction === TTB ? "vertical" : "");
+    pagination = Elements.pagination || create("ul", classes.pagination, Elements.root);
+    setAttribute(pagination, ROLE, "tablist");
+    setAttribute(pagination, ARIA_LABEL, i18n.select);
+    setAttribute(pagination, ARIA_ORIENTATION, options.direction === TTB ? "vertical" : "");
 
     for (var i = 0; i < max; i++) {
-      var li = create("li", null, list);
+      var li = create("li", null, pagination);
       var button = create("button", {
         class: classes.page,
         type: "button"
@@ -2578,7 +2610,7 @@ function Pagination(Splide2, Components2, options) {
     }
 
     emit(EVENT_PAGINATION_UPDATED, {
-      list: list,
+      list: pagination,
       items: items
     }, prev, curr);
   }

+ 98 - 67
dist/js/splide.js

@@ -4,7 +4,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
 /*!
  * Splide.js
- * Version  : 3.6.14
+ * Version  : 4.0.0
  * License  : MIT
  * Copyright: 2022 Naotoshi Fujita
  */
@@ -157,9 +157,10 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   }
 
   function children(parent, selector) {
-    return parent ? slice(parent.children).filter(function (child) {
+    var children2 = parent ? slice(parent.children) : [];
+    return selector ? children2.filter(function (child) {
       return matches(child, selector);
-    }) : [];
+    }) : children2;
   }
 
   function child(parent, selector) {
@@ -698,7 +699,6 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   var ARIA_LIVE = ARIA_PREFIX + "live";
   var ALL_ATTRIBUTES = [ROLE, TAB_INDEX, DISABLED, ARIA_CONTROLS, ARIA_CURRENT, ARIA_LABEL, ARIA_HIDDEN, ARIA_ORIENTATION, ARIA_ROLEDESCRIPTION, ARIA_ATOMIC, ARIA_LIVE];
   var CLASS_ROOT = PROJECT_CODE;
-  var CLASS_SLIDER = PROJECT_CODE + "__slider";
   var CLASS_TRACK = PROJECT_CODE + "__track";
   var CLASS_LIST = PROJECT_CODE + "__list";
   var CLASS_SLIDE = PROJECT_CODE + "__slide";
@@ -735,6 +735,24 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     spinner: CLASS_SPINNER
   };
 
+  function closest(from, selector) {
+    if (isFunction(from.closest)) {
+      return from.closest(selector);
+    }
+
+    var elm = from;
+
+    while (elm && elm.nodeType === 1) {
+      if (matches(elm, selector)) {
+        break;
+      }
+
+      elm = elm.parentElement;
+    }
+
+    return elm;
+  }
+
   function Elements(Splide2, Components2, options) {
     var _EventInterface = EventInterface(Splide2),
         on = _EventInterface.on;
@@ -744,7 +762,6 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     var elements = {};
     var slides = [];
     var classes;
-    var slider;
     var track;
     var list;
 
@@ -772,26 +789,27 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function collect() {
-      slider = child(root, "." + CLASS_SLIDER);
-      track = query(root, "." + CLASS_TRACK);
+      track = find("." + CLASS_TRACK);
       list = child(track, "." + CLASS_LIST);
       assert(track && list, "A track/list element is missing.");
       push(slides, children(list, "." + CLASS_SLIDE + ":not(." + CLASS_CLONE + ")"));
-      var autoplay = find("." + CLASS_AUTOPLAY);
-      var arrows = find("." + CLASS_ARROWS);
+      forOwn({
+        arrows: CLASS_ARROWS,
+        pagination: CLASS_PAGINATION,
+        autoplay: CLASS_AUTOPLAY,
+        prev: CLASS_ARROW_PREV,
+        next: CLASS_ARROW_NEXT,
+        bar: CLASS_PROGRESS_BAR,
+        play: CLASS_PLAY,
+        pause: CLASS_PAUSE
+      }, function (className, key) {
+        elements[key] = find("." + className);
+      });
       assign(elements, {
         root: root,
-        slider: slider,
         track: track,
         list: list,
-        slides: slides,
-        arrows: arrows,
-        autoplay: autoplay,
-        prev: query(arrows, "." + CLASS_ARROW_PREV),
-        next: query(arrows, "." + CLASS_ARROW_NEXT),
-        bar: query(find("." + CLASS_PROGRESS), "." + CLASS_PROGRESS_BAR),
-        play: query(autoplay, "." + CLASS_PLAY),
-        pause: query(autoplay, "." + CLASS_PAUSE)
+        slides: slides
       });
     }
 
@@ -806,7 +824,8 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function find(selector) {
-      return child(root, selector) || child(slider, selector);
+      var elm = query(root, selector);
+      return elm && closest(elm, "." + CLASS_ROOT) === root ? elm : null;
     }
 
     function getClasses() {
@@ -1703,13 +1722,15 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     var _EventInterface8 = EventInterface(Splide2),
         on = _EventInterface8.on,
         bind = _EventInterface8.bind,
-        emit = _EventInterface8.emit;
+        emit = _EventInterface8.emit,
+        destroyEvents = _EventInterface8.destroy;
 
     var classes = options.classes,
         i18n = options.i18n;
     var Elements = Components2.Elements,
         Controller = Components2.Controller;
-    var wrapper = Elements.arrows;
+    var userArrows = Elements.arrows;
+    var wrapper = userArrows;
     var prev = Elements.prev;
     var next = Elements.next;
     var created;
@@ -1717,51 +1738,65 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
     function mount() {
       init();
-      on(EVENT_UPDATED, init);
+      on(EVENT_UPDATED, remount);
+    }
+
+    function remount() {
+      destroy();
+      mount();
     }
 
     function init() {
-      if (options.arrows) {
-        if (!prev || !next) {
-          createArrows();
-        }
+      var enabled = options.arrows;
+
+      if (enabled && !(prev && next)) {
+        createArrows();
       }
 
       if (prev && next) {
-        if (!arrows.prev) {
-          setAttribute([prev, next], ARIA_CONTROLS, Elements.list.id);
-          arrows.prev = prev;
-          arrows.next = next;
+        assign(arrows, {
+          prev: prev,
+          next: next
+        });
+        display(wrapper, enabled ? "" : "none");
+
+        if (enabled) {
           listen();
+          update();
+          setAttribute([prev, next], ARIA_CONTROLS, Elements.list.id);
           emit(EVENT_ARROWS_MOUNTED, prev, next);
         }
-
-        display(wrapper, options.arrows === false ? "none" : "");
       }
     }
 
     function destroy() {
+      destroyEvents();
+
       if (created) {
-        remove(wrapper);
+        remove(userArrows ? [prev, next] : wrapper);
+        prev = next = null;
       } else {
         removeAttribute([prev, next], ALL_ATTRIBUTES);
       }
     }
 
     function listen() {
-      var go = Controller.go;
-      on([EVENT_MOUNTED, EVENT_MOVED, EVENT_UPDATED, EVENT_REFRESH, EVENT_SCROLLED], update);
-      bind(next, "click", apply(go, ">", true, void 0));
-      bind(prev, "click", apply(go, "<", true, void 0));
+      on([EVENT_MOVED, EVENT_REFRESH, EVENT_SCROLLED], update);
+      bind(next, "click", apply(go, ">"));
+      bind(prev, "click", apply(go, "<"));
+    }
+
+    function go(control) {
+      Controller.go(control, true);
     }
 
     function createArrows() {
-      wrapper = create("div", classes.arrows);
+      wrapper = userArrows || create("div", classes.arrows);
       prev = createArrow(true);
       next = createArrow(false);
       created = true;
       append(wrapper, [prev, next]);
-      before(wrapper, child(options.arrows === "slider" && Elements.slider || Splide2.root));
+      !userArrows && before(wrapper, Elements.track);
     }
 
     function createArrow(prev2) {
@@ -2079,11 +2114,9 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       clickPrevented = false;
 
       if (!disabled) {
-        var noDrag = options.noDrag;
         var isTouch = isTouchEvent(e);
-        var isDraggable = !noDrag || !matches(e.target, noDrag);
 
-        if (isDraggable && (isTouch || !e.button)) {
+        if (isDraggable(e.target) && (isTouch || !e.button)) {
           if (!Controller.isBusy()) {
             target = isTouch ? track : window;
             dragging = state.is([MOVING, SCROLLING]);
@@ -2158,15 +2191,16 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       var velocity = computeVelocity(e);
       var destination = computeDestination(velocity);
       var rewind = options.rewind && options.rewindByDrag;
+      var go = Controller.go;
 
       if (isFree) {
         Controller.scroll(destination, 0, options.snap);
       } else if (Splide2.is(FADE)) {
-        Controller.go(orient(sign(velocity)) < 0 ? rewind ? "<" : "-" : rewind ? ">" : "+");
+        go(orient(sign(velocity)) < 0 ? rewind ? "<" : "-" : rewind ? ">" : "+");
       } else if (Splide2.is(SLIDE) && exceeded && rewind) {
-        Controller.go(exceededLimit(true) ? ">" : "<");
+        go(exceededLimit(true) ? ">" : "<");
       } else {
-        Controller.go(Controller.toDest(destination), true);
+        go(Controller.toDest(destination), true);
       }
     }
 
@@ -2218,6 +2252,10 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       return diff / (exceeded && Splide2.is(SLIDE) ? FRICTION : 1);
     }
 
+    function isDraggable(target2) {
+      return !matches(target2, push((options.noDrag || "").split(",").filter(Boolean), ["." + CLASS_PAGINATION_PAGE, "." + CLASS_ARROW]).join(","));
+    }
+
     function isTouchEvent(e) {
       return typeof TouchEvent !== "undefined" && e instanceof TouchEvent;
     }
@@ -2445,7 +2483,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
         on = _EventInterface15.on,
         emit = _EventInterface15.emit,
         bind = _EventInterface15.bind,
-        unbind = _EventInterface15.unbind;
+        destroyEvents = _EventInterface15.destroy;
 
     var Slides = Components2.Slides,
         Elements = Components2.Elements,
@@ -2455,21 +2493,17 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
         go = Controller.go;
     var resolve = Components2.Direction.resolve;
     var items = [];
-    var list;
+    var pagination;
 
     function mount() {
-      init();
-      on([EVENT_UPDATED, EVENT_REFRESH], init);
-      on([EVENT_MOVE, EVENT_SCROLL, EVENT_SCROLLED], update);
-    }
-
-    function init() {
       destroy();
+      on([EVENT_UPDATED, EVENT_REFRESH], mount);
 
       if (options.pagination && Slides.isEnough()) {
+        on([EVENT_MOVE, EVENT_SCROLL, EVENT_SCROLLED], update);
         createPagination();
         emit(EVENT_PAGINATION_MOUNTED, {
-          list: list,
+          list: pagination,
           items: items
         }, getAt(Splide2.index));
         update();
@@ -2477,13 +2511,11 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function destroy() {
-      if (list) {
-        remove(list);
-        items.forEach(function (item) {
-          unbind(item.button, "click keydown focus");
-        });
+      if (pagination) {
+        destroyEvents();
+        remove(Elements.pagination ? slice(pagination.children) : pagination);
         empty(items);
-        list = null;
+        pagination = null;
       }
     }
 
@@ -2492,15 +2524,14 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       var classes = options.classes,
           i18n = options.i18n,
           perPage = options.perPage;
-      var parent = options.pagination === "slider" && Elements.slider || Elements.root;
       var max = hasFocus() ? length : ceil(length / perPage);
-      list = create("ul", classes.pagination, parent);
-      setAttribute(list, ROLE, "tablist");
-      setAttribute(list, ARIA_LABEL, i18n.select);
-      setAttribute(list, ARIA_ORIENTATION, options.direction === TTB ? "vertical" : "");
+      pagination = Elements.pagination || create("ul", classes.pagination, Elements.root);
+      setAttribute(pagination, ROLE, "tablist");
+      setAttribute(pagination, ARIA_LABEL, i18n.select);
+      setAttribute(pagination, ARIA_ORIENTATION, options.direction === TTB ? "vertical" : "");
 
       for (var i = 0; i < max; i++) {
-        var li = create("li", null, list);
+        var li = create("li", null, pagination);
         var button = create("button", {
           class: classes.page,
           type: "button"
@@ -2579,7 +2610,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       }
 
       emit(EVENT_PAGINATION_UPDATED, {
-        list: list,
+        list: pagination,
         items: items
       }, prev, curr);
     }

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/js/splide.min.js


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


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/js/splide.min.js.map


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

@@ -23,17 +23,17 @@ interface DirectionComponent extends BaseComponent {
  */
 interface ElementCollection {
     root: HTMLElement;
-    slider: HTMLElement;
     track: HTMLElement;
     list: HTMLElement;
     slides: HTMLElement[];
-    arrows: HTMLElement;
-    prev: HTMLButtonElement;
-    next: HTMLButtonElement;
-    bar: HTMLElement;
-    autoplay: HTMLElement;
-    play: HTMLButtonElement;
-    pause: HTMLButtonElement;
+    arrows: HTMLElement | null;
+    pagination: HTMLUListElement | null;
+    prev: HTMLButtonElement | null;
+    next: HTMLButtonElement | null;
+    bar: HTMLElement | null;
+    autoplay: HTMLElement | null;
+    play: HTMLButtonElement | null;
+    pause: HTMLButtonElement | null;
 }
 /**
  * The interface for the Elements component.
@@ -240,7 +240,7 @@ interface WheelComponent extends BaseComponent {
 /**
  * The interface for the Live component.
  *
- * @since 3.7.0
+ * @since 4.0.0
  */
 interface LiveComponent extends BaseComponent {
     disable(disabled: boolean): void;
@@ -562,11 +562,11 @@ interface ResponsiveOptions {
     /**
      * Determines whether to create/find arrows or not.
      */
-    arrows?: boolean | 'slider';
+    arrows?: boolean;
     /**
      * Determines whether to create pagination (indicator dots) or not.
      */
-    pagination?: boolean | 'slider';
+    pagination?: boolean;
     /**
      * The timing function for the CSS transition. For example, `linear`, ease or `cubic-bezier()`.
      */
@@ -799,7 +799,7 @@ declare type SlideMatcher = number | number[] | string | SlidesPredicate;
 /**
  * The type for an EventTarget or an array with EventTarget objects.
  *
- * @since 3.7.0
+ * @since 4.0.0
  */
 declare type EventTargets = EventTarget | EventTarget[];
 /**
@@ -816,7 +816,7 @@ interface EventBinderObject {
 /**
  * The constructor function to provide methods to subscribe native events.
  *
- * @since 3.7.0
+ * @since 4.0.0
  * @constructor
  *
  * @return An EventBinder object.

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "@splidejs/splide",
-  "version": "3.6.14",
+  "version": "4.0.0",
   "description": "Splide is a lightweight, flexible and accessible slider/carousel. No dependencies, no Lighthouse errors.",
   "author": "Naotoshi Fujita",
   "license": "MIT",

+ 2 - 0
src/css/template/default/object/objects/pagination.scss

@@ -33,6 +33,7 @@ $dot-transform-active: scale( 1.4 ) !default;
       height: $dot-height;
       margin: $dot-margin;
       padding: $dot-padding;
+      position: relative;
       transition: $dot-transition;
       width: $dot-width;
 
@@ -42,6 +43,7 @@ $dot-transform-active: scale( 1.4 ) !default;
 
       &.is-active {
         background: $dot-background-active;
+        z-index: 1;
 
         @if $dot-transform-active {
           transform: $dot-transform-active;

+ 40 - 24
src/js/components/Arrows/Arrows.ts

@@ -2,7 +2,6 @@ import { ALL_ATTRIBUTES, ARIA_CONTROLS, ARIA_LABEL } from '../../constants/attri
 import {
   EVENT_ARROWS_MOUNTED,
   EVENT_ARROWS_UPDATED,
-  EVENT_MOUNTED,
   EVENT_MOVED,
   EVENT_REFRESH,
   EVENT_SCROLLED,
@@ -14,8 +13,8 @@ import { BaseComponent, Components, Options } from '../../types';
 import {
   append,
   apply,
+  assign,
   before,
-  child,
   create,
   display,
   parseHtml,
@@ -47,14 +46,15 @@ export interface ArrowsComponent extends BaseComponent {
  * @return An Arrows component object.
  */
 export function Arrows( Splide: Splide, Components: Components, options: Options ): ArrowsComponent {
-  const { on, bind, emit } = EventInterface( Splide );
+  const { on, bind, emit, destroy: destroyEvents } = EventInterface( Splide );
   const { classes, i18n } = options;
   const { Elements, Controller } = Components;
+  const userArrows = Elements.arrows;
 
   /**
    * The wrapper element.
    */
-  let wrapper = Elements.arrows;
+  let wrapper = userArrows;
 
   /**
    * The previous arrow element.
@@ -81,32 +81,37 @@ export function Arrows( Splide: Splide, Components: Components, options: Options
    */
   function mount(): void {
     init();
-    on( EVENT_UPDATED, init );
+    on( EVENT_UPDATED, remount );
+  }
+
+  /**
+   * Remounts the component.
+   */
+  function remount(): void {
+    destroy();
+    mount();
   }
 
   /**
    * Initializes the component.
    */
   function init(): void {
-    if ( options.arrows ) {
-      if ( ! prev || ! next ) {
-        createArrows();
-      }
+    const enabled = options.arrows;
+
+    if ( enabled && ! ( prev && next ) ) {
+      createArrows();
     }
 
     if ( prev && next ) {
-      if ( ! arrows.prev ) {
-        setAttribute( [ prev, next ], ARIA_CONTROLS, Elements.list.id );
-
-        arrows.prev = prev;
-        arrows.next = next;
+      assign( arrows, { prev, next } );
+      display( wrapper, enabled ? '' : 'none' );
 
+      if ( enabled ) {
         listen();
-
+        update();
+        setAttribute( [ prev, next ], ARIA_CONTROLS, Elements.list.id );
         emit( EVENT_ARROWS_MOUNTED, prev, next );
       }
-
-      display( wrapper, options.arrows === false ? 'none' : '' );
     }
   }
 
@@ -114,8 +119,11 @@ export function Arrows( Splide: Splide, Components: Components, options: Options
    * Destroys the component.
    */
   function destroy(): void {
+    destroyEvents();
+
     if ( created ) {
-      remove( wrapper );
+      remove( userArrows ? [ prev, next ] : wrapper );
+      prev = next = null;
     } else {
       removeAttribute( [ prev, next ], ALL_ATTRIBUTES );
     }
@@ -125,23 +133,31 @@ export function Arrows( Splide: Splide, Components: Components, options: Options
    * Listens to some events.
    */
   function listen(): void {
-    const { go } = Controller;
-    on( [ EVENT_MOUNTED, EVENT_MOVED, EVENT_UPDATED, EVENT_REFRESH, EVENT_SCROLLED ], update );
-    bind( next, 'click', apply( go, '>', true, undefined ) );
-    bind( prev, 'click', apply( go, '<', true, undefined ) );
+    on( [ EVENT_MOVED, EVENT_REFRESH, EVENT_SCROLLED ], update );
+    bind( next, 'click', apply( go, '>' ) );
+    bind( prev, 'click', apply( go, '<' ) );
+  }
+
+  /**
+   * The wrapper function of Controller#go().
+   *
+   * @param control - The control pattern.
+   */
+  function go( control: string ): void {
+    Controller.go( control, true );
   }
 
   /**
    * Create arrows and append them to the slider.
    */
   function createArrows(): void {
-    wrapper = create( 'div', classes.arrows );
+    wrapper = userArrows || create( 'div', classes.arrows );
     prev    = createArrow( true );
     next    = createArrow( false );
     created = true;
 
     append( wrapper, [ prev, next ] );
-    before( wrapper, child( options.arrows === 'slider' && Elements.slider || Splide.root ) );
+    ! userArrows && before( wrapper, Elements.track );
   }
 
   /**

+ 22 - 8
src/js/components/Drag/Drag.ts

@@ -1,3 +1,4 @@
+import { CLASS_ARROW, CLASS_PAGINATION_PAGE } from '../../constants/classes';
 import { EVENT_DRAG, EVENT_DRAGGED, EVENT_DRAGGING, EVENT_MOUNTED, EVENT_UPDATED } from '../../constants/events';
 import { SCROLL_LISTENER_OPTIONS } from '../../constants/listener-options';
 import { DRAGGING, IDLE, MOVING, SCROLLING } from '../../constants/states';
@@ -5,7 +6,7 @@ import { FADE, LOOP, SLIDE } from '../../constants/types';
 import { EventInterface } from '../../constructors';
 import { Splide } from '../../core/Splide/Splide';
 import { BaseComponent, Components, Options } from '../../types';
-import { abs, isObject, matches, min, noop, prevent, sign, timeOf } from '../../utils';
+import { abs, isObject, matches, min, noop, prevent, push, sign, timeOf } from '../../utils';
 import { FRICTION, LOG_INTERVAL, POINTER_DOWN_EVENTS, POINTER_MOVE_EVENTS, POINTER_UP_EVENTS } from './constants';
 
 
@@ -117,11 +118,9 @@ export function Drag( Splide: Splide, Components: Components, options: Options )
     clickPrevented = false;
 
     if ( ! disabled ) {
-      const { noDrag } = options;
-      const isTouch     = isTouchEvent( e );
-      const isDraggable = ! noDrag || ! matches( e.target, noDrag );
+      const isTouch = isTouchEvent( e );
 
-      if ( isDraggable && ( isTouch || ! e.button ) ) {
+      if ( isDraggable( e.target ) && ( isTouch || ! e.button ) ) {
         if ( ! Controller.isBusy() ) {
           target        = isTouch ? track : window;
           dragging      = state.is( [ MOVING, SCROLLING ] );
@@ -227,15 +226,16 @@ export function Drag( Splide: Splide, Components: Components, options: Options )
     const velocity    = computeVelocity( e );
     const destination = computeDestination( velocity );
     const rewind      = options.rewind && options.rewindByDrag;
+    const { go } = Controller;
 
     if ( isFree ) {
       Controller.scroll( destination, 0, options.snap );
     } else if ( Splide.is( FADE ) ) {
-      Controller.go( orient( sign( velocity ) ) < 0 ? ( rewind ? '<' : '-' ) : ( rewind ? '>' : '+' ) );
+      go( orient( sign( velocity ) ) < 0 ? ( rewind ? '<' : '-' ) : ( rewind ? '>' : '+' ) );
     } else if ( Splide.is( SLIDE ) && exceeded && rewind ) {
-      Controller.go( exceededLimit( true ) ? '>' : '<' );
+      go( exceededLimit( true ) ? '>' : '<' );
     } else {
-      Controller.go( Controller.toDest( destination ), true );
+      go( Controller.toDest( destination ), true );
     }
   }
 
@@ -358,6 +358,20 @@ export function Drag( Splide: Splide, Components: Components, options: Options )
     return diff / ( exceeded && Splide.is( SLIDE ) ? FRICTION : 1 );
   }
 
+  /**
+   * Returns `true` if the user can drag the target.
+   *
+   * @param target - An event target.
+   *
+   * @return `true` if the target is draggable.
+   */
+  function isDraggable( target: EventTarget ): boolean {
+    return ! matches( target, push(
+      ( options.noDrag || '' ).split( ',' ).filter( Boolean ),
+      [ `.${ CLASS_PAGINATION_PAGE }`, `.${ CLASS_ARROW }` ]
+    ).join( ',' ) );
+  }
+
   /**
    * Checks if the provided event is TouchEvent or MouseEvent.
    *

+ 31 - 39
src/js/components/Elements/Elements.ts

@@ -7,13 +7,12 @@ import {
   CLASS_AUTOPLAY,
   CLASS_CLONE,
   CLASS_LIST,
+  CLASS_PAGINATION,
   CLASS_PAUSE,
   CLASS_PLAY,
-  CLASS_PROGRESS,
   CLASS_PROGRESS_BAR,
   CLASS_ROOT,
   CLASS_SLIDE,
-  CLASS_SLIDER,
   CLASS_TRACK,
 } from '../../constants/classes';
 import { EVENT_REFRESH, EVENT_UPDATED } from '../../constants/events';
@@ -28,6 +27,7 @@ import {
   child,
   children,
   empty,
+  forOwn,
   push,
   query,
   removeAttribute,
@@ -35,6 +35,7 @@ import {
   setAttribute,
   uniqueId,
 } from '../../utils';
+import { closest } from '../../utils/dom/closest/closest';
 
 
 /**
@@ -44,17 +45,17 @@ import {
  */
 export interface ElementCollection {
   root: HTMLElement;
-  slider: HTMLElement;
   track: HTMLElement;
   list: HTMLElement;
   slides: HTMLElement[];
-  arrows: HTMLElement;
-  prev: HTMLButtonElement;
-  next: HTMLButtonElement;
-  bar: HTMLElement;
-  autoplay: HTMLElement;
-  play: HTMLButtonElement;
-  pause: HTMLButtonElement;
+  arrows: HTMLElement | null;
+  pagination: HTMLUListElement | null;
+  prev: HTMLButtonElement | null;
+  next: HTMLButtonElement | null;
+  bar: HTMLElement | null;
+  autoplay: HTMLElement | null;
+  play: HTMLButtonElement | null;
+  pause: HTMLButtonElement | null;
 }
 
 /**
@@ -92,11 +93,6 @@ export function Elements( Splide: Splide, Components: Components, options: Optio
    */
   let classes: string[];
 
-  /**
-   * The slider element that may be `undefined`.
-   */
-  let slider: HTMLElement;
-
   /**
    * The track element.
    */
@@ -146,31 +142,26 @@ export function Elements( Splide: Splide, Components: Components, options: Optio
    * Collects elements which the slider consists of.
    */
   function collect(): void {
-    slider = child( root, `.${ CLASS_SLIDER }` );
-    track  = query( root, `.${ CLASS_TRACK }` );
-    list   = child( track, `.${ CLASS_LIST }` );
+    track = find( `.${ CLASS_TRACK }` );
+    list  = child( track, `.${ CLASS_LIST }` );
 
     assert( track && list, 'A track/list element is missing.' );
-
     push( slides, children( list, `.${ CLASS_SLIDE }:not(.${ CLASS_CLONE })` ) );
 
-    const autoplay = find( `.${ CLASS_AUTOPLAY }` );
-    const arrows   = find( `.${ CLASS_ARROWS }` );
-
-    assign( elements, {
-      root,
-      slider,
-      track,
-      list,
-      slides,
-      arrows,
-      autoplay,
-      prev : query( arrows, `.${ CLASS_ARROW_PREV }` ),
-      next : query( arrows, `.${ CLASS_ARROW_NEXT }` ),
-      bar  : query( find( `.${ CLASS_PROGRESS }` ), `.${ CLASS_PROGRESS_BAR }` ),
-      play : query( autoplay, `.${ CLASS_PLAY }` ),
-      pause: query( autoplay, `.${ CLASS_PAUSE }` ),
+    forOwn( {
+      arrows    : CLASS_ARROWS,
+      pagination: CLASS_PAGINATION,
+      autoplay  : CLASS_AUTOPLAY,
+      prev      : CLASS_ARROW_PREV,
+      next      : CLASS_ARROW_NEXT,
+      bar       : CLASS_PROGRESS_BAR,
+      play      : CLASS_PLAY,
+      pause     : CLASS_PAUSE,
+    }, ( className, key ) => {
+      elements[ key ] = find( `.${ className }` );
     } );
+
+    assign( elements, { root, track, list, slides } );
   }
 
   /**
@@ -188,12 +179,13 @@ export function Elements( Splide: Splide, Components: Components, options: Optio
   }
 
   /**
-   * Finds an element only in children of the root or slider element.
+   * Finds an element only in this slider, ignoring elements in a nested slider.
    *
-   * @return {Element} - A found element or undefined.
+   * @return A found element or null.
    */
-  function find( selector: string ): HTMLElement {
-    return child( root, selector ) || child( slider, selector );
+  function find( selector: string ): HTMLElement | null {
+    const elm = query<HTMLElement>( root, selector );
+    return elm && closest( elm, `.${ CLASS_ROOT }` ) === root ? elm : null;
   }
 
   /**

+ 20 - 25
src/js/components/Pagination/Pagination.ts

@@ -12,7 +12,8 @@ import {
   EVENT_MOVE,
   EVENT_PAGINATION_MOUNTED,
   EVENT_PAGINATION_UPDATED,
-  EVENT_REFRESH, EVENT_SCROLL,
+  EVENT_REFRESH,
+  EVENT_SCROLL,
   EVENT_SCROLLED,
   EVENT_UPDATED,
 } from '../../constants/events';
@@ -32,6 +33,7 @@ import {
   removeAttribute,
   removeClass,
   setAttribute,
+  slice,
 } from '../../utils';
 import { normalizeKey } from '../../utils/dom/normalizeKey/normalizeKey';
 
@@ -81,7 +83,7 @@ export interface PaginationItem {
  * @return A Pagination component object.
  */
 export function Pagination( Splide: Splide, Components: Components, options: Options ): PaginationComponent {
-  const { on, emit, bind, unbind } = EventInterface( Splide );
+  const { on, emit, bind, destroy: destroyEvents } = EventInterface( Splide );
   const { Slides, Elements, Controller } = Components;
   const { hasFocus, getIndex, go } = Controller;
   const { resolve } = Components.Direction;
@@ -94,26 +96,20 @@ export function Pagination( Splide: Splide, Components: Components, options: Opt
   /**
    * The pagination element.
    */
-  let list: HTMLUListElement;
+  let pagination: HTMLUListElement | null;
 
   /**
    * Called when the component is mounted.
    */
   function mount(): void {
-    init();
-    on( [ EVENT_UPDATED, EVENT_REFRESH ], init );
-    on( [ EVENT_MOVE, EVENT_SCROLL, EVENT_SCROLLED ], update );
-  }
-
-  /**
-   * Initializes the pagination.
-   */
-  function init(): void {
     destroy();
 
+    on( [ EVENT_UPDATED, EVENT_REFRESH ], mount );
+
     if ( options.pagination && Slides.isEnough() ) {
+      on( [ EVENT_MOVE, EVENT_SCROLL, EVENT_SCROLLED ], update );
       createPagination();
-      emit( EVENT_PAGINATION_MOUNTED, { list, items }, getAt( Splide.index ) );
+      emit( EVENT_PAGINATION_MOUNTED, { list: pagination, items }, getAt( Splide.index ) );
       update();
     }
   }
@@ -122,11 +118,11 @@ export function Pagination( Splide: Splide, Components: Components, options: Opt
    * Destroys the component.
    */
   function destroy(): void {
-    if ( list ) {
-      remove( list );
-      items.forEach( item => { unbind( item.button, 'click keydown focus' ) } );
+    if ( pagination ) {
+      destroyEvents();
+      remove( Elements.pagination ? slice( pagination.children ) : pagination );
       empty( items );
-      list = null;
+      pagination = null;
     }
   }
 
@@ -136,17 +132,16 @@ export function Pagination( Splide: Splide, Components: Components, options: Opt
   function createPagination(): void {
     const { length } = Splide;
     const { classes, i18n, perPage } = options;
-    const parent = options.pagination === 'slider' && Elements.slider || Elements.root;
-    const max    = hasFocus() ? length : ceil( length / perPage );
+    const max = hasFocus() ? length : ceil( length / perPage );
 
-    list = create( 'ul', classes.pagination, parent );
+    pagination = Elements.pagination || create( 'ul', classes.pagination, Elements.root );
 
-    setAttribute( list, ROLE, 'tablist' );
-    setAttribute( list, ARIA_LABEL, i18n.select );
-    setAttribute( list, ARIA_ORIENTATION, options.direction === TTB ? 'vertical' : '' );
+    setAttribute( pagination, ROLE, 'tablist' );
+    setAttribute( pagination, ARIA_LABEL, i18n.select );
+    setAttribute( pagination, ARIA_ORIENTATION, options.direction === TTB ? 'vertical' : '' );
 
     for ( let i = 0; i < max; i++ ) {
-      const li       = create( 'li', null, list );
+      const li       = create( 'li', null, pagination );
       const button   = create( 'button', { class: classes.page, type: 'button' }, li );
       const controls = Slides.getIn( i ).map( Slide => Slide.slide.id );
       const text     = ! hasFocus() && perPage > 1 ? i18n.pageX : i18n.slideX;
@@ -244,7 +239,7 @@ export function Pagination( Splide: Splide, Components: Components, options: Opt
       setAttribute( button, TAB_INDEX, '' );
     }
 
-    emit( EVENT_PAGINATION_UPDATED, { list, items }, prev, curr );
+    emit( EVENT_PAGINATION_UPDATED, { list: pagination, items }, prev, curr );
   }
 
   return {

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

@@ -345,12 +345,12 @@ export interface ResponsiveOptions {
   /**
    * Determines whether to create/find arrows or not.
    */
-  arrows?: boolean | 'slider';
+  arrows?: boolean;
 
   /**
    * Determines whether to create pagination (indicator dots) or not.
    */
-  pagination?: boolean | 'slider';
+  pagination?: boolean;
 
   /**
    * The timing function for the CSS transition. For example, `linear`, ease or `cubic-bezier()`.

+ 4 - 3
src/js/utils/dom/children/children.ts

@@ -6,10 +6,11 @@ import { matches } from '../matches/matches';
  * Finds children that has the specified tag or class name.
  *
  * @param parent   - A parent element.
- * @param selector - A selector to filter children.
+ * @param selector - Optional. A selector to filter children.
  *
  * @return An array with filtered children.
  */
-export function children<E extends HTMLElement>( parent: HTMLElement, selector: string ): E[] {
-  return parent ? slice( parent.children ).filter( child => matches( child, selector ) ) as E[] : [];
+export function children<E extends HTMLElement>( parent: HTMLElement, selector?: string ): E[] {
+  const children = parent ? slice( parent.children ) as E[] : [];
+  return selector ? children.filter( child => matches( child, selector ) ) : children;
 }

+ 54 - 0
src/js/utils/dom/closest/closest.test.ts

@@ -0,0 +1,54 @@
+import { closest } from './closest';
+
+
+describe.each( [ [ 'native' ], [ 'polyfill' ] ] )( 'closest (%s)', ( env ) => {
+  if ( env === 'polyfill' ) {
+    // Forces to disable the native method.
+    Element.prototype.closest = null as any;
+  }
+
+  beforeEach( () => {
+    document.body.innerHTML = `
+      <div id="container" class="wrapper">
+        <div id="outer" class="wrapper">
+          <div id="inner">
+            <span id="start">start</span>
+          </div>
+        </div>
+      </div>
+    `;
+  } );
+
+  test( 'can find the closest element.', () => {
+    const from = document.getElementById( 'start' );
+
+    if ( from ) {
+      expect( closest( from, '#inner' )?.id ).toBe( 'inner' );
+      expect( closest( from, '#outer' )?.id ).toBe( 'outer' );
+      expect( closest( from, 'div' )?.id ).toBe( 'inner' );
+      expect( closest( from, '.wrapper' )?.id ).toBe( 'outer' );
+    } else {
+      fail();
+    }
+  } );
+
+  test( 'should include the provided element itself.', () => {
+    const from = document.getElementById( 'start' );
+
+    if ( from ) {
+      expect( closest( from, 'span' )?.id ).toBe( 'start' );
+    } else {
+      fail();
+    }
+  } );
+
+  test( 'should return null if no element is found.', () => {
+    const from = document.getElementById( 'start' );
+
+    if ( from ) {
+      expect( closest( from, 'invalid' ) ).toBeNull();
+    } else {
+      fail();
+    }
+  } );
+} );

+ 29 - 0
src/js/utils/dom/closest/closest.ts

@@ -0,0 +1,29 @@
+import { isFunction } from '../../type/type';
+import { matches } from '../matches/matches';
+
+
+/**
+ * Starts from the provided element, searches for the first element that matches the selector in ascendants.
+ *
+ * @param from     - An element to search from.
+ * @param selector - A selector.
+ *
+ * @return The found element if available, or `null`.
+ */
+export function closest( from: HTMLElement, selector: string ): HTMLElement | null {
+  if ( isFunction( from.closest ) ) {
+    return from.closest( selector );
+  }
+
+  let elm: HTMLElement | null = from;
+
+  while ( elm && elm.nodeType === 1 ) {
+    if ( matches( elm, selector ) ) {
+      break;
+    }
+
+    elm = elm.parentElement;
+  }
+
+  return elm;
+}

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio