@evermade/overflow-slider 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +14 -2
  2. package/dist/core/details.esm.js +4 -4
  3. package/dist/core/details.min.js +1 -1
  4. package/dist/core/slider.esm.js +53 -30
  5. package/dist/core/slider.min.js +1 -1
  6. package/dist/core/utils.esm.js +15 -1
  7. package/dist/core/utils.min.js +1 -1
  8. package/dist/plugins/arrows/arrows/index.esm.js +15 -8
  9. package/dist/plugins/arrows/arrows/index.min.js +1 -1
  10. package/dist/plugins/drag-scrolling/drag-scrolling/index.esm.js +1 -1
  11. package/dist/plugins/drag-scrolling/drag-scrolling/index.min.js +1 -1
  12. package/dist/plugins/fade/fade/index.esm.js +4 -4
  13. package/dist/plugins/fade/fade/index.min.js +1 -1
  14. package/dist/plugins/scroll-indicator/scroll-indicator/index.esm.js +4 -4
  15. package/dist/plugins/scroll-indicator/scroll-indicator/index.min.js +1 -1
  16. package/dist/plugins/thumbnails/thumbnails/index.esm.js +1 -1
  17. package/dist/plugins/thumbnails/thumbnails/index.min.js +1 -1
  18. package/docs/dist/core/details.esm.js +4 -4
  19. package/docs/dist/core/details.min.js +1 -1
  20. package/docs/dist/core/slider.esm.js +53 -30
  21. package/docs/dist/core/slider.min.js +1 -1
  22. package/docs/dist/core/utils.esm.js +15 -1
  23. package/docs/dist/core/utils.min.js +1 -1
  24. package/docs/dist/plugins/arrows/arrows/index.esm.js +15 -8
  25. package/docs/dist/plugins/arrows/arrows/index.min.js +1 -1
  26. package/docs/dist/plugins/drag-scrolling/drag-scrolling/index.esm.js +1 -1
  27. package/docs/dist/plugins/drag-scrolling/drag-scrolling/index.min.js +1 -1
  28. package/docs/dist/plugins/fade/fade/index.esm.js +4 -4
  29. package/docs/dist/plugins/fade/fade/index.min.js +1 -1
  30. package/docs/dist/plugins/scroll-indicator/scroll-indicator/index.esm.js +4 -4
  31. package/docs/dist/plugins/scroll-indicator/scroll-indicator/index.min.js +1 -1
  32. package/docs/dist/plugins/thumbnails/thumbnails/index.esm.js +1 -1
  33. package/docs/dist/plugins/thumbnails/thumbnails/index.min.js +1 -1
  34. package/package.json +1 -1
  35. package/src/core/details.ts +4 -4
  36. package/src/core/slider.ts +60 -32
  37. package/src/core/types.ts +2 -0
  38. package/src/core/utils.ts +19 -1
  39. package/src/plugins/arrows/index.ts +16 -8
  40. package/src/plugins/drag-scrolling/index.ts +1 -1
  41. package/src/plugins/fade/index.ts +4 -5
  42. package/src/plugins/scroll-indicator/index.ts +4 -4
  43. package/src/plugins/thumbnails/index.ts +1 -2
@@ -1,5 +1,5 @@
1
1
  import details from './details.esm.js';
2
- import { generateId, objectsAreEqual } from './utils.esm.js';
2
+ import { generateId, objectsAreEqual, getOutermostChildrenEdgeMarginSum } from './utils.esm.js';
3
3
 
4
4
  function Slider(container, options, plugins) {
5
5
  let slider;
@@ -81,7 +81,7 @@ function Slider(container, options, plugins) {
81
81
  // any scroll
82
82
  slider.container.addEventListener('scroll', () => {
83
83
  const newScrollLeft = slider.container.scrollLeft;
84
- if (scrollLeft !== newScrollLeft) {
84
+ if (Math.floor(scrollLeft) !== Math.floor(newScrollLeft)) {
85
85
  if (!isScrolling) {
86
86
  isScrolling = true;
87
87
  slider.emit('scrollStart');
@@ -102,7 +102,7 @@ function Slider(container, options, plugins) {
102
102
  // user initted scroll (touchmove, mouse wheel, etc.)
103
103
  const nativeScrollHandler = () => {
104
104
  const newScrollLeft = slider.container.scrollLeft;
105
- if (nativeScrollLeft !== newScrollLeft && !isProgrammaticScrolling) {
105
+ if (Math.floor(nativeScrollLeft) !== Math.floor(newScrollLeft) && !isProgrammaticScrolling) {
106
106
  if (!isUserScrolling) {
107
107
  slider.emit('nativeScrollStart');
108
108
  isUserScrolling = true;
@@ -128,7 +128,7 @@ function Slider(container, options, plugins) {
128
128
  });
129
129
  slider.container.addEventListener('scroll', () => {
130
130
  const newScrollLeft = slider.container.scrollLeft;
131
- if (programmaticScrollLeft !== newScrollLeft && !isUserScrolling && isProgrammaticScrolling) {
131
+ if (Math.floor(programmaticScrollLeft) !== Math.floor(newScrollLeft) && !isUserScrolling && isProgrammaticScrolling) {
132
132
  programmaticScrollLeft = newScrollLeft;
133
133
  clearTimeout(programmaticScrollTimeout);
134
134
  programmaticScrollTimeout = setTimeout(() => {
@@ -194,13 +194,13 @@ function Slider(container, options, plugins) {
194
194
  const slideStart = slideRect.left - sliderRect.left + scrollLeft;
195
195
  const slideEnd = slideStart + slideRect.width;
196
196
  let scrollTarget = null;
197
- if (slideStart < scrollLeft) {
197
+ if (Math.floor(slideStart) < Math.floor(scrollLeft)) {
198
198
  scrollTarget = slideStart;
199
199
  }
200
- else if (slideEnd > scrollLeft + containerWidth) {
200
+ else if (Math.floor(slideEnd) > Math.floor(scrollLeft) + Math.floor(containerWidth)) {
201
201
  scrollTarget = slideEnd - containerWidth;
202
202
  }
203
- else if (slideStart === 0) {
203
+ else if (Math.floor(slideStart) === 0) {
204
204
  scrollTarget = 0;
205
205
  }
206
206
  else {
@@ -218,13 +218,20 @@ function Slider(container, options, plugins) {
218
218
  const scrollLeft = slider.container.scrollLeft;
219
219
  const slides = slider.slides;
220
220
  let activeSlideIdx = 0;
221
+ let scrolledPastLastSlide = false;
221
222
  for (let i = 0; i < slides.length; i++) {
222
223
  const slideRect = slides[i].getBoundingClientRect();
223
224
  const slideStart = slideRect.left - sliderRect.left + scrollLeft + getGapSize();
224
- if (slideStart > scrollLeft) {
225
+ if (Math.floor(slideStart) >= Math.floor(scrollLeft)) {
225
226
  activeSlideIdx = i;
226
227
  break;
227
228
  }
229
+ if (i === slides.length - 1) {
230
+ scrolledPastLastSlide = true;
231
+ }
232
+ }
233
+ if (scrolledPastLastSlide) {
234
+ activeSlideIdx = slides.length - 1;
228
235
  }
229
236
  const oldActiveSlideIdx = slider.activeSlideIdx;
230
237
  slider.activeSlideIdx = activeSlideIdx;
@@ -238,12 +245,18 @@ function Slider(container, options, plugins) {
238
245
  ensureSlideIsInView(slide);
239
246
  }
240
247
  }
248
+ function getInclusiveScrollWidth() {
249
+ return slider.container.scrollWidth + getOutermostChildrenEdgeMarginSum(slider.container);
250
+ }
251
+ function getInclusiveClientWidth() {
252
+ return slider.container.clientWidth + getOutermostChildrenEdgeMarginSum(slider.container);
253
+ }
241
254
  function getGapSize() {
242
255
  let gapSize = 0;
243
256
  if (slider.slides.length > 1) {
244
257
  const firstSlideRect = slider.slides[0].getBoundingClientRect();
245
258
  const secondSlideRect = slider.slides[1].getBoundingClientRect();
246
- gapSize = secondSlideRect.left - firstSlideRect.right;
259
+ gapSize = Math.floor(secondSlideRect.left - firstSlideRect.right);
247
260
  }
248
261
  return gapSize;
249
262
  }
@@ -253,7 +266,7 @@ function Slider(container, options, plugins) {
253
266
  if (fullWidthOffset) {
254
267
  offset = parseInt(fullWidthOffset);
255
268
  }
256
- return offset;
269
+ return Math.floor(offset);
257
270
  }
258
271
  function moveToDirection(direction = "prev") {
259
272
  const scrollStrategy = slider.options.scrollStrategy;
@@ -265,16 +278,16 @@ function Slider(container, options, plugins) {
265
278
  targetScrollPosition = Math.max(0, scrollLeft - slider.container.offsetWidth);
266
279
  }
267
280
  else if (direction === 'next') {
268
- targetScrollPosition = Math.min(slider.container.scrollWidth, scrollLeft + slider.container.offsetWidth);
281
+ targetScrollPosition = Math.min(slider.getInclusiveScrollWidth(), scrollLeft + slider.container.offsetWidth);
269
282
  }
270
283
  if (scrollStrategy === 'fullSlide') {
271
- let fullSldeTargetScrollPosition = null;
284
+ let fullSlideTargetScrollPosition = null;
272
285
  // extend targetScrollPosition to include gap
273
286
  if (direction === 'prev') {
274
- fullSldeTargetScrollPosition = Math.max(0, targetScrollPosition - getGapSize());
287
+ fullSlideTargetScrollPosition = Math.max(0, targetScrollPosition - getGapSize());
275
288
  }
276
289
  else {
277
- fullSldeTargetScrollPosition = Math.min(slider.container.scrollWidth, targetScrollPosition + getGapSize());
290
+ fullSlideTargetScrollPosition = Math.min(slider.getInclusiveScrollWidth(), targetScrollPosition + getGapSize());
278
291
  }
279
292
  if (direction === 'next') {
280
293
  let partialSlideFound = false;
@@ -282,17 +295,25 @@ function Slider(container, options, plugins) {
282
295
  const slideRect = slide.getBoundingClientRect();
283
296
  const slideStart = slideRect.left - sliderRect.left + scrollLeft;
284
297
  const slideEnd = slideStart + slideRect.width;
285
- if (slideStart < targetScrollPosition && slideEnd > targetScrollPosition) {
286
- fullSldeTargetScrollPosition = slideStart;
298
+ if (Math.floor(slideStart) < Math.floor(targetScrollPosition) && Math.floor(slideEnd) > Math.floor(targetScrollPosition)) {
299
+ fullSlideTargetScrollPosition = slideStart;
287
300
  partialSlideFound = true;
288
301
  break;
289
302
  }
290
303
  }
291
304
  if (!partialSlideFound) {
292
- fullSldeTargetScrollPosition = Math.min(targetScrollPosition, slider.container.scrollWidth - slider.container.offsetWidth);
305
+ fullSlideTargetScrollPosition = Math.min(targetScrollPosition, slider.getInclusiveScrollWidth() - slider.container.offsetWidth);
293
306
  }
294
- if (fullSldeTargetScrollPosition && fullSldeTargetScrollPosition > scrollLeft) {
295
- targetScrollPosition = fullSldeTargetScrollPosition;
307
+ if (fullSlideTargetScrollPosition) {
308
+ if (Math.floor(fullSlideTargetScrollPosition) > Math.floor(scrollLeft)) {
309
+ // make sure fullSlideTargetScrollPosition is possible considering the container width
310
+ const maxScrollPosition = Math.floor(slider.getInclusiveScrollWidth()) - Math.floor(containerWidth);
311
+ targetScrollPosition = Math.min(fullSlideTargetScrollPosition, maxScrollPosition);
312
+ }
313
+ else {
314
+ // cannot snap to slide, move one page worth of distance
315
+ targetScrollPosition = Math.min(slider.getInclusiveScrollWidth(), scrollLeft + containerWidth);
316
+ }
296
317
  }
297
318
  }
298
319
  else {
@@ -301,23 +322,23 @@ function Slider(container, options, plugins) {
301
322
  const slideRect = slide.getBoundingClientRect();
302
323
  const slideStart = slideRect.left - sliderRect.left + scrollLeft;
303
324
  const slideEnd = slideStart + slideRect.width;
304
- if (slideStart < scrollLeft && slideEnd > scrollLeft) {
305
- fullSldeTargetScrollPosition = slideEnd - containerWidth;
325
+ if (Math.floor(slideStart) < Math.floor(scrollLeft) && Math.floor(slideEnd) > Math.floor(scrollLeft)) {
326
+ fullSlideTargetScrollPosition = slideEnd - containerWidth;
306
327
  partialSlideFound = true;
307
328
  break;
308
329
  }
309
330
  }
310
331
  if (!partialSlideFound) {
311
- fullSldeTargetScrollPosition = Math.max(0, scrollLeft - containerWidth);
332
+ fullSlideTargetScrollPosition = Math.max(0, scrollLeft - containerWidth);
312
333
  }
313
- if (fullSldeTargetScrollPosition && fullSldeTargetScrollPosition < scrollLeft) {
314
- targetScrollPosition = fullSldeTargetScrollPosition;
334
+ if (fullSlideTargetScrollPosition && Math.floor(fullSlideTargetScrollPosition) < Math.floor(scrollLeft)) {
335
+ targetScrollPosition = fullSlideTargetScrollPosition;
315
336
  }
316
337
  }
317
338
  }
318
339
  // add left offset
319
340
  const offsettedTargetScrollPosition = targetScrollPosition - getLeftOffset();
320
- if (offsettedTargetScrollPosition >= 0) {
341
+ if (Math.floor(offsettedTargetScrollPosition) >= 0) {
321
342
  targetScrollPosition = offsettedTargetScrollPosition;
322
343
  }
323
344
  slider.emit('programmaticScrollStart');
@@ -349,11 +370,11 @@ function Slider(container, options, plugins) {
349
370
  if (isMovingForward) {
350
371
  for (let i = 0; i < slideReference.length; i++) {
351
372
  const item = slideReference[i];
352
- if (i === 0 && scrollPosition <= item.trigger) {
373
+ if (i === 0 && Math.floor(scrollPosition) <= Math.floor(item.trigger)) {
353
374
  snapTarget = 0;
354
375
  break;
355
376
  }
356
- if (slider.container.scrollLeft <= item.trigger) {
377
+ if (Math.floor(slider.container.scrollLeft) <= Math.floor(item.trigger)) {
357
378
  snapTarget = item.start;
358
379
  break;
359
380
  }
@@ -362,11 +383,11 @@ function Slider(container, options, plugins) {
362
383
  else {
363
384
  for (let i = slideReference.length - 1; i >= 0; i--) {
364
385
  const item = slideReference[i];
365
- if (i === slideReference.length - 1 && scrollPosition >= item.trigger) {
386
+ if (i === slideReference.length - 1 && Math.floor(scrollPosition) >= Math.floor(item.trigger)) {
366
387
  snapTarget = item.start;
367
388
  break;
368
389
  }
369
- if (slider.container.scrollLeft >= item.trigger) {
390
+ if (Math.floor(slider.container.scrollLeft) >= Math.floor(item.trigger)) {
370
391
  snapTarget = item.start;
371
392
  break;
372
393
  }
@@ -374,7 +395,7 @@ function Slider(container, options, plugins) {
374
395
  }
375
396
  if (snapTarget !== null) {
376
397
  const offsettedSnapTarget = snapTarget - getLeftOffset();
377
- if (offsettedSnapTarget >= 0) {
398
+ if (Math.floor(offsettedSnapTarget) >= 0) {
378
399
  snapTarget = offsettedSnapTarget;
379
400
  }
380
401
  const scrollBehavior = slider.options.scrollBehavior || 'smooth';
@@ -407,6 +428,8 @@ function Slider(container, options, plugins) {
407
428
  moveToDirection,
408
429
  moveToSlide,
409
430
  snapToClosestSlide,
431
+ getInclusiveScrollWidth,
432
+ getInclusiveClientWidth,
410
433
  on,
411
434
  options,
412
435
  };
@@ -1 +1 @@
1
- import t from"./details.min.js";import{generateId as e,objectsAreEqual as n}from"./utils.min.js";function o(o,i,l){let r,a={};function s(e=!1){const o=r.details,i=t(r);r.details=i,e||n(o,i)?e&&r.emit("detailsChanged"):r.emit("detailsChanged")}function c(){r.slides=Array.from(r.container.querySelectorAll(r.options.slidesSelector))}function d(){r.container.style.setProperty("--slider-container-width",`${r.details.containerWidth}px`),r.container.style.setProperty("--slider-scrollable-width",`${r.details.scrollableAreaWidth}px`),r.container.style.setProperty("--slider-slides-count",`${r.details.slideCount}`)}function f(){r.container.setAttribute("data-has-overflow",r.details.hasOverflow?"true":"false")}function u(t,e=null){const n=e||r.options.scrollBehavior,o=t.getBoundingClientRect(),i=r.container.getBoundingClientRect(),l=r.container.offsetWidth,a=r.container.scrollLeft,s=o.left-i.left+a,c=s+o.width;let d=null;d=s<a?s:c>a+l?c-l:0===s?0:s,null!==d&&setTimeout((t=>{r.emit("programmaticScrollStart"),r.container.scrollTo({left:t,behavior:n})}),50,d)}function m(){const t=r.container.getBoundingClientRect(),e=r.container.scrollLeft,n=r.slides;let o=0;for(let i=0;i<n.length;i++){if(n[i].getBoundingClientRect().left-t.left+e+h()>e){o=i;break}}const i=r.activeSlideIdx;r.activeSlideIdx=o,i!==o&&r.emit("activeSlideChanged")}function h(){let t=0;if(r.slides.length>1){const e=r.slides[0].getBoundingClientRect();t=r.slides[1].getBoundingClientRect().left-e.right}return t}function g(){let t=0;const e=r.container.getAttribute("data-full-width-offset");return e&&(t=parseInt(e)),t}return r={emit:function(t){var e;a&&a[t]&&a[t].forEach((t=>{t(r)}));const n=null===(e=null==r?void 0:r.options)||void 0===e?void 0:e[t];"function"==typeof n&&n(r)},moveToDirection:function(t="prev"){const e=r.options.scrollStrategy,n=r.container.scrollLeft,o=r.container.getBoundingClientRect(),i=r.container.offsetWidth;let l=n;if("prev"===t?l=Math.max(0,n-r.container.offsetWidth):"next"===t&&(l=Math.min(r.container.scrollWidth,n+r.container.offsetWidth)),"fullSlide"===e){let e=null;if(e="prev"===t?Math.max(0,l-h()):Math.min(r.container.scrollWidth,l+h()),"next"===t){let t=!1;for(let i of r.slides){const r=i.getBoundingClientRect(),a=r.left-o.left+n,s=a+r.width;if(a<l&&s>l){e=a,t=!0;break}}t||(e=Math.min(l,r.container.scrollWidth-r.container.offsetWidth)),e&&e>n&&(l=e)}else{let t=!1;for(let l of r.slides){const r=l.getBoundingClientRect(),a=r.left-o.left+n,s=a+r.width;if(a<n&&s>n){e=s-i,t=!0;break}}t||(e=Math.max(0,n-i)),e&&e<n&&(l=e)}}const a=l-g();a>=0&&(l=a),r.emit("programmaticScrollStart"),r.container.style.scrollBehavior=r.options.scrollBehavior,r.container.scrollLeft=l,setTimeout((()=>r.container.style.scrollBehavior=""),50)},moveToSlide:function(t){const e=r.slides[t];e&&u(e)},snapToClosestSlide:function(t="prev"){const e="next"===t,n=[];for(let t=0;t<r.slides.length;t++){const e=r.slides[t],o=e.offsetWidth,i=e.offsetLeft,l=i+o,a=i+o/2,s=Math.min(a,i+r.options.emulateScrollSnapMaxThreshold);n.push({start:i,middle:a,end:l,width:o,trigger:s,slide:e})}let o=null;const i=r.container.scrollLeft;if(e)for(let t=0;t<n.length;t++){const e=n[t];if(0===t&&i<=e.trigger){o=0;break}if(r.container.scrollLeft<=e.trigger){o=e.start;break}}else for(let t=n.length-1;t>=0;t--){const e=n[t];if(t===n.length-1&&i>=e.trigger){o=e.start;break}if(r.container.scrollLeft>=e.trigger){o=e.start;break}}if(null!==o){const t=o-g();t>=0&&(o=t);const e=r.options.scrollBehavior||"smooth";r.container.scrollTo({left:o,behavior:e})}},on:function(t,e){a[t]||(a[t]=[]),a[t].push(e)},options:i},function(){r.container=o;let t=o.getAttribute("id");null===t&&(t=e("overflow-slider"),o.setAttribute("id",t)),c(),s(!0),m(),r.on("contentsChanged",(()=>{c(),s(),m()})),r.on("containerSizeChanged",(()=>s()));let n=0;if(r.on("scroll",(()=>{n&&window.cancelAnimationFrame(n),n=window.requestAnimationFrame((()=>{s(),m()}))})),function(){new MutationObserver((()=>r.emit("contentsChanged"))).observe(r.container,{childList:!0});let t,e,n;new ResizeObserver((()=>r.emit("containerSizeChanged"))).observe(r.container);let o=r.container.scrollLeft,i=r.container.scrollLeft,l=r.container.scrollLeft,a=!1,s=!1,c=!1;r.container.addEventListener("scroll",(()=>{const e=r.container.scrollLeft;o!==e&&(a||(a=!0,r.emit("scrollStart")),o=e,clearTimeout(t),t=setTimeout((()=>{a=!1,r.emit("scrollEnd")}),50),r.emit("scroll")),s&&d()}));const d=()=>{const t=r.container.scrollLeft;i===t||c||(s||(r.emit("nativeScrollStart"),s=!0),r.emit("nativeScroll"),i=t,clearTimeout(e),e=setTimeout((()=>{s=!1,r.emit("nativeScrollEnd"),l=i}),50))};r.container.addEventListener("touchmove",d),r.container.addEventListener("mousewheel",d),r.container.addEventListener("wheel",d),r.on("programmaticScrollStart",(()=>{c=!0})),r.container.addEventListener("scroll",(()=>{const t=r.container.scrollLeft;l!==t&&!s&&c&&(l=t,clearTimeout(n),n=setTimeout((()=>{c=!1,r.emit("programmaticScrollEnd"),i=l}),50),r.emit("programmaticScroll"))})),r.on("programmaticScrollStart",(()=>{r.container.style.scrollSnapType="none"})),r.on("nativeScrollStart",(()=>{r.container.style.scrollSnapType=""}));let f=!1;r.container.addEventListener("mousedown",(()=>{f=!0})),r.container.addEventListener("touchstart",(()=>{f=!0}),{passive:!0}),r.container.addEventListener("focusin",(t=>{if(!f){let e=t.target;for(;e.parentElement!==r.container&&e.parentElement;)e=e.parentElement;u(e,"auto")}f=!1}))}(),f(),d(),l)for(const t of l)t(r);r.on("detailsChanged",(()=>{f(),d()})),r.emit("created"),r.container.setAttribute("data-ready","true")}(),r}export{o as default};
1
+ import t from"./details.min.js";import{generateId as e,objectsAreEqual as o,getOutermostChildrenEdgeMarginSum as n}from"./utils.min.js";function l(l,i,r){let a,c={};function s(e=!1){const n=a.details,l=t(a);a.details=l,e||o(n,l)?e&&a.emit("detailsChanged"):a.emit("detailsChanged")}function f(){a.slides=Array.from(a.container.querySelectorAll(a.options.slidesSelector))}function d(){a.container.style.setProperty("--slider-container-width",`${a.details.containerWidth}px`),a.container.style.setProperty("--slider-scrollable-width",`${a.details.scrollableAreaWidth}px`),a.container.style.setProperty("--slider-slides-count",`${a.details.slideCount}`)}function h(){a.container.setAttribute("data-has-overflow",a.details.hasOverflow?"true":"false")}function u(t,e=null){const o=e||a.options.scrollBehavior,n=t.getBoundingClientRect(),l=a.container.getBoundingClientRect(),i=a.container.offsetWidth,r=a.container.scrollLeft,c=n.left-l.left+r,s=c+n.width;let f=null;f=Math.floor(c)<Math.floor(r)?c:Math.floor(s)>Math.floor(r)+Math.floor(i)?s-i:0===Math.floor(c)?0:c,null!==f&&setTimeout((t=>{a.emit("programmaticScrollStart"),a.container.scrollTo({left:t,behavior:o})}),50,f)}function m(){const t=a.container.getBoundingClientRect(),e=a.container.scrollLeft,o=a.slides;let n=0,l=!1;for(let i=0;i<o.length;i++){const r=o[i].getBoundingClientRect().left-t.left+e+g();if(Math.floor(r)>=Math.floor(e)){n=i;break}i===o.length-1&&(l=!0)}l&&(n=o.length-1);const i=a.activeSlideIdx;a.activeSlideIdx=n,i!==n&&a.emit("activeSlideChanged")}function g(){let t=0;if(a.slides.length>1){const e=a.slides[0].getBoundingClientRect(),o=a.slides[1].getBoundingClientRect();t=Math.floor(o.left-e.right)}return t}function M(){let t=0;const e=a.container.getAttribute("data-full-width-offset");return e&&(t=parseInt(e)),Math.floor(t)}return a={emit:function(t){var e;c&&c[t]&&c[t].forEach((t=>{t(a)}));const o=null===(e=null==a?void 0:a.options)||void 0===e?void 0:e[t];"function"==typeof o&&o(a)},moveToDirection:function(t="prev"){const e=a.options.scrollStrategy,o=a.container.scrollLeft,n=a.container.getBoundingClientRect(),l=a.container.offsetWidth;let i=o;if("prev"===t?i=Math.max(0,o-a.container.offsetWidth):"next"===t&&(i=Math.min(a.getInclusiveScrollWidth(),o+a.container.offsetWidth)),"fullSlide"===e){let e=null;if(e="prev"===t?Math.max(0,i-g()):Math.min(a.getInclusiveScrollWidth(),i+g()),"next"===t){let t=!1;for(let l of a.slides){const r=l.getBoundingClientRect(),a=r.left-n.left+o,c=a+r.width;if(Math.floor(a)<Math.floor(i)&&Math.floor(c)>Math.floor(i)){e=a,t=!0;break}}if(t||(e=Math.min(i,a.getInclusiveScrollWidth()-a.container.offsetWidth)),e)if(Math.floor(e)>Math.floor(o)){const t=Math.floor(a.getInclusiveScrollWidth())-Math.floor(l);i=Math.min(e,t)}else i=Math.min(a.getInclusiveScrollWidth(),o+l)}else{let t=!1;for(let i of a.slides){const r=i.getBoundingClientRect(),a=r.left-n.left+o,c=a+r.width;if(Math.floor(a)<Math.floor(o)&&Math.floor(c)>Math.floor(o)){e=c-l,t=!0;break}}t||(e=Math.max(0,o-l)),e&&Math.floor(e)<Math.floor(o)&&(i=e)}}const r=i-M();Math.floor(r)>=0&&(i=r),a.emit("programmaticScrollStart"),a.container.style.scrollBehavior=a.options.scrollBehavior,a.container.scrollLeft=i,setTimeout((()=>a.container.style.scrollBehavior=""),50)},moveToSlide:function(t){const e=a.slides[t];e&&u(e)},snapToClosestSlide:function(t="prev"){const e="next"===t,o=[];for(let t=0;t<a.slides.length;t++){const e=a.slides[t],n=e.offsetWidth,l=e.offsetLeft,i=l+n,r=l+n/2,c=Math.min(r,l+a.options.emulateScrollSnapMaxThreshold);o.push({start:l,middle:r,end:i,width:n,trigger:c,slide:e})}let n=null;const l=a.container.scrollLeft;if(e)for(let t=0;t<o.length;t++){const e=o[t];if(0===t&&Math.floor(l)<=Math.floor(e.trigger)){n=0;break}if(Math.floor(a.container.scrollLeft)<=Math.floor(e.trigger)){n=e.start;break}}else for(let t=o.length-1;t>=0;t--){const e=o[t];if(t===o.length-1&&Math.floor(l)>=Math.floor(e.trigger)){n=e.start;break}if(Math.floor(a.container.scrollLeft)>=Math.floor(e.trigger)){n=e.start;break}}if(null!==n){const t=n-M();Math.floor(t)>=0&&(n=t);const e=a.options.scrollBehavior||"smooth";a.container.scrollTo({left:n,behavior:e})}},getInclusiveScrollWidth:function(){return a.container.scrollWidth+n(a.container)},getInclusiveClientWidth:function(){return a.container.clientWidth+n(a.container)},on:function(t,e){c[t]||(c[t]=[]),c[t].push(e)},options:i},function(){a.container=l;let t=l.getAttribute("id");null===t&&(t=e("overflow-slider"),l.setAttribute("id",t)),f(),s(!0),m(),a.on("contentsChanged",(()=>{f(),s(),m()})),a.on("containerSizeChanged",(()=>s()));let o=0;if(a.on("scroll",(()=>{o&&window.cancelAnimationFrame(o),o=window.requestAnimationFrame((()=>{s(),m()}))})),function(){new MutationObserver((()=>a.emit("contentsChanged"))).observe(a.container,{childList:!0});let t,e,o;new ResizeObserver((()=>a.emit("containerSizeChanged"))).observe(a.container);let n=a.container.scrollLeft,l=a.container.scrollLeft,i=a.container.scrollLeft,r=!1,c=!1,s=!1;a.container.addEventListener("scroll",(()=>{const e=a.container.scrollLeft;Math.floor(n)!==Math.floor(e)&&(r||(r=!0,a.emit("scrollStart")),n=e,clearTimeout(t),t=setTimeout((()=>{r=!1,a.emit("scrollEnd")}),50),a.emit("scroll")),c&&f()}));const f=()=>{const t=a.container.scrollLeft;Math.floor(l)===Math.floor(t)||s||(c||(a.emit("nativeScrollStart"),c=!0),a.emit("nativeScroll"),l=t,clearTimeout(e),e=setTimeout((()=>{c=!1,a.emit("nativeScrollEnd"),i=l}),50))};a.container.addEventListener("touchmove",f),a.container.addEventListener("mousewheel",f),a.container.addEventListener("wheel",f),a.on("programmaticScrollStart",(()=>{s=!0})),a.container.addEventListener("scroll",(()=>{const t=a.container.scrollLeft;Math.floor(i)!==Math.floor(t)&&!c&&s&&(i=t,clearTimeout(o),o=setTimeout((()=>{s=!1,a.emit("programmaticScrollEnd"),l=i}),50),a.emit("programmaticScroll"))})),a.on("programmaticScrollStart",(()=>{a.container.style.scrollSnapType="none"})),a.on("nativeScrollStart",(()=>{a.container.style.scrollSnapType=""}));let d=!1;a.container.addEventListener("mousedown",(()=>{d=!0})),a.container.addEventListener("touchstart",(()=>{d=!0}),{passive:!0}),a.container.addEventListener("focusin",(t=>{if(!d){let e=t.target;for(;e.parentElement!==a.container&&e.parentElement;)e=e.parentElement;u(e,"auto")}d=!1}))}(),h(),d(),r)for(const t of r)t(a);a.on("detailsChanged",(()=>{h(),d()})),a.emit("created"),a.container.setAttribute("data-ready","true")}(),a}export{l as default};
@@ -18,5 +18,19 @@ function objectsAreEqual(obj1, obj2) {
18
18
  }
19
19
  return true;
20
20
  }
21
+ function getOutermostChildrenEdgeMarginSum(el) {
22
+ if (el.children.length === 0) {
23
+ return 0;
24
+ }
25
+ // get the first child and its left margin
26
+ const firstChild = el.children[0];
27
+ const firstChildStyle = getComputedStyle(firstChild);
28
+ const firstChildMarginLeft = parseFloat(firstChildStyle.marginLeft);
29
+ // Get the last child and its right margin
30
+ const lastChild = el.children[el.children.length - 1];
31
+ const lastChildStyle = getComputedStyle(lastChild);
32
+ const lastChildMarginRight = parseFloat(lastChildStyle.marginRight);
33
+ return firstChildMarginLeft + lastChildMarginRight;
34
+ }
21
35
 
22
- export { generateId, objectsAreEqual };
36
+ export { generateId, getOutermostChildrenEdgeMarginSum, objectsAreEqual };
@@ -1 +1 @@
1
- function t(e,n=1){const r=`${e}-${n}`;return document.getElementById(r)?t(e,n+1):r}function e(t,e){const n=Object.keys(t),r=Object.keys(e);if(n.length!==r.length)return!1;for(let r of n)if(!1===e.hasOwnProperty(r)||t[r]!==e[r])return!1;return!0}export{t as generateId,e as objectsAreEqual};
1
+ function e(t,n=1){const r=`${t}-${n}`;return document.getElementById(r)?e(t,n+1):r}function t(e,t){const n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(let r of n)if(!1===t.hasOwnProperty(r)||e[r]!==t[r])return!1;return!0}function n(e){if(0===e.children.length)return 0;const t=e.children[0],n=getComputedStyle(t),r=parseFloat(n.marginLeft),o=e.children[e.children.length-1],l=getComputedStyle(o);return r+parseFloat(l.marginRight)}export{e as generateId,n as getOutermostChildrenEdgeMarginSum,t as objectsAreEqual};
@@ -31,7 +31,11 @@ function ArrowsPlugin(args) {
31
31
  prev.setAttribute('aria-controls', (_d = slider.container.getAttribute('id')) !== null && _d !== void 0 ? _d : '');
32
32
  prev.setAttribute('data-type', 'prev');
33
33
  prev.innerHTML = options.icons.prev;
34
- prev.addEventListener('click', () => slider.moveToDirection('prev'));
34
+ prev.addEventListener('click', () => {
35
+ if (prev.getAttribute('data-has-content') === 'true') {
36
+ slider.moveToDirection('prev');
37
+ }
38
+ });
35
39
  const next = document.createElement('button');
36
40
  next.setAttribute('class', options.classNames.nextButton);
37
41
  next.setAttribute('type', 'button');
@@ -39,22 +43,25 @@ function ArrowsPlugin(args) {
39
43
  next.setAttribute('aria-controls', (_e = slider.container.getAttribute('id')) !== null && _e !== void 0 ? _e : '');
40
44
  next.setAttribute('data-type', 'next');
41
45
  next.innerHTML = options.icons.next;
42
- next.addEventListener('click', () => slider.moveToDirection('next'));
46
+ next.addEventListener('click', () => {
47
+ if (next.getAttribute('data-has-content') === 'true') {
48
+ slider.moveToDirection('next');
49
+ }
50
+ });
43
51
  // insert buttons to the nav
44
52
  nav.appendChild(prev);
45
53
  nav.appendChild(next);
46
54
  const update = () => {
47
55
  const scrollLeft = slider.container.scrollLeft;
48
- const scrollWidth = slider.container.scrollWidth;
49
- const clientWidth = slider.container.clientWidth;
50
- const buffer = 1;
51
- if (scrollLeft === 0) {
56
+ const scrollWidth = slider.getInclusiveScrollWidth();
57
+ const clientWidth = slider.getInclusiveClientWidth();
58
+ if (Math.floor(scrollLeft) === 0) {
52
59
  prev.setAttribute('data-has-content', 'false');
53
60
  }
54
61
  else {
55
62
  prev.setAttribute('data-has-content', 'true');
56
63
  }
57
- if (scrollLeft + clientWidth >= scrollWidth - buffer) {
64
+ if (Math.floor(scrollLeft + clientWidth) >= Math.floor(scrollWidth)) {
58
65
  next.setAttribute('data-has-content', 'false');
59
66
  }
60
67
  else {
@@ -74,7 +81,7 @@ function ArrowsPlugin(args) {
74
81
  }
75
82
  }
76
83
  update();
77
- slider.on('scroll', update);
84
+ slider.on('scrollEnd', update);
78
85
  slider.on('contentsChanged', update);
79
86
  slider.on('containerSizeChanged', update);
80
87
  };
@@ -1 +1 @@
1
- const t={buttonPrevious:"Previous items",buttonNext:"Next items"},e={prev:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.6 3.4l-7.6 7.6 7.6 7.6 1.4-1.4-5-5h12.6v-2h-12.6l5-5z"/></svg>',next:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.4 3.4l-1.4 1.4 5 5h-12.6v2h12.6l-5 5 1.4 1.4 7.6-7.6z"/></svg>'},n={navContainer:"overflow-slider__arrows",prevButton:"overflow-slider__arrows-button overflow-slider__arrows-button--prev",nextButton:"overflow-slider__arrows-button overflow-slider__arrows-button--next"};function o(o){return i=>{var r,s,a,l,c,u;const d={texts:Object.assign(Object.assign({},t),(null==o?void 0:o.texts)||[]),icons:Object.assign(Object.assign({},e),(null==o?void 0:o.icons)||[]),classNames:Object.assign(Object.assign({},n),(null==o?void 0:o.classNames)||[]),container:null!==(r=null==o?void 0:o.container)&&void 0!==r?r:null,containerPrev:null!==(s=null==o?void 0:o.containerPrev)&&void 0!==s?s:null,containerNext:null!==(a=null==o?void 0:o.containerNext)&&void 0!==a?a:null},v=document.createElement("div");v.classList.add(d.classNames.navContainer);const b=document.createElement("button");b.setAttribute("class",d.classNames.prevButton),b.setAttribute("type","button"),b.setAttribute("aria-label",d.texts.buttonPrevious),b.setAttribute("aria-controls",null!==(l=i.container.getAttribute("id"))&&void 0!==l?l:""),b.setAttribute("data-type","prev"),b.innerHTML=d.icons.prev,b.addEventListener("click",(()=>i.moveToDirection("prev")));const p=document.createElement("button");p.setAttribute("class",d.classNames.nextButton),p.setAttribute("type","button"),p.setAttribute("aria-label",d.texts.buttonNext),p.setAttribute("aria-controls",null!==(c=i.container.getAttribute("id"))&&void 0!==c?c:""),p.setAttribute("data-type","next"),p.innerHTML=d.icons.next,p.addEventListener("click",(()=>i.moveToDirection("next"))),v.appendChild(b),v.appendChild(p);const x=()=>{const t=i.container.scrollLeft,e=i.container.scrollWidth,n=i.container.clientWidth;0===t?b.setAttribute("data-has-content","false"):b.setAttribute("data-has-content","true"),t+n>=e-1?p.setAttribute("data-has-content","false"):p.setAttribute("data-has-content","true")};d.containerNext&&d.containerPrev?(d.containerPrev.appendChild(b),d.containerNext.appendChild(p)):d.container?d.container.appendChild(v):null===(u=i.container.parentNode)||void 0===u||u.insertBefore(v,i.container.nextSibling),x(),i.on("scroll",x),i.on("contentsChanged",x),i.on("containerSizeChanged",x)}}export{o as default};
1
+ const t={buttonPrevious:"Previous items",buttonNext:"Next items"},e={prev:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.6 3.4l-7.6 7.6 7.6 7.6 1.4-1.4-5-5h12.6v-2h-12.6l5-5z"/></svg>',next:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.4 3.4l-1.4 1.4 5 5h-12.6v2h12.6l-5 5 1.4 1.4 7.6-7.6z"/></svg>'},n={navContainer:"overflow-slider__arrows",prevButton:"overflow-slider__arrows-button overflow-slider__arrows-button--prev",nextButton:"overflow-slider__arrows-button overflow-slider__arrows-button--next"};function o(o){return r=>{var i,s,a,l,c,u;const d={texts:Object.assign(Object.assign({},t),(null==o?void 0:o.texts)||[]),icons:Object.assign(Object.assign({},e),(null==o?void 0:o.icons)||[]),classNames:Object.assign(Object.assign({},n),(null==o?void 0:o.classNames)||[]),container:null!==(i=null==o?void 0:o.container)&&void 0!==i?i:null,containerPrev:null!==(s=null==o?void 0:o.containerPrev)&&void 0!==s?s:null,containerNext:null!==(a=null==o?void 0:o.containerNext)&&void 0!==a?a:null},v=document.createElement("div");v.classList.add(d.classNames.navContainer);const b=document.createElement("button");b.setAttribute("class",d.classNames.prevButton),b.setAttribute("type","button"),b.setAttribute("aria-label",d.texts.buttonPrevious),b.setAttribute("aria-controls",null!==(l=r.container.getAttribute("id"))&&void 0!==l?l:""),b.setAttribute("data-type","prev"),b.innerHTML=d.icons.prev,b.addEventListener("click",(()=>{"true"===b.getAttribute("data-has-content")&&r.moveToDirection("prev")}));const p=document.createElement("button");p.setAttribute("class",d.classNames.nextButton),p.setAttribute("type","button"),p.setAttribute("aria-label",d.texts.buttonNext),p.setAttribute("aria-controls",null!==(c=r.container.getAttribute("id"))&&void 0!==c?c:""),p.setAttribute("data-type","next"),p.innerHTML=d.icons.next,p.addEventListener("click",(()=>{"true"===p.getAttribute("data-has-content")&&r.moveToDirection("next")})),v.appendChild(b),v.appendChild(p);const h=()=>{const t=r.container.scrollLeft,e=r.getInclusiveScrollWidth(),n=r.getInclusiveClientWidth();0===Math.floor(t)?b.setAttribute("data-has-content","false"):b.setAttribute("data-has-content","true"),Math.floor(t+n)>=Math.floor(e)?p.setAttribute("data-has-content","false"):p.setAttribute("data-has-content","true")};d.containerNext&&d.containerPrev?(d.containerPrev.appendChild(b),d.containerNext.appendChild(p)):d.container?d.container.appendChild(v):null===(u=r.container.parentNode)||void 0===u||u.insertBefore(v,r.container.nextSibling),h(),r.on("scrollEnd",h),r.on("contentsChanged",h),r.on("containerSizeChanged",h)}}export{o as default};
@@ -49,7 +49,7 @@ function DragScrollingPlugin(args) {
49
49
  const walk = (x - startX);
50
50
  const newScrollLeft = scrollLeft - walk;
51
51
  mayNeedToSnap = true;
52
- if (slider.container.scrollLeft !== newScrollLeft) {
52
+ if (Math.floor(slider.container.scrollLeft) !== Math.floor(newScrollLeft)) {
53
53
  isMovingForward = slider.container.scrollLeft < newScrollLeft;
54
54
  }
55
55
  slider.container.scrollLeft = newScrollLeft;
@@ -1 +1 @@
1
- function e(e){var t;const o=null!==(t=null==e?void 0:e.draggedDistanceThatPreventsClick)&&void 0!==t?t:20;return e=>{let t=!1,n=0,r=0,a=!1,s=!1,i=!1;e.container.setAttribute("data-has-drag-scrolling","true");if(window.addEventListener("mousedown",(o=>{s=!1,e.details.hasOverflow&&e.container.contains(o.target)&&(t=!0,n=o.pageX-e.container.offsetLeft,r=e.container.scrollLeft,e.container.style.cursor="grabbing",e.container.style.scrollBehavior="auto",o.preventDefault(),o.stopPropagation())})),window.addEventListener("mousemove",(l=>{if(!e.details.hasOverflow)return void(s=!1);if(!t)return void(s=!1);l.preventDefault(),s||(s=!0,e.emit("programmaticScrollStart"));const c=l.pageX-e.container.offsetLeft-n,d=r-c;i=!0,e.container.scrollLeft!==d&&(a=e.container.scrollLeft<d),e.container.scrollLeft=d;const u=Math.abs(c),f=e.container.querySelectorAll(e.options.slidesSelector),v=u>o?"none":"";f.forEach((e=>{e.style.pointerEvents=v}))})),window.addEventListener("mouseup",(()=>{e.details.hasOverflow?(t=!1,e.container.style.cursor="",setTimeout((()=>{s=!1,e.container.style.scrollBehavior="";e.container.querySelectorAll(e.options.slidesSelector).forEach((e=>{e.style.pointerEvents=""}))}),50)):s=!1})),e.options.emulateScrollSnap){const o=()=>{i&&!t&&(i=!1,e.snapToClosestSlide(a?"next":"prev"))};e.on("programmaticScrollEnd",o),window.addEventListener("mouseup",o)}}}export{e as default};
1
+ function e(e){var t;const o=null!==(t=null==e?void 0:e.draggedDistanceThatPreventsClick)&&void 0!==t?t:20;return e=>{let t=!1,n=0,r=0,a=!1,l=!1,s=!1;e.container.setAttribute("data-has-drag-scrolling","true");if(window.addEventListener("mousedown",(o=>{l=!1,e.details.hasOverflow&&e.container.contains(o.target)&&(t=!0,n=o.pageX-e.container.offsetLeft,r=e.container.scrollLeft,e.container.style.cursor="grabbing",e.container.style.scrollBehavior="auto",o.preventDefault(),o.stopPropagation())})),window.addEventListener("mousemove",(i=>{if(!e.details.hasOverflow)return void(l=!1);if(!t)return void(l=!1);i.preventDefault(),l||(l=!0,e.emit("programmaticScrollStart"));const c=i.pageX-e.container.offsetLeft-n,d=r-c;s=!0,Math.floor(e.container.scrollLeft)!==Math.floor(d)&&(a=e.container.scrollLeft<d),e.container.scrollLeft=d;const f=Math.abs(c),u=e.container.querySelectorAll(e.options.slidesSelector),v=f>o?"none":"";u.forEach((e=>{e.style.pointerEvents=v}))})),window.addEventListener("mouseup",(()=>{e.details.hasOverflow?(t=!1,e.container.style.cursor="",setTimeout((()=>{l=!1,e.container.style.scrollBehavior="";e.container.querySelectorAll(e.options.slidesSelector).forEach((e=>{e.style.pointerEvents=""}))}),50)):l=!1})),e.options.emulateScrollSnap){const o=()=>{s&&!t&&(s=!1,e.snapToClosestSlide(a?"next":"prev"))};e.on("programmaticScrollEnd",o),window.addEventListener("mouseup",o)}}}export{e as default};
@@ -36,19 +36,19 @@ function FadePlugin(args) {
36
36
  };
37
37
  const fadeAtStartOpacity = () => {
38
38
  const position = slider.container.scrollLeft;
39
- if (position <= fadeItemStart.offsetWidth) {
39
+ if (Math.floor(position) <= Math.floor(fadeItemStart.offsetWidth)) {
40
40
  return position / Math.max(fadeItemStart.offsetWidth, 1);
41
41
  }
42
42
  return 1;
43
43
  };
44
44
  const hasFadeAtEnd = () => {
45
- return slider.container.scrollLeft < (slider.container.scrollWidth - slider.container.clientWidth - fadeItemEnd.offsetWidth);
45
+ return Math.floor(slider.container.scrollLeft) < Math.floor(slider.getInclusiveScrollWidth() - slider.getInclusiveClientWidth() - fadeItemEnd.offsetWidth);
46
46
  };
47
47
  const fadeAtEndOpacity = () => {
48
48
  const position = slider.container.scrollLeft;
49
- const maxPosition = slider.container.scrollWidth - slider.container.clientWidth;
49
+ const maxPosition = slider.getInclusiveScrollWidth() - slider.getInclusiveClientWidth();
50
50
  const maxFadePosition = maxPosition - fadeItemEnd.offsetWidth;
51
- if (position >= maxFadePosition) {
51
+ if (Math.floor(position) >= Math.floor(maxFadePosition)) {
52
52
  return ((maxFadePosition - position) / Math.max(fadeItemEnd.offsetWidth, 1)) + 1;
53
53
  }
54
54
  return 1;
@@ -1 +1 @@
1
- function t(t){return e=>{var n,a,i;const o={classNames:{fadeItem:"overflow-slider-fade",fadeItemStart:"overflow-slider-fade--start",fadeItemEnd:"overflow-slider-fade--end"},container:null!==(n=null==t?void 0:t.container)&&void 0!==n?n:null,containerStart:null!==(a=null==t?void 0:t.containerStart)&&void 0!==a?a:null,containerEnd:null!==(i=null==t?void 0:t.containerEnd)&&void 0!==i?i:null},r=document.createElement("div");r.classList.add(o.classNames.fadeItem,o.classNames.fadeItemStart),r.setAttribute("aria-hidden","true"),r.setAttribute("tabindex","-1");const d=document.createElement("div");d.classList.add(o.classNames.fadeItem,o.classNames.fadeItemEnd),d.setAttribute("aria-hidden","true"),d.setAttribute("tabindex","-1"),o.containerStart?o.containerStart.appendChild(r):o.container&&o.container.appendChild(r),o.containerEnd?o.containerEnd.appendChild(d):o.container&&o.container.appendChild(d);const l=()=>{r.setAttribute("data-has-fade",(e.container.scrollLeft>r.offsetWidth).toString()),r.style.opacity=(()=>{const t=e.container.scrollLeft;return t<=r.offsetWidth?t/Math.max(r.offsetWidth,1):1})().toString(),d.setAttribute("data-has-fade",(e.container.scrollLeft<e.container.scrollWidth-e.container.clientWidth-d.offsetWidth).toString()),d.style.opacity=(()=>{const t=e.container.scrollLeft,n=e.container.scrollWidth-e.container.clientWidth-d.offsetWidth;return t>=n?(n-t)/Math.max(d.offsetWidth,1)+1:1})().toString()};l(),e.on("created",l),e.on("contentsChanged",l),e.on("containerSizeChanged",l),e.on("scrollEnd",l),e.on("scrollStart",l);let s=0;e.on("scroll",(()=>{s&&window.cancelAnimationFrame(s),s=window.requestAnimationFrame((()=>{l()}))}))}}export{t as default};
1
+ function t(t){return e=>{var n,a,o;const i={classNames:{fadeItem:"overflow-slider-fade",fadeItemStart:"overflow-slider-fade--start",fadeItemEnd:"overflow-slider-fade--end"},container:null!==(n=null==t?void 0:t.container)&&void 0!==n?n:null,containerStart:null!==(a=null==t?void 0:t.containerStart)&&void 0!==a?a:null,containerEnd:null!==(o=null==t?void 0:t.containerEnd)&&void 0!==o?o:null},r=document.createElement("div");r.classList.add(i.classNames.fadeItem,i.classNames.fadeItemStart),r.setAttribute("aria-hidden","true"),r.setAttribute("tabindex","-1");const l=document.createElement("div");l.classList.add(i.classNames.fadeItem,i.classNames.fadeItemEnd),l.setAttribute("aria-hidden","true"),l.setAttribute("tabindex","-1"),i.containerStart?i.containerStart.appendChild(r):i.container&&i.container.appendChild(r),i.containerEnd?i.containerEnd.appendChild(l):i.container&&i.container.appendChild(l);const d=()=>{r.setAttribute("data-has-fade",(e.container.scrollLeft>r.offsetWidth).toString()),r.style.opacity=(()=>{const t=e.container.scrollLeft;return Math.floor(t)<=Math.floor(r.offsetWidth)?t/Math.max(r.offsetWidth,1):1})().toString(),l.setAttribute("data-has-fade",(Math.floor(e.container.scrollLeft)<Math.floor(e.getInclusiveScrollWidth()-e.getInclusiveClientWidth()-l.offsetWidth)).toString()),l.style.opacity=(()=>{const t=e.container.scrollLeft,n=e.getInclusiveScrollWidth()-e.getInclusiveClientWidth()-l.offsetWidth;return Math.floor(t)>=Math.floor(n)?(n-t)/Math.max(l.offsetWidth,1)+1:1})().toString()};d(),e.on("created",d),e.on("contentsChanged",d),e.on("containerSizeChanged",d),e.on("scrollEnd",d),e.on("scrollStart",d);let s=0;e.on("scroll",(()=>{s&&window.cancelAnimationFrame(s),s=window.requestAnimationFrame((()=>{d()}))}))}}export{t as default};
@@ -41,13 +41,13 @@ function ScrollIndicatorPlugin(args) {
41
41
  window.cancelAnimationFrame(requestId);
42
42
  }
43
43
  requestId = window.requestAnimationFrame(() => {
44
- const scrollbarButtonWidth = (slider.details.containerWidth / slider.details.scrollableAreaWidth) * 100;
44
+ const scrollbarButtonWidth = (slider.details.containerWidth / slider.container.scrollWidth) * 100;
45
45
  const scrollLeftInPortion = getScrollbarButtonLeftOffset();
46
46
  scrollbarButton.style.width = `${scrollbarButtonWidth}%`;
47
47
  scrollbarButton.style.transform = `translateX(${scrollLeftInPortion}px)`;
48
48
  // aria-valuenow
49
49
  const scrollLeft = slider.container.scrollLeft;
50
- const scrollWidth = slider.container.scrollWidth;
50
+ const scrollWidth = slider.getInclusiveScrollWidth();
51
51
  const containerWidth = slider.container.offsetWidth;
52
52
  const scrollPercentage = (scrollLeft / (scrollWidth - containerWidth)) * 100;
53
53
  scrollbarContainer.setAttribute('aria-valuenow', Math.round(Number.isNaN(scrollPercentage) ? 0 : scrollPercentage).toString());
@@ -81,10 +81,10 @@ function ScrollIndicatorPlugin(args) {
81
81
  const scrollbarButtonLeft = getScrollbarButtonLeftOffset();
82
82
  const scrollbarButtonRight = scrollbarButtonLeft + scrollbarButtonWidth;
83
83
  const clickX = e.pageX - scrollbarContainer.offsetLeft;
84
- if (clickX < scrollbarButtonLeft) {
84
+ if (Math.floor(clickX) < Math.floor(scrollbarButtonLeft)) {
85
85
  slider.moveToDirection('prev');
86
86
  }
87
- else if (clickX > scrollbarButtonRight) {
87
+ else if (Math.floor(clickX) > Math.floor(scrollbarButtonRight)) {
88
88
  slider.moveToDirection('next');
89
89
  }
90
90
  });
@@ -1 +1 @@
1
- const t={scrollIndicator:"overflow-slider__scroll-indicator",scrollIndicatorBar:"overflow-slider__scroll-indicator-bar",scrollIndicatorButton:"overflow-slider__scroll-indicator-button"};function e(e){return n=>{var o,r,a;const i={classNames:Object.assign(Object.assign({},t),(null==e?void 0:e.classNames)||[]),container:null!==(o=null==e?void 0:e.container)&&void 0!==o?o:null},s=document.createElement("div");s.setAttribute("class",i.classNames.scrollIndicator),s.setAttribute("tabindex","0"),s.setAttribute("role","scrollbar"),s.setAttribute("aria-controls",null!==(r=n.container.getAttribute("id"))&&void 0!==r?r:""),s.setAttribute("aria-orientation","horizontal"),s.setAttribute("aria-valuemax","100"),s.setAttribute("aria-valuemin","0"),s.setAttribute("aria-valuenow","0");const l=document.createElement("div");l.setAttribute("class",i.classNames.scrollIndicatorBar);const c=document.createElement("div");c.setAttribute("class",i.classNames.scrollIndicatorButton),c.setAttribute("data-is-grabbed","false"),l.appendChild(c),s.appendChild(l);const d=()=>{s.setAttribute("data-has-overflow",n.details.hasOverflow.toString())};d();const u=()=>{const t=c.offsetWidth/n.details.containerWidth;return n.container.scrollLeft*t};let v=0;const f=()=>{v&&window.cancelAnimationFrame(v),v=window.requestAnimationFrame((()=>{const t=n.details.containerWidth/n.details.scrollableAreaWidth*100,e=u();c.style.width=`${t}%`,c.style.transform=`translateX(${e}px)`;const o=n.container.scrollLeft/(n.container.scrollWidth-n.container.offsetWidth)*100;s.setAttribute("aria-valuenow",Math.round(Number.isNaN(o)?0:o).toString())}))};i.container?i.container.appendChild(s):null===(a=n.container.parentNode)||void 0===a||a.insertBefore(s,n.container.nextSibling),f(),n.on("scroll",f),n.on("contentsChanged",f),n.on("containerSizeChanged",f),n.on("detailsChanged",d),s.addEventListener("keydown",(t=>{"ArrowLeft"===t.key?n.moveToDirection("prev"):"ArrowRight"===t.key&&n.moveToDirection("next")})),s.addEventListener("click",(t=>{const e=c.offsetWidth,o=u(),r=o+e,a=t.pageX-s.offsetLeft;a<o?n.moveToDirection("prev"):a>r&&n.moveToDirection("next")}));let b=!1,m=0,h=0;const w=t=>{b=!0;const e=t.pageX||t.touches[0].pageX;m=e-s.offsetLeft,h=n.container.scrollLeft,c.style.cursor="grabbing",c.setAttribute("data-is-grabbed","true"),t.preventDefault(),t.stopPropagation()},p=t=>{if(!b)return;t.preventDefault();const e=(t.pageX||t.touches[0].pageX)-s.offsetLeft,o=n.details.scrollableAreaWidth/s.offsetWidth,r=(e-m)*o;n.container.scrollLeft=h+r},A=()=>{b=!1,c.style.cursor="",c.setAttribute("data-is-grabbed","false")};c.addEventListener("mousedown",w),c.addEventListener("touchstart",w),window.addEventListener("mousemove",p),window.addEventListener("touchmove",p,{passive:!1}),window.addEventListener("mouseup",A),window.addEventListener("touchend",A)}}export{e as default};
1
+ const t={scrollIndicator:"overflow-slider__scroll-indicator",scrollIndicatorBar:"overflow-slider__scroll-indicator-bar",scrollIndicatorButton:"overflow-slider__scroll-indicator-button"};function e(e){return o=>{var n,r,a;const i={classNames:Object.assign(Object.assign({},t),(null==e?void 0:e.classNames)||[]),container:null!==(n=null==e?void 0:e.container)&&void 0!==n?n:null},s=document.createElement("div");s.setAttribute("class",i.classNames.scrollIndicator),s.setAttribute("tabindex","0"),s.setAttribute("role","scrollbar"),s.setAttribute("aria-controls",null!==(r=o.container.getAttribute("id"))&&void 0!==r?r:""),s.setAttribute("aria-orientation","horizontal"),s.setAttribute("aria-valuemax","100"),s.setAttribute("aria-valuemin","0"),s.setAttribute("aria-valuenow","0");const l=document.createElement("div");l.setAttribute("class",i.classNames.scrollIndicatorBar);const c=document.createElement("div");c.setAttribute("class",i.classNames.scrollIndicatorButton),c.setAttribute("data-is-grabbed","false"),l.appendChild(c),s.appendChild(l);const d=()=>{s.setAttribute("data-has-overflow",o.details.hasOverflow.toString())};d();const u=()=>{const t=c.offsetWidth/o.details.containerWidth;return o.container.scrollLeft*t};let f=0;const v=()=>{f&&window.cancelAnimationFrame(f),f=window.requestAnimationFrame((()=>{const t=o.details.containerWidth/o.container.scrollWidth*100,e=u();c.style.width=`${t}%`,c.style.transform=`translateX(${e}px)`;const n=o.container.scrollLeft/(o.getInclusiveScrollWidth()-o.container.offsetWidth)*100;s.setAttribute("aria-valuenow",Math.round(Number.isNaN(n)?0:n).toString())}))};i.container?i.container.appendChild(s):null===(a=o.container.parentNode)||void 0===a||a.insertBefore(s,o.container.nextSibling),v(),o.on("scroll",v),o.on("contentsChanged",v),o.on("containerSizeChanged",v),o.on("detailsChanged",d),s.addEventListener("keydown",(t=>{"ArrowLeft"===t.key?o.moveToDirection("prev"):"ArrowRight"===t.key&&o.moveToDirection("next")})),s.addEventListener("click",(t=>{const e=c.offsetWidth,n=u(),r=n+e,a=t.pageX-s.offsetLeft;Math.floor(a)<Math.floor(n)?o.moveToDirection("prev"):Math.floor(a)>Math.floor(r)&&o.moveToDirection("next")}));let b=!1,h=0,m=0;const w=t=>{b=!0;const e=t.pageX||t.touches[0].pageX;h=e-s.offsetLeft,m=o.container.scrollLeft,c.style.cursor="grabbing",c.setAttribute("data-is-grabbed","true"),t.preventDefault(),t.stopPropagation()},g=t=>{if(!b)return;t.preventDefault();const e=(t.pageX||t.touches[0].pageX)-s.offsetLeft,n=o.details.scrollableAreaWidth/s.offsetWidth,r=(e-h)*n;o.container.scrollLeft=m+r},p=()=>{b=!1,c.style.cursor="",c.setAttribute("data-is-grabbed","false")};c.addEventListener("mousedown",w),c.addEventListener("touchstart",w),window.addEventListener("mousemove",g),window.addEventListener("touchmove",g,{passive:!1}),window.addEventListener("mouseup",p),window.addEventListener("touchend",p)}}export{e as default};
@@ -28,7 +28,7 @@ function FullWidthPlugin(args) {
28
28
  setActiveThumbnail();
29
29
  addClickListeners();
30
30
  // @todo debounce on scroll
31
- mainSlider.on('scrollEnd', () => {
31
+ mainSlider.on('activeSlideChanged', () => {
32
32
  setTimeout(() => {
33
33
  const activeSlideIdx = mainSlider.activeSlideIdx;
34
34
  const activeThumbnail = slider.slides[activeSlideIdx];
@@ -1 +1 @@
1
- function e(e){return i=>{const l={mainSlider:e.mainSlider}.mainSlider,t=(e=null)=>{null===e&&i.slides.length>0&&(e=i.slides[0]),null!==e&&(i.slides.forEach((e=>{e.setAttribute("aria-current","false")})),e.setAttribute("aria-current","true"))};t(),i.slides.forEach(((e,i)=>{e.addEventListener("click",(()=>{l.moveToSlide(i),t(e)}))})),l.on("scrollEnd",(()=>{setTimeout((()=>{const e=l.activeSlideIdx,r=i.slides[e];t(r),i.moveToSlide(e)}),50)}))}}export{e as default};
1
+ function e(e){return i=>{const t={mainSlider:e.mainSlider}.mainSlider,l=(e=null)=>{null===e&&i.slides.length>0&&(e=i.slides[0]),null!==e&&(i.slides.forEach((e=>{e.setAttribute("aria-current","false")})),e.setAttribute("aria-current","true"))};l(),i.slides.forEach(((e,i)=>{e.addEventListener("click",(()=>{t.moveToSlide(i),l(e)}))})),t.on("activeSlideChanged",(()=>{setTimeout((()=>{const e=t.activeSlideIdx,n=i.slides[e];l(n),i.moveToSlide(e)}),50)}))}}export{e as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evermade/overflow-slider",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "Accessible slider tha works with overflow: auto.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,7 +11,7 @@ export default function details( slider: Slider) {
11
11
  let amountOfPages = 0;
12
12
  let currentPage = 1;
13
13
 
14
- if (slider.container.scrollWidth > slider.container.clientWidth) {
14
+ if ( Math.floor( slider.getInclusiveScrollWidth() ) > Math.floor( slider.getInclusiveClientWidth() ) ) {
15
15
  hasOverflow = true;
16
16
  }
17
17
 
@@ -19,14 +19,14 @@ export default function details( slider: Slider) {
19
19
 
20
20
  containerWidth = slider.container.offsetWidth;
21
21
 
22
- scrollableAreaWidth = slider.container.scrollWidth;
22
+ scrollableAreaWidth = slider.getInclusiveScrollWidth();
23
23
 
24
24
  amountOfPages = Math.ceil(scrollableAreaWidth / containerWidth);
25
25
 
26
- if (slider.container.scrollLeft >= 0) {
26
+ if ( Math.floor( slider.container.scrollLeft ) >= 0) {
27
27
  currentPage = Math.floor(slider.container.scrollLeft / containerWidth);
28
28
  // consider as last page if the scrollLeft + containerWidth is equal to scrollWidth
29
- if (slider.container.scrollLeft + containerWidth === scrollableAreaWidth) {
29
+ if (Math.floor( slider.container.scrollLeft + containerWidth ) === Math.floor( scrollableAreaWidth ) ) {
30
30
  currentPage = amountOfPages - 1;
31
31
  }
32
32
  }