@evermade/overflow-slider 2.0.2 → 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 (64) hide show
  1. package/.nvmrc +1 -1
  2. package/README.md +26 -4
  3. package/dist/core/details.esm.js +4 -4
  4. package/dist/core/details.min.js +1 -1
  5. package/dist/core/overflow-slider.esm.js +2 -0
  6. package/dist/core/overflow-slider.min.js +1 -1
  7. package/dist/core/slider.esm.js +202 -29
  8. package/dist/core/slider.min.js +1 -1
  9. package/dist/core/utils.esm.js +15 -1
  10. package/dist/core/utils.min.js +1 -1
  11. package/dist/overflow-slider.css +1 -1
  12. package/dist/plugins/arrows/arrows/index.esm.js +15 -8
  13. package/dist/plugins/arrows/arrows/index.min.js +1 -1
  14. package/dist/plugins/dots/dots/index.esm.js +21 -22
  15. package/dist/plugins/dots/dots/index.min.js +1 -1
  16. package/dist/plugins/drag-scrolling/drag-scrolling/index.esm.js +30 -3
  17. package/dist/plugins/drag-scrolling/drag-scrolling/index.min.js +1 -1
  18. package/dist/plugins/fade/fade/index.esm.js +81 -0
  19. package/dist/plugins/fade/fade/index.min.js +1 -0
  20. package/dist/plugins/full-width/full-width/index.esm.js +1 -0
  21. package/dist/plugins/full-width/full-width/index.min.js +1 -1
  22. package/dist/plugins/scroll-indicator/scroll-indicator/index.esm.js +4 -6
  23. package/dist/plugins/scroll-indicator/scroll-indicator/index.min.js +1 -1
  24. package/dist/plugins/thumbnails/thumbnails/index.esm.js +1 -0
  25. package/docs/assets/demo.css +16 -0
  26. package/docs/assets/demo.js +44 -7
  27. package/docs/dist/core/details.esm.js +4 -4
  28. package/docs/dist/core/details.min.js +1 -1
  29. package/docs/dist/core/overflow-slider.esm.js +2 -0
  30. package/docs/dist/core/overflow-slider.min.js +1 -1
  31. package/docs/dist/core/slider.esm.js +202 -29
  32. package/docs/dist/core/slider.min.js +1 -1
  33. package/docs/dist/core/utils.esm.js +15 -1
  34. package/docs/dist/core/utils.min.js +1 -1
  35. package/docs/dist/overflow-slider.css +1 -1
  36. package/docs/dist/plugins/arrows/arrows/index.esm.js +15 -8
  37. package/docs/dist/plugins/arrows/arrows/index.min.js +1 -1
  38. package/docs/dist/plugins/dots/dots/index.esm.js +21 -22
  39. package/docs/dist/plugins/dots/dots/index.min.js +1 -1
  40. package/docs/dist/plugins/drag-scrolling/drag-scrolling/index.esm.js +30 -3
  41. package/docs/dist/plugins/drag-scrolling/drag-scrolling/index.min.js +1 -1
  42. package/docs/dist/plugins/fade/fade/index.esm.js +81 -0
  43. package/docs/dist/plugins/fade/fade/index.min.js +1 -0
  44. package/docs/dist/plugins/full-width/full-width/index.esm.js +1 -0
  45. package/docs/dist/plugins/full-width/full-width/index.min.js +1 -1
  46. package/docs/dist/plugins/scroll-indicator/scroll-indicator/index.esm.js +4 -6
  47. package/docs/dist/plugins/scroll-indicator/scroll-indicator/index.min.js +1 -1
  48. package/docs/dist/plugins/thumbnails/thumbnails/index.esm.js +1 -0
  49. package/docs/index.html +39 -7
  50. package/package.json +5 -1
  51. package/src/core/details.ts +4 -4
  52. package/src/core/overflow-slider.ts +2 -0
  53. package/src/core/slider.ts +226 -36
  54. package/src/core/types.ts +33 -1
  55. package/src/core/utils.ts +19 -1
  56. package/src/overflow-slider.scss +2 -1
  57. package/src/plugins/arrows/index.ts +16 -8
  58. package/src/plugins/dots/index.ts +21 -23
  59. package/src/plugins/drag-scrolling/index.ts +34 -5
  60. package/src/plugins/fade/index.ts +101 -0
  61. package/src/plugins/fade/styles.scss +27 -0
  62. package/src/plugins/full-width/index.ts +1 -0
  63. package/src/plugins/scroll-indicator/index.ts +4 -6
  64. package/src/plugins/thumbnails/index.ts +1 -1
@@ -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;
@@ -69,7 +69,87 @@ function Slider(container, options, plugins) {
69
69
  const resizeObserver = new ResizeObserver(() => slider.emit('containerSizeChanged'));
70
70
  resizeObserver.observe(slider.container);
71
71
  // scroll event with debouncing
72
- slider.container.addEventListener('scroll', () => slider.emit('scroll'));
72
+ let scrollTimeout;
73
+ let nativeScrollTimeout;
74
+ let programmaticScrollTimeout;
75
+ let scrollLeft = slider.container.scrollLeft;
76
+ let nativeScrollLeft = slider.container.scrollLeft;
77
+ let programmaticScrollLeft = slider.container.scrollLeft;
78
+ let isScrolling = false;
79
+ let isUserScrolling = false;
80
+ let isProgrammaticScrolling = false;
81
+ // any scroll
82
+ slider.container.addEventListener('scroll', () => {
83
+ const newScrollLeft = slider.container.scrollLeft;
84
+ if (Math.floor(scrollLeft) !== Math.floor(newScrollLeft)) {
85
+ if (!isScrolling) {
86
+ isScrolling = true;
87
+ slider.emit('scrollStart');
88
+ }
89
+ scrollLeft = newScrollLeft;
90
+ clearTimeout(scrollTimeout);
91
+ scrollTimeout = setTimeout(() => {
92
+ isScrolling = false;
93
+ slider.emit('scrollEnd');
94
+ }, 50);
95
+ slider.emit('scroll');
96
+ }
97
+ // keep up nativeScrolling to take into account scroll-snap
98
+ if (isUserScrolling) {
99
+ nativeScrollHandler();
100
+ }
101
+ });
102
+ // user initted scroll (touchmove, mouse wheel, etc.)
103
+ const nativeScrollHandler = () => {
104
+ const newScrollLeft = slider.container.scrollLeft;
105
+ if (Math.floor(nativeScrollLeft) !== Math.floor(newScrollLeft) && !isProgrammaticScrolling) {
106
+ if (!isUserScrolling) {
107
+ slider.emit('nativeScrollStart');
108
+ isUserScrolling = true;
109
+ }
110
+ slider.emit('nativeScroll');
111
+ nativeScrollLeft = newScrollLeft;
112
+ clearTimeout(nativeScrollTimeout);
113
+ nativeScrollTimeout = setTimeout(() => {
114
+ isUserScrolling = false;
115
+ slider.emit('nativeScrollEnd');
116
+ // update programmaticScrollLeft to match nativeScrollLeft
117
+ // this prevents programmaticScroll triggering with no real change to scrollLeft
118
+ programmaticScrollLeft = nativeScrollLeft;
119
+ }, 50);
120
+ }
121
+ };
122
+ slider.container.addEventListener('touchmove', nativeScrollHandler);
123
+ slider.container.addEventListener('mousewheel', nativeScrollHandler);
124
+ slider.container.addEventListener('wheel', nativeScrollHandler);
125
+ // programmatic scroll (scrollTo, etc.)
126
+ slider.on('programmaticScrollStart', () => {
127
+ isProgrammaticScrolling = true;
128
+ });
129
+ slider.container.addEventListener('scroll', () => {
130
+ const newScrollLeft = slider.container.scrollLeft;
131
+ if (Math.floor(programmaticScrollLeft) !== Math.floor(newScrollLeft) && !isUserScrolling && isProgrammaticScrolling) {
132
+ programmaticScrollLeft = newScrollLeft;
133
+ clearTimeout(programmaticScrollTimeout);
134
+ programmaticScrollTimeout = setTimeout(() => {
135
+ isProgrammaticScrolling = false;
136
+ slider.emit('programmaticScrollEnd');
137
+ // update nativeScrollLeft to match programmaticScrollLeft
138
+ // this prevents nativeScroll triggering with no real change to scrollLeft
139
+ nativeScrollLeft = programmaticScrollLeft;
140
+ }, 50);
141
+ slider.emit('programmaticScroll');
142
+ }
143
+ });
144
+ // Fix issues on scroll snapping not working on programmatic scroll (it's not smooth)
145
+ // by disabling scroll snap if scrolling is programmatic
146
+ slider.on('programmaticScrollStart', () => {
147
+ slider.container.style.scrollSnapType = 'none';
148
+ });
149
+ // restore scroll snap if user scroll starts
150
+ slider.on('nativeScrollStart', () => {
151
+ slider.container.style.scrollSnapType = '';
152
+ });
73
153
  // Listen for mouse down and touch start events on the document
74
154
  // This handles both mouse clicks and touch interactions
75
155
  let wasInteractedWith = false;
@@ -114,27 +194,23 @@ function Slider(container, options, plugins) {
114
194
  const slideStart = slideRect.left - sliderRect.left + scrollLeft;
115
195
  const slideEnd = slideStart + slideRect.width;
116
196
  let scrollTarget = null;
117
- if (slideStart < scrollLeft) {
197
+ if (Math.floor(slideStart) < Math.floor(scrollLeft)) {
118
198
  scrollTarget = slideStart;
119
199
  }
120
- else if (slideEnd > scrollLeft + containerWidth) {
200
+ else if (Math.floor(slideEnd) > Math.floor(scrollLeft) + Math.floor(containerWidth)) {
121
201
  scrollTarget = slideEnd - containerWidth;
122
202
  }
123
- else if (slideStart === 0) {
203
+ else if (Math.floor(slideStart) === 0) {
124
204
  scrollTarget = 0;
125
205
  }
206
+ else {
207
+ scrollTarget = slideStart;
208
+ }
126
209
  if (scrollTarget !== null) {
127
- slider.container.style.scrollSnapType = 'none';
128
- // seems like in order for scroll behavior: smooth to work, we need to wait a bit to disable scrollSnapType
129
210
  setTimeout((scrollTarget) => {
211
+ slider.emit('programmaticScrollStart');
130
212
  slider.container.scrollTo({ left: scrollTarget, behavior: behavior });
131
213
  }, 50, scrollTarget);
132
- setTimeout(() => {
133
- // leave snapping off to fix issues with slide moving back on focus
134
- if (behavior == 'smooth') {
135
- slider.container.style.scrollSnapType = '';
136
- }
137
- }, 500);
138
214
  }
139
215
  }
140
216
  function setActiveSlideIdx() {
@@ -142,13 +218,20 @@ function Slider(container, options, plugins) {
142
218
  const scrollLeft = slider.container.scrollLeft;
143
219
  const slides = slider.slides;
144
220
  let activeSlideIdx = 0;
221
+ let scrolledPastLastSlide = false;
145
222
  for (let i = 0; i < slides.length; i++) {
146
223
  const slideRect = slides[i].getBoundingClientRect();
147
224
  const slideStart = slideRect.left - sliderRect.left + scrollLeft + getGapSize();
148
- if (slideStart > scrollLeft) {
225
+ if (Math.floor(slideStart) >= Math.floor(scrollLeft)) {
149
226
  activeSlideIdx = i;
150
227
  break;
151
228
  }
229
+ if (i === slides.length - 1) {
230
+ scrolledPastLastSlide = true;
231
+ }
232
+ }
233
+ if (scrolledPastLastSlide) {
234
+ activeSlideIdx = slides.length - 1;
152
235
  }
153
236
  const oldActiveSlideIdx = slider.activeSlideIdx;
154
237
  slider.activeSlideIdx = activeSlideIdx;
@@ -162,15 +245,29 @@ function Slider(container, options, plugins) {
162
245
  ensureSlideIsInView(slide);
163
246
  }
164
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
+ }
165
254
  function getGapSize() {
166
255
  let gapSize = 0;
167
256
  if (slider.slides.length > 1) {
168
257
  const firstSlideRect = slider.slides[0].getBoundingClientRect();
169
258
  const secondSlideRect = slider.slides[1].getBoundingClientRect();
170
- gapSize = secondSlideRect.left - firstSlideRect.right;
259
+ gapSize = Math.floor(secondSlideRect.left - firstSlideRect.right);
171
260
  }
172
261
  return gapSize;
173
262
  }
263
+ function getLeftOffset() {
264
+ let offset = 0;
265
+ const fullWidthOffset = slider.container.getAttribute('data-full-width-offset');
266
+ if (fullWidthOffset) {
267
+ offset = parseInt(fullWidthOffset);
268
+ }
269
+ return Math.floor(offset);
270
+ }
174
271
  function moveToDirection(direction = "prev") {
175
272
  const scrollStrategy = slider.options.scrollStrategy;
176
273
  const scrollLeft = slider.container.scrollLeft;
@@ -181,16 +278,16 @@ function Slider(container, options, plugins) {
181
278
  targetScrollPosition = Math.max(0, scrollLeft - slider.container.offsetWidth);
182
279
  }
183
280
  else if (direction === 'next') {
184
- targetScrollPosition = Math.min(slider.container.scrollWidth, scrollLeft + slider.container.offsetWidth);
281
+ targetScrollPosition = Math.min(slider.getInclusiveScrollWidth(), scrollLeft + slider.container.offsetWidth);
185
282
  }
186
283
  if (scrollStrategy === 'fullSlide') {
187
- let fullSldeTargetScrollPosition = null;
284
+ let fullSlideTargetScrollPosition = null;
188
285
  // extend targetScrollPosition to include gap
189
286
  if (direction === 'prev') {
190
- fullSldeTargetScrollPosition = Math.max(0, targetScrollPosition - getGapSize());
287
+ fullSlideTargetScrollPosition = Math.max(0, targetScrollPosition - getGapSize());
191
288
  }
192
289
  else {
193
- fullSldeTargetScrollPosition = Math.min(slider.container.scrollWidth, targetScrollPosition + getGapSize());
290
+ fullSlideTargetScrollPosition = Math.min(slider.getInclusiveScrollWidth(), targetScrollPosition + getGapSize());
194
291
  }
195
292
  if (direction === 'next') {
196
293
  let partialSlideFound = false;
@@ -198,17 +295,25 @@ function Slider(container, options, plugins) {
198
295
  const slideRect = slide.getBoundingClientRect();
199
296
  const slideStart = slideRect.left - sliderRect.left + scrollLeft;
200
297
  const slideEnd = slideStart + slideRect.width;
201
- if (slideStart < targetScrollPosition && slideEnd > targetScrollPosition) {
202
- fullSldeTargetScrollPosition = slideStart;
298
+ if (Math.floor(slideStart) < Math.floor(targetScrollPosition) && Math.floor(slideEnd) > Math.floor(targetScrollPosition)) {
299
+ fullSlideTargetScrollPosition = slideStart;
203
300
  partialSlideFound = true;
204
301
  break;
205
302
  }
206
303
  }
207
304
  if (!partialSlideFound) {
208
- fullSldeTargetScrollPosition = Math.min(targetScrollPosition, slider.container.scrollWidth - slider.container.offsetWidth);
305
+ fullSlideTargetScrollPosition = Math.min(targetScrollPosition, slider.getInclusiveScrollWidth() - slider.container.offsetWidth);
209
306
  }
210
- if (fullSldeTargetScrollPosition && fullSldeTargetScrollPosition > scrollLeft) {
211
- 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
+ }
212
317
  }
213
318
  }
214
319
  else {
@@ -217,24 +322,89 @@ function Slider(container, options, plugins) {
217
322
  const slideRect = slide.getBoundingClientRect();
218
323
  const slideStart = slideRect.left - sliderRect.left + scrollLeft;
219
324
  const slideEnd = slideStart + slideRect.width;
220
- if (slideStart < scrollLeft && slideEnd > scrollLeft) {
221
- fullSldeTargetScrollPosition = slideEnd - containerWidth;
325
+ if (Math.floor(slideStart) < Math.floor(scrollLeft) && Math.floor(slideEnd) > Math.floor(scrollLeft)) {
326
+ fullSlideTargetScrollPosition = slideEnd - containerWidth;
222
327
  partialSlideFound = true;
223
328
  break;
224
329
  }
225
330
  }
226
331
  if (!partialSlideFound) {
227
- fullSldeTargetScrollPosition = Math.max(0, scrollLeft - containerWidth);
332
+ fullSlideTargetScrollPosition = Math.max(0, scrollLeft - containerWidth);
228
333
  }
229
- if (fullSldeTargetScrollPosition && fullSldeTargetScrollPosition < scrollLeft) {
230
- targetScrollPosition = fullSldeTargetScrollPosition;
334
+ if (fullSlideTargetScrollPosition && Math.floor(fullSlideTargetScrollPosition) < Math.floor(scrollLeft)) {
335
+ targetScrollPosition = fullSlideTargetScrollPosition;
231
336
  }
232
337
  }
233
338
  }
339
+ // add left offset
340
+ const offsettedTargetScrollPosition = targetScrollPosition - getLeftOffset();
341
+ if (Math.floor(offsettedTargetScrollPosition) >= 0) {
342
+ targetScrollPosition = offsettedTargetScrollPosition;
343
+ }
344
+ slider.emit('programmaticScrollStart');
234
345
  slider.container.style.scrollBehavior = slider.options.scrollBehavior;
235
346
  slider.container.scrollLeft = targetScrollPosition;
236
347
  setTimeout(() => slider.container.style.scrollBehavior = '', 50);
237
348
  }
349
+ function snapToClosestSlide(direction = "prev") {
350
+ const isMovingForward = direction === 'next';
351
+ const slideReference = [];
352
+ for (let i = 0; i < slider.slides.length; i++) {
353
+ const slide = slider.slides[i];
354
+ const slideWidth = slide.offsetWidth;
355
+ const slideStart = slide.offsetLeft;
356
+ const slideEnd = slideStart + slideWidth;
357
+ const slideMiddle = slideStart + slideWidth / 2;
358
+ const trigger = Math.min(slideMiddle, slideStart + slider.options.emulateScrollSnapMaxThreshold);
359
+ slideReference.push({
360
+ start: slideStart,
361
+ middle: slideMiddle,
362
+ end: slideEnd,
363
+ width: slideWidth,
364
+ trigger: trigger,
365
+ slide: slide,
366
+ });
367
+ }
368
+ let snapTarget = null;
369
+ const scrollPosition = slider.container.scrollLeft;
370
+ if (isMovingForward) {
371
+ for (let i = 0; i < slideReference.length; i++) {
372
+ const item = slideReference[i];
373
+ if (i === 0 && Math.floor(scrollPosition) <= Math.floor(item.trigger)) {
374
+ snapTarget = 0;
375
+ break;
376
+ }
377
+ if (Math.floor(slider.container.scrollLeft) <= Math.floor(item.trigger)) {
378
+ snapTarget = item.start;
379
+ break;
380
+ }
381
+ }
382
+ }
383
+ else {
384
+ for (let i = slideReference.length - 1; i >= 0; i--) {
385
+ const item = slideReference[i];
386
+ if (i === slideReference.length - 1 && Math.floor(scrollPosition) >= Math.floor(item.trigger)) {
387
+ snapTarget = item.start;
388
+ break;
389
+ }
390
+ if (Math.floor(slider.container.scrollLeft) >= Math.floor(item.trigger)) {
391
+ snapTarget = item.start;
392
+ break;
393
+ }
394
+ }
395
+ }
396
+ if (snapTarget !== null) {
397
+ const offsettedSnapTarget = snapTarget - getLeftOffset();
398
+ if (Math.floor(offsettedSnapTarget) >= 0) {
399
+ snapTarget = offsettedSnapTarget;
400
+ }
401
+ const scrollBehavior = slider.options.scrollBehavior || 'smooth';
402
+ slider.container.scrollTo({
403
+ left: snapTarget,
404
+ behavior: scrollBehavior
405
+ });
406
+ }
407
+ }
238
408
  function on(name, cb) {
239
409
  if (!subs[name]) {
240
410
  subs[name] = [];
@@ -257,6 +427,9 @@ function Slider(container, options, plugins) {
257
427
  emit,
258
428
  moveToDirection,
259
429
  moveToSlide,
430
+ snapToClosestSlide,
431
+ getInclusiveScrollWidth,
432
+ getInclusiveClientWidth,
260
433
  on,
261
434
  options,
262
435
  };
@@ -1 +1 @@
1
- import e from"./details.min.js";import{generateId as t,objectsAreEqual as n}from"./utils.min.js";function i(i,o,l){let r,s={};function a(t=!1){const i=r.details,o=e(r);r.details=o,t||n(i,o)?t&&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(e,t=null){const n=t||r.options.scrollBehavior,i=e.getBoundingClientRect(),o=r.container.getBoundingClientRect(),l=r.container.offsetWidth,s=r.container.scrollLeft,a=i.left-o.left+s,c=a+i.width;let d=null;a<s?d=a:c>s+l?d=c-l:0===a&&(d=0),null!==d&&(r.container.style.scrollSnapType="none",setTimeout((e=>{r.container.scrollTo({left:e,behavior:n})}),50,d),setTimeout((()=>{"smooth"==n&&(r.container.style.scrollSnapType="")}),500))}function h(){const e=r.container.getBoundingClientRect(),t=r.container.scrollLeft,n=r.slides;let i=0;for(let o=0;o<n.length;o++){if(n[o].getBoundingClientRect().left-e.left+t+m()>t){i=o;break}}const o=r.activeSlideIdx;r.activeSlideIdx=i,o!==i&&r.emit("activeSlideChanged")}function m(){let e=0;if(r.slides.length>1){const t=r.slides[0].getBoundingClientRect();e=r.slides[1].getBoundingClientRect().left-t.right}return e}return r={emit:function(e){var t;s&&s[e]&&s[e].forEach((e=>{e(r)}));const n=null===(t=null==r?void 0:r.options)||void 0===t?void 0:t[e];"function"==typeof n&&n(r)},moveToDirection:function(e="prev"){const t=r.options.scrollStrategy,n=r.container.scrollLeft,i=r.container.getBoundingClientRect(),o=r.container.offsetWidth;let l=n;if("prev"===e?l=Math.max(0,n-r.container.offsetWidth):"next"===e&&(l=Math.min(r.container.scrollWidth,n+r.container.offsetWidth)),"fullSlide"===t){let t=null;if(t="prev"===e?Math.max(0,l-m()):Math.min(r.container.scrollWidth,l+m()),"next"===e){let e=!1;for(let o of r.slides){const r=o.getBoundingClientRect(),s=r.left-i.left+n,a=s+r.width;if(s<l&&a>l){t=s,e=!0;break}}e||(t=Math.min(l,r.container.scrollWidth-r.container.offsetWidth)),t&&t>n&&(l=t)}else{let e=!1;for(let l of r.slides){const r=l.getBoundingClientRect(),s=r.left-i.left+n,a=s+r.width;if(s<n&&a>n){t=a-o,e=!0;break}}e||(t=Math.max(0,n-o)),t&&t<n&&(l=t)}}r.container.style.scrollBehavior=r.options.scrollBehavior,r.container.scrollLeft=l,setTimeout((()=>r.container.style.scrollBehavior=""),50)},moveToSlide:function(e){const t=r.slides[e];t&&u(t)},on:function(e,t){s[e]||(s[e]=[]),s[e].push(t)},options:o},function(){r.container=i;let e=i.getAttribute("id");null===e&&(e=t("overflow-slider"),i.setAttribute("id",e)),c(),a(!0),h(),r.on("contentsChanged",(()=>{c(),a(),h()})),r.on("containerSizeChanged",(()=>a()));let n=0;if(r.on("scroll",(()=>{n&&window.cancelAnimationFrame(n),n=window.requestAnimationFrame((()=>{a(),h()}))})),function(){new MutationObserver((()=>r.emit("contentsChanged"))).observe(r.container,{childList:!0});new ResizeObserver((()=>r.emit("containerSizeChanged"))).observe(r.container),r.container.addEventListener("scroll",(()=>r.emit("scroll")));let e=!1;r.container.addEventListener("mousedown",(()=>{e=!0})),r.container.addEventListener("touchstart",(()=>{e=!0}),{passive:!0}),r.container.addEventListener("focusin",(t=>{if(!e){let e=t.target;for(;e.parentElement!==r.container&&e.parentElement;)e=e.parentElement;u(e,"auto")}e=!1}))}(),f(),d(),l)for(const e of l)e(r);r.on("detailsChanged",(()=>{f(),d()})),r.emit("created"),r.container.setAttribute("data-ready","true")}(),r}export{i 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};
@@ -1 +1 @@
1
- .overflow-slider{-ms-overflow-style:none;display:grid;grid-auto-flow:column;grid-template-columns:max-content;max-width:-moz-max-content;max-width:max-content;overflow:auto;scrollbar-width:none;width:100%}.overflow-slider::-webkit-scrollbar{display:none}.overflow-slider>*{outline-offset:-2px;scroll-snap-align:start}:root{--overflow-slider-arrows-size:1.5rem;--overflow-slider-arrows-gap:.5rem;--overflow-slider-arrows-inactive-opacity:0.5}.overflow-slider__arrows{display:flex;gap:var(--overflow-slider-arrows-gap)}.overflow-slider__arrows-button{align-items:center;cursor:pointer;display:flex;outline-offset:-2px}.overflow-slider__arrows-button svg{height:var(--overflow-slider-arrows-size);width:var(--overflow-slider-arrows-size)}.overflow-slider__arrows-button[data-has-content=false]{opacity:var(--overflow-slider-arrows-inactive-opacity)}:root{--overflow-slider-dots-gap:0.5rem;--overflow-slider-dot-size:0.75rem;--overflow-slider-dot-inactive-color:rgba(0,0,0,.1);--overflow-slider-dot-active-color:rgba(0,0,0,.8)}.overflow-slider__dots{align-items:center;display:flex;justify-content:center}.overflow-slider__dots ul{display:flex;flex-wrap:wrap;gap:var(--overflow-slider-dots-gap);list-style:none;margin:0;padding:0}.overflow-slider__dots li{line-height:0;margin:0;padding:0}.overflow-slider__dot-item{background:var(--overflow-slider-dot-inactive-color);border-radius:50%;cursor:pointer;height:var(--overflow-slider-dot-size);margin:0;outline-offset:2px;padding:0;position:relative;width:var(--overflow-slider-dot-size)}.overflow-slider__dot-item:after{bottom:calc(var(--overflow-slider-dots-gap)*-1);content:"";display:block;left:calc(var(--overflow-slider-dots-gap)*-1);position:absolute;right:calc(var(--overflow-slider-dots-gap)*-1);top:calc(var(--overflow-slider-dots-gap)*-1)}.overflow-slider__dot-item:focus,.overflow-slider__dot-item:hover,.overflow-slider__dot-item[aria-pressed=true]{background:var(--overflow-slider-dot-active-color)}[data-has-drag-scrolling][data-has-overflow=true]{cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none}:root{--overflow-slider-scroll-indicator-button-height:4px;--overflow-slider-scroll-indicator-padding:1rem;--overflow-slider-scroll-indicator-button-color:rgba(0,0,0,.75);--overflow-slider-scroll-indicator-bar-color:rgba(0,0,0,.25)}.overflow-slider__scroll-indicator{cursor:pointer;outline:0;padding-block:var(--overflow-slider-scroll-indicator-padding);position:relative;width:100%}.overflow-slider__scroll-indicator[data-has-overflow=false]{display:none}.overflow-slider__scroll-indicator:focus-visible .overflow-slider__scroll-indicator-button{outline:2px solid;outline-offset:2px}.overflow-slider__scroll-indicator-bar{background:var(--overflow-slider-scroll-indicator-bar-color);border-radius:3px;height:2px;left:0;position:absolute;top:50%;transform:translateY(-50%);width:100%}.overflow-slider__scroll-indicator-button{background:var(--overflow-slider-scroll-indicator-button-color);border-radius:3px;cursor:grab;height:var(--overflow-slider-scroll-indicator-button-height);left:0;position:absolute;top:calc(50% - var(--overflow-slider-scroll-indicator-button-height)/2)}.overflow-slider__scroll-indicator-button:hover,.overflow-slider__scroll-indicator-button[data-is-grabbed=true]{--overflow-slider-scroll-indicator-button-height:6px}.overflow-slider__scroll-indicator-button:after{bottom:calc(var(--overflow-slider-scroll-indicator-padding)*-1);content:"";display:block;position:absolute;top:calc(var(--overflow-slider-scroll-indicator-padding)*-1);width:100%}
1
+ .overflow-slider{-ms-overflow-style:none;display:grid;grid-auto-flow:column;grid-template-columns:max-content;max-width:-moz-max-content;max-width:max-content;overflow:auto;position:relative;scrollbar-width:none;width:100%}.overflow-slider::-webkit-scrollbar{display:none}.overflow-slider>*{outline-offset:-2px;scroll-snap-align:start}:root{--overflow-slider-arrows-size:1.5rem;--overflow-slider-arrows-gap:.5rem;--overflow-slider-arrows-inactive-opacity:0.5}.overflow-slider__arrows{display:flex;gap:var(--overflow-slider-arrows-gap)}.overflow-slider__arrows-button{align-items:center;cursor:pointer;display:flex;outline-offset:-2px}.overflow-slider__arrows-button svg{height:var(--overflow-slider-arrows-size);width:var(--overflow-slider-arrows-size)}.overflow-slider__arrows-button[data-has-content=false]{opacity:var(--overflow-slider-arrows-inactive-opacity)}:root{--overflow-slider-dots-gap:0.5rem;--overflow-slider-dot-size:0.75rem;--overflow-slider-dot-inactive-color:rgba(0,0,0,.1);--overflow-slider-dot-active-color:rgba(0,0,0,.8)}.overflow-slider__dots{align-items:center;display:flex;justify-content:center}.overflow-slider__dots ul{display:flex;flex-wrap:wrap;gap:var(--overflow-slider-dots-gap);list-style:none;margin:0;padding:0}.overflow-slider__dots li{line-height:0;margin:0;padding:0}.overflow-slider__dot-item{background:var(--overflow-slider-dot-inactive-color);border-radius:50%;cursor:pointer;height:var(--overflow-slider-dot-size);margin:0;outline-offset:2px;padding:0;position:relative;width:var(--overflow-slider-dot-size)}.overflow-slider__dot-item:after{bottom:calc(var(--overflow-slider-dots-gap)*-1);content:"";display:block;left:calc(var(--overflow-slider-dots-gap)*-1);position:absolute;right:calc(var(--overflow-slider-dots-gap)*-1);top:calc(var(--overflow-slider-dots-gap)*-1)}.overflow-slider__dot-item:focus,.overflow-slider__dot-item:hover,.overflow-slider__dot-item[aria-pressed=true]{background:var(--overflow-slider-dot-active-color)}:root{--overflow-slider-fade-color:#fff;--overflow-slider-fade-width:3rem}.overflow-slider-fade{height:100%;pointer-events:none;position:absolute;top:0;width:var(--overflow-slider-fade-width);z-index:1}.overflow-slider-fade--start{background:linear-gradient(to right,var(--overflow-slider-fade-color) 0,transparent 100%);left:0}.overflow-slider-fade--end{background:linear-gradient(to left,var(--overflow-slider-fade-color) 0,transparent 100%);right:0}[data-has-drag-scrolling][data-has-overflow=true]{cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none}:root{--overflow-slider-scroll-indicator-button-height:4px;--overflow-slider-scroll-indicator-padding:1rem;--overflow-slider-scroll-indicator-button-color:rgba(0,0,0,.75);--overflow-slider-scroll-indicator-bar-color:rgba(0,0,0,.25)}.overflow-slider__scroll-indicator{cursor:pointer;outline:0;padding-block:var(--overflow-slider-scroll-indicator-padding);position:relative;width:100%}.overflow-slider__scroll-indicator[data-has-overflow=false]{display:none}.overflow-slider__scroll-indicator:focus-visible .overflow-slider__scroll-indicator-button{outline:2px solid;outline-offset:2px}.overflow-slider__scroll-indicator-bar{background:var(--overflow-slider-scroll-indicator-bar-color);border-radius:3px;height:2px;left:0;position:absolute;top:50%;transform:translateY(-50%);width:100%}.overflow-slider__scroll-indicator-button{background:var(--overflow-slider-scroll-indicator-button-color);border-radius:3px;cursor:grab;height:var(--overflow-slider-scroll-indicator-button-height);left:0;position:absolute;top:calc(50% - var(--overflow-slider-scroll-indicator-button-height)/2)}.overflow-slider__scroll-indicator-button:hover,.overflow-slider__scroll-indicator-button[data-is-grabbed=true]{--overflow-slider-scroll-indicator-button-height:6px}.overflow-slider__scroll-indicator-button:after{bottom:calc(var(--overflow-slider-scroll-indicator-padding)*-1);content:"";display:block;position:absolute;top:calc(var(--overflow-slider-scroll-indicator-padding)*-1);width:100%}
@@ -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};
@@ -20,8 +20,8 @@ function DotsPlugin(args) {
20
20
  dots.setAttribute('data-has-content', slider.details.hasOverflow.toString());
21
21
  dots.innerHTML = '';
22
22
  const dotsList = document.createElement('ul');
23
- const pages = slider.details.amountOfPages;
24
- const currentPage = slider.details.currentPage;
23
+ const pages = slider.details.slideCount;
24
+ const currentItem = slider.activeSlideIdx;
25
25
  if (pages <= 1) {
26
26
  return;
27
27
  }
@@ -31,23 +31,23 @@ function DotsPlugin(args) {
31
31
  dot.setAttribute('type', 'button');
32
32
  dot.setAttribute('class', options.classNames.dotsItem);
33
33
  dot.setAttribute('aria-label', options.texts.dotDescription.replace('%d', (i + 1).toString()).replace('%d', pages.toString()));
34
- dot.setAttribute('aria-pressed', (i === currentPage).toString());
35
- dot.setAttribute('data-page', (i + 1).toString());
34
+ dot.setAttribute('aria-pressed', (i === currentItem).toString());
35
+ dot.setAttribute('data-item', (i + 1).toString());
36
36
  dotListItem.appendChild(dot);
37
37
  dotsList.appendChild(dotListItem);
38
38
  dot.addEventListener('click', () => activateDot(i + 1));
39
39
  dot.addEventListener('focus', () => pageFocused = i + 1);
40
40
  dot.addEventListener('keydown', (e) => {
41
41
  var _a;
42
- const currentPageItem = dots.querySelector(`[aria-pressed="true"]`);
43
- if (!currentPageItem) {
42
+ const currentItemItem = dots.querySelector(`[aria-pressed="true"]`);
43
+ if (!currentItemItem) {
44
44
  return;
45
45
  }
46
- const currentPage = parseInt((_a = currentPageItem.getAttribute('data-page')) !== null && _a !== void 0 ? _a : '1');
46
+ const currentItem = parseInt((_a = currentItemItem.getAttribute('data-item')) !== null && _a !== void 0 ? _a : '1');
47
47
  if (e.key === 'ArrowLeft') {
48
- const previousPage = currentPage - 1;
48
+ const previousPage = currentItem - 1;
49
49
  if (previousPage > 0) {
50
- const matchingDot = dots.querySelector(`[data-page="${previousPage}"]`);
50
+ const matchingDot = dots.querySelector(`[data-item="${previousPage}"]`);
51
51
  if (matchingDot) {
52
52
  matchingDot.focus();
53
53
  }
@@ -55,9 +55,9 @@ function DotsPlugin(args) {
55
55
  }
56
56
  }
57
57
  if (e.key === 'ArrowRight') {
58
- const nextPage = currentPage + 1;
58
+ const nextPage = currentItem + 1;
59
59
  if (nextPage <= pages) {
60
- const matchingDot = dots.querySelector(`[data-page="${nextPage}"]`);
60
+ const matchingDot = dots.querySelector(`[data-item="${nextPage}"]`);
61
61
  if (matchingDot) {
62
62
  matchingDot.focus();
63
63
  }
@@ -69,19 +69,18 @@ function DotsPlugin(args) {
69
69
  dots.appendChild(dotsList);
70
70
  // return focus to same page after rebuild
71
71
  if (pageFocused) {
72
- const matchingDot = dots.querySelector(`[data-page="${pageFocused}"]`);
72
+ const matchingDot = dots.querySelector(`[data-item="${pageFocused}"]`);
73
73
  if (matchingDot) {
74
74
  matchingDot.focus();
75
75
  }
76
76
  }
77
77
  };
78
- const activateDot = (page) => {
79
- const scrollTargetPosition = slider.details.containerWidth * (page - 1);
80
- slider.container.style.scrollBehavior = slider.options.scrollBehavior;
81
- slider.container.style.scrollSnapType = 'none';
82
- slider.container.scrollLeft = scrollTargetPosition;
83
- slider.container.style.scrollBehavior = '';
84
- slider.container.style.scrollSnapType = '';
78
+ const activateDot = (item) => {
79
+ // const scrollTargetPosition = slider.details.containerWidth * ( page - 1 );
80
+ // slider.container.style.scrollBehavior = slider.options.scrollBehavior;
81
+ // slider.container.scrollLeft = scrollTargetPosition;
82
+ // slider.container.style.scrollBehavior = '';
83
+ slider.moveToSlide(item - 1);
85
84
  };
86
85
  buildDots();
87
86
  if (options.container) {
@@ -90,9 +89,9 @@ function DotsPlugin(args) {
90
89
  else {
91
90
  (_b = slider.container.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(dots, slider.container.nextSibling);
92
91
  }
93
- slider.on('detailsChanged', () => {
94
- buildDots();
95
- });
92
+ slider.on('scrollEnd', buildDots);
93
+ slider.on('contentsChanged', buildDots);
94
+ slider.on('containerSizeChanged', buildDots);
96
95
  };
97
96
  }
98
97
 
@@ -1 +1 @@
1
- const t={dotDescription:"Page %d of %d"},e={dotsContainer:"overflow-slider__dots",dotsItem:"overflow-slider__dot-item"};function n(n){return o=>{var a,s;const r={texts:Object.assign(Object.assign({},t),(null==n?void 0:n.texts)||[]),classNames:Object.assign(Object.assign({},e),(null==n?void 0:n.classNames)||[]),container:null!==(a=null==n?void 0:n.container)&&void 0!==a?a:null},i=document.createElement("div");i.classList.add(r.classNames.dotsContainer);let l=null;const c=()=>{i.setAttribute("data-has-content",o.details.hasOverflow.toString()),i.innerHTML="";const t=document.createElement("ul"),e=o.details.amountOfPages,n=o.details.currentPage;if(!(e<=1)){for(let o=0;o<e;o++){const a=document.createElement("li"),s=document.createElement("button");s.setAttribute("type","button"),s.setAttribute("class",r.classNames.dotsItem),s.setAttribute("aria-label",r.texts.dotDescription.replace("%d",(o+1).toString()).replace("%d",e.toString())),s.setAttribute("aria-pressed",(o===n).toString()),s.setAttribute("data-page",(o+1).toString()),a.appendChild(s),t.appendChild(a),s.addEventListener("click",(()=>d(o+1))),s.addEventListener("focus",(()=>l=o+1)),s.addEventListener("keydown",(t=>{var n;const o=i.querySelector('[aria-pressed="true"]');if(!o)return;const a=parseInt(null!==(n=o.getAttribute("data-page"))&&void 0!==n?n:"1");if("ArrowLeft"===t.key){const t=a-1;if(t>0){const e=i.querySelector(`[data-page="${t}"]`);e&&e.focus(),d(t)}}if("ArrowRight"===t.key){const t=a+1;if(t<=e){const e=i.querySelector(`[data-page="${t}"]`);e&&e.focus(),d(t)}}}))}if(i.appendChild(t),l){const t=i.querySelector(`[data-page="${l}"]`);t&&t.focus()}}},d=t=>{const e=o.details.containerWidth*(t-1);o.container.style.scrollBehavior=o.options.scrollBehavior,o.container.style.scrollSnapType="none",o.container.scrollLeft=e,o.container.style.scrollBehavior="",o.container.style.scrollSnapType=""};c(),r.container?r.container.appendChild(i):null===(s=o.container.parentNode)||void 0===s||s.insertBefore(i,o.container.nextSibling),o.on("detailsChanged",(()=>{c()}))}}export{n as default};
1
+ const t={dotDescription:"Page %d of %d"},e={dotsContainer:"overflow-slider__dots",dotsItem:"overflow-slider__dot-item"};function n(n){return o=>{var i,s;const a={texts:Object.assign(Object.assign({},t),(null==n?void 0:n.texts)||[]),classNames:Object.assign(Object.assign({},e),(null==n?void 0:n.classNames)||[]),container:null!==(i=null==n?void 0:n.container)&&void 0!==i?i:null},r=document.createElement("div");r.classList.add(a.classNames.dotsContainer);let d=null;const l=()=>{r.setAttribute("data-has-content",o.details.hasOverflow.toString()),r.innerHTML="";const t=document.createElement("ul"),e=o.details.slideCount,n=o.activeSlideIdx;if(!(e<=1)){for(let o=0;o<e;o++){const i=document.createElement("li"),s=document.createElement("button");s.setAttribute("type","button"),s.setAttribute("class",a.classNames.dotsItem),s.setAttribute("aria-label",a.texts.dotDescription.replace("%d",(o+1).toString()).replace("%d",e.toString())),s.setAttribute("aria-pressed",(o===n).toString()),s.setAttribute("data-item",(o+1).toString()),i.appendChild(s),t.appendChild(i),s.addEventListener("click",(()=>c(o+1))),s.addEventListener("focus",(()=>d=o+1)),s.addEventListener("keydown",(t=>{var n;const o=r.querySelector('[aria-pressed="true"]');if(!o)return;const i=parseInt(null!==(n=o.getAttribute("data-item"))&&void 0!==n?n:"1");if("ArrowLeft"===t.key){const t=i-1;if(t>0){const e=r.querySelector(`[data-item="${t}"]`);e&&e.focus(),c(t)}}if("ArrowRight"===t.key){const t=i+1;if(t<=e){const e=r.querySelector(`[data-item="${t}"]`);e&&e.focus(),c(t)}}}))}if(r.appendChild(t),d){const t=r.querySelector(`[data-item="${d}"]`);t&&t.focus()}}},c=t=>{o.moveToSlide(t-1)};l(),a.container?a.container.appendChild(r):null===(s=o.container.parentNode)||void 0===s||s.insertBefore(r,o.container.nextSibling),o.on("scrollEnd",l),o.on("contentsChanged",l),o.on("containerSizeChanged",l)}}export{n as default};