@evermade/overflow-slider 2.0.1 → 3.0.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.
- package/.nvmrc +1 -1
- package/README.md +17 -3
- package/dist/core/overflow-slider.esm.js +2 -0
- package/dist/core/overflow-slider.min.js +1 -1
- package/dist/core/slider.esm.js +159 -9
- package/dist/core/slider.min.js +1 -1
- package/dist/overflow-slider.css +1 -1
- package/dist/plugins/dots/dots/index.esm.js +21 -22
- package/dist/plugins/dots/dots/index.min.js +1 -1
- package/dist/plugins/drag-scrolling/drag-scrolling/index.esm.js +30 -3
- package/dist/plugins/drag-scrolling/drag-scrolling/index.min.js +1 -1
- package/dist/plugins/fade/fade/index.esm.js +81 -0
- package/dist/plugins/fade/fade/index.min.js +1 -0
- package/dist/plugins/full-width/full-width/index.esm.js +1 -0
- package/dist/plugins/full-width/full-width/index.min.js +1 -1
- package/dist/plugins/scroll-indicator/scroll-indicator/index.esm.js +0 -2
- package/dist/plugins/scroll-indicator/scroll-indicator/index.min.js +1 -1
- package/dist/plugins/thumbnails/thumbnails/index.esm.js +2 -1
- package/dist/plugins/thumbnails/thumbnails/index.min.js +1 -1
- package/docs/assets/demo.css +16 -0
- package/docs/assets/demo.js +44 -7
- package/docs/dist/core/overflow-slider.esm.js +2 -0
- package/docs/dist/core/overflow-slider.min.js +1 -1
- package/docs/dist/core/slider.esm.js +159 -9
- package/docs/dist/core/slider.min.js +1 -1
- package/docs/dist/overflow-slider.css +1 -1
- package/docs/dist/plugins/dots/dots/index.esm.js +21 -22
- package/docs/dist/plugins/dots/dots/index.min.js +1 -1
- package/docs/dist/plugins/drag-scrolling/drag-scrolling/index.esm.js +30 -3
- package/docs/dist/plugins/drag-scrolling/drag-scrolling/index.min.js +1 -1
- package/docs/dist/plugins/fade/fade/index.esm.js +81 -0
- package/docs/dist/plugins/fade/fade/index.min.js +1 -0
- package/docs/dist/plugins/full-width/full-width/index.esm.js +1 -0
- package/docs/dist/plugins/full-width/full-width/index.min.js +1 -1
- package/docs/dist/plugins/scroll-indicator/scroll-indicator/index.esm.js +0 -2
- package/docs/dist/plugins/scroll-indicator/scroll-indicator/index.min.js +1 -1
- package/docs/dist/plugins/thumbnails/thumbnails/index.esm.js +2 -1
- package/docs/dist/plugins/thumbnails/thumbnails/index.min.js +1 -1
- package/docs/index.html +39 -7
- package/package.json +7 -2
- package/src/core/overflow-slider.ts +2 -0
- package/src/core/slider.ts +176 -14
- package/src/core/types.ts +31 -1
- package/src/overflow-slider.scss +2 -1
- package/src/plugins/dots/index.ts +21 -23
- package/src/plugins/drag-scrolling/index.ts +34 -5
- package/src/plugins/fade/index.ts +102 -0
- package/src/plugins/fade/styles.scss +27 -0
- package/src/plugins/full-width/index.ts +1 -0
- package/src/plugins/scroll-indicator/index.ts +0 -2
- package/src/plugins/thumbnails/index.ts +2 -1
package/.nvmrc
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v16.16.0
|
|
1
|
+
v16.16.0
|
package/README.md
CHANGED
|
@@ -94,7 +94,7 @@ const slider = new OverflowSlider(
|
|
|
94
94
|
You can import base styles from the library to get started. The base styles include basic styles for the slider and some plugins.
|
|
95
95
|
|
|
96
96
|
```scss
|
|
97
|
-
@import "@evermade/overflow-slider/
|
|
97
|
+
@import "@evermade/overflow-slider/style.css";
|
|
98
98
|
```
|
|
99
99
|
|
|
100
100
|
You can use the CSS variables to override some values easily.
|
|
@@ -127,14 +127,28 @@ Auto-play is not supported at the moment but can probably be implemented as a pl
|
|
|
127
127
|
|
|
128
128
|
## To-do
|
|
129
129
|
|
|
130
|
-
* Make drag scrolling snapping smooth (might be browser limitation)
|
|
131
|
-
* Rethink dot amount calculation
|
|
132
130
|
* Maybe split styles to separate files for plugins (but keep offering bundle as well)
|
|
133
131
|
* Maybe add plugin that adds class for visible slides
|
|
134
132
|
* Document all plugins and their parameters here
|
|
135
133
|
|
|
136
134
|
## Changelog
|
|
137
135
|
|
|
136
|
+
### 3.0.0
|
|
137
|
+
|
|
138
|
+
* Breaking: Change dot plugin to calculate dots based on slides instead of container width "pages"
|
|
139
|
+
* Add: FadePlugin to hint that there are more slides to scroll to
|
|
140
|
+
* Add: Scroll snap emulation method
|
|
141
|
+
* Add: Scroll snap emulation for DragScrollingPlugin
|
|
142
|
+
* Add: Hooks for different types of scrolling (any, native, programmatic)
|
|
143
|
+
* Add: Hooks for different states of scrolling (start, scroll, end) for above types
|
|
144
|
+
* Refactor: Scroll snapping exceptions to be handled by the core slider
|
|
145
|
+
* Fix: Enhance performance by hooking some plugins only when scrolling has ended
|
|
146
|
+
* Fix: Full width alignment to take into account the container offset
|
|
147
|
+
|
|
148
|
+
### 2.0.2
|
|
149
|
+
|
|
150
|
+
* Fix: Import style.css from correct path
|
|
151
|
+
|
|
138
152
|
### 2.0.1
|
|
139
153
|
|
|
140
154
|
* Fix: Smooth scrolling for moveToSlide method
|
|
@@ -10,6 +10,8 @@ function OverflowSlider(container, options, plugins) {
|
|
|
10
10
|
scrollBehavior: "smooth",
|
|
11
11
|
scrollStrategy: "fullSlide",
|
|
12
12
|
slidesSelector: ":scope > *",
|
|
13
|
+
emulateScrollSnap: false,
|
|
14
|
+
emulateScrollSnapMaxThreshold: 64,
|
|
13
15
|
};
|
|
14
16
|
const sliderOptions = Object.assign(Object.assign({}, defaults), options);
|
|
15
17
|
// disable smooth scrolling if user prefers reduced motion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"./slider.min.js";function o(o,r,t){try{if(!(o instanceof Element))throw new Error("Container must be HTML element, found "+typeof o);const
|
|
1
|
+
import e from"./slider.min.js";function o(o,r,t){try{if(!(o instanceof Element))throw new Error("Container must be HTML element, found "+typeof o);const l={scrollBehavior:"smooth",scrollStrategy:"fullSlide",slidesSelector:":scope > *",emulateScrollSnap:!1,emulateScrollSnapMaxThreshold:64},s=Object.assign(Object.assign({},l),r);return window.matchMedia("(prefers-reduced-motion: reduce)").matches&&(s.scrollBehavior="auto"),e(o,s,t)}catch(e){console.error(e)}}export{o as default};
|
package/dist/core/slider.esm.js
CHANGED
|
@@ -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
|
-
|
|
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 (scrollLeft !== 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 (nativeScrollLeft !== 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 (programmaticScrollLeft !== 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;
|
|
@@ -123,18 +203,14 @@ function Slider(container, options, plugins) {
|
|
|
123
203
|
else if (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() {
|
|
@@ -171,6 +247,14 @@ function Slider(container, options, plugins) {
|
|
|
171
247
|
}
|
|
172
248
|
return gapSize;
|
|
173
249
|
}
|
|
250
|
+
function getLeftOffset() {
|
|
251
|
+
let offset = 0;
|
|
252
|
+
const fullWidthOffset = slider.container.getAttribute('data-full-width-offset');
|
|
253
|
+
if (fullWidthOffset) {
|
|
254
|
+
offset = parseInt(fullWidthOffset);
|
|
255
|
+
}
|
|
256
|
+
return offset;
|
|
257
|
+
}
|
|
174
258
|
function moveToDirection(direction = "prev") {
|
|
175
259
|
const scrollStrategy = slider.options.scrollStrategy;
|
|
176
260
|
const scrollLeft = slider.container.scrollLeft;
|
|
@@ -231,10 +315,75 @@ function Slider(container, options, plugins) {
|
|
|
231
315
|
}
|
|
232
316
|
}
|
|
233
317
|
}
|
|
318
|
+
// add left offset
|
|
319
|
+
const offsettedTargetScrollPosition = targetScrollPosition - getLeftOffset();
|
|
320
|
+
if (offsettedTargetScrollPosition >= 0) {
|
|
321
|
+
targetScrollPosition = offsettedTargetScrollPosition;
|
|
322
|
+
}
|
|
323
|
+
slider.emit('programmaticScrollStart');
|
|
234
324
|
slider.container.style.scrollBehavior = slider.options.scrollBehavior;
|
|
235
325
|
slider.container.scrollLeft = targetScrollPosition;
|
|
236
326
|
setTimeout(() => slider.container.style.scrollBehavior = '', 50);
|
|
237
327
|
}
|
|
328
|
+
function snapToClosestSlide(direction = "prev") {
|
|
329
|
+
const isMovingForward = direction === 'next';
|
|
330
|
+
const slideReference = [];
|
|
331
|
+
for (let i = 0; i < slider.slides.length; i++) {
|
|
332
|
+
const slide = slider.slides[i];
|
|
333
|
+
const slideWidth = slide.offsetWidth;
|
|
334
|
+
const slideStart = slide.offsetLeft;
|
|
335
|
+
const slideEnd = slideStart + slideWidth;
|
|
336
|
+
const slideMiddle = slideStart + slideWidth / 2;
|
|
337
|
+
const trigger = Math.min(slideMiddle, slideStart + slider.options.emulateScrollSnapMaxThreshold);
|
|
338
|
+
slideReference.push({
|
|
339
|
+
start: slideStart,
|
|
340
|
+
middle: slideMiddle,
|
|
341
|
+
end: slideEnd,
|
|
342
|
+
width: slideWidth,
|
|
343
|
+
trigger: trigger,
|
|
344
|
+
slide: slide,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
let snapTarget = null;
|
|
348
|
+
const scrollPosition = slider.container.scrollLeft;
|
|
349
|
+
if (isMovingForward) {
|
|
350
|
+
for (let i = 0; i < slideReference.length; i++) {
|
|
351
|
+
const item = slideReference[i];
|
|
352
|
+
if (i === 0 && scrollPosition <= item.trigger) {
|
|
353
|
+
snapTarget = 0;
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
if (slider.container.scrollLeft <= item.trigger) {
|
|
357
|
+
snapTarget = item.start;
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
for (let i = slideReference.length - 1; i >= 0; i--) {
|
|
364
|
+
const item = slideReference[i];
|
|
365
|
+
if (i === slideReference.length - 1 && scrollPosition >= item.trigger) {
|
|
366
|
+
snapTarget = item.start;
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
if (slider.container.scrollLeft >= item.trigger) {
|
|
370
|
+
snapTarget = item.start;
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
if (snapTarget !== null) {
|
|
376
|
+
const offsettedSnapTarget = snapTarget - getLeftOffset();
|
|
377
|
+
if (offsettedSnapTarget >= 0) {
|
|
378
|
+
snapTarget = offsettedSnapTarget;
|
|
379
|
+
}
|
|
380
|
+
const scrollBehavior = slider.options.scrollBehavior || 'smooth';
|
|
381
|
+
slider.container.scrollTo({
|
|
382
|
+
left: snapTarget,
|
|
383
|
+
behavior: scrollBehavior
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}
|
|
238
387
|
function on(name, cb) {
|
|
239
388
|
if (!subs[name]) {
|
|
240
389
|
subs[name] = [];
|
|
@@ -257,6 +406,7 @@ function Slider(container, options, plugins) {
|
|
|
257
406
|
emit,
|
|
258
407
|
moveToDirection,
|
|
259
408
|
moveToSlide,
|
|
409
|
+
snapToClosestSlide,
|
|
260
410
|
on,
|
|
261
411
|
options,
|
|
262
412
|
};
|
package/dist/core/slider.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
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};
|
package/dist/overflow-slider.css
CHANGED
|
@@ -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%}
|
|
@@ -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.
|
|
24
|
-
const
|
|
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 ===
|
|
35
|
-
dot.setAttribute('data-
|
|
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
|
|
43
|
-
if (!
|
|
42
|
+
const currentItemItem = dots.querySelector(`[aria-pressed="true"]`);
|
|
43
|
+
if (!currentItemItem) {
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
-
const
|
|
46
|
+
const currentItem = parseInt((_a = currentItemItem.getAttribute('data-item')) !== null && _a !== void 0 ? _a : '1');
|
|
47
47
|
if (e.key === 'ArrowLeft') {
|
|
48
|
-
const previousPage =
|
|
48
|
+
const previousPage = currentItem - 1;
|
|
49
49
|
if (previousPage > 0) {
|
|
50
|
-
const matchingDot = dots.querySelector(`[data-
|
|
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 =
|
|
58
|
+
const nextPage = currentItem + 1;
|
|
59
59
|
if (nextPage <= pages) {
|
|
60
|
-
const matchingDot = dots.querySelector(`[data-
|
|
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-
|
|
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 = (
|
|
79
|
-
const scrollTargetPosition = slider.details.containerWidth * (page - 1);
|
|
80
|
-
slider.container.style.scrollBehavior = slider.options.scrollBehavior;
|
|
81
|
-
slider.container.
|
|
82
|
-
slider.container.
|
|
83
|
-
slider.
|
|
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('
|
|
94
|
-
|
|
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
|
|
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};
|
|
@@ -8,9 +8,13 @@ function DragScrollingPlugin(args) {
|
|
|
8
8
|
let isMouseDown = false;
|
|
9
9
|
let startX = 0;
|
|
10
10
|
let scrollLeft = 0;
|
|
11
|
+
let isMovingForward = false;
|
|
12
|
+
let programmaticScrollStarted = false;
|
|
13
|
+
let mayNeedToSnap = false;
|
|
11
14
|
// add data attribute to container
|
|
12
15
|
slider.container.setAttribute('data-has-drag-scrolling', 'true');
|
|
13
16
|
const mouseDown = (e) => {
|
|
17
|
+
programmaticScrollStarted = false;
|
|
14
18
|
if (!slider.details.hasOverflow) {
|
|
15
19
|
return;
|
|
16
20
|
}
|
|
@@ -22,7 +26,6 @@ function DragScrollingPlugin(args) {
|
|
|
22
26
|
scrollLeft = slider.container.scrollLeft;
|
|
23
27
|
// change cursor to grabbing
|
|
24
28
|
slider.container.style.cursor = 'grabbing';
|
|
25
|
-
slider.container.style.scrollSnapType = 'none';
|
|
26
29
|
slider.container.style.scrollBehavior = 'auto';
|
|
27
30
|
// prevent focus going to the slides
|
|
28
31
|
e.preventDefault();
|
|
@@ -30,15 +33,26 @@ function DragScrollingPlugin(args) {
|
|
|
30
33
|
};
|
|
31
34
|
const mouseMove = (e) => {
|
|
32
35
|
if (!slider.details.hasOverflow) {
|
|
36
|
+
programmaticScrollStarted = false;
|
|
33
37
|
return;
|
|
34
38
|
}
|
|
35
39
|
if (!isMouseDown) {
|
|
40
|
+
programmaticScrollStarted = false;
|
|
36
41
|
return;
|
|
37
42
|
}
|
|
38
43
|
e.preventDefault();
|
|
44
|
+
if (!programmaticScrollStarted) {
|
|
45
|
+
programmaticScrollStarted = true;
|
|
46
|
+
slider.emit('programmaticScrollStart');
|
|
47
|
+
}
|
|
39
48
|
const x = e.pageX - slider.container.offsetLeft;
|
|
40
49
|
const walk = (x - startX);
|
|
41
|
-
|
|
50
|
+
const newScrollLeft = scrollLeft - walk;
|
|
51
|
+
mayNeedToSnap = true;
|
|
52
|
+
if (slider.container.scrollLeft !== newScrollLeft) {
|
|
53
|
+
isMovingForward = slider.container.scrollLeft < newScrollLeft;
|
|
54
|
+
}
|
|
55
|
+
slider.container.scrollLeft = newScrollLeft;
|
|
42
56
|
const absWalk = Math.abs(walk);
|
|
43
57
|
const slides = slider.container.querySelectorAll(slider.options.slidesSelector);
|
|
44
58
|
const pointerEvents = absWalk > options.draggedDistanceThatPreventsClick ? 'none' : '';
|
|
@@ -48,12 +62,13 @@ function DragScrollingPlugin(args) {
|
|
|
48
62
|
};
|
|
49
63
|
const mouseUp = () => {
|
|
50
64
|
if (!slider.details.hasOverflow) {
|
|
65
|
+
programmaticScrollStarted = false;
|
|
51
66
|
return;
|
|
52
67
|
}
|
|
53
68
|
isMouseDown = false;
|
|
54
69
|
slider.container.style.cursor = '';
|
|
55
70
|
setTimeout(() => {
|
|
56
|
-
|
|
71
|
+
programmaticScrollStarted = false;
|
|
57
72
|
slider.container.style.scrollBehavior = '';
|
|
58
73
|
const slides = slider.container.querySelectorAll(slider.options.slidesSelector);
|
|
59
74
|
slides.forEach((slide) => {
|
|
@@ -64,6 +79,18 @@ function DragScrollingPlugin(args) {
|
|
|
64
79
|
window.addEventListener('mousedown', mouseDown);
|
|
65
80
|
window.addEventListener('mousemove', mouseMove);
|
|
66
81
|
window.addEventListener('mouseup', mouseUp);
|
|
82
|
+
// emulate scroll snapping
|
|
83
|
+
if (slider.options.emulateScrollSnap) {
|
|
84
|
+
const snap = () => {
|
|
85
|
+
if (!mayNeedToSnap || isMouseDown) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
mayNeedToSnap = false;
|
|
89
|
+
slider.snapToClosestSlide(isMovingForward ? 'next' : 'prev');
|
|
90
|
+
};
|
|
91
|
+
slider.on('programmaticScrollEnd', snap);
|
|
92
|
+
window.addEventListener('mouseup', snap);
|
|
93
|
+
}
|
|
67
94
|
};
|
|
68
95
|
}
|
|
69
96
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e){var t;const
|
|
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};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
function FadePlugin(args) {
|
|
2
|
+
return (slider) => {
|
|
3
|
+
var _a, _b, _c;
|
|
4
|
+
const options = {
|
|
5
|
+
classNames: {
|
|
6
|
+
fadeItem: 'overflow-slider-fade',
|
|
7
|
+
fadeItemStart: 'overflow-slider-fade--start',
|
|
8
|
+
fadeItemEnd: 'overflow-slider-fade--end',
|
|
9
|
+
},
|
|
10
|
+
container: (_a = args === null || args === void 0 ? void 0 : args.container) !== null && _a !== void 0 ? _a : null,
|
|
11
|
+
containerStart: (_b = args === null || args === void 0 ? void 0 : args.containerStart) !== null && _b !== void 0 ? _b : null,
|
|
12
|
+
containerEnd: (_c = args === null || args === void 0 ? void 0 : args.containerEnd) !== null && _c !== void 0 ? _c : null,
|
|
13
|
+
};
|
|
14
|
+
const fadeItemStart = document.createElement('div');
|
|
15
|
+
fadeItemStart.classList.add(options.classNames.fadeItem, options.classNames.fadeItemStart);
|
|
16
|
+
fadeItemStart.setAttribute('aria-hidden', 'true');
|
|
17
|
+
fadeItemStart.setAttribute('tabindex', '-1');
|
|
18
|
+
const fadeItemEnd = document.createElement('div');
|
|
19
|
+
fadeItemEnd.classList.add(options.classNames.fadeItem, options.classNames.fadeItemEnd);
|
|
20
|
+
fadeItemEnd.setAttribute('aria-hidden', 'true');
|
|
21
|
+
fadeItemEnd.setAttribute('tabindex', '-1');
|
|
22
|
+
if (options.containerStart) {
|
|
23
|
+
options.containerStart.appendChild(fadeItemStart);
|
|
24
|
+
}
|
|
25
|
+
else if (options.container) {
|
|
26
|
+
options.container.appendChild(fadeItemStart);
|
|
27
|
+
}
|
|
28
|
+
if (options.containerEnd) {
|
|
29
|
+
options.containerEnd.appendChild(fadeItemEnd);
|
|
30
|
+
}
|
|
31
|
+
else if (options.container) {
|
|
32
|
+
options.container.appendChild(fadeItemEnd);
|
|
33
|
+
}
|
|
34
|
+
const hasFadeAtStart = () => {
|
|
35
|
+
return slider.container.scrollLeft > fadeItemStart.offsetWidth;
|
|
36
|
+
};
|
|
37
|
+
const fadeAtStartOpacity = () => {
|
|
38
|
+
const position = slider.container.scrollLeft;
|
|
39
|
+
if (position <= fadeItemStart.offsetWidth) {
|
|
40
|
+
return position / Math.max(fadeItemStart.offsetWidth, 1);
|
|
41
|
+
}
|
|
42
|
+
return 1;
|
|
43
|
+
};
|
|
44
|
+
const hasFadeAtEnd = () => {
|
|
45
|
+
return slider.container.scrollLeft < (slider.container.scrollWidth - slider.container.clientWidth - fadeItemEnd.offsetWidth);
|
|
46
|
+
};
|
|
47
|
+
const fadeAtEndOpacity = () => {
|
|
48
|
+
const position = slider.container.scrollLeft;
|
|
49
|
+
const maxPosition = slider.container.scrollWidth - slider.container.clientWidth;
|
|
50
|
+
const maxFadePosition = maxPosition - fadeItemEnd.offsetWidth;
|
|
51
|
+
if (position >= maxFadePosition) {
|
|
52
|
+
return ((maxFadePosition - position) / Math.max(fadeItemEnd.offsetWidth, 1)) + 1;
|
|
53
|
+
}
|
|
54
|
+
return 1;
|
|
55
|
+
};
|
|
56
|
+
const update = () => {
|
|
57
|
+
fadeItemStart.setAttribute('data-has-fade', hasFadeAtStart().toString());
|
|
58
|
+
fadeItemStart.style.opacity = fadeAtStartOpacity().toString();
|
|
59
|
+
fadeItemEnd.setAttribute('data-has-fade', hasFadeAtEnd().toString());
|
|
60
|
+
fadeItemEnd.style.opacity = fadeAtEndOpacity().toString();
|
|
61
|
+
};
|
|
62
|
+
update();
|
|
63
|
+
slider.on('created', update);
|
|
64
|
+
slider.on('contentsChanged', update);
|
|
65
|
+
slider.on('containerSizeChanged', update);
|
|
66
|
+
slider.on('scrollEnd', update);
|
|
67
|
+
slider.on('scrollStart', update);
|
|
68
|
+
let requestId = 0;
|
|
69
|
+
const debouncedUpdate = () => {
|
|
70
|
+
if (requestId) {
|
|
71
|
+
window.cancelAnimationFrame(requestId);
|
|
72
|
+
}
|
|
73
|
+
requestId = window.requestAnimationFrame(() => {
|
|
74
|
+
update();
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
slider.on('scroll', debouncedUpdate);
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { FadePlugin as default };
|
|
@@ -0,0 +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};
|
|
@@ -21,6 +21,7 @@ function FullWidthPlugin(args) {
|
|
|
21
21
|
if (options.addMarginAfter) {
|
|
22
22
|
lastSlide.style.marginRight = `${marginAmount}px`;
|
|
23
23
|
}
|
|
24
|
+
slider.container.setAttribute('data-full-width-offset', marginAmount.toString());
|
|
24
25
|
};
|
|
25
26
|
update();
|
|
26
27
|
slider.on('contentsChanged', update);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const t=t=>{var n,e;return null!==(e=null===(n=t.container.parentElement)||void 0===n?void 0:n.offsetWidth)&&void 0!==e?e:window.innerWidth};function n(n){return e=>{var i,r,o;const d={targetWidth:null!==(i=null==n?void 0:n.targetWidth)&&void 0!==i?i:t,addMarginBefore:null===(r=null==n?void 0:n.addMarginBefore)||void 0===r||r,addMarginAfter:null===(o=null==n?void 0:n.addMarginAfter)||void 0===o||o},a=()=>{const t=e.container.querySelectorAll(e.options.slidesSelector);if(!t.length)return;const n=t[0],i=t[t.length-1],r=Math.floor((window.innerWidth-d.targetWidth(e))/2);d.addMarginBefore&&(n.style.marginLeft=`${r}px`),d.addMarginAfter&&(i.style.marginRight=`${r}px`),e.container.setAttribute("data-full-width-offset",r.toString())};a(),e.on("contentsChanged",a),e.on("containerSizeChanged",a)}}export{n as default};
|