@evermade/overflow-slider 4.0.0 → 4.2.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 (58) hide show
  1. package/README.md +50 -5
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.esm.js +39 -3
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.min.js +1 -1
  6. package/dist/index.min.js.map +1 -1
  7. package/dist/plugins/arrows/index.d.ts +1 -1
  8. package/dist/plugins/autoplay/index.d.ts +1 -1
  9. package/dist/plugins/classnames/index.d.ts +14 -0
  10. package/dist/plugins/classnames/index.esm.js +107 -0
  11. package/dist/plugins/classnames/index.min.js +1 -0
  12. package/dist/plugins/core/index.d.ts +10 -62
  13. package/dist/plugins/core/index.d2.ts +63 -10
  14. package/dist/plugins/dots/index.d.ts +2 -1
  15. package/dist/plugins/dots/index.esm.js +31 -19
  16. package/dist/plugins/dots/index.min.js +1 -1
  17. package/dist/plugins/drag-scrolling/index.d.ts +1 -1
  18. package/dist/plugins/fade/index.d.ts +1 -1
  19. package/dist/plugins/full-width/index.d.ts +2 -2
  20. package/dist/plugins/full-width/index.esm.js +36 -19
  21. package/dist/plugins/full-width/index.min.js +1 -1
  22. package/dist/plugins/scroll-indicator/index.d.ts +1 -1
  23. package/dist/plugins/skip-links/index.d.ts +1 -1
  24. package/dist/plugins/thumbnails/index.d.ts +1 -1
  25. package/docs/assets/demo.css +42 -0
  26. package/docs/assets/demo.js +62 -28
  27. package/docs/dist/index.d.ts +1 -1
  28. package/docs/dist/index.esm.js +39 -3
  29. package/docs/dist/index.esm.js.map +1 -1
  30. package/docs/dist/index.min.js +1 -1
  31. package/docs/dist/index.min.js.map +1 -1
  32. package/docs/dist/plugins/arrows/index.d.ts +1 -1
  33. package/docs/dist/plugins/autoplay/index.d.ts +1 -1
  34. package/docs/dist/plugins/classnames/index.d.ts +14 -0
  35. package/docs/dist/plugins/classnames/index.esm.js +107 -0
  36. package/docs/dist/plugins/classnames/index.min.js +1 -0
  37. package/docs/dist/plugins/core/index.d.ts +63 -10
  38. package/docs/dist/plugins/core/index.d2.ts +10 -62
  39. package/docs/dist/plugins/dots/index.d.ts +2 -1
  40. package/docs/dist/plugins/dots/index.esm.js +31 -19
  41. package/docs/dist/plugins/dots/index.min.js +1 -1
  42. package/docs/dist/plugins/drag-scrolling/index.d.ts +1 -1
  43. package/docs/dist/plugins/fade/index.d.ts +1 -1
  44. package/docs/dist/plugins/full-width/index.d.ts +2 -2
  45. package/docs/dist/plugins/full-width/index.esm.js +36 -19
  46. package/docs/dist/plugins/full-width/index.min.js +1 -1
  47. package/docs/dist/plugins/infinite-scroll/index.d.ts +1 -1
  48. package/docs/dist/plugins/scroll-indicator/index.d.ts +1 -1
  49. package/docs/dist/plugins/skip-links/index.d.ts +1 -1
  50. package/docs/dist/plugins/thumbnails/index.d.ts +1 -1
  51. package/docs/index.html +39 -17
  52. package/package.json +6 -6
  53. package/src/core/slider.ts +42 -4
  54. package/src/core/types.ts +1 -0
  55. package/src/plugins/classnames/index.ts +145 -0
  56. package/src/plugins/dots/index.ts +28 -16
  57. package/src/plugins/full-width/index.ts +41 -21
  58. package/src/plugins/infinite-scroll/index.ts +0 -109
@@ -7,11 +7,12 @@ const DEFAULT_CLASS_NAMES = {
7
7
  };
8
8
  function DotsPlugin(args) {
9
9
  return (slider) => {
10
- var _a, _b;
10
+ var _a, _b, _c;
11
11
  const options = {
12
+ type: (_a = args === null || args === void 0 ? void 0 : args.type) !== null && _a !== void 0 ? _a : 'slide',
12
13
  texts: Object.assign(Object.assign({}, DEFAULT_TEXTS), (args === null || args === void 0 ? void 0 : args.texts) || []),
13
14
  classNames: Object.assign(Object.assign({}, DEFAULT_CLASS_NAMES), (args === null || args === void 0 ? void 0 : args.classNames) || []),
14
- container: (_a = args === null || args === void 0 ? void 0 : args.container) !== null && _a !== void 0 ? _a : null,
15
+ container: (_b = args === null || args === void 0 ? void 0 : args.container) !== null && _b !== void 0 ? _b : null,
15
16
  };
16
17
  const dots = document.createElement('div');
17
18
  dots.classList.add(options.classNames.dotsContainer);
@@ -20,18 +21,18 @@ function DotsPlugin(args) {
20
21
  dots.setAttribute('data-has-content', slider.details.hasOverflow.toString());
21
22
  dots.innerHTML = '';
22
23
  const dotsList = document.createElement('ul');
23
- const pages = slider.details.slideCount;
24
- const currentItem = slider.activeSlideIdx;
25
- if (pages <= 1) {
24
+ const count = options.type === 'view' ? slider.details.amountOfPages : slider.details.slideCount;
25
+ const currentIndex = options.type === 'view' ? slider.details.currentPage : slider.activeSlideIdx;
26
+ if (count <= 1) {
26
27
  return;
27
28
  }
28
- for (let i = 0; i < pages; i++) {
29
+ for (let i = 0; i < count; i++) {
29
30
  const dotListItem = document.createElement('li');
30
31
  const dot = document.createElement('button');
31
32
  dot.setAttribute('type', 'button');
32
33
  dot.setAttribute('class', options.classNames.dotsItem);
33
- dot.setAttribute('aria-label', options.texts.dotDescription.replace('%d', (i + 1).toString()).replace('%d', pages.toString()));
34
- dot.setAttribute('aria-pressed', (i === currentItem).toString());
34
+ dot.setAttribute('aria-label', options.texts.dotDescription.replace('%d', (i + 1).toString()).replace('%d', count.toString()));
35
+ dot.setAttribute('aria-pressed', (i === currentIndex).toString());
35
36
  dot.setAttribute('data-item', (i + 1).toString());
36
37
  dotListItem.appendChild(dot);
37
38
  dotsList.appendChild(dotListItem);
@@ -45,23 +46,23 @@ function DotsPlugin(args) {
45
46
  }
46
47
  const currentItem = parseInt((_a = currentItemItem.getAttribute('data-item')) !== null && _a !== void 0 ? _a : '1');
47
48
  if (e.key === 'ArrowLeft') {
48
- const previousPage = currentItem - 1;
49
- if (previousPage > 0) {
50
- const matchingDot = dots.querySelector(`[data-item="${previousPage}"]`);
49
+ const previousIndex = currentItem - 1;
50
+ if (previousIndex > 0) {
51
+ const matchingDot = dots.querySelector(`[data-item="${previousIndex}"]`);
51
52
  if (matchingDot) {
52
53
  matchingDot.focus();
53
54
  }
54
- activateDot(previousPage);
55
+ activateDot(previousIndex);
55
56
  }
56
57
  }
57
58
  if (e.key === 'ArrowRight') {
58
- const nextPage = currentItem + 1;
59
- if (nextPage <= pages) {
60
- const matchingDot = dots.querySelector(`[data-item="${nextPage}"]`);
59
+ const nextIndex = currentItem + 1;
60
+ if (nextIndex <= count) {
61
+ const matchingDot = dots.querySelector(`[data-item="${nextIndex}"]`);
61
62
  if (matchingDot) {
62
63
  matchingDot.focus();
63
64
  }
64
- activateDot(nextPage);
65
+ activateDot(nextIndex);
65
66
  }
66
67
  }
67
68
  });
@@ -75,19 +76,30 @@ function DotsPlugin(args) {
75
76
  }
76
77
  }
77
78
  };
78
- const activateDot = (item) => {
79
- slider.moveToSlide(item - 1);
79
+ const activateDot = (index) => {
80
+ if (options.type === 'view') {
81
+ const targetPosition = slider.details.containerWidth * (index - 1);
82
+ const scrollLeft = slider.options.rtl ? -targetPosition : targetPosition;
83
+ slider.container.scrollTo({
84
+ left: scrollLeft,
85
+ behavior: slider.options.scrollBehavior
86
+ });
87
+ }
88
+ else {
89
+ slider.moveToSlide(index - 1);
90
+ }
80
91
  };
81
92
  buildDots();
82
93
  if (options.container) {
83
94
  options.container.appendChild(dots);
84
95
  }
85
96
  else {
86
- (_b = slider.container.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(dots, slider.container.nextSibling);
97
+ (_c = slider.container.parentNode) === null || _c === void 0 ? void 0 : _c.insertBefore(dots, slider.container.nextSibling);
87
98
  }
88
99
  slider.on('scrollEnd', buildDots);
89
100
  slider.on('contentsChanged', buildDots);
90
101
  slider.on('containerSizeChanged', buildDots);
102
+ slider.on('detailsChanged', buildDots);
91
103
  };
92
104
  }
93
105
 
@@ -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 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};
1
+ const t={dotDescription:"Page %d of %d"},e={dotsContainer:"overflow-slider__dots",dotsItem:"overflow-slider__dot-item"};function n(n){return i=>{var o,s,a;const r={type:null!==(o=null==n?void 0:n.type)&&void 0!==o?o:"slide",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!==(s=null==n?void 0:n.container)&&void 0!==s?s:null},l=document.createElement("div");l.classList.add(r.classNames.dotsContainer);let d=null;const c=()=>{l.setAttribute("data-has-content",i.details.hasOverflow.toString()),l.innerHTML="";const t=document.createElement("ul"),e="view"===r.type?i.details.amountOfPages:i.details.slideCount,n="view"===r.type?i.details.currentPage:i.activeSlideIdx;if(!(e<=1)){for(let i=0;i<e;i++){const o=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",(i+1).toString()).replace("%d",e.toString())),s.setAttribute("aria-pressed",(i===n).toString()),s.setAttribute("data-item",(i+1).toString()),o.appendChild(s),t.appendChild(o),s.addEventListener("click",()=>u(i+1)),s.addEventListener("focus",()=>d=i+1),s.addEventListener("keydown",t=>{var n;const i=l.querySelector('[aria-pressed="true"]');if(!i)return;const o=parseInt(null!==(n=i.getAttribute("data-item"))&&void 0!==n?n:"1");if("ArrowLeft"===t.key){const t=o-1;if(t>0){const e=l.querySelector(`[data-item="${t}"]`);e&&e.focus(),u(t)}}if("ArrowRight"===t.key){const t=o+1;if(t<=e){const e=l.querySelector(`[data-item="${t}"]`);e&&e.focus(),u(t)}}})}if(l.appendChild(t),d){const t=l.querySelector(`[data-item="${d}"]`);t&&t.focus()}}},u=t=>{if("view"===r.type){const e=i.details.containerWidth*(t-1),n=i.options.rtl?-e:e;i.container.scrollTo({left:n,behavior:i.options.scrollBehavior})}else i.moveToSlide(t-1)};c(),r.container?r.container.appendChild(l):null===(a=i.container.parentNode)||void 0===a||a.insertBefore(l,i.container.nextSibling),i.on("scrollEnd",c),i.on("contentsChanged",c),i.on("containerSizeChanged",c),i.on("detailsChanged",c)}}export{n as default};
@@ -1,4 +1,4 @@
1
- import { DeepPartial, Slider } from '../core/index.js';
1
+ import { DeepPartial, Slider } from '../core/index.d2.ts';
2
2
 
3
3
  type DragScrollingOptions = {
4
4
  draggedDistanceThatPreventsClick: number;
@@ -1,4 +1,4 @@
1
- import { DeepPartial, Slider } from '../core/index.js';
1
+ import { DeepPartial, Slider } from '../core/index.d2.ts';
2
2
 
3
3
  type FadeOptions = {
4
4
  classNames: {
@@ -1,7 +1,7 @@
1
- import { DeepPartial, Slider } from '../core/index.js';
1
+ import { DeepPartial, Slider } from '../core/index.d2.ts';
2
2
 
3
3
  type FullWidthOptions = {
4
- targetWidth: (slider: Slider) => number;
4
+ targetWidth?: (slider: Slider) => number;
5
5
  addMarginBefore: boolean;
6
6
  addMarginAfter: boolean;
7
7
  };
@@ -1,42 +1,59 @@
1
1
  const DEFAULT_TARGET_WIDTH = (slider) => { var _a, _b; return (_b = (_a = slider.container.parentElement) === null || _a === void 0 ? void 0 : _a.offsetWidth) !== null && _b !== void 0 ? _b : window.innerWidth; };
2
2
  function FullWidthPlugin(args) {
3
3
  return (slider) => {
4
- var _a, _b, _c;
4
+ var _a, _b, _c, _d;
5
5
  const options = {
6
- targetWidth: (_a = args === null || args === void 0 ? void 0 : args.targetWidth) !== null && _a !== void 0 ? _a : null,
6
+ targetWidth: (_a = args === null || args === void 0 ? void 0 : args.targetWidth) !== null && _a !== void 0 ? _a : undefined,
7
7
  addMarginBefore: (_b = args === null || args === void 0 ? void 0 : args.addMarginBefore) !== null && _b !== void 0 ? _b : true,
8
8
  addMarginAfter: (_c = args === null || args === void 0 ? void 0 : args.addMarginAfter) !== null && _c !== void 0 ? _c : true,
9
9
  };
10
+ if (typeof slider.options.targetWidth !== 'function') {
11
+ slider.options.targetWidth = (_d = options.targetWidth) !== null && _d !== void 0 ? _d : DEFAULT_TARGET_WIDTH;
12
+ }
13
+ const resolveTargetWidth = () => {
14
+ var _a;
15
+ if (typeof slider.options.targetWidth === 'function') {
16
+ return slider.options.targetWidth;
17
+ }
18
+ return (_a = options.targetWidth) !== null && _a !== void 0 ? _a : DEFAULT_TARGET_WIDTH;
19
+ };
10
20
  const update = () => {
11
21
  const slides = slider.container.querySelectorAll(slider.options.slidesSelector);
12
22
  if (!slides.length) {
13
23
  return;
14
24
  }
25
+ const targetWidthFn = resolveTargetWidth();
26
+ const rawMargin = (window.innerWidth - targetWidthFn(slider)) / 2;
27
+ const marginAmount = Math.max(0, Math.floor(rawMargin));
28
+ const marginValue = marginAmount ? `${marginAmount}px` : '';
29
+ slides.forEach((slide) => {
30
+ const element = slide;
31
+ element.style.marginInlineStart = '';
32
+ element.style.marginInlineEnd = '';
33
+ });
15
34
  const firstSlide = slides[0];
16
35
  const lastSlide = slides[slides.length - 1];
17
- const marginAmount = Math.floor((window.innerWidth - getTargetWidth()) / 2);
18
36
  if (options.addMarginBefore) {
19
- firstSlide.style.marginInlineStart = `${marginAmount}px`;
37
+ firstSlide.style.marginInlineStart = marginValue;
38
+ slider.container.style.setProperty('scroll-padding-inline-start', marginValue || '0px');
20
39
  }
21
- if (options.addMarginAfter) {
22
- lastSlide.style.marginInlineEnd = `${marginAmount}px`;
40
+ else {
41
+ slider.container.style.removeProperty('scroll-padding-inline-start');
23
42
  }
24
- slider.container.setAttribute('data-full-width-offset', marginAmount.toString());
25
- setCSS();
26
- };
27
- const getTargetWidth = () => {
28
- if (typeof options.targetWidth === 'function') {
29
- return options.targetWidth(slider);
43
+ if (options.addMarginAfter) {
44
+ lastSlide.style.marginInlineEnd = marginValue;
45
+ slider.container.style.setProperty('scroll-padding-inline-end', marginValue || '0px');
30
46
  }
31
- if (typeof slider.options.targetWidth === 'function') {
32
- return slider.options.targetWidth(slider);
47
+ else {
48
+ slider.container.style.removeProperty('scroll-padding-inline-end');
33
49
  }
34
- return DEFAULT_TARGET_WIDTH(slider);
50
+ slider.container.setAttribute('data-full-width-offset', `${marginAmount}`);
51
+ setCSS(targetWidthFn);
52
+ slider.emit('fullWidthPluginUpdate');
35
53
  };
36
- const setCSS = () => {
37
- if (typeof slider.options.targetWidth === 'function') {
38
- slider.options.cssVariableContainer.style.setProperty('--slider-container-target-width', `${getTargetWidth()}px`);
39
- }
54
+ const setCSS = (targetWidthFn) => {
55
+ const width = targetWidthFn(slider);
56
+ slider.options.cssVariableContainer.style.setProperty('--slider-container-target-width', `${width}px`);
40
57
  };
41
58
  update();
42
59
  slider.on('contentsChanged', update);
@@ -1 +1 @@
1
- function t(t){return n=>{var e,i,o;const r={targetWidth:null!==(e=null==t?void 0:t.targetWidth)&&void 0!==e?e:null,addMarginBefore:null===(i=null==t?void 0:t.addMarginBefore)||void 0===i||i,addMarginAfter:null===(o=null==t?void 0:t.addMarginAfter)||void 0===o||o},d=()=>{const t=n.container.querySelectorAll(n.options.slidesSelector);if(!t.length)return;const e=t[0],i=t[t.length-1],o=Math.floor((window.innerWidth-a())/2);r.addMarginBefore&&(e.style.marginInlineStart=`${o}px`),r.addMarginAfter&&(i.style.marginInlineEnd=`${o}px`),n.container.setAttribute("data-full-width-offset",o.toString()),l()},a=()=>"function"==typeof r.targetWidth?r.targetWidth(n):"function"==typeof n.options.targetWidth?n.options.targetWidth(n):(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})(n),l=()=>{"function"==typeof n.options.targetWidth&&n.options.cssVariableContainer.style.setProperty("--slider-container-target-width",`${a()}px`)};d(),n.on("contentsChanged",d),n.on("containerSizeChanged",d),window.addEventListener("resize",d)}}export{t as default};
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,d;const l={targetWidth:null!==(i=null==n?void 0:n.targetWidth)&&void 0!==i?i:void 0,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};"function"!=typeof e.options.targetWidth&&(e.options.targetWidth=null!==(d=l.targetWidth)&&void 0!==d?d:t);const a=()=>{const n=e.container.querySelectorAll(e.options.slidesSelector);if(!n.length)return;const i=(()=>{var n;return"function"==typeof e.options.targetWidth?e.options.targetWidth:null!==(n=l.targetWidth)&&void 0!==n?n:t})(),r=(window.innerWidth-i(e))/2,o=Math.max(0,Math.floor(r)),d=o?`${o}px`:"";n.forEach(t=>{const n=t;n.style.marginInlineStart="",n.style.marginInlineEnd=""});const a=n[0],c=n[n.length-1];l.addMarginBefore?(a.style.marginInlineStart=d,e.container.style.setProperty("scroll-padding-inline-start",d||"0px")):e.container.style.removeProperty("scroll-padding-inline-start"),l.addMarginAfter?(c.style.marginInlineEnd=d,e.container.style.setProperty("scroll-padding-inline-end",d||"0px")):e.container.style.removeProperty("scroll-padding-inline-end"),e.container.setAttribute("data-full-width-offset",`${o}`),s(i),e.emit("fullWidthPluginUpdate")},s=t=>{const n=t(e);e.options.cssVariableContainer.style.setProperty("--slider-container-target-width",`${n}px`)};a(),e.on("contentsChanged",a),e.on("containerSizeChanged",a),window.addEventListener("resize",a)}}export{n as default};
@@ -1,4 +1,4 @@
1
- import { DeepPartial, Slider } from '../core/index.js';
1
+ import { DeepPartial, Slider } from '../core/index.d2.ts';
2
2
 
3
3
  type ScrollIndicatorOptions = {
4
4
  classNames: {
@@ -1,4 +1,4 @@
1
- import { DeepPartial, Slider } from '../core/index.js';
1
+ import { DeepPartial, Slider } from '../core/index.d2.ts';
2
2
 
3
3
  type SkipLinkOptions = {
4
4
  texts: {
@@ -1,4 +1,4 @@
1
- import { DeepPartial, Slider } from '../core/index.js';
1
+ import { DeepPartial, Slider } from '../core/index.d2.ts';
2
2
 
3
3
  type ThumbnailsOptions = {
4
4
  mainSlider: Slider;
@@ -625,6 +625,46 @@ h3:before {
625
625
  height: 1.625rem !important;
626
626
  }
627
627
 
628
+ .example-container-1-classname-opacity .example-item {
629
+ transition: .5s ease-in-out;
630
+ }
631
+
632
+ .example-container-1-classname-opacity .is-visible {
633
+ opacity: 1;
634
+ }
635
+ .example-container-1-classname-opacity .is-hidden {
636
+ opacity: 0;
637
+ }
638
+
639
+ .example-container-1-classname-partly {
640
+ width: 100vw;
641
+ margin-inline-start: calc(-50vw + 50%);
642
+ scroll-snap-type: x mandatory;
643
+ }
644
+
645
+ @media (min-width: 768px) {
646
+ .example-container-1-classname-partly .example-item {
647
+ width: calc( ( var( --slider-container-target-width ) / 4 ) - ( 3 / 4 * var( --slide-gap ) ) );
648
+ }
649
+
650
+ .example-container-1-classname-partly .example-item {
651
+ transition: .2s ease-in-out;
652
+ }
653
+
654
+ .example-container-1-classname-partly .is-visible {
655
+ opacity: 1;
656
+ /* transform: scale(1); */
657
+ }
658
+
659
+ .example-container-1-classname-partly .is-partly-visible {
660
+ opacity: .5;
661
+ /* transform: scale(0.85); */
662
+ }
663
+ .example-container-1-classname-partly .is-hidden {
664
+ opacity: .2;
665
+ /* transform: scale(0); */
666
+ }
667
+
628
668
  /* ===========================================================================
629
669
  Example 4: Filters
630
670
  =========================================================================== */
@@ -722,6 +762,7 @@ h3:before {
722
762
  .example-container-4-full-width {
723
763
  width: 100vw;
724
764
  margin-inline-start: calc(-50vw + 50%);
765
+ scroll-snap-type: x mandatory;
725
766
  }
726
767
 
727
768
  /* ===========================================================================
@@ -776,6 +817,7 @@ h3:before {
776
817
  .example-container-4-hero {
777
818
  --slider-gap: 0;
778
819
  gap: 0;
820
+ scroll-snap-type: x mandatory;
779
821
  }
780
822
 
781
823
  .example-container-4-hero > * {
@@ -20,7 +20,8 @@ import DotsPlugin from '../dist/plugins/dots/index.esm.js';
20
20
  import FullWidthPlugin from '../dist/plugins/full-width/index.esm.js';
21
21
  import ThumbnailsPlugin from '../dist/plugins/thumbnails/index.esm.js';
22
22
  import FadePlugin from '../dist/plugins/fade/index.esm.js';
23
- // import InfiniteScrollPlugin from '../dist/plugins/infinite-scroll/index.esm.js';
23
+ import ClassNamesPlugin from '../dist/plugins/classnames/index.esm.js';
24
+
24
25
 
25
26
  (function () {
26
27
  const init = () => {
@@ -120,6 +121,24 @@ import FadePlugin from '../dist/plugins/fade/index.esm.js';
120
121
  );
121
122
  console.log( '1-dots', example1Dots );
122
123
 
124
+ const example1DotsView = new OverflowSlider(
125
+ document.querySelector( '.example-container-1-dots-view' ),
126
+ {
127
+ emulateScrollSnap: true,
128
+ rtl: document.documentElement.dir === 'rtl',
129
+ },
130
+ [
131
+ DragScrollingPlugin(),
132
+ SkipLinksPlugin(),
133
+ DotsPlugin(
134
+ {
135
+ type: 'view',
136
+ }
137
+ ),
138
+ ]
139
+ );
140
+ console.log( '1-dots-view', example1DotsView );
141
+
123
142
  const example1Fade = new OverflowSlider(
124
143
  document.querySelector( '.example-container-1-fade' ),
125
144
  {
@@ -135,6 +154,43 @@ import FadePlugin from '../dist/plugins/fade/index.esm.js';
135
154
  );
136
155
  console.log( '1-fade', example1Fade );
137
156
 
157
+ const example1ClassNames = new OverflowSlider(
158
+ document.querySelector( '.example-container-1-classname-opacity' ),
159
+ {
160
+ emulateScrollSnap: true,
161
+ rtl: document.documentElement.dir === 'rtl',
162
+ },
163
+ [
164
+ DragScrollingPlugin(),
165
+ ClassNamesPlugin(),
166
+ ]
167
+ );
168
+ console.log( '1-classname-opacity', example1ClassNames );
169
+
170
+ const example1ClassNamesPartly = new OverflowSlider(
171
+ document.querySelector( '.example-container-1-classname-partly' ),
172
+ {
173
+ emulateScrollSnap: true,
174
+ rtl: document.documentElement.dir === 'rtl',
175
+ targetWidth: (slider) => {
176
+ return slider.container.parentElement.clientWidth;
177
+ }
178
+ },
179
+ [
180
+ DragScrollingPlugin(),
181
+ FullWidthPlugin(),
182
+ ClassNamesPlugin(
183
+ {
184
+ classnames: {
185
+ partlyVisible: 'is-partly-visible',
186
+ },
187
+ freezeStateOnVisible: true,
188
+ }
189
+ ),
190
+ ]
191
+ );
192
+ console.log( '1-classname-partly', example1ClassNamesPartly );
193
+
138
194
  const example1AutoplaySlide = new OverflowSlider(
139
195
  document.querySelector( '.example-container-1-autoplay-slide' ),
140
196
  {
@@ -163,25 +219,6 @@ import FadePlugin from '../dist/plugins/fade/index.esm.js';
163
219
  );
164
220
  console.log( '1-autoplay-view', example1AutoplayView );
165
221
 
166
- // const example1Infinite = new OverflowSlider(
167
- // document.querySelector( '.example-container-1-infinite' ),
168
- // {
169
- // emulateScrollSnap: true,
170
- // rtl: document.documentElement.dir === 'rtl',
171
- // },
172
- // [
173
- // DragScrollingPlugin(),
174
- // AutoplayPlugin({
175
- // movementType: 'slide',
176
- // delayInMs: 1000,
177
- // // loop: false, // infinite should loop it
178
- // }),
179
- // ScrollIndicatorPlugin(),
180
- // InfiniteScrollPlugin(),
181
- // ]
182
- // );
183
- // console.log( '1-infinite', example1Infinite );
184
-
185
222
  const example2PerfectFit = new OverflowSlider(
186
223
  document.querySelector( '.example-container-2-perfect-fit' ),
187
224
  {
@@ -288,17 +325,14 @@ import FadePlugin from '../dist/plugins/fade/index.esm.js';
288
325
  document.querySelector( '.example-container-4-full-width' ),
289
326
  {
290
327
  rtl: document.documentElement.dir === 'rtl',
328
+ emulateScrollSnap: true,
329
+ targetWidth: (slider) => {
330
+ return slider.container.parentElement.clientWidth;
331
+ }
291
332
  },
292
333
  [
293
334
  DragScrollingPlugin(),
294
- FullWidthPlugin(
295
- {
296
- targetWidth: (slider) => {
297
- // copy the width of the parent element
298
- return slider.container.parentElement.clientWidth;
299
- }
300
- }
301
- ),
335
+ FullWidthPlugin(),
302
336
  ScrollIndicatorPlugin(),
303
337
  ]
304
338
  );
@@ -1 +1 @@
1
- export { default as OverflowSlider } from './plugins/core/index.js';
1
+ export { default as OverflowSlider } from './plugins/core/index.d2.ts';
@@ -74,6 +74,16 @@ function getOutermostChildrenEdgeMarginSum(el) {
74
74
  function Slider(container, options, plugins) {
75
75
  let slider;
76
76
  let subs = {};
77
+ const overrideTransitions = () => {
78
+ slider.slides.forEach((slide) => {
79
+ slide.style.transition = 'none';
80
+ });
81
+ };
82
+ const restoreTransitions = () => {
83
+ slider.slides.forEach((slide) => {
84
+ slide.style.removeProperty('transition');
85
+ });
86
+ };
77
87
  function init() {
78
88
  slider.container = container;
79
89
  // ensure container has id
@@ -83,6 +93,8 @@ function Slider(container, options, plugins) {
83
93
  container.setAttribute('id', containerId);
84
94
  }
85
95
  setSlides();
96
+ // CSS transitions can cause delays for calculations
97
+ overrideTransitions();
86
98
  setDetails(true);
87
99
  setActiveSlideIdx();
88
100
  slider.on('contentsChanged', () => {
@@ -109,12 +121,20 @@ function Slider(container, options, plugins) {
109
121
  for (const plugin of plugins) {
110
122
  plugin(slider);
111
123
  }
124
+ // plugins may mutate layout: refresh details and derived data after they run
125
+ // setTimeout( () => {
126
+ setDetails();
127
+ setActiveSlideIdx();
128
+ setCSSVariables();
129
+ slider.emit('pluginsLoaded');
130
+ // }, 250 );
112
131
  }
113
132
  slider.on('detailsChanged', () => {
114
133
  setDataAttributes();
115
134
  setCSSVariables();
116
135
  });
117
136
  slider.emit('created');
137
+ restoreTransitions();
118
138
  slider.container.setAttribute('data-ready', 'true');
119
139
  }
120
140
  function setDetails(isInit = false) {
@@ -515,14 +535,30 @@ function Slider(container, options, plugins) {
515
535
  // Get container rect once (includes any CSS transforms)
516
536
  const containerRect = container.getBoundingClientRect();
517
537
  const factor = rtl ? -1 : 1;
538
+ // Calculate target area offset if targetWidth is defined
539
+ let targetAreaOffset = 0;
540
+ if (typeof options.targetWidth === 'function') {
541
+ try {
542
+ const targetWidth = options.targetWidth(slider);
543
+ const containerWidth = containerRect.width;
544
+ if (Number.isFinite(targetWidth) && targetWidth > 0 && targetWidth < containerWidth) {
545
+ targetAreaOffset = (containerWidth - targetWidth) / 2;
546
+ }
547
+ }
548
+ catch (error) {
549
+ // ignore errors, use default offset of 0
550
+ }
551
+ }
518
552
  // Build slide metadata
519
553
  const slideData = [...slides].map(slide => {
520
554
  const { width } = slide.getBoundingClientRect();
521
555
  const slideRect = slide.getBoundingClientRect();
522
- // position relative to containers left edge
556
+ // position relative to container's left edge
523
557
  const relativeStart = (slideRect.left - containerRect.left) + scrollPos;
524
- const triggerPoint = Math.min(relativeStart + width / 2, relativeStart + emulateScrollSnapMaxThreshold);
525
- return { start: relativeStart, trigger: triggerPoint };
558
+ // Adjust trigger point to align with target area start instead of container edge
559
+ const alignmentPoint = relativeStart - targetAreaOffset;
560
+ const triggerPoint = Math.min(alignmentPoint + width / 2, alignmentPoint + emulateScrollSnapMaxThreshold);
561
+ return { start: relativeStart - targetAreaOffset, trigger: triggerPoint };
526
562
  });
527
563
  // Pick the target start based on drag direction
528
564
  let targetStart = null;