motionrail 0.7.0 → 0.8.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/README.md CHANGED
@@ -1,18 +1,19 @@
1
1
  # MotionRail
2
2
 
3
- > ⚠️ **Not Ready for Production** - This library is currently in development and not yet ready for production use.
4
-
5
3
  A lightweight, smooth carousel library with momentum-based scrolling, snap alignment, and responsive breakpoints. Works with vanilla JavaScript or your favorite framework.
6
4
 
7
5
  ## Features
8
6
 
9
- - 🎯 Momentum-based scrolling with natural drag physics
10
- - 📱 Responsive breakpoints for different screen sizes
11
- - 🔄 Autoplay support with pause on interaction
12
- - ↔️ RTL support built-in
13
- - 🪶 Zero dependencies, minimal bundle size
14
- - 🧩 Extension system (arrows, dots, thumbnails)
15
- - ⚛️ Framework integrations (React, Preact, Solid, Vue, Svelte, Qwik)
7
+ - 🎯󠅅󠅞󠅢󠅙󠅦󠅑󠅜󠅕󠅔󠄐󠅣󠅝󠅟󠅟󠅤󠅘󠅞󠅕󠅣󠅣󠄐󠅑󠅞󠅔󠄐󠅓󠅟󠅞󠅤󠅢󠅟󠅜 **Momentum-based scrolling** - Natural drag physics with smooth animations
8
+ - 📱󠄵󠅖󠅖󠅟󠅢󠅤󠅜󠅕󠅣󠅣󠄐󠅢󠅕󠅣󠅠󠅟󠅞󠅣󠅙󠅦󠅕󠄐󠅜󠅑󠅩󠅟󠅥󠅤󠅣 **Responsive breakpoints** - Configure columns and gaps for different screen sizes
9
+ - ♿󠅀󠅢󠅕󠅓󠅙󠅣󠅙󠅟󠅞󠄐󠅣󠅞󠅑󠅠󠄐󠅑󠅜󠅙󠅗󠅞󠅝󠅕󠅞󠅤󠄜󠄐󠅑󠅜󠅧󠅑󠅩󠅣󠄐󠅠󠅕󠅢󠅖󠅕󠅓󠅤 **Snap alignment** - Automatic snap-to-item positioning
10
+ - 🔄󠄱󠅥󠅤󠅟󠅠󠅜󠅑󠅩󠄐󠅤󠅘󠅑󠅤󠄐󠅖󠅕󠅕󠅜󠅣󠄐󠅞󠅑󠅤󠅥󠅢󠅑󠅜 **Autoplay support** - Optional auto-scrolling with pause on interaction
11
+ - ↔️󠅂󠅄󠄼󠄐󠅣󠅥󠅠󠅠󠅟󠅢󠅤󠄜󠄐󠅞󠅟󠄐󠅓󠅟󠅝󠅠󠅢󠅟󠅝󠅙󠅣󠅕󠅣 **RTL support** - Built-in right-to-left layout support
12
+ - 🎨󠄽󠅟󠅔󠅕󠅢󠅞󠄐󠄳󠅃󠅃󠄐󠄷󠅢󠅙󠅔󠄐󠅝󠅑󠅣󠅤󠅕󠅢󠅩 **CSS Grid based** - Modern layout with customizable styling
13
+ - 🪶󠄽󠅙󠅞󠅙󠅝󠅑󠅜󠄜󠄐󠅥󠅜󠅤󠅢󠅑󠄝󠅜󠅙󠅗󠅘󠅤󠅧󠅕󠅙󠅗󠅘󠅤 **Lightweight** - Zero dependencies, minimal bundle size
14
+ - 🎮󠅄󠅟󠅤󠅑󠅜󠄐󠄱󠅀󠄹󠄐󠅓󠅟󠅞󠅤󠅢󠅟󠅜󠄜󠄐󠅞󠅟󠄐󠅜󠅙󠅝󠅙󠅤󠅣 **Full control API** - Programmatic navigation and playback control
15
+ - 🧩󠄵󠅨󠅤󠅕󠅞󠅣󠅙󠅟󠅞󠅣󠄐󠅖󠅟󠅢󠄐󠅕󠅞󠅔󠅜󠅕󠅣󠅣󠄐󠅠󠅟󠅣󠅣󠅙󠅒󠅙󠅜󠅙󠅤󠅙󠅕󠅣 **Extension system** - Modular architecture with built-in extensions
16
+ - ⚡󠅃󠅕󠅑󠅝󠅜󠅕󠅣󠅣󠄐󠅖󠅢󠅑󠅝󠅕󠅧󠅟󠅢󠅛󠄐󠅙󠅞󠅤󠅕󠅗󠅢󠅑󠅤󠅙󠅟󠅞 **Framework integrations** - React, Preact, Qwik, Solid, Vue, Svelte components
16
17
 
17
18
  ## Installation
18
19
 
@@ -37,27 +38,27 @@ npm install motionrail
37
38
  ```
38
39
 
39
40
  ```js
40
- import { MotionRail } from 'motionrail';
41
- import 'motionrail/style.css';
41
+ import { MotionRail } from "motionrail";
42
+ import "motionrail/style.css";
42
43
 
43
- const carousel = new MotionRail(document.getElementById('carousel'), {
44
+ const carousel = new MotionRail(document.getElementById("carousel"), {
44
45
  breakpoints: [
45
- { columns: 1, gap: '16px' },
46
- { width: 768, columns: 2, gap: '16px' },
47
- { width: 1024, columns: 3, gap: '20px' }
48
- ]
46
+ { columns: 1, gap: "16px" },
47
+ { width: 768, columns: 2, gap: "16px" },
48
+ { width: 1024, columns: 3, gap: "20px" },
49
+ ],
49
50
  });
50
51
  ```
51
52
 
52
53
  ### React
53
54
 
54
55
  ```jsx
55
- import { MotionRail } from 'motionrail/react';
56
- import 'motionrail/style.css';
56
+ import { MotionRail } from "motionrail/react";
57
+ import "motionrail/style.css";
57
58
 
58
59
  function App() {
59
60
  return (
60
- <MotionRail options={{ breakpoints: [{ columns: 3, gap: '20px' }] }}>
61
+ <MotionRail options={{ breakpoints: [{ columns: 3, gap: "20px" }] }}>
61
62
  <div>Item 1</div>
62
63
  <div>Item 2</div>
63
64
  <div>Item 3</div>
@@ -69,22 +70,19 @@ function App() {
69
70
  ### With Extensions
70
71
 
71
72
  ```js
72
- import { MotionRail } from 'motionrail';
73
- import { Arrows } from 'motionrail/extensions/arrows';
74
- import { Dots } from 'motionrail/extensions/dots';
75
- import 'motionrail/style.css';
76
- import 'motionrail/extensions/arrows/style.css';
77
- import 'motionrail/extensions/dots/style.css';
73
+ import { MotionRail } from "motionrail";
74
+ import { Arrows } from "motionrail/extensions/arrows";
75
+ import { Dots } from "motionrail/extensions/dots";
76
+ import "motionrail/style.css";
77
+ import "motionrail/extensions/arrows/style.css";
78
+ import "motionrail/extensions/dots/style.css";
78
79
 
79
80
  const carousel = new MotionRail(element, {
80
81
  breakpoints: [
81
- { columns: 1, gap: '16px' },
82
- { width: 768, columns: 2, gap: '16px' }
82
+ { columns: 1, gap: "16px" },
83
+ { width: 768, columns: 2, gap: "16px" },
83
84
  ],
84
- extensions: [
85
- Arrows({ loop: true }),
86
- Dots({ showIndex: true })
87
- ]
85
+ extensions: [Arrows({ loop: true }), Dots({ showIndex: true })],
88
86
  });
89
87
  ```
90
88
 
@@ -96,9 +94,9 @@ const carousel = new MotionRail(element, {
96
94
  delay: 3000,
97
95
  resumeDelay: 4000,
98
96
  breakpoints: [
99
- { columns: 1, gap: '16px' },
100
- { width: 768, columns: 2, gap: '16px' }
101
- ]
97
+ { columns: 1, gap: "16px" },
98
+ { width: 768, columns: 2, gap: "16px" },
99
+ ],
102
100
  });
103
101
  ```
104
102
 
@@ -114,4 +112,4 @@ MIT
114
112
 
115
113
  ---
116
114
 
117
- [![Sponsor juji](https://img.shields.io/badge/sponsor-juji-ea4aaa?style=for-the-badge&logo=github)](https://github.com/sponsors/juji)
115
+ [![Sponsor juji](https://img.shields.io/badge/sponsor-juji-ea4aaa?style=for-the-badge&logo=github)](https://github.com/sponsors/juji)
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`motionrail`)):typeof define==`function`&&define.amd?define([`exports`,`motionrail`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRailArrows={},e.MotionRail))})(this,function(e,t){function n(e){let{leftIcon:t=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-left-icon lucide-chevron-left"><path d="m15 18-6-6 6-6"/></svg>`,rightIcon:n=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right-icon lucide-chevron-right"><path d="m9 18 6-6-6-6"/></svg>`,loop:r=!0,log:i=!1}=e||{},a=null,o=null;return{name:`ArrowExtension`,onInit(e,r){let{totalItems:i}=r;if(i===0)return;let{rtl:s}=e.getOptions();a=document.createElement(`button`),a.innerHTML=t,a.className=`motionrail-arrow motionrail-arrow-left`,a.addEventListener(`click`,()=>{s?e.next():e.prev()}),o=document.createElement(`button`),o.innerHTML=n,o.className=`motionrail-arrow motionrail-arrow-right`,o.addEventListener(`click`,()=>{s?e.prev():e.next()}),e.element.appendChild(a),e.element.appendChild(o)},onUpdate(e,t){if(!a||!o)return;let{isFirstItemVisible:n,isLastItemVisible:s,totalItems:c,visibleItemIndexes:l}=t;r||(a.disabled=n,o.disabled=s),l.length<c?(a.style.removeProperty(`display`),o.style.removeProperty(`display`)):(a.style.display=`none`,o.style.display=`none`),c||(a.style.display=`none`,o.style.display=`none`),i&&console.log(`ArrowExtension updated`,t)},onDestroy(e,t){a?.remove(),o?.remove()}}}e.Arrows=n});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`motionrail`)):typeof define==`function`&&define.amd?define([`exports`,`motionrail`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRail={},e.MotionRail))})(this,function(e,t){function n(e){let{leftIcon:t=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-left-icon lucide-chevron-left"><path d="m15 18-6-6 6-6"/></svg>`,rightIcon:n=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right-icon lucide-chevron-right"><path d="m9 18 6-6-6-6"/></svg>`,loop:r=!0,log:i=!1}=e||{},a=null,o=null;return{name:`ArrowExtension`,onInit(e,r){let{totalItems:i}=r;if(i===0)return;let{rtl:s}=e.getOptions();a=document.createElement(`button`),a.innerHTML=t,a.className=`motionrail-arrow motionrail-arrow-left`,a.addEventListener(`click`,()=>{s?e.next():e.prev()}),o=document.createElement(`button`),o.innerHTML=n,o.className=`motionrail-arrow motionrail-arrow-right`,o.addEventListener(`click`,()=>{s?e.prev():e.next()}),e.element.appendChild(a),e.element.appendChild(o)},onUpdate(e,t){if(!a||!o)return;let{isFirstItemVisible:n,isLastItemVisible:s,totalItems:c,visibleItemIndexes:l}=t;r||(a.disabled=n,o.disabled=s),l.length<c?(a.style.removeProperty(`display`),o.style.removeProperty(`display`)):(a.style.display=`none`,o.style.display=`none`),c||(a.style.display=`none`,o.style.display=`none`),i&&console.log(`ArrowExtension updated`,t)},onDestroy(e,t){a?.remove(),o?.remove()}}}e.Arrows=n});
2
2
  //# sourceMappingURL=arrows.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"arrows.umd.js","names":["leftArrow: HTMLButtonElement | null","rightArrow: HTMLButtonElement | null"],"sources":["../src/arrows.ts"],"sourcesContent":["import { MotionRail } from \"motionrail\";\nimport type { MotionRailExtension, MotionRailState } from \"motionrail\";\nimport \"./style.css\";\n\nexport function Arrows(par?: {\n leftIcon?: string;\n rightIcon?: string;\n loop?: boolean;\n log?: boolean;\n}): MotionRailExtension {\n const {\n leftIcon = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-chevron-left-icon lucide-chevron-left\"><path d=\"m15 18-6-6 6-6\"/></svg>',\n rightIcon = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-chevron-right-icon lucide-chevron-right\"><path d=\"m9 18 6-6-6-6\"/></svg>',\n loop = true,\n log = false,\n } = par || {};\n\n let leftArrow: HTMLButtonElement | null = null;\n let rightArrow: HTMLButtonElement | null = null;\n\n return {\n name: \"ArrowExtension\",\n onInit(motionRail: MotionRail, state: MotionRailState) {\n const { totalItems } = state;\n\n if (totalItems === 0) {\n return;\n }\n\n const { rtl } = motionRail.getOptions();\n leftArrow = document.createElement(\"button\");\n leftArrow.innerHTML = leftIcon;\n leftArrow.className = \"motionrail-arrow motionrail-arrow-left\";\n leftArrow.addEventListener(\"click\", () => {\n rtl ? motionRail.next() : motionRail.prev();\n });\n\n rightArrow = document.createElement(\"button\");\n rightArrow.innerHTML = rightIcon;\n rightArrow.className = \"motionrail-arrow motionrail-arrow-right\";\n rightArrow.addEventListener(\"click\", () => {\n rtl ? motionRail.prev() : motionRail.next();\n });\n\n motionRail.element.appendChild(leftArrow);\n motionRail.element.appendChild(rightArrow);\n },\n onUpdate(_motionRail: MotionRail, state: MotionRailState) {\n if (!leftArrow || !rightArrow) return;\n const {\n isFirstItemVisible,\n isLastItemVisible,\n totalItems,\n visibleItemIndexes,\n } = state;\n if (!loop) {\n leftArrow.disabled = isFirstItemVisible;\n rightArrow.disabled = isLastItemVisible;\n }\n\n if (visibleItemIndexes.length < totalItems) {\n leftArrow.style.removeProperty(\"display\");\n rightArrow.style.removeProperty(\"display\");\n } else {\n leftArrow.style.display = \"none\";\n rightArrow.style.display = \"none\";\n }\n\n if (!totalItems) {\n leftArrow.style.display = \"none\";\n rightArrow.style.display = \"none\";\n }\n\n if (log) {\n console.log(\"ArrowExtension updated\", state);\n }\n },\n onDestroy(_motionRail: MotionRail, _state: MotionRailState) {\n leftArrow?.remove();\n rightArrow?.remove();\n },\n };\n}\n"],"mappings":"6QAIA,SAAgB,EAAO,EAKC,CACtB,GAAM,CACJ,WAAW,oRACX,YAAY,qRACZ,OAAO,GACP,MAAM,IACJ,GAAO,EAAE,CAETA,EAAsC,KACtCC,EAAuC,KAE3C,MAAO,CACL,KAAM,iBACN,OAAO,EAAwB,EAAwB,CACrD,GAAM,CAAE,cAAe,EAEvB,GAAI,IAAe,EACjB,OAGF,GAAM,CAAE,OAAQ,EAAW,YAAY,CACvC,EAAY,SAAS,cAAc,SAAS,CAC5C,EAAU,UAAY,EACtB,EAAU,UAAY,yCACtB,EAAU,iBAAiB,YAAe,CACxC,EAAM,EAAW,MAAM,CAAG,EAAW,MAAM,EAC3C,CAEF,EAAa,SAAS,cAAc,SAAS,CAC7C,EAAW,UAAY,EACvB,EAAW,UAAY,0CACvB,EAAW,iBAAiB,YAAe,CACzC,EAAM,EAAW,MAAM,CAAG,EAAW,MAAM,EAC3C,CAEF,EAAW,QAAQ,YAAY,EAAU,CACzC,EAAW,QAAQ,YAAY,EAAW,EAE5C,SAAS,EAAyB,EAAwB,CACxD,GAAI,CAAC,GAAa,CAAC,EAAY,OAC/B,GAAM,CACJ,qBACA,oBACA,aACA,sBACE,EACC,IACH,EAAU,SAAW,EACrB,EAAW,SAAW,GAGpB,EAAmB,OAAS,GAC9B,EAAU,MAAM,eAAe,UAAU,CACzC,EAAW,MAAM,eAAe,UAAU,GAE1C,EAAU,MAAM,QAAU,OAC1B,EAAW,MAAM,QAAU,QAGxB,IACH,EAAU,MAAM,QAAU,OAC1B,EAAW,MAAM,QAAU,QAGzB,GACF,QAAQ,IAAI,yBAA0B,EAAM,EAGhD,UAAU,EAAyB,EAAyB,CAC1D,GAAW,QAAQ,CACnB,GAAY,QAAQ,EAEvB"}
1
+ {"version":3,"file":"arrows.umd.js","names":["leftArrow: HTMLButtonElement | null","rightArrow: HTMLButtonElement | null"],"sources":["../src/arrows.ts"],"sourcesContent":["import { MotionRail } from \"motionrail\";\nimport type { MotionRailExtension, MotionRailState } from \"motionrail\";\nimport \"./style.css\";\n\nexport function Arrows(par?: {\n leftIcon?: string;\n rightIcon?: string;\n loop?: boolean;\n log?: boolean;\n}): MotionRailExtension {\n const {\n leftIcon = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-chevron-left-icon lucide-chevron-left\"><path d=\"m15 18-6-6 6-6\"/></svg>',\n rightIcon = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-chevron-right-icon lucide-chevron-right\"><path d=\"m9 18 6-6-6-6\"/></svg>',\n loop = true,\n log = false,\n } = par || {};\n\n let leftArrow: HTMLButtonElement | null = null;\n let rightArrow: HTMLButtonElement | null = null;\n\n return {\n name: \"ArrowExtension\",\n onInit(motionRail: MotionRail, state: MotionRailState) {\n const { totalItems } = state;\n\n if (totalItems === 0) {\n return;\n }\n\n const { rtl } = motionRail.getOptions();\n leftArrow = document.createElement(\"button\");\n leftArrow.innerHTML = leftIcon;\n leftArrow.className = \"motionrail-arrow motionrail-arrow-left\";\n leftArrow.addEventListener(\"click\", () => {\n rtl ? motionRail.next() : motionRail.prev();\n });\n\n rightArrow = document.createElement(\"button\");\n rightArrow.innerHTML = rightIcon;\n rightArrow.className = \"motionrail-arrow motionrail-arrow-right\";\n rightArrow.addEventListener(\"click\", () => {\n rtl ? motionRail.prev() : motionRail.next();\n });\n\n motionRail.element.appendChild(leftArrow);\n motionRail.element.appendChild(rightArrow);\n },\n onUpdate(_motionRail: MotionRail, state: MotionRailState) {\n if (!leftArrow || !rightArrow) return;\n const {\n isFirstItemVisible,\n isLastItemVisible,\n totalItems,\n visibleItemIndexes,\n } = state;\n if (!loop) {\n leftArrow.disabled = isFirstItemVisible;\n rightArrow.disabled = isLastItemVisible;\n }\n\n if (visibleItemIndexes.length < totalItems) {\n leftArrow.style.removeProperty(\"display\");\n rightArrow.style.removeProperty(\"display\");\n } else {\n leftArrow.style.display = \"none\";\n rightArrow.style.display = \"none\";\n }\n\n if (!totalItems) {\n leftArrow.style.display = \"none\";\n rightArrow.style.display = \"none\";\n }\n\n if (log) {\n console.log(\"ArrowExtension updated\", state);\n }\n },\n onDestroy(_motionRail: MotionRail, _state: MotionRailState) {\n leftArrow?.remove();\n rightArrow?.remove();\n },\n };\n}\n"],"mappings":"uQAIA,SAAgB,EAAO,EAKC,CACtB,GAAM,CACJ,WAAW,oRACX,YAAY,qRACZ,OAAO,GACP,MAAM,IACJ,GAAO,EAAE,CAETA,EAAsC,KACtCC,EAAuC,KAE3C,MAAO,CACL,KAAM,iBACN,OAAO,EAAwB,EAAwB,CACrD,GAAM,CAAE,cAAe,EAEvB,GAAI,IAAe,EACjB,OAGF,GAAM,CAAE,OAAQ,EAAW,YAAY,CACvC,EAAY,SAAS,cAAc,SAAS,CAC5C,EAAU,UAAY,EACtB,EAAU,UAAY,yCACtB,EAAU,iBAAiB,YAAe,CACxC,EAAM,EAAW,MAAM,CAAG,EAAW,MAAM,EAC3C,CAEF,EAAa,SAAS,cAAc,SAAS,CAC7C,EAAW,UAAY,EACvB,EAAW,UAAY,0CACvB,EAAW,iBAAiB,YAAe,CACzC,EAAM,EAAW,MAAM,CAAG,EAAW,MAAM,EAC3C,CAEF,EAAW,QAAQ,YAAY,EAAU,CACzC,EAAW,QAAQ,YAAY,EAAW,EAE5C,SAAS,EAAyB,EAAwB,CACxD,GAAI,CAAC,GAAa,CAAC,EAAY,OAC/B,GAAM,CACJ,qBACA,oBACA,aACA,sBACE,EACC,IACH,EAAU,SAAW,EACrB,EAAW,SAAW,GAGpB,EAAmB,OAAS,GAC9B,EAAU,MAAM,eAAe,UAAU,CACzC,EAAW,MAAM,eAAe,UAAU,GAE1C,EAAU,MAAM,QAAU,OAC1B,EAAW,MAAM,QAAU,QAGxB,IACH,EAAU,MAAM,QAAU,OAC1B,EAAW,MAAM,QAAU,QAGzB,GACF,QAAQ,IAAI,yBAA0B,EAAM,EAGhD,UAAU,EAAyB,EAAyB,CAC1D,GAAW,QAAQ,CACnB,GAAY,QAAQ,EAEvB"}
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`motionrail`)):typeof define==`function`&&define.amd?define([`exports`,`motionrail`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRailDots={},e.MotionRail))})(this,function(e,t){function n(e){let t=null,n=[],{showIndex:r=!1,log:i=!1}=e||{};return{name:`DotsExtension`,onInit(e,i){let{totalItems:a}=i;if(a!==0){t=document.createElement(`div`),t.className=`motionrail-dots`;for(let i=0;i<a;i++){let a=document.createElement(`button`);a.className=`motionrail-dot`,a.setAttribute(`aria-label`,`Go to item ${i+1}`),r&&(a.textContent=(i+1).toString()),a.addEventListener(`click`,()=>{e.scrollToIndex(i)}),n.push(a),t.appendChild(a)}e.element.appendChild(t)}},onUpdate(e,r){let{visibleItemIndexes:a,totalItems:o}=r;if(t){if(!o){t.style.display=`none`;return}if(t.style.removeProperty(`display`),n.forEach((e,t)=>{a.includes(t)?e.classList.add(`motionrail-dot-active`):e.classList.remove(`motionrail-dot-active`)}),a.length>0){let e=n[a[0]];if(e){let n=t.offsetWidth,r=e.offsetLeft,i=e.offsetWidth,a=r-n/2+i/2;t.scrollTo({left:a,behavior:`smooth`})}}i&&console.log(`DotsExtension updated`,r)}},onDestroy(e,r){t?.remove(),n.length=0}}}e.Dots=n});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`motionrail`)):typeof define==`function`&&define.amd?define([`exports`,`motionrail`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRail={},e.MotionRail))})(this,function(e,t){function n(e){let t=null,n=[],{showIndex:r=!1,log:i=!1}=e||{};return{name:`DotsExtension`,onInit(e,i){let{totalItems:a}=i;if(a!==0){t=document.createElement(`div`),t.className=`motionrail-dots`;for(let i=0;i<a;i++){let a=document.createElement(`button`);a.className=`motionrail-dot`,a.setAttribute(`aria-label`,`Go to item ${i+1}`),r&&(a.textContent=(i+1).toString()),a.addEventListener(`click`,()=>{e.scrollToIndex(i)}),n.push(a),t.appendChild(a)}e.element.appendChild(t)}},onUpdate(e,r){let{visibleItemIndexes:a,totalItems:o}=r;if(t){if(!o){t.style.display=`none`;return}if(t.style.removeProperty(`display`),n.forEach((e,t)=>{a.includes(t)?e.classList.add(`motionrail-dot-active`):e.classList.remove(`motionrail-dot-active`)}),a.length>0){let e=n[a[0]];if(e){let n=t.offsetWidth,r=e.offsetLeft,i=e.offsetWidth,a=r-n/2+i/2;t.scrollTo({left:a,behavior:`smooth`})}}i&&console.log(`DotsExtension updated`,r)}},onDestroy(e,r){t?.remove(),n.length=0}}}e.Dots=n});
2
2
  //# sourceMappingURL=dots.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dots.umd.js","names":["dotsContainer: HTMLDivElement | null","dots: HTMLButtonElement[]"],"sources":["../src/dots.ts"],"sourcesContent":["import { MotionRail } from \"motionrail\";\nimport type { MotionRailExtension, MotionRailState } from \"motionrail\";\nimport \"./style.css\";\n\nexport function Dots(par?: {\n showIndex?: boolean;\n log?: boolean;\n}): MotionRailExtension {\n let dotsContainer: HTMLDivElement | null = null;\n const dots: HTMLButtonElement[] = [];\n const { showIndex = false, log = false } = par || {};\n\n return {\n name: \"DotsExtension\",\n onInit(motionRail: MotionRail, state: MotionRailState) {\n const { totalItems } = state;\n\n if (totalItems === 0) {\n return;\n }\n\n dotsContainer = document.createElement(\"div\");\n\n dotsContainer.className = \"motionrail-dots\";\n\n for (let i = 0; i < totalItems; i++) {\n const dot = document.createElement(\"button\");\n dot.className = \"motionrail-dot\";\n dot.setAttribute(\"aria-label\", `Go to item ${i + 1}`);\n\n if (showIndex) {\n dot.textContent = (i + 1).toString();\n }\n\n dot.addEventListener(\"click\", () => {\n motionRail.scrollToIndex(i);\n });\n\n dots.push(dot);\n dotsContainer.appendChild(dot);\n }\n\n motionRail.element.appendChild(dotsContainer);\n },\n onUpdate(_motionRail: MotionRail, state: MotionRailState) {\n const { visibleItemIndexes, totalItems } = state;\n if (!dotsContainer) return;\n\n if (!totalItems) {\n dotsContainer.style.display = \"none\";\n return;\n }\n\n dotsContainer.style.removeProperty(\"display\");\n\n dots.forEach((dot, index) => {\n if (visibleItemIndexes.includes(index)) {\n dot.classList.add(\"motionrail-dot-active\");\n } else {\n dot.classList.remove(\"motionrail-dot-active\");\n }\n });\n\n if (visibleItemIndexes.length > 0) {\n const firstActiveDot = dots[visibleItemIndexes[0]];\n if (firstActiveDot) {\n const containerWidth = dotsContainer.offsetWidth;\n const dotLeft = firstActiveDot.offsetLeft;\n const dotWidth = firstActiveDot.offsetWidth;\n const scrollPosition = dotLeft - containerWidth / 2 + dotWidth / 2;\n\n dotsContainer.scrollTo({\n left: scrollPosition,\n behavior: \"smooth\",\n });\n }\n }\n\n if (log) {\n console.log(\"DotsExtension updated\", state);\n }\n },\n onDestroy(_motionRail: MotionRail, _state: MotionRailState) {\n dotsContainer?.remove();\n dots.length = 0;\n },\n };\n}\n"],"mappings":"2QAIA,SAAgB,EAAK,EAGG,CACtB,IAAIA,EAAuC,KACrCC,EAA4B,EAAE,CAC9B,CAAE,YAAY,GAAO,MAAM,IAAU,GAAO,EAAE,CAEpD,MAAO,CACL,KAAM,gBACN,OAAO,EAAwB,EAAwB,CACrD,GAAM,CAAE,cAAe,EAEnB,OAAe,EAMnB,CAFA,EAAgB,SAAS,cAAc,MAAM,CAE7C,EAAc,UAAY,kBAE1B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,IAAK,CACnC,IAAM,EAAM,SAAS,cAAc,SAAS,CAC5C,EAAI,UAAY,iBAChB,EAAI,aAAa,aAAc,cAAc,EAAI,IAAI,CAEjD,IACF,EAAI,aAAe,EAAI,GAAG,UAAU,EAGtC,EAAI,iBAAiB,YAAe,CAClC,EAAW,cAAc,EAAE,EAC3B,CAEF,EAAK,KAAK,EAAI,CACd,EAAc,YAAY,EAAI,CAGhC,EAAW,QAAQ,YAAY,EAAc,GAE/C,SAAS,EAAyB,EAAwB,CACxD,GAAM,CAAE,qBAAoB,cAAe,EACtC,KAEL,IAAI,CAAC,EAAY,CACf,EAAc,MAAM,QAAU,OAC9B,OAaF,GAVA,EAAc,MAAM,eAAe,UAAU,CAE7C,EAAK,SAAS,EAAK,IAAU,CACvB,EAAmB,SAAS,EAAM,CACpC,EAAI,UAAU,IAAI,wBAAwB,CAE1C,EAAI,UAAU,OAAO,wBAAwB,EAE/C,CAEE,EAAmB,OAAS,EAAG,CACjC,IAAM,EAAiB,EAAK,EAAmB,IAC/C,GAAI,EAAgB,CAClB,IAAM,EAAiB,EAAc,YAC/B,EAAU,EAAe,WACzB,EAAW,EAAe,YAC1B,EAAiB,EAAU,EAAiB,EAAI,EAAW,EAEjE,EAAc,SAAS,CACrB,KAAM,EACN,SAAU,SACX,CAAC,EAIF,GACF,QAAQ,IAAI,wBAAyB,EAAM,GAG/C,UAAU,EAAyB,EAAyB,CAC1D,GAAe,QAAQ,CACvB,EAAK,OAAS,GAEjB"}
1
+ {"version":3,"file":"dots.umd.js","names":["dotsContainer: HTMLDivElement | null","dots: HTMLButtonElement[]"],"sources":["../src/dots.ts"],"sourcesContent":["import { MotionRail } from \"motionrail\";\nimport type { MotionRailExtension, MotionRailState } from \"motionrail\";\nimport \"./style.css\";\n\nexport function Dots(par?: {\n showIndex?: boolean;\n log?: boolean;\n}): MotionRailExtension {\n let dotsContainer: HTMLDivElement | null = null;\n const dots: HTMLButtonElement[] = [];\n const { showIndex = false, log = false } = par || {};\n\n return {\n name: \"DotsExtension\",\n onInit(motionRail: MotionRail, state: MotionRailState) {\n const { totalItems } = state;\n\n if (totalItems === 0) {\n return;\n }\n\n dotsContainer = document.createElement(\"div\");\n\n dotsContainer.className = \"motionrail-dots\";\n\n for (let i = 0; i < totalItems; i++) {\n const dot = document.createElement(\"button\");\n dot.className = \"motionrail-dot\";\n dot.setAttribute(\"aria-label\", `Go to item ${i + 1}`);\n\n if (showIndex) {\n dot.textContent = (i + 1).toString();\n }\n\n dot.addEventListener(\"click\", () => {\n motionRail.scrollToIndex(i);\n });\n\n dots.push(dot);\n dotsContainer.appendChild(dot);\n }\n\n motionRail.element.appendChild(dotsContainer);\n },\n onUpdate(_motionRail: MotionRail, state: MotionRailState) {\n const { visibleItemIndexes, totalItems } = state;\n if (!dotsContainer) return;\n\n if (!totalItems) {\n dotsContainer.style.display = \"none\";\n return;\n }\n\n dotsContainer.style.removeProperty(\"display\");\n\n dots.forEach((dot, index) => {\n if (visibleItemIndexes.includes(index)) {\n dot.classList.add(\"motionrail-dot-active\");\n } else {\n dot.classList.remove(\"motionrail-dot-active\");\n }\n });\n\n if (visibleItemIndexes.length > 0) {\n const firstActiveDot = dots[visibleItemIndexes[0]];\n if (firstActiveDot) {\n const containerWidth = dotsContainer.offsetWidth;\n const dotLeft = firstActiveDot.offsetLeft;\n const dotWidth = firstActiveDot.offsetWidth;\n const scrollPosition = dotLeft - containerWidth / 2 + dotWidth / 2;\n\n dotsContainer.scrollTo({\n left: scrollPosition,\n behavior: \"smooth\",\n });\n }\n }\n\n if (log) {\n console.log(\"DotsExtension updated\", state);\n }\n },\n onDestroy(_motionRail: MotionRail, _state: MotionRailState) {\n dotsContainer?.remove();\n dots.length = 0;\n },\n };\n}\n"],"mappings":"uQAIA,SAAgB,EAAK,EAGG,CACtB,IAAIA,EAAuC,KACrCC,EAA4B,EAAE,CAC9B,CAAE,YAAY,GAAO,MAAM,IAAU,GAAO,EAAE,CAEpD,MAAO,CACL,KAAM,gBACN,OAAO,EAAwB,EAAwB,CACrD,GAAM,CAAE,cAAe,EAEnB,OAAe,EAMnB,CAFA,EAAgB,SAAS,cAAc,MAAM,CAE7C,EAAc,UAAY,kBAE1B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,IAAK,CACnC,IAAM,EAAM,SAAS,cAAc,SAAS,CAC5C,EAAI,UAAY,iBAChB,EAAI,aAAa,aAAc,cAAc,EAAI,IAAI,CAEjD,IACF,EAAI,aAAe,EAAI,GAAG,UAAU,EAGtC,EAAI,iBAAiB,YAAe,CAClC,EAAW,cAAc,EAAE,EAC3B,CAEF,EAAK,KAAK,EAAI,CACd,EAAc,YAAY,EAAI,CAGhC,EAAW,QAAQ,YAAY,EAAc,GAE/C,SAAS,EAAyB,EAAwB,CACxD,GAAM,CAAE,qBAAoB,cAAe,EACtC,KAEL,IAAI,CAAC,EAAY,CACf,EAAc,MAAM,QAAU,OAC9B,OAaF,GAVA,EAAc,MAAM,eAAe,UAAU,CAE7C,EAAK,SAAS,EAAK,IAAU,CACvB,EAAmB,SAAS,EAAM,CACpC,EAAI,UAAU,IAAI,wBAAwB,CAE1C,EAAI,UAAU,OAAO,wBAAwB,EAE/C,CAEE,EAAmB,OAAS,EAAG,CACjC,IAAM,EAAiB,EAAK,EAAmB,IAC/C,GAAI,EAAgB,CAClB,IAAM,EAAiB,EAAc,YAC/B,EAAU,EAAe,WACzB,EAAW,EAAe,YAC1B,EAAiB,EAAU,EAAiB,EAAI,EAAW,EAEjE,EAAc,SAAS,CACrB,KAAM,EACN,SAAU,SACX,CAAC,EAIF,GACF,QAAQ,IAAI,wBAAyB,EAAM,GAG/C,UAAU,EAAyB,EAAyB,CAC1D,GAAe,QAAQ,CACvB,EAAK,OAAS,GAEjB"}
@@ -1,2 +1,8 @@
1
- import type { MotionRailExtension } from "motionrail";
2
- export declare function Logger(): MotionRailExtension;
1
+ import { MotionRail } from "motionrail";
2
+ import type { MotionRailExtension, MotionRailState } from "motionrail";
3
+ export declare function Logger(par?: {
4
+ onInit?: (motionRail: MotionRail, state: MotionRailState) => void;
5
+ onUpdate?: (motionRail: MotionRail, state: MotionRailState) => void;
6
+ onDestroy?: (motionRail: MotionRail, state: MotionRailState) => void;
7
+ outputToConsole?: boolean;
8
+ }): MotionRailExtension;
@@ -1,15 +1,16 @@
1
1
  import "motionrail";
2
- function Logger() {
2
+ function Logger(e) {
3
+ let { onInit: t, onUpdate: n, onDestroy: r, outputToConsole: i = !0 } = e || { outputToConsole: !0 };
3
4
  return {
4
5
  name: "LoggerExtension",
5
- onInit(e, t) {
6
- console.debug("[LoggerExtension] MotionRail initialized", t), console.debug(e);
6
+ onInit(e, n) {
7
+ i && (console.debug("[LoggerExtension] MotionRail initialized", n), console.debug(e)), t && t(e, n);
7
8
  },
8
9
  onUpdate(e, t) {
9
- console.debug("[LoggerExtension] MotionRail updated", t), console.debug(e);
10
+ i && (console.debug("[LoggerExtension] MotionRail updated", t), console.debug(e)), n && n(e, t);
10
11
  },
11
12
  onDestroy(e, t) {
12
- console.debug("[LoggerExtension] MotionRail destroyed", t), console.debug(e);
13
+ i && (console.debug("[LoggerExtension] MotionRail destroyed", t), console.debug(e)), r && r(e, t);
13
14
  }
14
15
  };
15
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"logger.es.js","names":[],"sources":["../src/logger.ts"],"sourcesContent":["import { MotionRail } from \"motionrail\";\nimport type { MotionRailExtension, MotionRailState } from \"motionrail\";\n\nexport function Logger(): MotionRailExtension {\n return {\n name: \"LoggerExtension\",\n onInit(motionRail: MotionRail, state: MotionRailState) {\n console.debug(`[LoggerExtension] MotionRail initialized`, state);\n console.debug(motionRail);\n },\n onUpdate(motionRail: MotionRail, state: MotionRailState) {\n console.debug(`[LoggerExtension] MotionRail updated`, state);\n console.debug(motionRail);\n },\n onDestroy(motionRail: MotionRail, state: MotionRailState) {\n console.debug(`[LoggerExtension] MotionRail destroyed`, state);\n console.debug(motionRail);\n },\n };\n}\n"],"mappings":";AAGA,SAAgB,SAA8B;AAC5C,QAAO;EACL,MAAM;EACN,OAAO,GAAwB,GAAwB;AAErD,GADA,QAAQ,MAAM,4CAA4C,EAAM,EAChE,QAAQ,MAAM,EAAW;;EAE3B,SAAS,GAAwB,GAAwB;AAEvD,GADA,QAAQ,MAAM,wCAAwC,EAAM,EAC5D,QAAQ,MAAM,EAAW;;EAE3B,UAAU,GAAwB,GAAwB;AAExD,GADA,QAAQ,MAAM,0CAA0C,EAAM,EAC9D,QAAQ,MAAM,EAAW;;EAE5B"}
1
+ {"version":3,"file":"logger.es.js","names":[],"sources":["../src/logger.ts"],"sourcesContent":["import { MotionRail } from \"motionrail\";\nimport type { MotionRailExtension, MotionRailState } from \"motionrail\";\n\nexport function Logger(par?: {\n onInit?: (motionRail: MotionRail, state: MotionRailState) => void;\n onUpdate?: (motionRail: MotionRail, state: MotionRailState) => void;\n onDestroy?: (motionRail: MotionRail, state: MotionRailState) => void;\n outputToConsole?: boolean;\n}): MotionRailExtension {\n const {\n onInit,\n onUpdate,\n onDestroy,\n outputToConsole = true,\n } = par || { outputToConsole: true };\n\n return {\n name: \"LoggerExtension\",\n onInit(motionRail: MotionRail, state: MotionRailState) {\n if (outputToConsole) {\n console.debug(`[LoggerExtension] MotionRail initialized`, state);\n console.debug(motionRail);\n }\n onInit && onInit(motionRail, state);\n },\n onUpdate(motionRail: MotionRail, state: MotionRailState) {\n if (outputToConsole) {\n console.debug(`[LoggerExtension] MotionRail updated`, state);\n console.debug(motionRail);\n }\n onUpdate && onUpdate(motionRail, state);\n },\n onDestroy(motionRail: MotionRail, state: MotionRailState) {\n if (outputToConsole) {\n console.debug(`[LoggerExtension] MotionRail destroyed`, state);\n console.debug(motionRail);\n }\n onDestroy && onDestroy(motionRail, state);\n },\n };\n}\n"],"mappings":";AAGA,SAAgB,OAAO,GAKC;CACtB,IAAM,EACJ,WACA,aACA,cACA,qBAAkB,OAChB,KAAO,EAAE,iBAAiB,IAAM;AAEpC,QAAO;EACL,MAAM;EACN,OAAO,GAAwB,GAAwB;AAKrD,GAJI,MACF,QAAQ,MAAM,4CAA4C,EAAM,EAChE,QAAQ,MAAM,EAAW,GAE3B,KAAU,EAAO,GAAY,EAAM;;EAErC,SAAS,GAAwB,GAAwB;AAKvD,GAJI,MACF,QAAQ,MAAM,wCAAwC,EAAM,EAC5D,QAAQ,MAAM,EAAW,GAE3B,KAAY,EAAS,GAAY,EAAM;;EAEzC,UAAU,GAAwB,GAAwB;AAKxD,GAJI,MACF,QAAQ,MAAM,0CAA0C,EAAM,EAC9D,QAAQ,MAAM,EAAW,GAE3B,KAAa,EAAU,GAAY,EAAM;;EAE5C"}
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`motionrail`)):typeof define==`function`&&define.amd?define([`exports`,`motionrail`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRailLogger={},e.MotionRail))})(this,function(e,t){function n(){return{name:`LoggerExtension`,onInit(e,t){console.debug(`[LoggerExtension] MotionRail initialized`,t),console.debug(e)},onUpdate(e,t){console.debug(`[LoggerExtension] MotionRail updated`,t),console.debug(e)},onDestroy(e,t){console.debug(`[LoggerExtension] MotionRail destroyed`,t),console.debug(e)}}}e.Logger=n});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`motionrail`)):typeof define==`function`&&define.amd?define([`exports`,`motionrail`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRail={},e.MotionRail))})(this,function(e,t){function n(e){let{onInit:t,onUpdate:n,onDestroy:r,outputToConsole:i=!0}=e||{outputToConsole:!0};return{name:`LoggerExtension`,onInit(e,n){i&&(console.debug(`[LoggerExtension] MotionRail initialized`,n),console.debug(e)),t&&t(e,n)},onUpdate(e,t){i&&(console.debug(`[LoggerExtension] MotionRail updated`,t),console.debug(e)),n&&n(e,t)},onDestroy(e,t){i&&(console.debug(`[LoggerExtension] MotionRail destroyed`,t),console.debug(e)),r&&r(e,t)}}}e.Logger=n});
2
2
  //# sourceMappingURL=logger.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.umd.js","names":[],"sources":["../src/logger.ts"],"sourcesContent":["import { MotionRail } from \"motionrail\";\nimport type { MotionRailExtension, MotionRailState } from \"motionrail\";\n\nexport function Logger(): MotionRailExtension {\n return {\n name: \"LoggerExtension\",\n onInit(motionRail: MotionRail, state: MotionRailState) {\n console.debug(`[LoggerExtension] MotionRail initialized`, state);\n console.debug(motionRail);\n },\n onUpdate(motionRail: MotionRail, state: MotionRailState) {\n console.debug(`[LoggerExtension] MotionRail updated`, state);\n console.debug(motionRail);\n },\n onDestroy(motionRail: MotionRail, state: MotionRailState) {\n console.debug(`[LoggerExtension] MotionRail destroyed`, state);\n console.debug(motionRail);\n },\n };\n}\n"],"mappings":"6QAGA,SAAgB,GAA8B,CAC5C,MAAO,CACL,KAAM,kBACN,OAAO,EAAwB,EAAwB,CACrD,QAAQ,MAAM,2CAA4C,EAAM,CAChE,QAAQ,MAAM,EAAW,EAE3B,SAAS,EAAwB,EAAwB,CACvD,QAAQ,MAAM,uCAAwC,EAAM,CAC5D,QAAQ,MAAM,EAAW,EAE3B,UAAU,EAAwB,EAAwB,CACxD,QAAQ,MAAM,yCAA0C,EAAM,CAC9D,QAAQ,MAAM,EAAW,EAE5B"}
1
+ {"version":3,"file":"logger.umd.js","names":[],"sources":["../src/logger.ts"],"sourcesContent":["import { MotionRail } from \"motionrail\";\nimport type { MotionRailExtension, MotionRailState } from \"motionrail\";\n\nexport function Logger(par?: {\n onInit?: (motionRail: MotionRail, state: MotionRailState) => void;\n onUpdate?: (motionRail: MotionRail, state: MotionRailState) => void;\n onDestroy?: (motionRail: MotionRail, state: MotionRailState) => void;\n outputToConsole?: boolean;\n}): MotionRailExtension {\n const {\n onInit,\n onUpdate,\n onDestroy,\n outputToConsole = true,\n } = par || { outputToConsole: true };\n\n return {\n name: \"LoggerExtension\",\n onInit(motionRail: MotionRail, state: MotionRailState) {\n if (outputToConsole) {\n console.debug(`[LoggerExtension] MotionRail initialized`, state);\n console.debug(motionRail);\n }\n onInit && onInit(motionRail, state);\n },\n onUpdate(motionRail: MotionRail, state: MotionRailState) {\n if (outputToConsole) {\n console.debug(`[LoggerExtension] MotionRail updated`, state);\n console.debug(motionRail);\n }\n onUpdate && onUpdate(motionRail, state);\n },\n onDestroy(motionRail: MotionRail, state: MotionRailState) {\n if (outputToConsole) {\n console.debug(`[LoggerExtension] MotionRail destroyed`, state);\n console.debug(motionRail);\n }\n onDestroy && onDestroy(motionRail, state);\n },\n };\n}\n"],"mappings":"uQAGA,SAAgB,EAAO,EAKC,CACtB,GAAM,CACJ,SACA,WACA,YACA,kBAAkB,IAChB,GAAO,CAAE,gBAAiB,GAAM,CAEpC,MAAO,CACL,KAAM,kBACN,OAAO,EAAwB,EAAwB,CACjD,IACF,QAAQ,MAAM,2CAA4C,EAAM,CAChE,QAAQ,MAAM,EAAW,EAE3B,GAAU,EAAO,EAAY,EAAM,EAErC,SAAS,EAAwB,EAAwB,CACnD,IACF,QAAQ,MAAM,uCAAwC,EAAM,CAC5D,QAAQ,MAAM,EAAW,EAE3B,GAAY,EAAS,EAAY,EAAM,EAEzC,UAAU,EAAwB,EAAwB,CACpD,IACF,QAAQ,MAAM,yCAA0C,EAAM,CAC9D,QAAQ,MAAM,EAAW,EAE3B,GAAa,EAAU,EAAY,EAAM,EAE5C"}
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`motionrail`)):typeof define==`function`&&define.amd?define([`exports`,`motionrail`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRailThumbnails={},e.MotionRail))})(this,function(e,t){function n(e){let t=null,n=[],{thumbnailWidth:r=80,thumbnailHeight:i=80,log:a=!1}=e||{};return{name:`ThumbnailsExtension`,onInit(e,a){let{totalItems:o}=a;o!==0&&(t=document.createElement(`div`),t.className=`motionrail-thumbnails`,t.style.setProperty(`--thumbnail-width`,`${r}px`),t.style.setProperty(`--thumbnail-height`,`${i}px`),e.element.querySelectorAll(`[data-motionrail-grid] > *`).forEach((r,i)=>{let a=document.createElement(`button`);a.className=`motionrail-thumbnail`,a.setAttribute(`aria-label`,`Go to item ${i+1}`);let o=r.cloneNode(!0);o.removeAttribute(`data-motionrail-item`),a.appendChild(o),a.addEventListener(`click`,()=>{e.scrollToIndex(i)}),n.push(a),t.appendChild(a)}),e.element.appendChild(t))},onUpdate(e,r){let{visibleItemIndexes:i,totalItems:o}=r;if(t){if(!o){t.style.display=`none`;return}if(t.style.removeProperty(`display`),n.forEach((e,t)=>{i.includes(t)?e.classList.add(`motionrail-thumbnail-active`):e.classList.remove(`motionrail-thumbnail-active`)}),i.length>0){let e=n[i[0]];if(e){let n=t.offsetWidth,r=e.offsetLeft,i=e.offsetWidth,a=r-n/2+i/2;t.scrollTo({left:a,behavior:`smooth`})}}a&&console.log(`ThumbnailsExtension updated`,r)}},onDestroy(e,r){t?.remove(),n.length=0}}}e.Thumbnails=n});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`motionrail`)):typeof define==`function`&&define.amd?define([`exports`,`motionrail`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRail={},e.MotionRail))})(this,function(e,t){function n(e){let t=null,n=[],{thumbnailWidth:r=80,thumbnailHeight:i=80,log:a=!1}=e||{};return{name:`ThumbnailsExtension`,onInit(e,a){let{totalItems:o}=a;o!==0&&(t=document.createElement(`div`),t.className=`motionrail-thumbnails`,t.style.setProperty(`--thumbnail-width`,`${r}px`),t.style.setProperty(`--thumbnail-height`,`${i}px`),e.element.querySelectorAll(`[data-motionrail-grid] > *`).forEach((r,i)=>{let a=document.createElement(`button`);a.className=`motionrail-thumbnail`,a.setAttribute(`aria-label`,`Go to item ${i+1}`);let o=r.cloneNode(!0);o.removeAttribute(`data-motionrail-item`),a.appendChild(o),a.addEventListener(`click`,()=>{e.scrollToIndex(i)}),n.push(a),t.appendChild(a)}),e.element.appendChild(t))},onUpdate(e,r){let{visibleItemIndexes:i,totalItems:o}=r;if(t){if(!o){t.style.display=`none`;return}if(t.style.removeProperty(`display`),n.forEach((e,t)=>{i.includes(t)?e.classList.add(`motionrail-thumbnail-active`):e.classList.remove(`motionrail-thumbnail-active`)}),i.length>0){let e=n[i[0]];if(e){let n=t.offsetWidth,r=e.offsetLeft,i=e.offsetWidth,a=r-n/2+i/2;t.scrollTo({left:a,behavior:`smooth`})}}a&&console.log(`ThumbnailsExtension updated`,r)}},onDestroy(e,r){t?.remove(),n.length=0}}}e.Thumbnails=n});
2
2
  //# sourceMappingURL=thumbnails.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"thumbnails.umd.js","names":["thumbnailsContainer: HTMLDivElement | null","thumbnails: HTMLButtonElement[]"],"sources":["../src/thumbnails.ts"],"sourcesContent":["import { MotionRail } from \"motionrail\";\nimport type { MotionRailExtension, MotionRailState } from \"motionrail\";\nimport \"./style.css\";\n\nexport function Thumbnails(par?: {\n thumbnailWidth?: number;\n thumbnailHeight?: number;\n log?: boolean;\n}): MotionRailExtension {\n let thumbnailsContainer: HTMLDivElement | null = null;\n const thumbnails: HTMLButtonElement[] = [];\n const { thumbnailWidth = 80, thumbnailHeight = 80, log = false } = par || {};\n\n return {\n name: \"ThumbnailsExtension\",\n onInit(motionRail: MotionRail, state: MotionRailState) {\n const { totalItems } = state;\n\n if (totalItems === 0) {\n return;\n }\n\n thumbnailsContainer = document.createElement(\"div\");\n\n thumbnailsContainer.className = \"motionrail-thumbnails\";\n thumbnailsContainer.style.setProperty(\n \"--thumbnail-width\",\n `${thumbnailWidth}px`,\n );\n thumbnailsContainer.style.setProperty(\n \"--thumbnail-height\",\n `${thumbnailHeight}px`,\n );\n\n const items = motionRail.element.querySelectorAll(\n \"[data-motionrail-grid] > *\",\n );\n\n items.forEach((item, index) => {\n const thumbnail = document.createElement(\"button\");\n thumbnail.className = \"motionrail-thumbnail\";\n thumbnail.setAttribute(\"aria-label\", `Go to item ${index + 1}`);\n\n const clone = item.cloneNode(true) as HTMLElement;\n clone.removeAttribute(\"data-motionrail-item\");\n thumbnail.appendChild(clone);\n\n thumbnail.addEventListener(\"click\", () => {\n motionRail.scrollToIndex(index);\n });\n\n thumbnails.push(thumbnail);\n thumbnailsContainer!.appendChild(thumbnail);\n });\n\n motionRail.element.appendChild(thumbnailsContainer);\n },\n onUpdate(_motionRail: MotionRail, state: MotionRailState) {\n const { visibleItemIndexes, totalItems } = state;\n if (!thumbnailsContainer) return;\n\n if (!totalItems) {\n thumbnailsContainer.style.display = \"none\";\n return;\n }\n\n thumbnailsContainer.style.removeProperty(\"display\");\n thumbnails.forEach((thumbnail, index) => {\n if (visibleItemIndexes.includes(index)) {\n thumbnail.classList.add(\"motionrail-thumbnail-active\");\n } else {\n thumbnail.classList.remove(\"motionrail-thumbnail-active\");\n }\n });\n\n if (visibleItemIndexes.length > 0) {\n const firstActiveThumbnail = thumbnails[visibleItemIndexes[0]];\n if (firstActiveThumbnail) {\n const containerWidth = thumbnailsContainer.offsetWidth;\n const thumbnailLeft = firstActiveThumbnail.offsetLeft;\n const thumbnailWidth = firstActiveThumbnail.offsetWidth;\n const scrollPosition =\n thumbnailLeft - containerWidth / 2 + thumbnailWidth / 2;\n\n thumbnailsContainer.scrollTo({\n left: scrollPosition,\n behavior: \"smooth\",\n });\n }\n }\n\n if (log) {\n console.log(\"ThumbnailsExtension updated\", state);\n }\n },\n onDestroy(_motionRail: MotionRail, _state: MotionRailState) {\n thumbnailsContainer?.remove();\n thumbnails.length = 0;\n },\n };\n}\n"],"mappings":"iRAIA,SAAgB,EAAW,EAIH,CACtB,IAAIA,EAA6C,KAC3CC,EAAkC,EAAE,CACpC,CAAE,iBAAiB,GAAI,kBAAkB,GAAI,MAAM,IAAU,GAAO,EAAE,CAE5E,MAAO,CACL,KAAM,sBACN,OAAO,EAAwB,EAAwB,CACrD,GAAM,CAAE,cAAe,EAEnB,IAAe,IAInB,EAAsB,SAAS,cAAc,MAAM,CAEnD,EAAoB,UAAY,wBAChC,EAAoB,MAAM,YACxB,oBACA,GAAG,EAAe,IACnB,CACD,EAAoB,MAAM,YACxB,qBACA,GAAG,EAAgB,IACpB,CAEa,EAAW,QAAQ,iBAC/B,6BACD,CAEK,SAAS,EAAM,IAAU,CAC7B,IAAM,EAAY,SAAS,cAAc,SAAS,CAClD,EAAU,UAAY,uBACtB,EAAU,aAAa,aAAc,cAAc,EAAQ,IAAI,CAE/D,IAAM,EAAQ,EAAK,UAAU,GAAK,CAClC,EAAM,gBAAgB,uBAAuB,CAC7C,EAAU,YAAY,EAAM,CAE5B,EAAU,iBAAiB,YAAe,CACxC,EAAW,cAAc,EAAM,EAC/B,CAEF,EAAW,KAAK,EAAU,CAC1B,EAAqB,YAAY,EAAU,EAC3C,CAEF,EAAW,QAAQ,YAAY,EAAoB,GAErD,SAAS,EAAyB,EAAwB,CACxD,GAAM,CAAE,qBAAoB,cAAe,EACtC,KAEL,IAAI,CAAC,EAAY,CACf,EAAoB,MAAM,QAAU,OACpC,OAYF,GATA,EAAoB,MAAM,eAAe,UAAU,CACnD,EAAW,SAAS,EAAW,IAAU,CACnC,EAAmB,SAAS,EAAM,CACpC,EAAU,UAAU,IAAI,8BAA8B,CAEtD,EAAU,UAAU,OAAO,8BAA8B,EAE3D,CAEE,EAAmB,OAAS,EAAG,CACjC,IAAM,EAAuB,EAAW,EAAmB,IAC3D,GAAI,EAAsB,CACxB,IAAM,EAAiB,EAAoB,YACrC,EAAgB,EAAqB,WACrC,EAAiB,EAAqB,YACtC,EACJ,EAAgB,EAAiB,EAAI,EAAiB,EAExD,EAAoB,SAAS,CAC3B,KAAM,EACN,SAAU,SACX,CAAC,EAIF,GACF,QAAQ,IAAI,8BAA+B,EAAM,GAGrD,UAAU,EAAyB,EAAyB,CAC1D,GAAqB,QAAQ,CAC7B,EAAW,OAAS,GAEvB"}
1
+ {"version":3,"file":"thumbnails.umd.js","names":["thumbnailsContainer: HTMLDivElement | null","thumbnails: HTMLButtonElement[]"],"sources":["../src/thumbnails.ts"],"sourcesContent":["import { MotionRail } from \"motionrail\";\nimport type { MotionRailExtension, MotionRailState } from \"motionrail\";\nimport \"./style.css\";\n\nexport function Thumbnails(par?: {\n thumbnailWidth?: number;\n thumbnailHeight?: number;\n log?: boolean;\n}): MotionRailExtension {\n let thumbnailsContainer: HTMLDivElement | null = null;\n const thumbnails: HTMLButtonElement[] = [];\n const { thumbnailWidth = 80, thumbnailHeight = 80, log = false } = par || {};\n\n return {\n name: \"ThumbnailsExtension\",\n onInit(motionRail: MotionRail, state: MotionRailState) {\n const { totalItems } = state;\n\n if (totalItems === 0) {\n return;\n }\n\n thumbnailsContainer = document.createElement(\"div\");\n\n thumbnailsContainer.className = \"motionrail-thumbnails\";\n thumbnailsContainer.style.setProperty(\n \"--thumbnail-width\",\n `${thumbnailWidth}px`,\n );\n thumbnailsContainer.style.setProperty(\n \"--thumbnail-height\",\n `${thumbnailHeight}px`,\n );\n\n const items = motionRail.element.querySelectorAll(\n \"[data-motionrail-grid] > *\",\n );\n\n items.forEach((item, index) => {\n const thumbnail = document.createElement(\"button\");\n thumbnail.className = \"motionrail-thumbnail\";\n thumbnail.setAttribute(\"aria-label\", `Go to item ${index + 1}`);\n\n const clone = item.cloneNode(true) as HTMLElement;\n clone.removeAttribute(\"data-motionrail-item\");\n thumbnail.appendChild(clone);\n\n thumbnail.addEventListener(\"click\", () => {\n motionRail.scrollToIndex(index);\n });\n\n thumbnails.push(thumbnail);\n thumbnailsContainer!.appendChild(thumbnail);\n });\n\n motionRail.element.appendChild(thumbnailsContainer);\n },\n onUpdate(_motionRail: MotionRail, state: MotionRailState) {\n const { visibleItemIndexes, totalItems } = state;\n if (!thumbnailsContainer) return;\n\n if (!totalItems) {\n thumbnailsContainer.style.display = \"none\";\n return;\n }\n\n thumbnailsContainer.style.removeProperty(\"display\");\n thumbnails.forEach((thumbnail, index) => {\n if (visibleItemIndexes.includes(index)) {\n thumbnail.classList.add(\"motionrail-thumbnail-active\");\n } else {\n thumbnail.classList.remove(\"motionrail-thumbnail-active\");\n }\n });\n\n if (visibleItemIndexes.length > 0) {\n const firstActiveThumbnail = thumbnails[visibleItemIndexes[0]];\n if (firstActiveThumbnail) {\n const containerWidth = thumbnailsContainer.offsetWidth;\n const thumbnailLeft = firstActiveThumbnail.offsetLeft;\n const thumbnailWidth = firstActiveThumbnail.offsetWidth;\n const scrollPosition =\n thumbnailLeft - containerWidth / 2 + thumbnailWidth / 2;\n\n thumbnailsContainer.scrollTo({\n left: scrollPosition,\n behavior: \"smooth\",\n });\n }\n }\n\n if (log) {\n console.log(\"ThumbnailsExtension updated\", state);\n }\n },\n onDestroy(_motionRail: MotionRail, _state: MotionRailState) {\n thumbnailsContainer?.remove();\n thumbnails.length = 0;\n },\n };\n}\n"],"mappings":"uQAIA,SAAgB,EAAW,EAIH,CACtB,IAAIA,EAA6C,KAC3CC,EAAkC,EAAE,CACpC,CAAE,iBAAiB,GAAI,kBAAkB,GAAI,MAAM,IAAU,GAAO,EAAE,CAE5E,MAAO,CACL,KAAM,sBACN,OAAO,EAAwB,EAAwB,CACrD,GAAM,CAAE,cAAe,EAEnB,IAAe,IAInB,EAAsB,SAAS,cAAc,MAAM,CAEnD,EAAoB,UAAY,wBAChC,EAAoB,MAAM,YACxB,oBACA,GAAG,EAAe,IACnB,CACD,EAAoB,MAAM,YACxB,qBACA,GAAG,EAAgB,IACpB,CAEa,EAAW,QAAQ,iBAC/B,6BACD,CAEK,SAAS,EAAM,IAAU,CAC7B,IAAM,EAAY,SAAS,cAAc,SAAS,CAClD,EAAU,UAAY,uBACtB,EAAU,aAAa,aAAc,cAAc,EAAQ,IAAI,CAE/D,IAAM,EAAQ,EAAK,UAAU,GAAK,CAClC,EAAM,gBAAgB,uBAAuB,CAC7C,EAAU,YAAY,EAAM,CAE5B,EAAU,iBAAiB,YAAe,CACxC,EAAW,cAAc,EAAM,EAC/B,CAEF,EAAW,KAAK,EAAU,CAC1B,EAAqB,YAAY,EAAU,EAC3C,CAEF,EAAW,QAAQ,YAAY,EAAoB,GAErD,SAAS,EAAyB,EAAwB,CACxD,GAAM,CAAE,qBAAoB,cAAe,EACtC,KAEL,IAAI,CAAC,EAAY,CACf,EAAoB,MAAM,QAAU,OACpC,OAYF,GATA,EAAoB,MAAM,eAAe,UAAU,CACnD,EAAW,SAAS,EAAW,IAAU,CACnC,EAAmB,SAAS,EAAM,CACpC,EAAU,UAAU,IAAI,8BAA8B,CAEtD,EAAU,UAAU,OAAO,8BAA8B,EAE3D,CAEE,EAAmB,OAAS,EAAG,CACjC,IAAM,EAAuB,EAAW,EAAmB,IAC3D,GAAI,EAAsB,CACxB,IAAM,EAAiB,EAAoB,YACrC,EAAgB,EAAqB,WACrC,EAAiB,EAAqB,YACtC,EACJ,EAAgB,EAAiB,EAAI,EAAiB,EAExD,EAAoB,SAAS,CAC3B,KAAM,EACN,SAAU,SACX,CAAC,EAIF,GACF,QAAQ,IAAI,8BAA+B,EAAM,GAGrD,UAAU,EAAyB,EAAyB,CAC1D,GAAqB,QAAQ,CAC7B,EAAW,OAAS,GAEvB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "motionrail",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "A lightweight carousel library for modern web applications",
5
5
  "main": "./main/dist/motionrail.umd.js",
6
6
  "module": "./main/dist/motionrail.es.js",