@evermade/overflow-slider 3.3.1 → 4.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.
Files changed (113) hide show
  1. package/.nvmrc +1 -1
  2. package/README.md +115 -29
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.esm.js +609 -1
  5. package/dist/index.esm.js.map +1 -0
  6. package/dist/index.min.js +2 -1
  7. package/dist/index.min.js.map +1 -0
  8. package/dist/mixins.scss +14 -0
  9. package/dist/overflow-slider.css +1 -1
  10. package/dist/plugins/arrows/index.d.ts +26 -0
  11. package/dist/plugins/arrows/index.min.js +1 -1
  12. package/dist/plugins/autoplay/index.d.ts +41 -0
  13. package/dist/plugins/autoplay/index.esm.js +233 -0
  14. package/dist/plugins/autoplay/index.min.js +1 -0
  15. package/dist/plugins/core/index.d.ts +75 -0
  16. package/dist/plugins/core/index.d2.ts +23 -0
  17. package/dist/plugins/dots/index.d.ts +16 -0
  18. package/dist/plugins/dots/index.min.js +1 -1
  19. package/dist/plugins/drag-scrolling/index.d.ts +9 -0
  20. package/dist/plugins/drag-scrolling/index.esm.js +2 -2
  21. package/dist/plugins/drag-scrolling/index.min.js +1 -1
  22. package/dist/plugins/fade/index.d.ts +16 -0
  23. package/dist/plugins/fade/index.min.js +1 -1
  24. package/dist/plugins/full-width/index.d.ts +11 -0
  25. package/dist/plugins/full-width/index.esm.js +14 -3
  26. package/dist/plugins/full-width/index.min.js +1 -1
  27. package/dist/plugins/infinite-scroll/index.d.ts +25 -0
  28. package/dist/plugins/infinite-scroll/index.esm.js +75 -0
  29. package/dist/plugins/infinite-scroll/index.min.js +1 -0
  30. package/dist/plugins/scroll-indicator/index.d.ts +14 -0
  31. package/dist/plugins/scroll-indicator/index.esm.js +3 -1
  32. package/dist/plugins/scroll-indicator/index.min.js +1 -1
  33. package/dist/plugins/skip-links/index.d.ts +17 -0
  34. package/dist/plugins/skip-links/index.esm.js +7 -1
  35. package/dist/plugins/skip-links/index.min.js +1 -1
  36. package/dist/plugins/thumbnails/index.d.ts +9 -0
  37. package/dist/plugins/thumbnails/index.min.js +1 -1
  38. package/dist/{core/utils.min.js → utils-Sxwcz8zp.js} +1 -1
  39. package/dist/{core/utils.esm.js → utils-ayDxlweP.js} +1 -1
  40. package/docs/assets/demo.css +115 -0
  41. package/docs/assets/demo.js +68 -0
  42. package/docs/dist/index.d.ts +1 -0
  43. package/docs/dist/index.esm.js +609 -1
  44. package/docs/dist/index.esm.js.map +1 -0
  45. package/docs/dist/index.min.js +2 -1
  46. package/docs/dist/index.min.js.map +1 -0
  47. package/docs/dist/mixins.scss +14 -0
  48. package/docs/dist/overflow-slider.css +1 -1
  49. package/docs/dist/plugins/arrows/index.d.ts +26 -0
  50. package/docs/dist/plugins/arrows/index.min.js +1 -1
  51. package/docs/dist/plugins/autoplay/index.d.ts +41 -0
  52. package/docs/dist/plugins/autoplay/index.esm.js +233 -0
  53. package/docs/dist/plugins/autoplay/index.min.js +1 -0
  54. package/docs/dist/plugins/core/index.d.ts +23 -0
  55. package/docs/dist/plugins/core/index.d2.ts +75 -0
  56. package/docs/dist/plugins/dots/index.d.ts +16 -0
  57. package/docs/dist/plugins/dots/index.min.js +1 -1
  58. package/docs/dist/plugins/drag-scrolling/index.d.ts +9 -0
  59. package/docs/dist/plugins/drag-scrolling/index.esm.js +2 -2
  60. package/docs/dist/plugins/drag-scrolling/index.min.js +1 -1
  61. package/docs/dist/plugins/fade/index.d.ts +16 -0
  62. package/docs/dist/plugins/fade/index.min.js +1 -1
  63. package/docs/dist/plugins/full-width/index.d.ts +11 -0
  64. package/docs/dist/plugins/full-width/index.esm.js +14 -3
  65. package/docs/dist/plugins/full-width/index.min.js +1 -1
  66. package/docs/dist/plugins/infinite-scroll/index.d.ts +25 -0
  67. package/docs/dist/plugins/infinite-scroll/index.esm.js +75 -0
  68. package/docs/dist/plugins/infinite-scroll/index.min.js +1 -0
  69. package/docs/dist/plugins/scroll-indicator/index.d.ts +14 -0
  70. package/docs/dist/plugins/scroll-indicator/index.esm.js +3 -1
  71. package/docs/dist/plugins/scroll-indicator/index.min.js +1 -1
  72. package/docs/dist/plugins/skip-links/index.d.ts +17 -0
  73. package/docs/dist/plugins/skip-links/index.esm.js +7 -1
  74. package/docs/dist/plugins/skip-links/index.min.js +1 -1
  75. package/docs/dist/plugins/thumbnails/index.d.ts +9 -0
  76. package/docs/dist/plugins/thumbnails/index.min.js +1 -1
  77. package/docs/dist/{core/utils.min.js → utils-Sxwcz8zp.js} +1 -1
  78. package/docs/dist/{core/utils.esm.js → utils-ayDxlweP.js} +1 -1
  79. package/docs/index-rtl.html +78 -2
  80. package/docs/index.html +77 -1
  81. package/package.json +50 -27
  82. package/rollup.config.js +90 -66
  83. package/src/core/details.ts +4 -0
  84. package/src/core/overflow-slider.ts +4 -2
  85. package/src/core/slider.ts +91 -64
  86. package/src/core/types.ts +29 -1
  87. package/src/mixins.scss +14 -0
  88. package/src/overflow-slider.scss +12 -10
  89. package/src/plugins/arrows/index.ts +2 -2
  90. package/src/plugins/autoplay/index.ts +276 -0
  91. package/src/plugins/autoplay/styles.scss +11 -0
  92. package/src/plugins/dots/index.ts +2 -2
  93. package/src/plugins/drag-scrolling/index.ts +4 -4
  94. package/src/plugins/fade/index.ts +2 -2
  95. package/src/plugins/full-width/index.ts +17 -5
  96. package/src/plugins/infinite-scroll/index.ts +109 -0
  97. package/src/plugins/scroll-indicator/index.ts +5 -3
  98. package/src/plugins/skip-links/index.ts +2 -2
  99. package/src/plugins/thumbnails/index.ts +2 -2
  100. package/tsconfig.json +4 -2
  101. package/changelog.md +0 -5
  102. package/dist/core/details.esm.js +0 -35
  103. package/dist/core/details.min.js +0 -1
  104. package/dist/core/overflow-slider.esm.js +0 -29
  105. package/dist/core/overflow-slider.min.js +0 -1
  106. package/dist/core/slider.esm.js +0 -499
  107. package/dist/core/slider.min.js +0 -1
  108. package/docs/dist/core/details.esm.js +0 -35
  109. package/docs/dist/core/details.min.js +0 -1
  110. package/docs/dist/core/overflow-slider.esm.js +0 -29
  111. package/docs/dist/core/overflow-slider.min.js +0 -1
  112. package/docs/dist/core/slider.esm.js +0 -499
  113. package/docs/dist/core/slider.min.js +0 -1
@@ -1,4 +1,4 @@
1
- import { Slider } from '../../core/types';
1
+ import { Slider, DeepPartial } from '../../core/types';
2
2
 
3
3
  const DEFAULT_TARGET_WIDTH = ( slider: Slider ) => slider.container.parentElement?.offsetWidth ?? window.innerWidth;
4
4
 
@@ -8,11 +8,11 @@ export type FullWidthOptions = {
8
8
  addMarginAfter: boolean,
9
9
  };
10
10
 
11
- export default function FullWidthPlugin( args: { [key: string]: unknown } ) {
11
+ export default function FullWidthPlugin( args?: DeepPartial<FullWidthOptions> ) {
12
12
  return ( slider: Slider ) => {
13
13
 
14
14
  const options = <FullWidthOptions>{
15
- targetWidth: args?.targetWidth ?? DEFAULT_TARGET_WIDTH,
15
+ targetWidth: args?.targetWidth ?? null,
16
16
  addMarginBefore: args?.addMarginBefore ?? true,
17
17
  addMarginAfter: args?.addMarginAfter ?? true,
18
18
  };
@@ -27,7 +27,7 @@ export default function FullWidthPlugin( args: { [key: string]: unknown } ) {
27
27
  const firstSlide = slides[0] as HTMLElement;
28
28
  const lastSlide = slides[slides.length - 1] as HTMLElement;
29
29
 
30
- const marginAmount = Math.floor((window.innerWidth - options.targetWidth(slider)) / 2);
30
+ const marginAmount = Math.floor((window.innerWidth - getTargetWidth()) / 2);
31
31
  if ( options.addMarginBefore ) {
32
32
  firstSlide.style.marginInlineStart = `${marginAmount}px`;
33
33
  }
@@ -38,8 +38,20 @@ export default function FullWidthPlugin( args: { [key: string]: unknown } ) {
38
38
  setCSS();
39
39
  };
40
40
 
41
+ const getTargetWidth = () => {
42
+ if ( typeof options.targetWidth === 'function' ) {
43
+ return options.targetWidth(slider);
44
+ }
45
+ if ( typeof slider.options.targetWidth === 'function' ) {
46
+ return slider.options.targetWidth(slider);
47
+ }
48
+ return DEFAULT_TARGET_WIDTH(slider);
49
+ }
50
+
41
51
  const setCSS = () => {
42
- slider.container.style.setProperty('--slider-container-target-width', `${options.targetWidth(slider)}px`);
52
+ if ( typeof slider.options.targetWidth === 'function' ) {
53
+ slider.options.cssVariableContainer.style.setProperty('--slider-container-target-width', `${getTargetWidth()}px`);
54
+ }
43
55
  };
44
56
 
45
57
  update();
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Infinite‐scroll plugin
3
+ *
4
+ * Experimental work-in-progress not available for public use yet.
5
+ */
6
+ import { Slider, SliderPlugin } from '../../core/types';
7
+
8
+ /**
9
+ * @typedef {Object} InfiniteScrollOptions
10
+ * @property {number} [lookAheadCount=1] Number of slides to look ahead when deciding to reparent.
11
+ */
12
+
13
+ /**
14
+ * Creates an infinite scroll plugin for a slider that re-parents multiple slides
15
+ * before hitting the container edge, to avoid blank space and keep the same
16
+ * active slide visible.
17
+ *
18
+ * @param {InfiniteScrollOptions} [options] Plugin configuration.
19
+ * @returns {SliderPlugin} The configured slider plugin.
20
+ */
21
+ export default function InfiniteScrollPlugin(
22
+ options: { lookAheadCount?: number } = {}
23
+ ): SliderPlugin {
24
+ const { lookAheadCount = 1 } = options;
25
+
26
+ return (slider: Slider) => {
27
+ const { container, options: sliderOpts } = slider;
28
+ let rafId: number | null = null;
29
+
30
+ /**
31
+ * Sum widths of the first or last N slides for lookahead.
32
+ *
33
+ * @param {HTMLElement[]} slides List of slide elements.
34
+ * @param {boolean} fromEnd If true, sum last N; otherwise, first N.
35
+ * @returns {number} Total pixel width of N slides.
36
+ */
37
+ function getLookAheadWidth(
38
+ slides: HTMLElement[],
39
+ fromEnd: boolean
40
+ ): number {
41
+ const slice = fromEnd
42
+ ? slides.slice(-lookAheadCount)
43
+ : slides.slice(0, lookAheadCount);
44
+
45
+ return slice.reduce(
46
+ (total, slide) => total + slide.offsetWidth,
47
+ 0
48
+ );
49
+ }
50
+
51
+ /**
52
+ * Handler for slider.scrollEnd event that re-parents slides
53
+ * and retains the active slide element by recalculating its
54
+ * new index after DOM shifts.
55
+ */
56
+ function onScroll(): void {
57
+ const activeSlideIdx = slider.activeSlideIdx;
58
+ const scrollLeft = slider.getScrollLeft();
59
+ const viewportWidth = slider.getInclusiveClientWidth();
60
+ const totalWidth = slider.getInclusiveScrollWidth();
61
+
62
+ // Grab current slide elements
63
+ let slides = Array.from(
64
+ container.querySelectorAll(
65
+ sliderOpts.slidesSelector
66
+ )
67
+ ) as HTMLElement[];
68
+
69
+ if (slides.length === 0) return;
70
+
71
+ // Store reference to currently active slide element
72
+ const activeSlideEl = slides[activeSlideIdx];
73
+
74
+ const aheadRight = getLookAheadWidth(slides, false);
75
+ const aheadLeft = getLookAheadWidth(slides, true);
76
+
77
+ // 🐆 Tip: Batch DOM reads/writes inside requestAnimationFrame to avoid thrashing.
78
+ if (scrollLeft + viewportWidth >= totalWidth - aheadRight) {
79
+ for (let i = 0; i < lookAheadCount && slides.length; i++) {
80
+ container.append(slides.shift()!);
81
+ }
82
+ } else if (scrollLeft <= aheadLeft) {
83
+ for (let i = 0; i < lookAheadCount && slides.length; i++) {
84
+ container.prepend(slides.pop()!);
85
+ }
86
+ }
87
+
88
+ slider.setActiveSlideIdx();
89
+
90
+ // Re-query slides after DOM mutation
91
+ slides = Array.from(
92
+ container.querySelectorAll(
93
+ sliderOpts.slidesSelector
94
+ )
95
+ ) as HTMLElement[];
96
+
97
+ const newIndex = slides.indexOf(activeSlideEl);
98
+ const newEl = slides[newIndex];
99
+
100
+ if (newIndex >= 0 && slider.canMoveToSlide(newIndex)) {
101
+ slider.moveToSlide(newIndex);
102
+ } else {
103
+ slider.snapToClosestSlide('next');
104
+ }
105
+ }
106
+
107
+ slider.on('scrollEnd', onScroll);
108
+ };
109
+ }
@@ -1,4 +1,4 @@
1
- import { Slider } from '../../core/types';
1
+ import { Slider, DeepPartial } from '../../core/types';
2
2
 
3
3
  const DEFAULT_CLASS_NAMES = {
4
4
  scrollIndicator: 'overflow-slider__scroll-indicator',
@@ -15,7 +15,7 @@ export type ScrollIndicatorOptions = {
15
15
  container: HTMLElement | null,
16
16
  };
17
17
 
18
- export default function ScrollIndicatorPlugin(args: { [key: string]: unknown }) {
18
+ export default function ScrollIndicatorPlugin(args?: DeepPartial<ScrollIndicatorOptions>) {
19
19
  return (slider: Slider) => {
20
20
 
21
21
  const options = <ScrollIndicatorOptions>{
@@ -112,10 +112,12 @@ export default function ScrollIndicatorPlugin(args: { [key: string]: unknown })
112
112
  const scrollbarButtonWidth = scrollbarButton.offsetWidth;
113
113
  const scrollbarButtonLeft = getScrollbarButtonLeftOffset();
114
114
  const scrollbarButtonRight = scrollbarButtonLeft + scrollbarButtonWidth;
115
- const clickX = e.pageX - Math.abs( scrollbarContainer.offsetLeft );
115
+ const clickX = (e as MouseEvent).pageX - scrollbarContainer.getBoundingClientRect().left;
116
116
  if (Math.floor(clickX) < Math.floor(scrollbarButtonLeft)) {
117
+ console.log('move left');
117
118
  slider.moveToDirection(slider.options.rtl ? 'next' : 'prev');
118
119
  } else if (Math.floor(clickX) > Math.floor(scrollbarButtonRight)) {
120
+ console.log('move right');
119
121
  slider.moveToDirection(slider.options.rtl ? 'prev' : 'next');
120
122
  }
121
123
  });
@@ -1,4 +1,4 @@
1
- import { Slider } from '../../core/types';
1
+ import { Slider, DeepPartial } from '../../core/types';
2
2
  import { generateId } from '../../core/utils';
3
3
 
4
4
  const DEFAULT_TEXTS = {
@@ -22,7 +22,7 @@ export type SkipLinkOptions = {
22
22
  containerAfter: HTMLElement | null,
23
23
  };
24
24
 
25
- export default function SkipLinksPlugin( args: { [key: string]: unknown } ) {
25
+ export default function SkipLinksPlugin( args?: DeepPartial<SkipLinkOptions> ) {
26
26
  return ( slider: Slider ) => {
27
27
  const options = <SkipLinkOptions>{
28
28
  texts: {
@@ -1,10 +1,10 @@
1
- import { Slider } from '../../core/types';
1
+ import { Slider, DeepPartial } from '../../core/types';
2
2
 
3
3
  export type ThumbnailsOptions = {
4
4
  mainSlider: Slider,
5
5
  };
6
6
 
7
- export default function FullWidthPlugin( args: { [key: string]: unknown } ) {
7
+ export default function FullWidthPlugin( args: DeepPartial<ThumbnailsOptions> ) {
8
8
  return ( slider: Slider ) => {
9
9
 
10
10
  const options = <ThumbnailsOptions>{
package/tsconfig.json CHANGED
@@ -8,11 +8,13 @@
8
8
  "sourceMap": false
9
9
  },
10
10
  "include": [
11
- "src/**/*"
11
+ "src/**/*.ts"
12
12
  ],
13
13
  "exclude": [
14
14
  "node_modules",
15
15
  "dist",
16
- "**/*.spec.ts"
16
+ "**/*.spec.ts",
17
+ "**/*.scss",
18
+ "*.scss"
17
19
  ]
18
20
  }
package/changelog.md DELETED
@@ -1,5 +0,0 @@
1
- # Changelog
2
-
3
- ## Version 1.0.0
4
-
5
- - Initial release
@@ -1,35 +0,0 @@
1
- function details(slider) {
2
- var _a;
3
- let instance;
4
- let hasOverflow = false;
5
- let slideCount = 0;
6
- let containerWidth = 0;
7
- let scrollableAreaWidth = 0;
8
- let amountOfPages = 0;
9
- let currentPage = 1;
10
- if (Math.floor(slider.getInclusiveScrollWidth()) > Math.floor(slider.getInclusiveClientWidth())) {
11
- hasOverflow = true;
12
- }
13
- slideCount = (_a = slider.slides.length) !== null && _a !== void 0 ? _a : 0;
14
- containerWidth = slider.container.offsetWidth;
15
- scrollableAreaWidth = slider.getInclusiveScrollWidth();
16
- amountOfPages = Math.ceil(scrollableAreaWidth / containerWidth);
17
- if (Math.floor(slider.getScrollLeft()) >= 0) {
18
- currentPage = Math.floor(slider.getScrollLeft() / containerWidth);
19
- // consider as last page if the scrollLeft + containerWidth is equal to scrollWidth
20
- if (Math.floor(slider.getScrollLeft() + containerWidth) === Math.floor(scrollableAreaWidth)) {
21
- currentPage = amountOfPages - 1;
22
- }
23
- }
24
- instance = {
25
- hasOverflow,
26
- slideCount,
27
- containerWidth,
28
- scrollableAreaWidth,
29
- amountOfPages,
30
- currentPage,
31
- };
32
- return instance;
33
- }
34
-
35
- export { details as default };
@@ -1 +0,0 @@
1
- function t(t){var l;let e,o=!1,r=0,a=0,i=0,n=0,f=1;return Math.floor(t.getInclusiveScrollWidth())>Math.floor(t.getInclusiveClientWidth())&&(o=!0),r=null!==(l=t.slides.length)&&void 0!==l?l:0,a=t.container.offsetWidth,i=t.getInclusiveScrollWidth(),n=Math.ceil(i/a),Math.floor(t.getScrollLeft())>=0&&(f=Math.floor(t.getScrollLeft()/a),Math.floor(t.getScrollLeft()+a)===Math.floor(i)&&(f=n-1)),e={hasOverflow:o,slideCount:r,containerWidth:a,scrollableAreaWidth:i,amountOfPages:n,currentPage:f},e}export{t as default};
@@ -1,29 +0,0 @@
1
- import Slider from './slider.esm.js';
2
-
3
- function OverflowSlider(container, options, plugins) {
4
- try {
5
- // check that container HTML element
6
- if (!(container instanceof Element)) {
7
- throw new Error(`Container must be HTML element, found ${typeof container}`);
8
- }
9
- const defaults = {
10
- scrollBehavior: "smooth",
11
- scrollStrategy: "fullSlide",
12
- slidesSelector: ":scope > *",
13
- emulateScrollSnap: false,
14
- emulateScrollSnapMaxThreshold: 64,
15
- rtl: false,
16
- };
17
- const sliderOptions = Object.assign(Object.assign({}, defaults), options);
18
- // disable smooth scrolling if user prefers reduced motion
19
- if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
20
- sliderOptions.scrollBehavior = "auto";
21
- }
22
- return Slider(container, sliderOptions, plugins);
23
- }
24
- catch (e) {
25
- console.error(e);
26
- }
27
- }
28
-
29
- export { OverflowSlider as default };
@@ -1 +0,0 @@
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,rtl:!1},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};