motionrail 0.1.1 → 0.1.3

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
@@ -2,7 +2,7 @@
2
2
 
3
3
  > ⚠️ **Not Ready for Production** - This library is currently in development and not yet ready for production use.
4
4
 
5
- A lightweight, smooth carousel library with momentum-based scrolling, snap alignment, and responsive breakpoints.
5
+ A lightweight, smooth carousel library with momentum-based scrolling, snap alignment, and responsive breakpoints. Works with vanilla JavaScript or your favorite framework.
6
6
 
7
7
  ## Features
8
8
 
@@ -14,7 +14,8 @@ A lightweight, smooth carousel library with momentum-based scrolling, snap align
14
14
  - 🎨 **CSS Grid based** - Modern layout with customizable styling
15
15
  - 🪶 **Lightweight** - Zero dependencies, minimal bundle size
16
16
  - 🎮 **Full control API** - Programmatic navigation and playback control
17
- - 🧩 **Extension system** - Modular architecture with built-in extensions (Arrows, Logger)
17
+ - 🧩 **Extension system** - Modular architecture with built-in extensions
18
+ - ⚛️ **Framework integrations** - React, Solid, Vue, Svelte components
18
19
 
19
20
  ## Installation
20
21
 
@@ -24,6 +25,8 @@ npm install motionrail
24
25
 
25
26
  ## Quick Start
26
27
 
28
+ ### Vanilla JavaScript
29
+
27
30
  ```js
28
31
  import { MotionRail } from 'motionrail';
29
32
  import 'motionrail/style.css';
@@ -37,14 +40,101 @@ const carousel = new MotionRail(document.getElementById('carousel'), {
37
40
  });
38
41
  ```
39
42
 
43
+ ### React
44
+
45
+ ```jsx
46
+ import { MotionRail } from 'motionrail/react';
47
+ import 'motionrail/style.css';
48
+
49
+ function App() {
50
+ return (
51
+ <MotionRail options={{ breakpoints: [{ columns: 3, gap: '20px' }] }}>
52
+ <div>Item 1</div>
53
+ <div>Item 2</div>
54
+ <div>Item 3</div>
55
+ </MotionRail>
56
+ );
57
+ }
58
+ ```
59
+
60
+ ### Solid.js
61
+
62
+ ```jsx
63
+ import { MotionRail } from 'motionrail/solid';
64
+ import 'motionrail/style.css';
65
+
66
+ function App() {
67
+ return (
68
+ <MotionRail options={{ breakpoints: [{ columns: 3, gap: '20px' }] }}>
69
+ <div>Item 1</div>
70
+ <div>Item 2</div>
71
+ <div>Item 3</div>
72
+ </MotionRail>
73
+ );
74
+ }
75
+ ```
76
+
77
+ ### Vue
78
+
79
+ ```vue
80
+ <script setup>
81
+ import { MotionRail } from 'motionrail/vue';
82
+ import 'motionrail/style.css';
83
+
84
+ const options = { breakpoints: [{ columns: 3, gap: '20px' }] };
85
+ </script>
86
+
87
+ <template>
88
+ <MotionRail :options="options">
89
+ <div>Item 1</div>
90
+ <div>Item 2</div>
91
+ <div>Item 3</div>
92
+ </MotionRail>
93
+ </template>
94
+ ```
95
+
96
+ ### Svelte
97
+
98
+ ```svelte
99
+ <script>
100
+ import { MotionRail } from 'motionrail/svelte';
101
+ import 'motionrail/style.css';
102
+
103
+ const options = { breakpoints: [{ columns: 3, gap: '20px' }] };
104
+ </script>
105
+
106
+ <MotionRail {options}>
107
+ <div>Item 1</div>
108
+ <div>Item 2</div>
109
+ <div>Item 3</div>
110
+ </MotionRail>
111
+ ```
112
+
113
+ ### Svelte 5 (with Runes)
114
+
115
+ ```svelte
116
+ <script>
117
+ import { MotionRail } from 'motionrail/svelte5';
118
+ import 'motionrail/style.css';
119
+
120
+ const options = { breakpoints: [{ columns: 3, gap: '20px' }] };
121
+ </script>
122
+
123
+ <MotionRail {options}>
124
+ <div>Item 1</div>
125
+ <div>Item 2</div>
126
+ <div>Item 3</div>
127
+ </MotionRail>
128
+ ```
129
+
40
130
  ## Usage
41
131
 
42
132
  ### HTML Structure
43
133
 
44
134
  ```html
45
- <div data-motion-rail id="carousel">
46
- <div data-motion-rail-scrollable>
47
- <div data-motion-rail-grid>
135
+ <div data-motionrail id="carousel">
136
+ <div data-motionrail-scrollable>
137
+ <div data-motionrail-grid>
48
138
  <div>Item 1</div>
49
139
  <div>Item 2</div>
50
140
  <div>Item 3</div>
@@ -55,9 +145,9 @@ const carousel = new MotionRail(document.getElementById('carousel'), {
55
145
  ```
56
146
 
57
147
  **Structure layers:**
58
- - `[data-motion-rail]` - Wrapper element (receives the ID)
59
- - `[data-motion-rail-scrollable]` - Scrollable container with overflow and snap behavior
60
- - `[data-motion-rail-grid]` - Grid layout container
148
+ - `[data-motionrail]` - Wrapper element (receives the ID)
149
+ - `[data-motionrail-scrollable]` - Scrollable container with overflow and snap behavior
150
+ - `[data-motionrail-grid]` - Grid layout container
61
151
  - Direct children - Carousel items (no specific class or attribute required)
62
152
 
63
153
  ### CSS Import
@@ -66,7 +156,7 @@ const carousel = new MotionRail(document.getElementById('carousel'), {
66
156
  import 'motionrail/style.css';
67
157
  ```
68
158
 
69
- ### JavaScript
159
+ ### Vanilla JavaScript
70
160
 
71
161
  ```js
72
162
  import { MotionRail } from 'motionrail';
@@ -88,6 +178,235 @@ const carousel = new MotionRail(element, {
88
178
  });
89
179
  ```
90
180
 
181
+ ## Framework Integrations
182
+
183
+ MotionRail provides first-class framework integrations for React, Solid.js, Vue, and Svelte. All integrations are lightweight and use the same API.
184
+
185
+ ### Bundle Sizes
186
+
187
+ - **React**: 0.87 kB (gzipped: 0.42 kB)
188
+ - **Solid.js**: 0.89 kB (gzipped: 0.48 kB)
189
+ - **Vue**: 1.22 kB (gzipped: 0.62 kB)
190
+ - **Svelte**: 2.21 kB (gzipped: 0.94 kB)
191
+ - **Svelte 5**: 1.80 kB (gzipped: 0.82 kB)
192
+
193
+ ### React Integration
194
+
195
+ ```jsx
196
+ import { MotionRail } from 'motionrail/react';
197
+ import 'motionrail/style.css';
198
+
199
+ function MyCarousel() {
200
+ const carouselRef = useRef(null);
201
+ const containerRef = useRef(null);
202
+
203
+ const handleNext = () => {
204
+ carouselRef.current?.next();
205
+ };
206
+
207
+ return (
208
+ <>
209
+ <MotionRail
210
+ ref={carouselRef}
211
+ divRef={containerRef}
212
+ options={{
213
+ autoplay: true,
214
+ delay: 3000,
215
+ breakpoints: [
216
+ { columns: 1, gap: '16px' },
217
+ { width: 768, columns: 2, gap: '16px' },
218
+ { width: 1024, columns: 3, gap: '20px' }
219
+ ],
220
+ onChange: (state) => console.log(state)
221
+ }}
222
+ >
223
+ <div>Item 1</div>
224
+ <div>Item 2</div>
225
+ <div>Item 3</div>
226
+ </MotionRail>
227
+ <button onClick={handleNext}>Next</button>
228
+ </>
229
+ );
230
+ }
231
+ ```
232
+
233
+ **Props:**
234
+ - `options`: MotionRailOptions object
235
+ - `ref`: Receives the MotionRail instance
236
+ - `divRef`: Receives the container HTMLDivElement
237
+ - `children`: Carousel items
238
+
239
+ ### Solid.js Integration
240
+
241
+ ```jsx
242
+ import { MotionRail } from 'motionrail/solid';
243
+ import 'motionrail/style.css';
244
+
245
+ function MyCarousel() {
246
+ let carousel;
247
+ let container;
248
+
249
+ const handleNext = () => {
250
+ carousel?.next();
251
+ };
252
+
253
+ return (
254
+ <>
255
+ <MotionRail
256
+ ref={(instance) => carousel = instance}
257
+ divRef={(el) => container = el}
258
+ options={{
259
+ autoplay: true,
260
+ delay: 3000,
261
+ breakpoints: [
262
+ { columns: 1, gap: '16px' },
263
+ { width: 768, columns: 2, gap: '16px' },
264
+ { width: 1024, columns: 3, gap: '20px' }
265
+ ],
266
+ onChange: (state) => console.log(state)
267
+ }}
268
+ >
269
+ <div>Item 1</div>
270
+ <div>Item 2</div>
271
+ <div>Item 3</div>
272
+ </MotionRail>
273
+ <button onClick={handleNext}>Next</button>
274
+ </>
275
+ );
276
+ }
277
+ ```
278
+
279
+ **Props:**
280
+ - `options`: MotionRailOptions object
281
+ - `ref`: Callback that receives the MotionRail instance
282
+ - `divRef`: Callback that receives the container HTMLDivElement
283
+ - `children`: Carousel items
284
+
285
+ ### Vue Integration
286
+
287
+ ```vue
288
+ <script setup>
289
+ import { ref } from 'vue';
290
+ import { MotionRail } from 'motionrail/vue';
291
+ import 'motionrail/style.css';
292
+
293
+ const carouselRef = ref(null);
294
+
295
+ const options = {
296
+ autoplay: true,
297
+ delay: 3000,
298
+ breakpoints: [
299
+ { columns: 1, gap: '16px' },
300
+ { width: 768, columns: 2, gap: '16px' },
301
+ { width: 1024, columns: 3, gap: '20px' }
302
+ ],
303
+ onChange: (state) => console.log(state)
304
+ };
305
+
306
+ const handleNext = () => {
307
+ carouselRef.value?.instance?.next();
308
+ };
309
+ </script>
310
+
311
+ <template>
312
+ <div>
313
+ <MotionRail ref="carouselRef" :options="options">
314
+ <div>Item 1</div>
315
+ <div>Item 2</div>
316
+ <div>Item 3</div>
317
+ </MotionRail>
318
+ <button @click="handleNext">Next</button>
319
+ </div>
320
+ </template>
321
+ ```
322
+
323
+ **Props:**
324
+ - `options`: MotionRailOptions object
325
+
326
+ **Template Ref Access:**
327
+ - `instance`: MotionRail instance
328
+ - `container`: Container HTMLDivElement
329
+
330
+ ### Svelte Integration
331
+
332
+ ```svelte
333
+ <script>
334
+ import { MotionRail } from 'motionrail/svelte';
335
+ import 'motionrail/style.css';
336
+
337
+ let instance;
338
+ let container;
339
+
340
+ const options = {
341
+ autoplay: true,
342
+ delay: 3000,
343
+ breakpoints: [
344
+ { columns: 1, gap: '16px' },
345
+ { width: 768, columns: 2, gap: '16px' },
346
+ { width: 1024, columns: 3, gap: '20px' }
347
+ ],
348
+ onChange: (state) => console.log(state)
349
+ };
350
+
351
+ function handleNext() {
352
+ instance?.next();
353
+ }
354
+ </script>
355
+
356
+ <MotionRail {options} bind:instance bind:container>
357
+ <div>Item 1</div>
358
+ <div>Item 2</div>
359
+ <div>Item 3</div>
360
+ </MotionRail>
361
+ <button on:click={handleNext}>Next</button>
362
+ ```
363
+
364
+ **Props:**
365
+ - `options`: MotionRailOptions object
366
+ - `bind:instance`: Binds the MotionRail instance
367
+ - `bind:container`: Binds the container HTMLDivElement
368
+
369
+ ### Svelte 5 Integration (Runes)
370
+
371
+ ```svelte
372
+ <script>
373
+ import { MotionRail } from 'motionrail/svelte5';
374
+ import 'motionrail/style.css';
375
+
376
+ let instance = $state();
377
+ let container = $state();
378
+
379
+ const options = {
380
+ autoplay: true,
381
+ delay: 3000,
382
+ breakpoints: [
383
+ { columns: 1, gap: '16px' },
384
+ { width: 768, columns: 2, gap: '16px' },
385
+ { width: 1024, columns: 3, gap: '20px' }
386
+ ],
387
+ onChange: (state) => console.log(state)
388
+ };
389
+
390
+ function handleNext() {
391
+ instance?.next();
392
+ }
393
+ </script>
394
+
395
+ <MotionRail {options} bind:instance bind:container>
396
+ <div>Item 1</div>
397
+ <div>Item 2</div>
398
+ <div>Item 3</div>
399
+ </MotionRail>
400
+ <button onclick={handleNext}>Next</button>
401
+ ```
402
+
403
+ **Props:**
404
+ - `options`: MotionRailOptions object
405
+ - `bind:instance`: Binds the MotionRail instance (using $bindable)
406
+ - `bind:container`: Binds the container HTMLDivElement (using $bindable)
407
+
408
+ **Note:** All framework integrations automatically handle dynamic children updates using the `update()` method. No manual reinitialization needed when items change.
409
+
91
410
  ## Configuration Options
92
411
 
93
412
  | Option | Type | Default | Description |
@@ -215,7 +534,7 @@ Refresh the carousel after dynamically adding or removing items from the DOM. Th
215
534
 
216
535
  ```js
217
536
  // Add items to the DOM
218
- const grid = document.querySelector('[data-motion-rail-grid]');
537
+ const grid = document.querySelector('[data-motionrail-grid]');
219
538
  const newItem = document.createElement('div');
220
539
  newItem.textContent = 'New Item';
221
540
  grid.appendChild(newItem);
@@ -452,9 +771,9 @@ const carousel = new MotionRail(
452
771
  ### With Navigation Controls
453
772
 
454
773
  ```html
455
- <div data-motion-rail id="carousel">
456
- <div data-motion-rail-scrollable>
457
- <div data-motion-rail-grid>
774
+ <div data-motionrail id="carousel">
775
+ <div data-motionrail-scrollable>
776
+ <div data-motionrail-grid>
458
777
  <div>Item 1</div>
459
778
  <div>Item 2</div>
460
779
  <div>Item 3</div>
@@ -492,9 +811,9 @@ document.getElementById('pause').addEventListener('click', () => carousel.pause(
492
811
  ### Dynamic Content
493
812
 
494
813
  ```html
495
- <div data-motion-rail id="carousel">
496
- <div data-motion-rail-scrollable>
497
- <div data-motion-rail-grid id="carousel-grid">
814
+ <div data-motionrail id="carousel">
815
+ <div data-motionrail-scrollable>
816
+ <div data-motionrail-grid id="carousel-grid">
498
817
  <div>Item 1</div>
499
818
  <div>Item 2</div>
500
819
  <div>Item 3</div>
@@ -540,11 +859,11 @@ document.getElementById('remove-item').addEventListener('click', () => {
540
859
  The library includes base styles via `motionrail/style.css`. You can customize the appearance of items with your own CSS:
541
860
 
542
861
  ```css
543
- [data-motion-rail] {
862
+ [data-motionrail] {
544
863
  height: 400px; /* Set carousel height */
545
864
  }
546
865
 
547
- [data-motion-rail-grid] > * {
866
+ [data-motionrail-grid] > * {
548
867
  /* Style your carousel items */
549
868
  background: #f0f0f0;
550
869
  border-radius: 8px;
@@ -554,10 +873,10 @@ The library includes base styles via `motionrail/style.css`. You can customize t
554
873
  ```
555
874
 
556
875
  **Key selectors:**
557
- - `[data-motion-rail]` - Wrapper element
558
- - `[data-motion-rail-scrollable]` - Scrollable container (has overflow and snap type)
559
- - `[data-motion-rail-grid]` - Grid layout container
560
- - `[data-motion-rail-grid] > *` - Direct children (carousel items)
876
+ - `[data-motionrail]` - Wrapper element
877
+ - `[data-motionrail-scrollable]` - Scrollable container (has overflow and snap type)
878
+ - `[data-motionrail-grid]` - Grid layout container
879
+ - `[data-motionrail-grid] > *` - Direct children (carousel items)
561
880
 
562
881
  ## Browser Support
563
882
 
@@ -1,4 +1,4 @@
1
- import "../motionrail-Dq8joDtA.js";
1
+ import "../motionrail-DsLqZe8W.js";
2
2
  function Arrows(e) {
3
3
  let t = document.createElement("button"), n = document.createElement("button"), { leftIcon: r = "<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: i = "<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: a = !0, log: o = !1 } = e || {};
4
4
  return {
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRailArrows={}))})(this,function(e){var t=document.createElement(`style`);t.textContent=`[data-motion-rail-scrollable]::-webkit-scrollbar{display:none}[data-motion-rail]{position:relative}[data-motion-rail] [data-motion-rail-scrollable]{anchor-name:--motionrail-scrollable;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;cursor:grab;position:relative;overflow:scroll hidden;container-type:inline-size}[data-motion-rail] [data-motion-rail-scrollable]:active{cursor:grabbing}[data-motion-rail] [data-motion-rail-scrollable] [data-motion-rail-grid]{grid-auto-flow:column;height:100%;display:grid}[data-motion-rail] [data-motion-rail-scrollable] [data-motion-rail-grid]>*{pointer-events:none;scroll-snap-align:start}
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRailArrows={}))})(this,function(e){var t=document.createElement(`style`);t.textContent=`[data-motionrail-scrollable]::-webkit-scrollbar{display:none}[data-motionrail]{position:relative}[data-motionrail] [data-motionrail-scrollable]{anchor-name:--motionrail-scrollable;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;cursor:grab;position:relative;overflow:scroll hidden;container-type:inline-size}[data-motionrail] [data-motionrail-scrollable]:active{cursor:grabbing}[data-motionrail] [data-motionrail-scrollable] [data-motionrail-grid]{grid-auto-flow:column;height:100%;display:grid}[data-motionrail] [data-motionrail-scrollable] [data-motionrail-grid]>*{pointer-events:none;scroll-snap-align:start}
2
2
  /*$vite$:1*/`,document.head.appendChild(t);function n(e){let t=document.createElement(`button`),n=document.createElement(`button`),{leftIcon:r=`<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:i=`<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:a=!0,log:o=!1}=e||{};return{name:`ArrowExtension`,onInit(e,a){let{totalItems:o}=a;if(o===0)return;let{rtl:s}=e.getOptions();t.innerHTML=r,t.className=`motionrail-arrow motionrail-arrow-left`,t.addEventListener(`click`,()=>{s?e.next():e.prev()}),n.innerHTML=i,n.className=`motionrail-arrow motionrail-arrow-right`,n.addEventListener(`click`,()=>{s?e.prev():e.next()}),e.element.appendChild(t),e.element.appendChild(n)},onUpdate(e,r){let{isFirstItemVisible:i,isLastItemVisible:s,totalItems:c,visibleItemIndexes:l}=r;a||(t.disabled=i,n.disabled=s),l.length<c?(t.style.removeProperty(`display`),n.style.removeProperty(`display`)):(t.style.display=`none`,n.style.display=`none`),c||(t.style.display=`none`,n.style.display=`none`),o&&console.log(`ArrowExtension updated`,r)},onDestroy(e,r){t.remove(),n.remove()}}}e.Arrows=n});
@@ -1,4 +1,4 @@
1
- import "../motionrail-Dq8joDtA.js";
1
+ import "../motionrail-DsLqZe8W.js";
2
2
  function Dots(e) {
3
3
  let t = document.createElement("div"), n = [], { showIndex: r = !1, dotSize: i = 44, log: a = !1 } = e || {};
4
4
  return {
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRailDots={}))})(this,function(e){var t=document.createElement(`style`);t.textContent=`[data-motion-rail-scrollable]::-webkit-scrollbar{display:none}[data-motion-rail]{position:relative}[data-motion-rail] [data-motion-rail-scrollable]{anchor-name:--motionrail-scrollable;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;cursor:grab;position:relative;overflow:scroll hidden;container-type:inline-size}[data-motion-rail] [data-motion-rail-scrollable]:active{cursor:grabbing}[data-motion-rail] [data-motion-rail-scrollable] [data-motion-rail-grid]{grid-auto-flow:column;height:100%;display:grid}[data-motion-rail] [data-motion-rail-scrollable] [data-motion-rail-grid]>*{pointer-events:none;scroll-snap-align:start}
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRailDots={}))})(this,function(e){var t=document.createElement(`style`);t.textContent=`[data-motionrail-scrollable]::-webkit-scrollbar{display:none}[data-motionrail]{position:relative}[data-motionrail] [data-motionrail-scrollable]{anchor-name:--motionrail-scrollable;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;cursor:grab;position:relative;overflow:scroll hidden;container-type:inline-size}[data-motionrail] [data-motionrail-scrollable]:active{cursor:grabbing}[data-motionrail] [data-motionrail-scrollable] [data-motionrail-grid]{grid-auto-flow:column;height:100%;display:grid}[data-motionrail] [data-motionrail-scrollable] [data-motionrail-grid]>*{pointer-events:none;scroll-snap-align:start}
2
2
  /*$vite$:1*/`,document.head.appendChild(t);function n(e){let t=document.createElement(`div`),n=[],{showIndex:r=!1,dotSize:i=44,log:a=!1}=e||{};return{name:`DotsExtension`,onInit(e,a){let{totalItems:o}=a;if(o!==0){t.className=`motionrail-dots`,t.style.setProperty(`--dot-size`,`${i}px`);for(let i=0;i<o;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:i,totalItems:o}=r;if(!o){t.style.display=`none`;return}if(t.style.removeProperty(`display`),n.forEach((e,t)=>{i.includes(t)?e.classList.add(`motionrail-dot-active`):e.classList.remove(`motionrail-dot-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(`DotsExtension updated`,r)},onDestroy(e,r){t.remove(),n.length=0}}}e.Dots=n});
@@ -1,4 +1,4 @@
1
- import "../motionrail-Dq8joDtA.js";
1
+ import "../motionrail-DsLqZe8W.js";
2
2
  function Logger() {
3
3
  return {
4
4
  name: "LoggerExtension",
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRailLogger={}))})(this,function(e){var t=document.createElement(`style`);t.textContent=`[data-motion-rail-scrollable]::-webkit-scrollbar{display:none}[data-motion-rail]{position:relative}[data-motion-rail] [data-motion-rail-scrollable]{anchor-name:--motionrail-scrollable;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;cursor:grab;position:relative;overflow:scroll hidden;container-type:inline-size}[data-motion-rail] [data-motion-rail-scrollable]:active{cursor:grabbing}[data-motion-rail] [data-motion-rail-scrollable] [data-motion-rail-grid]{grid-auto-flow:column;height:100%;display:grid}[data-motion-rail] [data-motion-rail-scrollable] [data-motion-rail-grid]>*{pointer-events:none;scroll-snap-align:start}
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRailLogger={}))})(this,function(e){var t=document.createElement(`style`);t.textContent=`[data-motionrail-scrollable]::-webkit-scrollbar{display:none}[data-motionrail]{position:relative}[data-motionrail] [data-motionrail-scrollable]{anchor-name:--motionrail-scrollable;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;cursor:grab;position:relative;overflow:scroll hidden;container-type:inline-size}[data-motionrail] [data-motionrail-scrollable]:active{cursor:grabbing}[data-motionrail] [data-motionrail-scrollable] [data-motionrail-grid]{grid-auto-flow:column;height:100%;display:grid}[data-motionrail] [data-motionrail-scrollable] [data-motionrail-grid]>*{pointer-events:none;scroll-snap-align:start}
2
2
  /*$vite$:1*/`,document.head.appendChild(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,15 +1,15 @@
1
- import "../motionrail-Dq8joDtA.js";
1
+ import "../motionrail-DsLqZe8W.js";
2
2
  function Thumbnails(e) {
3
3
  let t = document.createElement("div"), n = [], { thumbnailWidth: r = 80, thumbnailHeight: i = 80, log: a = !1 } = e || {};
4
4
  return {
5
5
  name: "ThumbnailsExtension",
6
6
  onInit(e, a) {
7
7
  let { totalItems: o } = a;
8
- o !== 0 && (t.className = "motionrail-thumbnails", t.style.setProperty("--thumbnail-width", `${r}px`), t.style.setProperty("--thumbnail-height", `${i}px`), e.element.querySelectorAll("[data-motion-rail-grid] > *").forEach((r, i) => {
8
+ o !== 0 && (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) => {
9
9
  let a = document.createElement("button");
10
10
  a.className = "motionrail-thumbnail", a.setAttribute("aria-label", `Go to item ${i + 1}`);
11
11
  let o = r.cloneNode(!0);
12
- o.removeAttribute("data-motion-rail-item"), a.appendChild(o), a.addEventListener("click", () => {
12
+ o.removeAttribute("data-motionrail-item"), a.appendChild(o), a.addEventListener("click", () => {
13
13
  e.scrollToIndex(i);
14
14
  }), n.push(a), t.appendChild(a);
15
15
  }), e.element.appendChild(t));
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRailThumbnails={}))})(this,function(e){var t=document.createElement(`style`);t.textContent=`[data-motion-rail-scrollable]::-webkit-scrollbar{display:none}[data-motion-rail]{position:relative}[data-motion-rail] [data-motion-rail-scrollable]{anchor-name:--motionrail-scrollable;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;cursor:grab;position:relative;overflow:scroll hidden;container-type:inline-size}[data-motion-rail] [data-motion-rail-scrollable]:active{cursor:grabbing}[data-motion-rail] [data-motion-rail-scrollable] [data-motion-rail-grid]{grid-auto-flow:column;height:100%;display:grid}[data-motion-rail] [data-motion-rail-scrollable] [data-motion-rail-grid]>*{pointer-events:none;scroll-snap-align:start}
2
- /*$vite$:1*/`,document.head.appendChild(t);function n(e){let t=document.createElement(`div`),n=[],{thumbnailWidth:r=80,thumbnailHeight:i=80,log:a=!1}=e||{};return{name:`ThumbnailsExtension`,onInit(e,a){let{totalItems:o}=a;o!==0&&(t.className=`motionrail-thumbnails`,t.style.setProperty(`--thumbnail-width`,`${r}px`),t.style.setProperty(`--thumbnail-height`,`${i}px`),e.element.querySelectorAll(`[data-motion-rail-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-motion-rail-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(!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):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRailThumbnails={}))})(this,function(e){var t=document.createElement(`style`);t.textContent=`[data-motionrail-scrollable]::-webkit-scrollbar{display:none}[data-motionrail]{position:relative}[data-motionrail] [data-motionrail-scrollable]{anchor-name:--motionrail-scrollable;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;cursor:grab;position:relative;overflow:scroll hidden;container-type:inline-size}[data-motionrail] [data-motionrail-scrollable]:active{cursor:grabbing}[data-motionrail] [data-motionrail-scrollable] [data-motionrail-grid]{grid-auto-flow:column;height:100%;display:grid}[data-motionrail] [data-motionrail-scrollable] [data-motionrail-grid]>*{pointer-events:none;scroll-snap-align:start}
2
+ /*$vite$:1*/`,document.head.appendChild(t);function n(e){let t=document.createElement(`div`),n=[],{thumbnailWidth:r=80,thumbnailHeight:i=80,log:a=!1}=e||{};return{name:`ThumbnailsExtension`,onInit(e,a){let{totalItems:o}=a;o!==0&&(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(!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});
@@ -38,9 +38,9 @@ var MotionRail = class {
38
38
  columns: 1,
39
39
  gap: "0px"
40
40
  }], this.element = e, this.extensions = t.extensions || [];
41
- let n = this.element.querySelector("[data-motion-rail-scrollable]");
42
- if (!n) throw Error("MotionRail: [data-motion-rail-scrollable] element not found");
43
- this.scrollable = n, this.delay = t.delay || 3e3, this.resumeDelay = t.resumeDelay || 4e3, this.onChange = t.onChange, this.state.totalItems = this.element.querySelectorAll("[data-motion-rail-grid] > *").length, this.setBreakPoints(), this.setLogicalScroll(0), this.attachPointerEvents(), this.cacheSnapPoints(), this.observeResize(), this.observeEdgeItems(), this.autoplay && this.play();
41
+ let n = this.element.querySelector("[data-motionrail-scrollable]");
42
+ if (!n) throw Error("MotionRail: [data-motionrail-scrollable] element not found");
43
+ this.scrollable = n, this.delay = t.delay || 3e3, this.resumeDelay = t.resumeDelay || 4e3, this.onChange = t.onChange, this.state.totalItems = this.element.querySelectorAll("[data-motionrail-grid] > *").length, this.setBreakPoints(), this.setLogicalScroll(0), this.attachPointerEvents(), this.cacheSnapPoints(), this.observeResize(), this.observeEdgeItems(), this.autoplay && this.play();
44
44
  let r = this.getState();
45
45
  this.extensions.forEach((e) => {
46
46
  e.onInit && e.onInit(this, r);
@@ -50,7 +50,7 @@ var MotionRail = class {
50
50
  return `motion-rail-${Math.random().toString(36).substring(2, 11)}`;
51
51
  }
52
52
  setBreakPoints() {
53
- let e = this.element.querySelector("[data-motion-rail-scrollable]");
53
+ let e = this.element.querySelector("[data-motionrail-scrollable]");
54
54
  if (!e) return;
55
55
  let t = "";
56
56
  e.style.containerName ? t = e.style.containerName : (t = this.randomContainerName(), e.style.containerName = t);
@@ -59,7 +59,7 @@ var MotionRail = class {
59
59
  let n = e.columns || 1, i = e.gap || "0px", o = `calc((100cqw - (${n - 1} * ${i})) / ${n})`, s = "";
60
60
  s = e.width ? `(min-width: ${e.width}px)` : a ? `(max-width: ${a - 1}px)` : "(min-width: 0px)", r += `
61
61
  @container ${t} ${s} {
62
- [data-motion-rail-grid] {
62
+ [data-motionrail-grid] {
63
63
  grid-template-columns: repeat(${this.state.totalItems}, ${o});
64
64
  gap: ${i};
65
65
  }
@@ -86,7 +86,7 @@ var MotionRail = class {
86
86
  }
87
87
  observeEdgeItems() {
88
88
  if (typeof IntersectionObserver > "u") return;
89
- let e = this.element.querySelectorAll("[data-motion-rail-grid] > *");
89
+ let e = this.element.querySelectorAll("[data-motionrail-grid] > *");
90
90
  if (e.length === 0) return;
91
91
  let t = e[0], n = e[e.length - 1];
92
92
  this.intersectionObserver = new IntersectionObserver((r) => {
@@ -114,7 +114,7 @@ var MotionRail = class {
114
114
  }), e.forEach((e) => this.intersectionObserver.observe(e));
115
115
  }
116
116
  cacheSnapPoints() {
117
- let e = this.element.querySelectorAll("[data-motion-rail-grid] > *"), t = this.scrollable.scrollWidth - this.scrollable.clientWidth;
117
+ let e = this.element.querySelectorAll("[data-motionrail-grid] > *"), t = this.scrollable.scrollWidth - this.scrollable.clientWidth;
118
118
  this.snapPoints = Array.from(e).map((e) => Math.min(e.offsetLeft, t));
119
119
  }
120
120
  findNearestSnapPoint(e) {
@@ -201,7 +201,7 @@ var MotionRail = class {
201
201
  };
202
202
  }
203
203
  update() {
204
- this.intersectionObserver &&= (this.intersectionObserver.disconnect(), null), this.state.totalItems = this.element.querySelectorAll("[data-motion-rail-grid] > *").length, this.state.visibleItemIndexes = [], this.state.isFirstItemVisible = !1, this.state.isLastItemVisible = !1, this.setBreakPoints(), this.cacheSnapPoints(), this.observeEdgeItems(), this.handleStateChange();
204
+ this.intersectionObserver &&= (this.intersectionObserver.disconnect(), null), this.state.totalItems = this.element.querySelectorAll("[data-motionrail-grid] > *").length, this.state.visibleItemIndexes = [], this.state.isFirstItemVisible = !1, this.state.isLastItemVisible = !1, this.setBreakPoints(), this.cacheSnapPoints(), this.observeEdgeItems(), this.handleStateChange();
205
205
  }
206
206
  destroy() {
207
207
  let e = this.getState();
@@ -1,2 +1,2 @@
1
- import { t as MotionRail } from "./motionrail-Dq8joDtA.js";
1
+ import { t as MotionRail } from "./motionrail-DsLqZe8W.js";
2
2
  export { MotionRail };
@@ -1,9 +1,9 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRail={}))})(this,function(e){var t=document.createElement(`style`);t.textContent=`[data-motion-rail-scrollable]::-webkit-scrollbar{display:none}[data-motion-rail]{position:relative}[data-motion-rail] [data-motion-rail-scrollable]{anchor-name:--motionrail-scrollable;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;cursor:grab;position:relative;overflow:scroll hidden;container-type:inline-size}[data-motion-rail] [data-motion-rail-scrollable]:active{cursor:grabbing}[data-motion-rail] [data-motion-rail-scrollable] [data-motion-rail-grid]{grid-auto-flow:column;height:100%;display:grid}[data-motion-rail] [data-motion-rail-scrollable] [data-motion-rail-grid]>*{pointer-events:none;scroll-snap-align:start}
2
- /*$vite$:1*/`,document.head.appendChild(t),e.MotionRail=class{element;scrollable;rtl=!1;autoplay=!1;delay=3e3;resumeDelay=4e3;onChange;handleStateChange=()=>{let e=this.getState();this.extensions.forEach(t=>{t.onUpdate&&t.onUpdate(this,e)}),this.onChange&&this.onChange(e)};extensions=[];breakpoints=[];autoPlayIntervalId=null;autoPlayTimeoutId=null;isDragging=!1;startX=0;startLogicalScroll=0;cancelScroll=null;lastPointerX=0;lastPointerTime=0;velocity=0;pointerId=null;snapPoints=[];resizeObserver=null;intersectionObserver=null;state={totalItems:0,visibleItemIndexes:[],isFirstItemVisible:!1,isLastItemVisible:!1};constructor(e,t){this.autoplay=t.autoplay||!1,this.rtl=t.rtl||!1,this.breakpoints=t.breakpoints||[{columns:1,gap:`0px`}],this.element=e,this.extensions=t.extensions||[];let n=this.element.querySelector(`[data-motion-rail-scrollable]`);if(!n)throw Error(`MotionRail: [data-motion-rail-scrollable] element not found`);this.scrollable=n,this.delay=t.delay||3e3,this.resumeDelay=t.resumeDelay||4e3,this.onChange=t.onChange,this.state.totalItems=this.element.querySelectorAll(`[data-motion-rail-grid] > *`).length,this.setBreakPoints(),this.setLogicalScroll(0),this.attachPointerEvents(),this.cacheSnapPoints(),this.observeResize(),this.observeEdgeItems(),this.autoplay&&this.play();let r=this.getState();this.extensions.forEach(e=>{e.onInit&&e.onInit(this,r)})}randomContainerName(){return`motion-rail-${Math.random().toString(36).substring(2,11)}`}setBreakPoints(){let e=this.element.querySelector(`[data-motion-rail-scrollable]`);if(!e)return;let t=``;e.style.containerName?t=e.style.containerName:(t=this.randomContainerName(),e.style.containerName=t);let n=document.createElement(`style`),r=``,i=this.breakpoints.filter(e=>e.width),a=i.length>0?Math.min(...i.map(e=>e.width)):null;return this.breakpoints.forEach(e=>{let n=e.columns||1,i=e.gap||`0px`,o=`calc((100cqw - (${n-1} * ${i})) / ${n})`,s=``;s=e.width?`(min-width: ${e.width}px)`:a?`(max-width: ${a-1}px)`:`(min-width: 0px)`,r+=`
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.MotionRail={}))})(this,function(e){var t=document.createElement(`style`);t.textContent=`[data-motionrail-scrollable]::-webkit-scrollbar{display:none}[data-motionrail]{position:relative}[data-motionrail] [data-motionrail-scrollable]{anchor-name:--motionrail-scrollable;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;cursor:grab;position:relative;overflow:scroll hidden;container-type:inline-size}[data-motionrail] [data-motionrail-scrollable]:active{cursor:grabbing}[data-motionrail] [data-motionrail-scrollable] [data-motionrail-grid]{grid-auto-flow:column;height:100%;display:grid}[data-motionrail] [data-motionrail-scrollable] [data-motionrail-grid]>*{pointer-events:none;scroll-snap-align:start}
2
+ /*$vite$:1*/`,document.head.appendChild(t),e.MotionRail=class{element;scrollable;rtl=!1;autoplay=!1;delay=3e3;resumeDelay=4e3;onChange;handleStateChange=()=>{let e=this.getState();this.extensions.forEach(t=>{t.onUpdate&&t.onUpdate(this,e)}),this.onChange&&this.onChange(e)};extensions=[];breakpoints=[];autoPlayIntervalId=null;autoPlayTimeoutId=null;isDragging=!1;startX=0;startLogicalScroll=0;cancelScroll=null;lastPointerX=0;lastPointerTime=0;velocity=0;pointerId=null;snapPoints=[];resizeObserver=null;intersectionObserver=null;state={totalItems:0,visibleItemIndexes:[],isFirstItemVisible:!1,isLastItemVisible:!1};constructor(e,t){this.autoplay=t.autoplay||!1,this.rtl=t.rtl||!1,this.breakpoints=t.breakpoints||[{columns:1,gap:`0px`}],this.element=e,this.extensions=t.extensions||[];let n=this.element.querySelector(`[data-motionrail-scrollable]`);if(!n)throw Error(`MotionRail: [data-motionrail-scrollable] element not found`);this.scrollable=n,this.delay=t.delay||3e3,this.resumeDelay=t.resumeDelay||4e3,this.onChange=t.onChange,this.state.totalItems=this.element.querySelectorAll(`[data-motionrail-grid] > *`).length,this.setBreakPoints(),this.setLogicalScroll(0),this.attachPointerEvents(),this.cacheSnapPoints(),this.observeResize(),this.observeEdgeItems(),this.autoplay&&this.play();let r=this.getState();this.extensions.forEach(e=>{e.onInit&&e.onInit(this,r)})}randomContainerName(){return`motion-rail-${Math.random().toString(36).substring(2,11)}`}setBreakPoints(){let e=this.element.querySelector(`[data-motionrail-scrollable]`);if(!e)return;let t=``;e.style.containerName?t=e.style.containerName:(t=this.randomContainerName(),e.style.containerName=t);let n=document.createElement(`style`),r=``,i=this.breakpoints.filter(e=>e.width),a=i.length>0?Math.min(...i.map(e=>e.width)):null;return this.breakpoints.forEach(e=>{let n=e.columns||1,i=e.gap||`0px`,o=`calc((100cqw - (${n-1} * ${i})) / ${n})`,s=``;s=e.width?`(min-width: ${e.width}px)`:a?`(max-width: ${a-1}px)`:`(min-width: 0px)`,r+=`
3
3
  @container ${t} ${s} {
4
- [data-motion-rail-grid] {
4
+ [data-motionrail-grid] {
5
5
  grid-template-columns: repeat(${this.state.totalItems}, ${o});
6
6
  gap: ${i};
7
7
  }
8
8
  }
9
- `}),n.textContent=r,document.head.appendChild(n),n}getLogicalScroll(){return this.scrollable.scrollLeft}setLogicalScroll(e){this.scrollable.scrollLeft=e}scrollToLogical(e,t=`auto`){this.scrollable.scrollTo({left:e,behavior:t})}observeResize(){typeof ResizeObserver>`u`||(this.resizeObserver=new ResizeObserver(()=>{this.cacheSnapPoints()}),this.resizeObserver.observe(this.scrollable))}observeEdgeItems(){if(typeof IntersectionObserver>`u`)return;let e=this.element.querySelectorAll(`[data-motion-rail-grid] > *`);if(e.length===0)return;let t=e[0],n=e[e.length-1];this.intersectionObserver=new IntersectionObserver(r=>{let i=!1;r.forEach(r=>{let a=Array.from(e).indexOf(r.target);if(a!==-1){if(r.isIntersecting)this.state.visibleItemIndexes.includes(a)||(this.state.visibleItemIndexes.push(a),this.state.visibleItemIndexes.sort((e,t)=>e-t),i=!0);else{let e=this.state.visibleItemIndexes.length;this.state.visibleItemIndexes=this.state.visibleItemIndexes.filter(e=>e!==a),this.state.visibleItemIndexes.length!==e&&(i=!0)}if(r.target===t){let e=r.isIntersecting;this.state.isFirstItemVisible!==e&&(this.state.isFirstItemVisible=e,i=!0)}else if(r.target===n){let e=r.isIntersecting;this.state.isLastItemVisible!==e&&(this.state.isLastItemVisible=e,i=!0)}}}),i&&this.handleStateChange()},{root:this.scrollable,threshold:.5}),e.forEach(e=>this.intersectionObserver.observe(e))}cacheSnapPoints(){let e=this.element.querySelectorAll(`[data-motion-rail-grid] > *`),t=this.scrollable.scrollWidth-this.scrollable.clientWidth;this.snapPoints=Array.from(e).map(e=>Math.min(e.offsetLeft,t))}findNearestSnapPoint(e){let t=0,n=1/0;for(let r of this.snapPoints){let i=Math.abs(r-e);i<n&&(n=i,t=r)}return t}attachPointerEvents(){window.matchMedia(`(pointer: fine)`).matches&&(this.scrollable.addEventListener(`pointerdown`,this.handlePointerDown),this.scrollable.addEventListener(`pointermove`,this.handlePointerMove),this.scrollable.addEventListener(`pointerup`,this.handlePointerUp),this.scrollable.addEventListener(`pointerleave`,this.handlePointerUp))}handlePointerDown=e=>{this.pointerId===null&&(this.pointerId=e.pointerId,this.scrollable.setPointerCapture(e.pointerId),this.isDragging=!0,this.startX=e.clientX,this.startLogicalScroll=this.getLogicalScroll(),this.lastPointerX=e.clientX,this.lastPointerTime=e.timeStamp,this.velocity=0,this.scrollable.style.userSelect=`none`,this.scrollable.style.scrollSnapType=`none`,this.pause(),this.cancelScroll&&this.cancelScroll(),this.autoPlayTimeoutId&&clearTimeout(this.autoPlayTimeoutId))};handlePointerMove=e=>{if(!this.isDragging||e.pointerId!==this.pointerId)return;e.preventDefault();let t=e.clientX-this.startX,n=this.startLogicalScroll-t;this.setLogicalScroll(n);let r=e.timeStamp-this.lastPointerTime;r>0&&(this.velocity=(e.clientX-this.lastPointerX)/r,this.lastPointerX=e.clientX,this.lastPointerTime=e.timeStamp)};handlePointerUp=e=>{if(!this.isDragging||e.pointerId!==this.pointerId)return;this.scrollable.releasePointerCapture(e.pointerId),this.pointerId=null,this.isDragging=!1,this.scrollable.style.userSelect=``;let t=Math.abs(this.velocity),n=Math.min(100+Math.sqrt(t)*50,200),r=-this.velocity*n,i=this.getLogicalScroll()+r;this.cancelScroll&&this.cancelScroll();let a=this.findNearestSnapPoint(i);this.cancelScroll=this.animateLogicalScroll(a,n,()=>{this.scrollable.style.scrollSnapType=`x mandatory`,this.cancelScroll=null,this.autoplay&&(this.autoPlayTimeoutId=window.setTimeout(()=>{this.play(),this.autoPlayTimeoutId=null},this.resumeDelay))}),this.velocity=0};animateLogicalScroll(e,t,n){let r=this.getLogicalScroll(),i=performance.now(),a=!1,o=s=>{if(a)return;let c=s-i,l=Math.min(c/t,1),u=1-(1-l)**3,d=r+(e-r)*u;this.setLogicalScroll(d),l<1?requestAnimationFrame(o):n()};return requestAnimationFrame(o),()=>{a=!0}}scrollByPage(e){if(this.state.visibleItemIndexes.length===0)return;let t,n=this.state.visibleItemIndexes[0],r=this.state.visibleItemIndexes[this.state.visibleItemIndexes.length-1],i=this.state.visibleItemIndexes.length;e===1?(t=r+1,this.rtl&&(t=r+i),t>=this.snapPoints.length-1&&this.state.isLastItemVisible?t=0:t>=this.snapPoints.length-1&&!this.state.isLastItemVisible&&(t=this.snapPoints.length-1)):(t=n-i,this.rtl&&(t=r-i),t<=0&&this.state.isFirstItemVisible?t=this.snapPoints.length-1:t<=0&&!this.state.isFirstItemVisible&&(t=0)),this.scrollToLogical(this.snapPoints[t],`smooth`)}play(){this.autoPlayIntervalId=window.setInterval(()=>{this.scrollByPage(1)},this.delay)}next(){this.pause(),this.scrollByPage(1)}prev(){this.pause(),this.scrollByPage(-1)}pause(){this.autoPlayIntervalId&&=(clearInterval(this.autoPlayIntervalId),null),this.autoPlayTimeoutId&&=(clearTimeout(this.autoPlayTimeoutId),null),!this.isDragging&&this.autoplay&&(this.autoPlayTimeoutId=window.setTimeout(()=>{this.play(),this.autoPlayTimeoutId=null},this.resumeDelay))}scrollToIndex(e){this.pause(),e>=0&&e<this.snapPoints.length&&this.scrollToLogical(this.snapPoints[e],`smooth`)}getState(){return{...this.state,visibleItemIndexes:[...this.state.visibleItemIndexes]}}getOptions(){return{autoplay:this.autoplay,rtl:this.rtl,delay:this.delay,resumeDelay:this.resumeDelay,breakpoints:this.breakpoints.map(e=>({...e}))}}update(){this.intersectionObserver&&=(this.intersectionObserver.disconnect(),null),this.state.totalItems=this.element.querySelectorAll(`[data-motion-rail-grid] > *`).length,this.state.visibleItemIndexes=[],this.state.isFirstItemVisible=!1,this.state.isLastItemVisible=!1,this.setBreakPoints(),this.cacheSnapPoints(),this.observeEdgeItems(),this.handleStateChange()}destroy(){let e=this.getState();this.extensions.forEach(t=>{t.onDestroy&&t.onDestroy(this,e)}),this.autoPlayIntervalId&&=(clearInterval(this.autoPlayIntervalId),null),this.cancelScroll&&=(this.cancelScroll(),null),this.autoPlayTimeoutId&&=(clearTimeout(this.autoPlayTimeoutId),null),this.resizeObserver&&=(this.resizeObserver.disconnect(),null),this.intersectionObserver&&=(this.intersectionObserver.disconnect(),null),this.scrollable.removeEventListener(`pointerdown`,this.handlePointerDown),this.scrollable.removeEventListener(`pointermove`,this.handlePointerMove),this.scrollable.removeEventListener(`pointerup`,this.handlePointerUp),this.scrollable.removeEventListener(`pointerleave`,this.handlePointerUp)}}});
9
+ `}),n.textContent=r,document.head.appendChild(n),n}getLogicalScroll(){return this.scrollable.scrollLeft}setLogicalScroll(e){this.scrollable.scrollLeft=e}scrollToLogical(e,t=`auto`){this.scrollable.scrollTo({left:e,behavior:t})}observeResize(){typeof ResizeObserver>`u`||(this.resizeObserver=new ResizeObserver(()=>{this.cacheSnapPoints()}),this.resizeObserver.observe(this.scrollable))}observeEdgeItems(){if(typeof IntersectionObserver>`u`)return;let e=this.element.querySelectorAll(`[data-motionrail-grid] > *`);if(e.length===0)return;let t=e[0],n=e[e.length-1];this.intersectionObserver=new IntersectionObserver(r=>{let i=!1;r.forEach(r=>{let a=Array.from(e).indexOf(r.target);if(a!==-1){if(r.isIntersecting)this.state.visibleItemIndexes.includes(a)||(this.state.visibleItemIndexes.push(a),this.state.visibleItemIndexes.sort((e,t)=>e-t),i=!0);else{let e=this.state.visibleItemIndexes.length;this.state.visibleItemIndexes=this.state.visibleItemIndexes.filter(e=>e!==a),this.state.visibleItemIndexes.length!==e&&(i=!0)}if(r.target===t){let e=r.isIntersecting;this.state.isFirstItemVisible!==e&&(this.state.isFirstItemVisible=e,i=!0)}else if(r.target===n){let e=r.isIntersecting;this.state.isLastItemVisible!==e&&(this.state.isLastItemVisible=e,i=!0)}}}),i&&this.handleStateChange()},{root:this.scrollable,threshold:.5}),e.forEach(e=>this.intersectionObserver.observe(e))}cacheSnapPoints(){let e=this.element.querySelectorAll(`[data-motionrail-grid] > *`),t=this.scrollable.scrollWidth-this.scrollable.clientWidth;this.snapPoints=Array.from(e).map(e=>Math.min(e.offsetLeft,t))}findNearestSnapPoint(e){let t=0,n=1/0;for(let r of this.snapPoints){let i=Math.abs(r-e);i<n&&(n=i,t=r)}return t}attachPointerEvents(){window.matchMedia(`(pointer: fine)`).matches&&(this.scrollable.addEventListener(`pointerdown`,this.handlePointerDown),this.scrollable.addEventListener(`pointermove`,this.handlePointerMove),this.scrollable.addEventListener(`pointerup`,this.handlePointerUp),this.scrollable.addEventListener(`pointerleave`,this.handlePointerUp))}handlePointerDown=e=>{this.pointerId===null&&(this.pointerId=e.pointerId,this.scrollable.setPointerCapture(e.pointerId),this.isDragging=!0,this.startX=e.clientX,this.startLogicalScroll=this.getLogicalScroll(),this.lastPointerX=e.clientX,this.lastPointerTime=e.timeStamp,this.velocity=0,this.scrollable.style.userSelect=`none`,this.scrollable.style.scrollSnapType=`none`,this.pause(),this.cancelScroll&&this.cancelScroll(),this.autoPlayTimeoutId&&clearTimeout(this.autoPlayTimeoutId))};handlePointerMove=e=>{if(!this.isDragging||e.pointerId!==this.pointerId)return;e.preventDefault();let t=e.clientX-this.startX,n=this.startLogicalScroll-t;this.setLogicalScroll(n);let r=e.timeStamp-this.lastPointerTime;r>0&&(this.velocity=(e.clientX-this.lastPointerX)/r,this.lastPointerX=e.clientX,this.lastPointerTime=e.timeStamp)};handlePointerUp=e=>{if(!this.isDragging||e.pointerId!==this.pointerId)return;this.scrollable.releasePointerCapture(e.pointerId),this.pointerId=null,this.isDragging=!1,this.scrollable.style.userSelect=``;let t=Math.abs(this.velocity),n=Math.min(100+Math.sqrt(t)*50,200),r=-this.velocity*n,i=this.getLogicalScroll()+r;this.cancelScroll&&this.cancelScroll();let a=this.findNearestSnapPoint(i);this.cancelScroll=this.animateLogicalScroll(a,n,()=>{this.scrollable.style.scrollSnapType=`x mandatory`,this.cancelScroll=null,this.autoplay&&(this.autoPlayTimeoutId=window.setTimeout(()=>{this.play(),this.autoPlayTimeoutId=null},this.resumeDelay))}),this.velocity=0};animateLogicalScroll(e,t,n){let r=this.getLogicalScroll(),i=performance.now(),a=!1,o=s=>{if(a)return;let c=s-i,l=Math.min(c/t,1),u=1-(1-l)**3,d=r+(e-r)*u;this.setLogicalScroll(d),l<1?requestAnimationFrame(o):n()};return requestAnimationFrame(o),()=>{a=!0}}scrollByPage(e){if(this.state.visibleItemIndexes.length===0)return;let t,n=this.state.visibleItemIndexes[0],r=this.state.visibleItemIndexes[this.state.visibleItemIndexes.length-1],i=this.state.visibleItemIndexes.length;e===1?(t=r+1,this.rtl&&(t=r+i),t>=this.snapPoints.length-1&&this.state.isLastItemVisible?t=0:t>=this.snapPoints.length-1&&!this.state.isLastItemVisible&&(t=this.snapPoints.length-1)):(t=n-i,this.rtl&&(t=r-i),t<=0&&this.state.isFirstItemVisible?t=this.snapPoints.length-1:t<=0&&!this.state.isFirstItemVisible&&(t=0)),this.scrollToLogical(this.snapPoints[t],`smooth`)}play(){this.autoPlayIntervalId=window.setInterval(()=>{this.scrollByPage(1)},this.delay)}next(){this.pause(),this.scrollByPage(1)}prev(){this.pause(),this.scrollByPage(-1)}pause(){this.autoPlayIntervalId&&=(clearInterval(this.autoPlayIntervalId),null),this.autoPlayTimeoutId&&=(clearTimeout(this.autoPlayTimeoutId),null),!this.isDragging&&this.autoplay&&(this.autoPlayTimeoutId=window.setTimeout(()=>{this.play(),this.autoPlayTimeoutId=null},this.resumeDelay))}scrollToIndex(e){this.pause(),e>=0&&e<this.snapPoints.length&&this.scrollToLogical(this.snapPoints[e],`smooth`)}getState(){return{...this.state,visibleItemIndexes:[...this.state.visibleItemIndexes]}}getOptions(){return{autoplay:this.autoplay,rtl:this.rtl,delay:this.delay,resumeDelay:this.resumeDelay,breakpoints:this.breakpoints.map(e=>({...e}))}}update(){this.intersectionObserver&&=(this.intersectionObserver.disconnect(),null),this.state.totalItems=this.element.querySelectorAll(`[data-motionrail-grid] > *`).length,this.state.visibleItemIndexes=[],this.state.isFirstItemVisible=!1,this.state.isLastItemVisible=!1,this.setBreakPoints(),this.cacheSnapPoints(),this.observeEdgeItems(),this.handleStateChange()}destroy(){let e=this.getState();this.extensions.forEach(t=>{t.onDestroy&&t.onDestroy(this,e)}),this.autoPlayIntervalId&&=(clearInterval(this.autoPlayIntervalId),null),this.cancelScroll&&=(this.cancelScroll(),null),this.autoPlayTimeoutId&&=(clearTimeout(this.autoPlayTimeoutId),null),this.resizeObserver&&=(this.resizeObserver.disconnect(),null),this.intersectionObserver&&=(this.intersectionObserver.disconnect(),null),this.scrollable.removeEventListener(`pointerdown`,this.handlePointerDown),this.scrollable.removeEventListener(`pointermove`,this.handlePointerMove),this.scrollable.removeEventListener(`pointerup`,this.handlePointerUp),this.scrollable.removeEventListener(`pointerleave`,this.handlePointerUp)}}});
package/dist/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as MotionRail } from "./motionrail-Dq8joDtA.js";
1
+ import { t as MotionRail } from "./motionrail-DsLqZe8W.js";
2
2
  import { useEffect, useRef } from "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  function MotionRailReact({ options: i, ref: a, divRef: o, ...s }) {
@@ -11,12 +11,12 @@ function MotionRailReact({ options: i, ref: a, divRef: o, ...s }) {
11
11
  l.current && l.current.update();
12
12
  }, [u]), /* @__PURE__ */ jsx("div", {
13
13
  ref: c,
14
- "data-motion-rail": !0,
14
+ "data-motionrail": !0,
15
15
  ...d,
16
16
  children: /* @__PURE__ */ jsx("div", {
17
- "data-motion-rail-scrollable": !0,
17
+ "data-motionrail-scrollable": !0,
18
18
  children: /* @__PURE__ */ jsx("div", {
19
- "data-motion-rail-grid": !0,
19
+ "data-motionrail-grid": !0,
20
20
  children: u
21
21
  })
22
22
  })
package/dist/solid.js CHANGED
@@ -1,7 +1,7 @@
1
- import { t as MotionRail } from "./motionrail-Dq8joDtA.js";
1
+ import { t as MotionRail } from "./motionrail-DsLqZe8W.js";
2
2
  import { insert, spread, template, use } from "solid-js/web";
3
3
  import { createEffect, onCleanup, onMount, splitProps } from "solid-js";
4
- var _tmpl$ = /* @__PURE__ */ template("<div data-motion-rail><div data-motion-rail-scrollable><div data-motion-rail-grid>");
4
+ var _tmpl$ = /* @__PURE__ */ template("<div data-motionrail><div data-motionrail-scrollable><div data-motionrail-grid>");
5
5
  function MotionRailSolid(c) {
6
6
  let [u, d] = splitProps(c, [
7
7
  "options",
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- [data-motion-rail-scrollable]::-webkit-scrollbar{display:none}[data-motion-rail]{position:relative}[data-motion-rail] [data-motion-rail-scrollable]{anchor-name:--motionrail-scrollable;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;cursor:grab;position:relative;overflow:scroll hidden;container-type:inline-size}[data-motion-rail] [data-motion-rail-scrollable]:active{cursor:grabbing}[data-motion-rail] [data-motion-rail-scrollable] [data-motion-rail-grid]{grid-auto-flow:column;height:100%;display:grid}[data-motion-rail] [data-motion-rail-scrollable] [data-motion-rail-grid]>*{pointer-events:none;scroll-snap-align:start}
1
+ [data-motionrail-scrollable]::-webkit-scrollbar{display:none}[data-motionrail]{position:relative}[data-motionrail] [data-motionrail-scrollable]{anchor-name:--motionrail-scrollable;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;cursor:grab;position:relative;overflow:scroll hidden;container-type:inline-size}[data-motionrail] [data-motionrail-scrollable]:active{cursor:grabbing}[data-motionrail] [data-motionrail-scrollable] [data-motionrail-grid]{grid-auto-flow:column;height:100%;display:grid}[data-motionrail] [data-motionrail-scrollable] [data-motionrail-grid]>*{pointer-events:none;scroll-snap-align:start}
package/dist/svelte.js CHANGED
@@ -1,8 +1,8 @@
1
- import { t as MotionRail } from "./motionrail-Dq8joDtA.js";
1
+ import { t as MotionRail } from "./motionrail-DsLqZe8W.js";
2
2
  import { C as reset, S as push, T as enable_legacy_mode_flag, _ as child, a as bind_this, c as slot, d as from_html, f as deep_read_state, h as legacy_pre_effect_reset, i as init, m as legacy_pre_effect, n as prop, o as bind_prop, p as get, s as attribute_effect, t as legacy_rest_props, u as append, v as mutable_source, x as pop, y as set } from "./client-pmAKFFi-.js";
3
3
  import { onDestroy, onMount } from "svelte";
4
4
  enable_legacy_mode_flag();
5
- var root = from_html("<div><div data-motion-rail-scrollable=\"\"><div data-motion-rail-grid=\"\"><!></div></div></div>");
5
+ var root = from_html("<div><div data-motionrail-scrollable=\"\"><div data-motionrail-grid=\"\"><!></div></div></div>");
6
6
  function Svelte(S, C) {
7
7
  let w = legacy_rest_props(legacy_rest_props(C, [
8
8
  "children",
@@ -27,7 +27,7 @@ function Svelte(S, C) {
27
27
  onMount(() => {
28
28
  if (!get(O)) return;
29
29
  set(k, new MotionRail(get(O), T()));
30
- let x = get(O).querySelector("[data-motion-rail-grid]");
30
+ let x = get(O).querySelector("[data-motionrail-grid]");
31
31
  x && (A = new MutationObserver(() => {
32
32
  get(k) && get(k).update();
33
33
  }), A.observe(x, {
@@ -50,7 +50,7 @@ function Svelte(S, C) {
50
50
  init();
51
51
  var P = root();
52
52
  attribute_effect(P, () => ({
53
- "data-motion-rail": !0,
53
+ "data-motionrail": !0,
54
54
  ...w
55
55
  }));
56
56
  var F = child(P), I = child(F);
package/dist/svelte5.js CHANGED
@@ -1,7 +1,7 @@
1
- import { t as MotionRail } from "./motionrail-Dq8joDtA.js";
1
+ import { t as MotionRail } from "./motionrail-DsLqZe8W.js";
2
2
  import { C as reset, S as push, _ as child, a as bind_this, b as state, d as from_html, g as user_effect, l as snippet, n as prop, p as get, r as rest_props, s as attribute_effect, u as append, w as noop, x as pop, y as set } from "./client-pmAKFFi-.js";
3
3
  import { onMount } from "svelte";
4
- var root = from_html("<div><div data-motion-rail-scrollable=\"\"><div data-motion-rail-grid=\"\"><!></div></div></div>");
4
+ var root = from_html("<div><div data-motionrail-scrollable=\"\"><div data-motionrail-grid=\"\"><!></div></div></div>");
5
5
  function Svelte5(v, y) {
6
6
  push(y, !0);
7
7
  let b = prop(y, "options", 19, () => ({})), x = prop(y, "instance", 15), S = prop(y, "container", 15), C = rest_props(y, [
@@ -27,7 +27,7 @@ function Svelte5(v, y) {
27
27
  onMount(() => {
28
28
  if (!get(w)) return;
29
29
  set(T, new MotionRail(get(w), b()), !0);
30
- let _ = get(w).querySelector("[data-motion-rail-grid]");
30
+ let _ = get(w).querySelector("[data-motionrail-grid]");
31
31
  return _ && (set(E, new MutationObserver(() => {
32
32
  get(T) && get(T).update();
33
33
  }), !0), get(E).observe(_, {
@@ -44,7 +44,7 @@ function Svelte5(v, y) {
44
44
  getContainer: O
45
45
  }, A = root();
46
46
  attribute_effect(A, () => ({
47
- "data-motion-rail": !0,
47
+ "data-motionrail": !0,
48
48
  ...C
49
49
  }));
50
50
  var j = child(A), M = child(j);
package/dist/vue.js CHANGED
@@ -1,6 +1,6 @@
1
- import { t as MotionRail } from "./motionrail-Dq8joDtA.js";
1
+ import { t as MotionRail } from "./motionrail-DsLqZe8W.js";
2
2
  import { createElementBlock, createElementVNode, defineComponent, mergeProps, onBeforeUnmount, onMounted, openBlock, ref, renderSlot, useSlots, watch } from "vue";
3
- var _hoisted_1 = { "data-motion-rail-scrollable": "" }, _hoisted_2 = { "data-motion-rail-grid": "" }, vue_default = /* @__PURE__ */ defineComponent({
3
+ var _hoisted_1 = { "data-motionrail-scrollable": "" }, _hoisted_2 = { "data-motionrail-grid": "" }, vue_default = /* @__PURE__ */ defineComponent({
4
4
  __name: "vue",
5
5
  props: { options: { default: () => ({}) } },
6
6
  emits: ["mounted"],
@@ -20,7 +20,7 @@ var _hoisted_1 = { "data-motion-rail-scrollable": "" }, _hoisted_2 = { "data-mot
20
20
  }), (e, p) => (openBlock(), createElementBlock("div", mergeProps({
21
21
  ref_key: "containerRef",
22
22
  ref: y,
23
- "data-motion-rail": ""
23
+ "data-motionrail": ""
24
24
  }, e.$attrs), [createElementVNode("div", _hoisted_1, [createElementVNode("div", _hoisted_2, [renderSlot(e.$slots, "default")])])], 16));
25
25
  }
26
26
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "motionrail",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "module": "./dist/motionrail.js",
6
6
  "types": "./dist/motionrail.d.ts",