morphing-scroll 1.1.7 → 1.1.8

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Georg Schilin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,619 @@
1
+ <div align="center" style="height: 282px;">
2
+ <img src="https://drive.google.com/uc?export=view&id=1mpb5TAElX3Xla4sGFISp4bQMu0zuNJaa" alt="logo"/>
3
+ </div>
4
+
5
+ ## 〈♦ Table of contents 〉
6
+
7
+ - [About](#-about-)
8
+ - [Installation](#-installation-)
9
+ - [MorphScroll](#-morph_scroll-)
10
+ - [ResizeTracker](#-resizet_racker-)
11
+ - [IntersectionTracker](#-intersection_tracker-)
12
+ - [More](#-More-)
13
+ - [API](#-api-)
14
+
15
+ ## 〈♦ About 〉
16
+
17
+ `morphing-scroll` is a `React` library designed to optimize the rendering of data lists. It leverages virtual rendering and lazy loading to handle large datasets efficiently, significantly enhancing performance. The library also resolves cross-browser inconsistencies in scroll element rendering by replacing them with custom ones. Additionally, it provides convenient horizontal scrolling with flexible content movement options.
18
+
19
+ ## 〈♦ Installation 〉
20
+
21
+ To install the library, use the following command:
22
+
23
+ ```bash
24
+ npm install morphing-scroll
25
+ ```
26
+
27
+ ## 〈♦ MorphScroll 〉
28
+
29
+ `MorphScroll` is the main component of the library responsible for displaying your data.
30
+
31
+ ### Props:
32
+
33
+ ##### - GENERAL SETTINGS:
34
+
35
+ - **`className`:** _Additional classes for the component._
36
+ <details>
37
+ <summary><strong><em>MORE:</em></strong></summary>
38
+ <br />
39
+ <strong>• Type:</strong> string<br />
40
+ <br />
41
+ <strong>• Description:</strong> <em><br />
42
+ This parameter allows you to apply custom CSS classes to the <code>MorphScroll</code> component, enabling further customization and styling to fit your design needs.✨</em><br />
43
+ <br />
44
+ <strong>• Example:</strong>
45
+
46
+ ```tsx
47
+ <MorphScroll
48
+ className="your-class"
49
+ // another props
50
+ >
51
+ {children}
52
+ </MorphScroll>
53
+ ```
54
+
55
+ </details>
56
+ <h2>
57
+
58
+ - **`children` (required):** _Custom user content._
59
+ <details>
60
+ <summary><strong><em>MORE:</em></strong></summary>
61
+ <br />
62
+ <strong>• Type:</strong> React.ReactNode<br />
63
+ <br />
64
+ <strong>• Description:</strong> <em><br />
65
+ This is where you can pass your list elements.<br />
66
+ Make sure to provide unique keys for each list item, as per React's rules. The <code>MorphScroll</code> component ensures that the cells it generates will use the same keys as your list items, allowing it to render the correct cells for the current list.<br />
67
+ Additionally, <code>MorphScroll</code> handles a passed <code>null</code> value the same way as <code>undefined</code>, rendering nothing in both cases.</em><br />
68
+ <br />
69
+ <strong>• Example:</strong>
70
+
71
+ ```tsx
72
+ <MorphScroll
73
+ // props
74
+ >
75
+ {children}
76
+ </MorphScroll>
77
+ ```
78
+
79
+ </details>
80
+
81
+ ##### - SCROLL SETTINGS:
82
+
83
+ - **`type`:** _Type of progress element._
84
+ <details>
85
+ <summary><strong><em>MORE:</em></strong></summary>
86
+ <br />
87
+ <strong>• Type:</strong> "scroll" | "slider"<br />
88
+ <br />
89
+ <strong>• Default:</strong> "scroll"<br />
90
+ <br />
91
+ <strong>• Description:</strong> <em><br />
92
+ This parameter defines how the provided <code>progressElement</code> behaves within <code>progressTrigger</code> and how you interact with it.<br />
93
+ With the default <code>type="scroll"</code>, it functions as a typical scrollbar. However, with <code>type="slider"</code>, it displays distinct elements indicating the number of full scroll steps within the list.<br />
94
+ For More details, refer to <code>progressTrigger/progressElement</code>.</em><br />
95
+ <br />
96
+ <strong>• Example:</strong>
97
+
98
+ ```tsx
99
+ <MorphScroll
100
+ type="slider"
101
+ // another props
102
+ >
103
+ {children}
104
+ </MorphScroll>
105
+ ```
106
+
107
+ </details>
108
+ <h2>
109
+
110
+ - **`direction`:** _Scrolling direction._
111
+ <details>
112
+ <summary><strong><em>MORE:</em></strong></summary>
113
+ <br />
114
+ <strong>• Type:</strong> "x" | "y"<br />
115
+ <br />
116
+ <strong>• Default:</strong> "y"<br />
117
+ <br />
118
+ <strong>• Description:</strong> <em><br />
119
+ This parameter changes the scroll or slider type direction based on the provided value.<br />
120
+ You can set it to horizontal or vertical to customize the component according to your needs.</em><br />
121
+ <br />
122
+ <strong>• Example:</strong>
123
+
124
+ ```tsx
125
+ <MorphScroll
126
+ direction="x"
127
+ // another props
128
+ >
129
+ {children}
130
+ </MorphScroll>
131
+ ```
132
+
133
+ </details>
134
+ <h2>
135
+
136
+ - **`scrollTop`:** _Scroll position and animation duration._
137
+ <details>
138
+ <summary><strong><em>MORE:</em></strong></summary>
139
+ <br />
140
+ <strong>• Type:</strong> { value: number | "end" | null; duration?: number }<br />
141
+ <br />
142
+ <strong>• Default:</strong> { value: 1; duration: 200 }<br />
143
+ <br />
144
+ <strong>• Description:</strong> <em><br />
145
+ This parameter will help you set your own scroll values.<br />
146
+ The default value for <code>value</code> is set to 1 to prevent sudden scrolling to the start of the list, especially when loading new elements at the top of the MorphScroll. The value parameter also accepts <code>null</code>, this is done so that after using <code>scrollTop</code> you can reset the passed value for later use of the same value. The value <code>"end"</code> scrolls to the end of the list upon loading and is useful when adding new items to the bottom of the list and will not work when adding new items to the top.<br />
147
+ The <code>duration</code> parameter specifies the scrolling speed for the <code>scrollTop</code> values. This parameter is optional and you can only use `value'.</em><br />
148
+ <br />
149
+ <strong>• Example:</strong>
150
+
151
+ ```tsx
152
+ <MorphScroll
153
+ scrollTop={{ value: 100; duration: 100 }}
154
+ // another props
155
+ >
156
+ {children}
157
+ </MorphScroll>
158
+ ```
159
+
160
+ </details>
161
+ <h2>
162
+
163
+ - **`stopLoadOnScroll`:** _Stop loading when scrolling._
164
+ <details>
165
+ <summary><strong><em>MORE:</em></strong></summary>
166
+ <br />
167
+ <strong>• Type:</strong> boolean<br />
168
+ <br />
169
+ <strong>• Default:</strong> false<br />
170
+ <br />
171
+ <strong>• Description:</strong> <em><br />
172
+ This parameter helps optimize list performance during scrolling. When set to <code>true</code>, new items will not load while the list is being scrolled and will only load after scrolling stops. This can be particularly useful for lists with a large number of items.</em><br />
173
+ <br />
174
+ <strong>• Example:</strong>
175
+
176
+ ```tsx
177
+ <MorphScroll
178
+ stopLoadOnScroll
179
+ // another props
180
+ >
181
+ {children}
182
+ </MorphScroll>
183
+ ```
184
+
185
+ </details>
186
+ <h2>
187
+
188
+ - **`onScrollValue`:** _Callback for scroll value._
189
+ <details>
190
+ <summary><strong><em>MORE:</em></strong></summary>
191
+ <br />
192
+ <strong>• Type:</strong> (scroll: number) => void<br />
193
+ <br />
194
+ <strong>• Description:</strong> <em><br />
195
+ This parameter accepts a callback function that is triggered on every scroll event. The callback receives the current scroll position as a number. The return value of the callback can be used to determine custom behavior based on the scroll value.</em><br />
196
+ <br />
197
+ <strong>• Example:</strong>
198
+
199
+ ```tsx
200
+ <MorphScroll
201
+ onScrollValue={
202
+ (scroll) => {
203
+ console.log("Scroll position:", scroll);
204
+ return scroll > 100;
205
+ },
206
+ }
207
+ // another props
208
+ >
209
+ {children}
210
+ </MorphScroll>
211
+ ```
212
+
213
+ </details>
214
+ <h2>
215
+
216
+ - **`isScrolling`:** _Callback function for scroll status._
217
+ <details>
218
+ <summary><strong><em>MORE:</em></strong></summary>
219
+ <br />
220
+ <strong>• Type:</strong> (motion: boolean) => void<br />
221
+ <br />
222
+ <strong>• Description:</strong> <em><br />
223
+ This parameter accepts a callback function that is triggered whenever the scroll status changes. The callback receives a boolean value, where <code>true</code> indicates that scrolling is in progress, and <code>false</code> indicates that scrolling has stopped. This can be useful for triggering additional actions, such as pausing animations or loading indicators based on the scroll state.</em><br />
224
+ <br />
225
+ <strong>• Example:</strong>
226
+
227
+ ```tsx
228
+ <MorphScroll
229
+ isScrolling={(motion) => {
230
+ console.log(motion ? "Scrolling..." : "Scroll stopped.");
231
+ }}
232
+ // another props
233
+ >
234
+ {children}
235
+ </MorphScroll>
236
+ ```
237
+
238
+ </details>
239
+
240
+ ##### - VISUAL SETTINGS:
241
+
242
+ - **`size`:** _MorphScroll width and height._
243
+ <details>
244
+ <summary><strong><em>MORE:</em></strong></summary>
245
+ <br />
246
+ <strong>• Type:</strong> number[]<br />
247
+ <br />
248
+ <strong>• Description:</strong> <em><br />
249
+ This parameter sets the width and height of the <code>MorphScroll</code> component as an array of two numbers. These values help define the visual container for the scrollable area.<br />
250
+ *The values are specified following the <code>width/height</code> rule in pixels, regardless of the <code>direction</code>.<br />
251
+ <br />
252
+ If this parameter is not specified, <code>MorphScroll</code> will use the <code>ResizeTracker</code> component to measure the width and height of the area where <code>MorphScroll</code> is added. The dimensions will automatically adjust when the container changes.<br />
253
+ *See the <code>ResizeTracker</code> section for more details.</em><br />
254
+ <br />
255
+ <strong>• Example:</strong>
256
+
257
+ ```tsx
258
+ <MorphScroll
259
+ size={[100, 400]}
260
+ // another props
261
+ >
262
+ {children}
263
+ </MorphScroll>
264
+ ```
265
+
266
+ </details>
267
+ <h2>
268
+
269
+ - **`objectsSize` (required):** _Required: Size of cells for each object._
270
+ <details>
271
+ <summary><strong><em>MORE:</em></strong></summary>
272
+ <br />
273
+ <strong>• Type:</strong> (number | "none" | "firstChild")[]<br />
274
+ <br />
275
+ <strong>• Description:</strong> <em><br />
276
+ This parameter is the only required one. It defines the size of cells for each of your objects. <code>ObjectsSize</code> use an array of values.<br />
277
+ *The values are specified following the <code>width/height</code> rule, regardless of the <code>direction</code>.<br />
278
+ <br />
279
+ If you pass <code>"none"</code>, cells will still be created, but <code>MorphScroll</code> will not calculate their sizes-they will simply wrap your objects. In this case, for example, you won’t be able to use the <code>infiniteScroll</code> feature, as it requires specific cell sizes for absolute positioning.. However, this is not a drawback if you are building something like a chat or a news feed, where the content can have varying heights, and it’s better to load new content as the user approaches the end of the existing list.<br />
280
+ <br />
281
+ If you specify the value <code>"firstChild"</code>, a <code>ResizeTracker</code> wrapper will be created for the first child of your list. This wrapper will calculate the size of the first child, and these dimensions will be applied to all cells in the list.</em><br />
282
+ <br />
283
+ <strong>• Example:</strong>
284
+
285
+ ```tsx
286
+ <MorphScroll
287
+ objectsSize={[40, 40]}
288
+ // objectsSize={["none", "none"]}
289
+ // objectsSize={["firstChild", "firstChild"]}
290
+ // another props
291
+ >
292
+ {children}
293
+ </MorphScroll>
294
+ ```
295
+
296
+ </details>
297
+ <h2>
298
+
299
+ - **`gap`:** _Gap between cells._
300
+ <details>
301
+ <summary><strong><em>MORE:</em></strong></summary>
302
+ <br />
303
+ <strong>• Type:</strong> number[] | number<br />
304
+ <br />
305
+ <strong>• Description:</strong> <em><br />
306
+ This parameter allows you to set spacing between list items both horizontally and vertically. You can provide a single value, which will apply to both directions, or an array of two numbers to define separate spacing values.<br />
307
+ *The values are specified following the <code>horizontal/vertical</code> rule in pixels, regardless of the <code>direction</code>.</em><br />
308
+ <br />
309
+ <strong>• Example:</strong>
310
+
311
+ ```tsx
312
+ <MorphScroll
313
+ gap={10}
314
+ // gap={[10, 10]}
315
+ // another props
316
+ >
317
+ {children}
318
+ </MorphScroll>
319
+ ```
320
+
321
+ </details>
322
+ <h2>
323
+
324
+ - **`padding`:** _Padding for the `objectsWrapper`._
325
+ <details>
326
+ <summary><strong><em>MORE:</em></strong></summary>
327
+ <br />
328
+ <strong>• Type:</strong> number[] | number<br />
329
+ <br />
330
+ <strong>• Description:</strong> <em><br />
331
+ This parameter defines the spacing between the list items and their wrapper, effectively increasing the width or height of the scrollable area. You can provide a single number, which will apply to all sides, or an array of two or four numbers to specify spacing for specific directions.<br />
332
+ <br />
333
+ *For a two-number array, the values follow the <code>horizontal/vertical</code> rule, while a four-number array follows the <code>top/right/bottom/left</code> rule. All values are in pixels and apply regardless of the <code>direction</code>.<br />
334
+ <br />
335
+ *Important: this is not a CSS property, even though its name might suggest otherwise. It specifically refers to modifying the width and height of the scrollable wrapper, affecting the dimensions of the scrollable area.</em><br />
336
+ <br />
337
+ <strong>• Example:</strong>
338
+
339
+ ```tsx
340
+ <MorphScroll
341
+ padding={10}
342
+ // padding={[10, 10]}
343
+ // padding={[10, 10, 10, 10]}
344
+ // another props
345
+ >
346
+ {children}
347
+ </MorphScroll>
348
+ ```
349
+
350
+ </details>
351
+ <h2>
352
+
353
+ - **`contentAlign`:** _Aligns the content when it is smaller than the MorphScroll `size`._
354
+ <details>
355
+ <summary><strong><em>MORE:</em></strong></summary>
356
+ <br />
357
+ <strong>• Type:</strong> ["start" | "center" | "end", "start" | "center" | "end"]<br />
358
+ <br />
359
+ <strong>• Description:</strong> <em><br />
360
+ .</em><br />
361
+ <br />
362
+ <strong>• Example:</strong>
363
+
364
+ ```tsx
365
+ <MorphScroll
366
+ // another props
367
+ >
368
+ {children}
369
+ </MorphScroll>
370
+ ```
371
+
372
+ </details>
373
+ <h2>
374
+
375
+ - **`elementsAlign`:** _Aligns the objects within the `objectsWrapper`._
376
+ <details>
377
+ <summary><strong><em>MORE:</em></strong></summary>
378
+ <br />
379
+ <strong>• Type:</strong> "start" | "center" | "end"<br />
380
+ <br />
381
+ <strong>• Description:</strong> <em><br />
382
+ .</em><br />
383
+ <br />
384
+ <strong>• Example:</strong>
385
+
386
+ ```tsx
387
+ <MorphScroll
388
+ // another props
389
+ >
390
+ {children}
391
+ </MorphScroll>
392
+ ```
393
+
394
+ </details>
395
+ <h2>
396
+
397
+ - **`edgeGradient`:** _Edge gradient._
398
+ <details>
399
+ <summary><strong><em>MORE:</em></strong></summary>
400
+ <br />
401
+ <strong>• Type:</strong> boolean | { color?: string; size?: number }<br />
402
+ <br />
403
+ <strong>• Default:</strong> if true { color: "rgba(0,0,0,0.4)", size: 40 }<br />
404
+ <br />
405
+ <strong>• Description:</strong> <em><br />
406
+ .</em><br />
407
+ <br />
408
+ <strong>• Example:</strong>
409
+
410
+ ```tsx
411
+ <MorphScroll
412
+ // another props
413
+ >
414
+ {children}
415
+ </MorphScroll>
416
+ ```
417
+
418
+ </details>
419
+ <h2>
420
+
421
+ - **`progressReverse`:** _Reverse the progress bar direction._
422
+ <details>
423
+ <summary><strong><em>MORE:</em></strong></summary>
424
+ <br />
425
+ <strong>• Type:</strong> boolean<br />
426
+ <br />
427
+ <strong>• Default:</strong> false<br />
428
+ <br />
429
+ <strong>• Description:</strong> <em><br />
430
+ .</em><br />
431
+ <br />
432
+ <strong>• Example:</strong>
433
+
434
+ ```tsx
435
+ <MorphScroll
436
+ // another props
437
+ >
438
+ {children}
439
+ </MorphScroll>
440
+ ```
441
+
442
+ </details>
443
+ <h2>
444
+
445
+ - **`progressVisibility`:** _Visibility of the progress bar._
446
+ <details>
447
+ <summary><strong><em>MORE:</em></strong></summary>
448
+ <br />
449
+ <strong>• Type:</strong> "visible" | "hover" | "hidden"<br />
450
+ <br />
451
+ <strong>• Default:</strong> "visible"<br />
452
+ <br />
453
+ <strong>• Description:</strong> <em><br />
454
+ .</em><br />
455
+ <br />
456
+ <strong>• Example:</strong>
457
+
458
+ ```tsx
459
+ <MorphScroll
460
+ // another props
461
+ >
462
+ {children}
463
+ </MorphScroll>
464
+ ```
465
+
466
+ </details>
467
+ <h2>
468
+
469
+ - **`objectsWrapFullMinSize`:** _Sets the `min-height` CSS property of the `objectsWrapper` to match the height of the MorphScroll._
470
+ <details>
471
+ <summary><strong><em>MORE:</em></strong></summary>
472
+ <br />
473
+ <strong>• Type:</strong> boolean<br />
474
+ <br />
475
+ <strong>• Default:</strong> false<br />
476
+ <br />
477
+ <strong>• Description:</strong> <em><br />
478
+ .</em><br />
479
+ <br />
480
+ <strong>• Example:</strong>
481
+
482
+ ```tsx
483
+ <MorphScroll
484
+ // another props
485
+ >
486
+ {children}
487
+ </MorphScroll>
488
+ ```
489
+
490
+ </details>
491
+
492
+ ##### - PROGRESS AND RENDERING:
493
+
494
+ - **`progressTrigger`:** _Triggers for the progress bar._
495
+ <details>
496
+ <summary><strong><em>MORE:</em></strong></summary>
497
+ <br />
498
+ <strong>• Type:</strong> {<br />
499
+ wheel?: boolean;<br />
500
+ content?: boolean;<br />
501
+ progressElement?: boolean | React.ReactNode;<br />
502
+ arrows?: boolean | { size?: number; element?: React.ReactNode };<br />
503
+ }<br />
504
+ <br />
505
+ <strong>• Default:</strong> { wheel: true }<br />
506
+ <br />
507
+ <strong>• Description:</strong> <em><br />
508
+ .</em><br />
509
+ <br />
510
+ <strong>• Example:</strong>
511
+
512
+ ```tsx
513
+ <MorphScroll
514
+ // another props
515
+ >
516
+ {children}
517
+ </MorphScroll>
518
+ ```
519
+
520
+ </details>
521
+ <h2>
522
+
523
+ - **`render`:** _Types of rendering for optimization._
524
+ <details>
525
+ <summary><strong><em>MORE:</em></strong></summary>
526
+ <br />
527
+ <strong>• Type:</strong><br />
528
+ | { type: "default" }<br />
529
+ | { type: "lazy"; rootMargin?: number }<br />
530
+ | { type: "virtual" }<br />
531
+ <br />
532
+ <strong>• Default:</strong> false<br />
533
+ <br />
534
+ <strong>• Description:</strong> <em><br />
535
+ .</em><br />
536
+ <br />
537
+ <strong>• Example:</strong>
538
+
539
+ ```tsx
540
+ <MorphScroll
541
+ // another props
542
+ >
543
+ {children}
544
+ </MorphScroll>
545
+ ```
546
+
547
+ </details>
548
+ <h2>
549
+
550
+ - **`emptyElements`:** _Processing of empty scroll elements._
551
+ <details>
552
+ <summary><strong><em>MORE:</em></strong></summary>
553
+ <br />
554
+ <strong>• Type:</strong><br />
555
+ | { mode: "clear" }<br />
556
+ | { mode: "fallback"; element?: React.ReactNode }<br />
557
+ <br />
558
+ <strong>• Default:</strong> false<br />
559
+ <br />
560
+ <strong>• Description:</strong> <em><br />
561
+ .</em><br />
562
+ <br />
563
+ <strong>• Example:</strong>
564
+
565
+ ```tsx
566
+ <MorphScroll
567
+ // another props
568
+ >
569
+ {children}
570
+ </MorphScroll>
571
+ ```
572
+
573
+ </details>
574
+ <h2>
575
+
576
+ - **`suspending`:** _Adds React Suspense._
577
+ <details>
578
+ <summary><strong><em>MORE:</em></strong></summary>
579
+ <br />
580
+ <strong>• Type:</strong> boolean<br />
581
+ <br />
582
+ <strong>• Default:</strong> false<br />
583
+ <br />
584
+ <strong>• Description:</strong> <em><br />
585
+ .</em><br />
586
+ <br />
587
+ <strong>• Example:</strong>
588
+
589
+ ```tsx
590
+ <MorphScroll
591
+ // another props
592
+ >
593
+ {children}
594
+ </MorphScroll>
595
+ ```
596
+
597
+ </details>
598
+ <h2>
599
+
600
+ - **`fallback`:** _Fallback element for error handling._
601
+ <details>
602
+ <summary><strong><em>MORE:</em></strong></summary>
603
+ <br />
604
+ <strong>• Type:</strong> React.ReactNode<br />
605
+ <br />
606
+ <strong>• Description:</strong> <em><br />
607
+ .</em><br />
608
+ <br />
609
+ <strong>• Example:</strong>
610
+
611
+ ```tsx
612
+ <MorphScroll
613
+ // another props
614
+ >
615
+ {children}
616
+ </MorphScroll>
617
+ ```
618
+
619
+ </details>
package/index.d.ts CHANGED
@@ -1,124 +1,308 @@
1
1
  import React from "react";
2
2
 
3
+ // RESIZE_TRACKER //////////////////////////////////
3
4
  type ResizeTrackerT = {
4
- measure?: "inner" | "outer" | "all";
5
+ /**---
6
+ * ✨ *Render-prop function receiving the container's size.*
7
+ *
8
+ * @param width - Current width in pixels.
9
+ * @param height - Current height in pixels.
10
+ * @example
11
+ * ```tsx
12
+ * <ResizeTracker>
13
+ * {(width, height) => <div>{`${width}x${height}`}</div>}
14
+ * </ResizeTracker>
15
+ * ```
16
+ * */
17
+ children: (width: number, height: number) => React.ReactNode;
18
+ /**---
19
+ * ✨ *Custom inline styles for the ResizeTracker.*
20
+ */
5
21
  style?: React.CSSProperties;
22
+ /**---
23
+ * ✨ *Defines size measurement behavior*
24
+ * #### Options:
25
+ * - `"inner"`: Fits content.
26
+ * - `"outer"`: Fills parent.
27
+ * - `"all"`: Combines both.
28
+ *
29
+ * @default-"inner"
30
+ */
31
+ measure?: "inner" | "outer" | "all";
32
+ /**---
33
+ * ✨ *Callback on dimension change.*
34
+ *
35
+ * @param width - Updated width (in px).
36
+ * @param height - Updated height (in px).
37
+ * @example
38
+ * ```typescript
39
+ * onResize={(width, height) => console.log(`New size: ${width}x${height}`)}
40
+ * ```
41
+ */
6
42
  onResize?: (width: number, height: number) => void;
7
- children: (width: number, height: number) => React.ReactNode;
8
43
  };
9
44
 
45
+ /**
46
+ * ## *ResizeTracker component*〈♦〉
47
+ *
48
+ * ---
49
+ * ## PROPS:
50
+ * - `children` *◄ REQUIRED ►*
51
+ * - `style`
52
+ * - `measure`
53
+ * - `onResize`
54
+ * ##### ! MORE DETAILS IN PROPS OR LINKS !
55
+ *
56
+ * ---
57
+ * ## RETURNS:
58
+ * React component.
59
+ *
60
+ * ---
61
+ * ## LINKS:
62
+ * [ResizeTracker Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
63
+ *
64
+ * [MDN Reference for Resize Observer API](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver)
65
+ */
10
66
  declare const ResizeTracker: React.FC<ResizeTrackerT>;
11
67
 
68
+ // INTERSECTION_TRACKER ////////////////////////////
12
69
  type IntersectionTrackerT = {
70
+ /**---
71
+ * ✨ *Child elements to be rendered when visible.*
72
+ */
13
73
  children: React.ReactNode;
74
+ /**---
75
+ * ✨ *Custom inline styles for the IntersectionTracker component.*
76
+ */
77
+ style?: React.CSSProperties;
78
+ /**---
79
+ * ✨ *The root element for IntersectionObserver.*
80
+ * @default-viewport
81
+ */
14
82
  root?: Element | null;
83
+ /**---
84
+ * ✨ *Margin around the root.
85
+ * Can be a single number or an array of up to 4 numbers (top, right, bottom, left).*
86
+ */
87
+ rootMargin?: number[] | number;
88
+ /**---
89
+ * ✨ Visibility threshold for triggering intersection events.
90
+ * A value between 0.0 (out of view) and 1.0 (fully visible).
91
+ */
15
92
  threshold?: number;
16
- rootMargin?: number[] | number | null;
17
- style?: React.CSSProperties;
93
+ /**---
94
+ * ✨ Renders children regardless of their visibility in the viewport.
95
+ * @default-false
96
+ */
18
97
  visibleContent?: boolean;
98
+ /**---
99
+ * ✨ Callback function triggered when `children` become visible.
100
+ */
19
101
  onVisible?: () => void;
20
- intersectionDeley?: number;
102
+ /**---
103
+ * ✨ Delay (in ms) before invoking `onVisible`.
104
+ */
105
+ intersectionDelay?: number;
21
106
  };
22
107
 
108
+ /**
109
+ * ## *IntersectionTracker component*〈♦〉
110
+ *
111
+ * ---
112
+ * ## PROPS:
113
+ * - `children` *◄ REQUIRED ►*
114
+ * - `style`
115
+ * - `root`
116
+ * - `rootMargin`
117
+ * - `threshold`
118
+ * - `visibleContent`
119
+ * - `onVisible`
120
+ * - `intersectionDelay`
121
+ * ##### ! MORE DETAILS IN PROPS OR LINKS !
122
+ *
123
+ * ---
124
+ * ## RETURNS:
125
+ * React component.
126
+ *
127
+ * ---
128
+ * ## LINKS:
129
+ * [IntersectionTracker Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
130
+ *
131
+ * [MDN Reference for Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
132
+ */
23
133
  declare const IntersectionTracker: React.FC<IntersectionTrackerT>;
24
134
 
135
+ // MORPH_SCROLL ////////////////////////////////////
25
136
  export type MorphScrollT = {
26
- // General Settings
27
- scrollID?: string;
137
+ /**---
138
+ * ✨ *Additional class for the component.*
139
+ */
28
140
  className?: string;
141
+ /**---
142
+ * ✨ *Child elements.*
143
+ */
29
144
  children?: React.ReactNode;
30
-
31
- // Scroll Settings
145
+ /**---
146
+ * *Type of progress element.*
147
+ * @default-"scroll"
148
+ */
32
149
  type?: "scroll" | "slider";
150
+ /**---
151
+ * ✨ *Scrolling direction.*
152
+ * @default-"y"
153
+ */
33
154
  direction?: "x" | "y";
34
- scrollTop?: { value: number | "end"; duration?: number };
155
+ /**---
156
+ * ✨ *Scroll position and animation duration.*
157
+ */
158
+ scrollTop?: { value: number | "end" | null; duration?: number };
159
+ /**---
160
+ * ✨ *Stop loading when scrolling.*
161
+ * @default-false
162
+ */
35
163
  stopLoadOnScroll?: boolean;
36
- onScrollValue?: Array<(scroll: number) => boolean>;
37
- isScrolling?: (status: boolean) => void;
38
-
39
- // Visual Settings
164
+ /**---
165
+ * *Callback for scroll value.*
166
+ * @example
167
+ * `onScrollValue={
168
+ * (scroll) => scroll > 200 && console.log("scroll > 200")
169
+ * }`
170
+ */
171
+ onScrollValue?: (scroll: number) => void;
172
+ /**---
173
+ * ✨ *Callback for scroll status.*
174
+ * @example `isScrolling={(value) => console.log(value)}`
175
+ */
176
+ isScrolling?: (motion: boolean) => void;
177
+ /**---
178
+ * ✨ *MorphScroll width and height.*
179
+ */
40
180
  size?: number[];
181
+ /**---
182
+ * ✨ *Required: Size of cells for each object.*
183
+ */
41
184
  objectsSize: (number | "none" | "firstChild")[];
185
+ /**---
186
+ * ✨ *Gap between cells.*
187
+ */
42
188
  gap?: number[] | number;
189
+ /**---
190
+ * ✨ *Padding for the `objectsWrapper`.*
191
+ */
43
192
  padding?: number[] | number;
193
+ /**---
194
+ * ✨ *Aligns the content when it is smaller than the MorphScroll `size`.*
195
+ */
44
196
  contentAlign?: ["start" | "center" | "end", "start" | "center" | "end"];
197
+ /**---
198
+ * ✨ *Aligns the objects within the `objectsWrapper`.*
199
+ */
45
200
  elementsAlign?: "start" | "center" | "end";
201
+ /**---
202
+ * ✨ *Edge gradient.*
203
+ * @default if true { color: "rgba(0,0,0,0.4)", size: 40 }
204
+ */
46
205
  edgeGradient?: boolean | { color?: string; size?: number };
47
- objectsWrapFullMinSize?: boolean;
48
-
49
- // Progress and Rendering
206
+ /**---
207
+ * ✨ *Reverse the progress bar direction.*
208
+ * @default false
209
+ */
50
210
  progressReverse?: boolean;
211
+ /**---
212
+ * ✨ *Visibility of the progress bar.*
213
+ * @default "visible"
214
+ */
51
215
  progressVisibility?: "visible" | "hover" | "hidden";
216
+ /**---
217
+ * ✨ *Sets the `min-height` CSS property of the `objectsWrapper` to match the height of the MorphScroll.*
218
+ */
219
+ objectsWrapFullMinSize?: boolean;
220
+ /**---
221
+ * ✨ *Triggers for the progress bar.*
222
+ * @default-{ wheel: true }
223
+ * @example
224
+ * `progressTrigger={
225
+ * wheel: true,
226
+ * content: true,
227
+ * progressElement: true // false // <YourProgressComponent/>,
228
+ * arrows: true // { size: number, element: <YourArrowComponent/> }
229
+ * }`
230
+ */
52
231
  progressTrigger?: {
53
232
  wheel?: boolean;
54
233
  content?: boolean;
55
234
  progressElement?: boolean | React.ReactNode;
56
235
  arrows?: boolean | { size?: number; element?: React.ReactNode };
57
236
  };
58
-
59
- // Additional Settings
60
- lazyRender?: boolean;
61
- infiniteScroll?: boolean;
62
- rootMargin?: number[] | number;
237
+ /**---
238
+ * *Types of rendering for optimization.*
239
+ * @default-{ type: "default" }
240
+ */
241
+ render?:
242
+ | { type: "default" }
243
+ | { type: "lazy"; rootMargin?: number }
244
+ | { type: "virtual" };
245
+ /**---
246
+ * ✨ *Processing of empty scroll elements.*
247
+ */
248
+ emptyElements?:
249
+ | { mode: "clear" }
250
+ | { mode: "fallback"; element?: React.ReactNode };
251
+ /**---
252
+ * ✨ *Adds React Suspense.*
253
+ */
63
254
  suspending?: boolean;
255
+ /**---
256
+ * ✨ *Fallback element for error handling.*
257
+ */
64
258
  fallback?: React.ReactNode;
65
259
  };
66
260
 
67
261
  /**
68
- * `MorphScroll` component.
262
+ * ## *MorphScroll component*〈♦〉
69
263
  *
70
- * ### General Settings
71
- * @param scrollID - Optional: Scroll identifier.
72
- * @param className - Optional: Additional CSS class for the component.
73
- * @param children - Optional: Child elements.
264
+ * ---
265
+ * ## PROPS:
266
+ * #### GENERAL SETTINGS:
267
+ * - `className`
268
+ * - `children`
74
269
  *
75
- * ### Scroll Settings
76
- * @param type - Optional: Type of progress element. Default: `"scroll"`.
77
- * @param direction - Optional: Scrolling direction.
78
- * @param scrollTop - Optional: Scroll position and animation duration.
79
- * @param stopLoadOnScroll - Optional: Stop loading when scrolling.
80
- * @param onScrollValue - Optional: Callback for scroll value.
81
- * @example
82
- * `onScrollValue={[
83
- * (scroll) => scroll > 200 && console.log("scroll > 200"),
84
- * ]}`
85
- * @param isScrolling - Optional: Callback for scroll status.
86
- * @example
87
- * `isScrolling={(value) => console.log(value)}`
270
+ * #### SCROLL SETTINGS:
271
+ * - `type`
272
+ * - `direction`
273
+ * - `scrollTop`
274
+ * - `stopLoadOnScroll`
275
+ * - `onScrollValue`
276
+ * - `isScrolling`
88
277
  *
89
- * ### Visual Settings
90
- * @param size - Optional: Scroll width and height.
91
- * @param objectsSize - Required: Size of cells for each object.
92
- * @param gap - Optional: Gap between cells.
93
- * @param padding - Optional: Padding for the `objectsWrapper`.
94
- * @param contentAlign - Optional: Aligns the content when it is smaller than the MorphScroll `size`.
95
- * @param elementsAlign - Optional: Aligns the objects within the `objectsWrapper`.
96
- * @param edgeGradient - Optional: Edge gradient. Default: `{ color: "rgba(0,0,0,0.4)", size: 40 }`.
97
- * @param objectsWrapFullMinSize - Optional: Sets the `min-height` of the `objectsWrapper` to match the height of the MorphScroll.
278
+ * #### VISUAL SETTINGS:
279
+ * - `size`
280
+ * - `objectsSize` *◄ REQUIRED ►*
281
+ * - `gap`
282
+ * - `padding`
283
+ * - `contentAlign`
284
+ * - `elementsAlign`
285
+ * - `edgeGradient`
286
+ * - `progressReverse`
287
+ * - `progressVisibility`
288
+ * - `objectsWrapFullMinSize`
98
289
  *
99
- * ### Progress and Rendering
100
- * @param progressReverse - Optional: Reverse the progress bar direction.
101
- * @param progressVisibility - Optional: Visibility of the progress bar.
102
- * @param progressTrigger - Optional: Triggers for the progress bar. Default: `{ wheel: true }`.
103
- * @example
104
- * `progressTrigger={
105
- * wheel: true,
106
- * content: true,
107
- * progressElement: `true/false` or <YourProgressComponent/>
108
- * arrows: true or { size: number, element: <YourArrowComponent/> }
109
- * }`
290
+ * #### PROGRESS AND RENDERING:
291
+ * - `progressTrigger`
292
+ * - `render`
293
+ * - `emptyElements`
294
+ * - `suspending`
295
+ * - `fallback`
296
+ * ##### ! MORE DETAILS IN PROPS OR LINKS !
110
297
  *
111
- * ### Additional Settings
112
- * @param lazyRender - Optional: Lazy rendering of objects.
113
- * @param infiniteScroll - Optional: Infinite scrolling.
114
- * @param rootMargin - Optional: Margin expansion for object rendering.
115
- * @param suspending - Optional: Adds React Suspense.
116
- * @param fallback - Optional: Fallback element for error handling.
298
+ * ---
299
+ * ## RETURNS:
300
+ * React component.
117
301
  *
118
- * @returns React component.
119
- * @see [Documentation](https://github.com/voodoofugu/morphing-scroll?tab=readme-ov-file#-scroll)
302
+ * ---
303
+ * ## LINKS:
304
+ * [MorphScroll Documentation](https://github.com/voodoofugu/morphing-scroll?tab=readme-ov-file#-scroll)
120
305
  */
121
-
122
306
  declare const MorphScroll: React.FC<MorphScrollT>;
123
307
 
124
308
  export { MorphScroll, ResizeTracker, IntersectionTracker };
package/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("react");const t=({children:t,root:r,threshold:n,rootMargin:s,style:o,visibleContent:l=!1,onVisible:i,intersectionDeley:c})=>{const[a,u]=e.useState(!1),g=e.useRef(null),d=e.useRef(null),h=s?"number"==typeof s?`${s}px ${s}px ${s}px ${s}px`:2===s.length?`${s[0]}px ${s[1]}px ${s[0]}px ${s[1]}px`:`${s[0]}px ${s[1]}px ${s[2]}px ${s[3]}px`:"",m=e=>{e.forEach((e=>{u(e.isIntersecting)}))},p={root:r,threshold:n,rootMargin:h};return e.useEffect((()=>{const e=new IntersectionObserver(m,p);return g.current&&e.observe(g.current),()=>{g.current&&e.unobserve(g.current)}}),[r,n,s]),e.useEffect((()=>(c?d.current=setTimeout((()=>{a&&i&&i()}),c):a&&i&&i(),()=>{d.current&&clearTimeout(d.current)})),[a]),e.createElement("div",{ref:g,style:o},(l||a)&&t)},r=({measure:t="inner",style:r,onResize:n,children:s})=>{const o=e.useRef(null),[l,i]=e.useState({width:0,height:0});e.useEffect((()=>{const e=o.current;if(null==e||e.parentElement,!e)return;const t=new ResizeObserver((e=>{for(const t of e){const e=t.contentRect.width,r=t.contentRect.height;i({width:e,height:r}),n&&n(e,r)}}));return t.observe(e),()=>{t.unobserve(e),t.disconnect()}}),[t,n]);const c={minWidth:"100%",minHeight:"100%"},a={width:"max-content",height:"max-content"},u={inner:Object.assign({},a),outer:Object.assign({},c),all:Object.assign(Object.assign({},c),a)};return e.createElement("div",{className:"resizeTracker",ref:o,style:Object.assign(Object.assign({},u[t]),r)},s(l.width,l.height))},n=e.memo((({children:r,elementTop:n,left:s,mRootLocal:o,scrollElementRef:l,xyObject:i,xyObjectReverse:c,objectsSizeLocal:a,rootMargin:u,suspending:g,fallback:d,infiniteScroll:h,lazyRender:m,attribute:p,objectsPerDirection:f,direction:b})=>{const y=g?e.createElement(e.Suspense,{fallback:d},r):r,v=Object.assign({width:c?`${c}px`:"",height:i?`${i}px`:""},"x"===b&&{display:"flex"}),x=Object.assign({width:a[0]?`${a[0]}px`:""},"x"===b&&{transform:"rotate(-90deg) scaleX(-1)"}),j={root:l.current,rootMargin:h?u:o,style:h?Object.assign(Object.assign(Object.assign(Object.assign({},v),{position:"absolute",top:`${n}px`}),s&&{left:`${s}px`}),!c&&1===f&&{transform:"translateX(-50%)"}):v},w=e.createElement("div",Object.assign({},p?{"wrap-id":p}:{},{style:x}),y);return h?e.createElement("div",{style:Object.assign(Object.assign(Object.assign({position:"absolute",top:`${n}px`},s&&{left:`${s}px`}),!c&&1===f&&{transform:"translateX(-50%)"}),v)},w):m?e.createElement(t,Object.assign({},j),w):e.createElement("div",{style:v},w)}));n.displayName="ScrollObject",exports.IntersectionTracker=t,exports.MorphScroll=({scrollID:t="",type:s="scroll",className:o="",size:l,objectsSize:i,direction:c="y",gap:a,padding:u=[0,0,0,0],progressReverse:g=!1,progressTrigger:d={wheel:!0},progressVisibility:h="visible",lazyRender:m=!1,rootMargin:p=0,suspending:f=!1,fallback:b=null,scrollTop:y,infiniteScroll:v=!1,edgeGradient:x,objectsWrapFullMinSize:j,children:w,onScrollValue:O,elementsAlign:E=!1,contentAlign:$,isScrolling:M,stopLoadOnScroll:R})=>{var T;const z=e.useReducer((()=>({})),{})[1],k=e.useRef(null),S=e.useRef(null),C=e.useRef(null),N=e.useRef(null),A=e.useRef(null),B=e.useRef(null),Y=e.useRef("none"),L=e.useRef(0),D=e.useRef([]),q=e.useRef(null),I=e.useRef(0),V=e.useRef(null),[F,W]=e.useState(!1),[X,H]=e.useState({width:0,height:0}),[P,G]=e.useState({width:0,height:0}),[J,K]=e.useState({width:0,height:0}),Q=`${e.useId()}`.replace(/^(.{2})(.*).$/,"$2"),U=Object.assign({value:1,duration:200},y),Z={position:"absolute",width:"100%",display:"flex",justifyContent:"center",alignItems:"center",cursor:"pointer"},_={color:"rgba(0,0,0,0.4)",size:40},ee=e.useMemo((()=>e.Children.toArray(w).filter((e=>null!=e))),[w]),te=e.useMemo((()=>{if("end"===U.value&&ee.length>0){const t=ee[0];if(e.isValidElement(t))return t.key}}),[ee]),re=Object.assign(Object.assign({},{size:40}),"object"==typeof d.arrows?d.arrows:{}),ne="object"==typeof x?Object.assign(Object.assign({},_),x):_,se={position:"absolute",left:0,width:"100%",pointerEvents:"none",transition:"opacity 0.1s ease-in-out",background:`linear-gradient(${ne.color}, transparent)`,height:`${ne.size}px`},oe="number"==typeof u?[u,u,u,u]:2===u.length?[u[0],u[1],u[0],u[1]]:3===u.length?[u[0],u[1],u[2],u[1]]:u,[le,ie,ce,ae]="x"===c?[oe[1],oe[2],oe[3],oe[0]]:oe,ue=oe[1]+oe[3],ge=le+ce,de=ae+ie,[he,me]=e.useMemo((()=>{var e,t;return"number"==typeof a?[a,a]:"x"===c?[null!==(e=null==a?void 0:a[1])&&void 0!==e?e:0,null!==(t=null==a?void 0:a[0])&&void 0!==t?t:0]:[0,0]}),[a,c]),pe=e.useMemo((()=>["number"==typeof i[0]?i[0]:"none"===i[0]?null:"firstChild"===i[0]?J.width:null,"number"==typeof i[1]?i[1]:"none"===i[1]?null:"firstChild"===i[1]?J.height:null]),[i,ue,J]),fe="x"===c?pe[0]:pe[1],be="x"===c?pe[1]:pe[0],ye=p?"number"==typeof p?[p,p,p,p]:"x"===c?2===p.length?[p[0],p[1],p[0],p[1]]:[p[1],p[0],p[3],p[2]]:2===p.length?[p[1],p[0],p[1],p[0]]:p:null,[ve,xe]=ye&&p?"x"===c?[ye[3],ye[1]]:[ye[2],ye[0]]:[0,0],je=e.useMemo((()=>{const[e,t]=l&&Array.isArray(l)?l:[X.width,X.height];return d.arrows&&re.size?"x"===c?[e?e-2*re.size:e,t,e,t]:[e,t?t-2*re.size:t,e,t]:[e,t,e,t]}),[l,c,re.size,X]),we="x"===c?je[0]:je[1],Oe="x"===c?je[1]:je[0],Ee=e.useMemo((()=>{const e=be?be+he:null;return e?Math.floor((Oe-ue)/e):1}),[be,Oe,he,ue]),$e=e.useMemo((()=>{if(!v||Ee<=1)return[];const e=ee.map(((e,t)=>t));if(!e)return[];const t=Array.from({length:Ee},(()=>[]));return e.forEach((e=>{t[e%Ee].push(e)})),t}),[w,Ee,v]),Me=e.useMemo((()=>Ee>1?Math.ceil(ee.length/Ee):ee.length),[ee.length,Ee]),Re=e.useMemo((()=>{const e=Ee||1;return be?be*e+(e-1)*me:v?(J.width+me)*e-me:P.width}),[be,Ee,me,P,J]),Te=e.useMemo((()=>fe?fe*Me+(Me-1)*he:v?(J.height+he)*Me-he:P.height),[fe,Me,he,P,J]),ze=e.useMemo((()=>Te+ge),[Te,ge]),ke=e.useMemo((()=>Re+de),[Re,de]),Se=(null===(T=C.current)||void 0===T?void 0:T.scrollTop)||0,Ce=Math.round(Se+we)!==ze,Ne=e.useMemo((()=>"hidden"===h&&ze||0===Te?0:we?Math.round(we/ze*we):0),[we,ze,h]),Ae=e.useMemo((()=>we?ze-we:ze),[ze,we]),Be=e.useMemo((()=>"number"==typeof U.value?U.value:"end"===U.value&&ze>we?Ae:1),[y,ze,Ae]),Ye=e.useMemo((()=>je[0]&&je[1]?je[0]/2-je[1]/2:0),[je]),Le=e.useMemo((()=>{let e=[],t=0;if(v&&E){const r=Array.from({length:ee.length},((e,t)=>t)),n=Math.abs(Math.floor(ee.length/Ee)*Ee-ee.length);e=n?r.slice(-n):[],"center"===E?t=((null!=be?be:0)+me)*(Ee-n)/2:"end"===E&&(t=((null!=be?be:0)+me)*(Ee-n))}return ee.map(((r,n)=>{const s=function(e,t){if(!t)return[0,e];for(let r=0;r<t.length;r++){const n=t[r].indexOf(e);if(-1!==n)return[r,n]}return[0,0]}(n,$e),o=function(e){return 0!==e?((null!=fe?fe:0)+he)*e+le:le}(v?Ee>1?s[1]:n:0),l=v&&pe[1]?o+pe[1]:0,i=v&&be?be*s[0]+me*s[0]+("x"===c?oe[0]:oe[1])+(E&&e.length>0&&e.includes(n)?t:0):0;return{elementTop:o,elementBottom:l,left:i}}))}),[w,$e,pe,a,v,Ee]),De=e.useMemo((()=>{var e,t;if(!$)return{};const[r,n="start"]=$,s="start"===r?"flex-start":"center"===r?"center":"flex-end",o="start"===n?"flex-start":"center"===n?"center":"flex-end",l=null!==(e=je[0])&&void 0!==e?e:0,i=null!==(t=je[1])&&void 0!==t?t:0,a="x"===c?l>ze:i>ze,u={};return("x"===c?i>ke:l>ke)&&(u.justifyContent="x"===c?o:s),a&&(u.alignItems="x"===c?s:o),u}),[$,c,je,ze,ke]),qe=e.useCallback((e=>(e?Math.ceil:Math.floor)(ze/we)),[we,ze]),Ie=e=>{e&&(e.style.cursor="grabbing")},Ve=e=>{e&&"grabbing"===e.style.cursor&&(e.style.cursor="grab")},Fe=(e,t)=>{if(e){const r=e.querySelector(`.${t}`);r&&(r.style.opacity="0")}},We=e.useCallback((e=>{const t=C.current,r=N.current;if(!t||!r)return;const n=r.clientHeight,s=qe(),o=e=>_e(e);"first"===e&&t.scrollTop>0&&o(t.scrollTop<=we?0:t.scrollTop-we),"last"===e&&s&&t.scrollTop+we!==n&&o(t.scrollTop+we>=we*s?n:t.scrollTop+we)}),[C,N,qe]),Xe=e.useCallback((()=>{const e=C.current;if(e&&S.current&&B.current){function t(){var t;const r=null===(t=B.current)||void 0===t?void 0:t.querySelectorAll(".sliderElem");r&&r.forEach(((t,r)=>{var n,s;const o=(null!==(n=null==e?void 0:e.scrollTop)&&void 0!==n?n:0)>=we*r&&(null!==(s=null==e?void 0:e.scrollTop)&&void 0!==s?s:0)<we*(r+1);t.classList.toggle("active",o)}))}t()}}),[we,ze]),He=e.useCallback((()=>{z();const e=C.current;if(e){if(R&&W(!0),null==M||M(!0),V.current&&clearTimeout(V.current),V.current=setTimeout((()=>{R&&W(!1),null==M||M(!1)}),200),0!==Ne&&"hidden"!==h){const t=Math.abs(Math.round(e.scrollTop/Ae*(we-Ne)));t!==I.current&&"slider"!==s&&(I.current=Ne+t>we?we-Ne:t),0===e.scrollTop&&"none"===Y.current&&(e.scrollTop=1),O&&O.forEach((t=>{t(e.scrollTop)}))}x&&Xe()}}),[we,Ne,I,h,O,Xe,M]),Pe=e.useCallback((e=>{const t=C.current,r=qe();if(t&&r){if(["thumb","wrapp"].includes(Y.current)){const n="thumb"===Y.current?1:-1;t.scrollTop+=("x"===c?e.movementX:e.movementY)*r*n}if("slider"===Y.current){const r=N.current;if(!r)return;const n=r.clientHeight,s=e=>_e(e,(()=>{L.current=0,z()})),o=e=>{const r=t.scrollTop+e*we;s(e>0?Math.min(r,n-we):Math.max(r,0))};e.movementY>0&&L.current<1?(L.current+=e.movementY,L.current>=1&&t.scrollTop+we!=n&&o(1)):e.movementY<0&&L.current>-1&&(L.current-=Math.abs(e.movementY),L.current<=-1&&0!=t.scrollTop&&o(-1))}}}),[c,C,qe]),Ge=e.useCallback((e=>{if(window.removeEventListener("mousemove",Pe),window.removeEventListener("mouseup",Ge),document.body.style.removeProperty("cursor"),Ve(N.current),Ve(A.current),Y.current="none","hover"===h){let t=e.target,r=!1;for(;t&&t!==document.body;){if(t===S.current){r=!0;break}t=t.parentNode}r||Fe(S.current,"scroll"===s?"scrollBar":"sliderBar")}z()}),[Pe,k,h,s]),Je=e.useCallback((e=>{Y.current=e,z(),window.addEventListener("mousemove",Pe),window.addEventListener("mouseup",Ge),document.body.style.cursor="grabbing"}),[Pe,Ge,k]),Ke=e.useCallback(((e,t)=>{const r={width:e,height:t-ge};X.width===r.width&&X.height===r.height||H(r)}),[ge,X]),Qe=e.useCallback(((e,t)=>{const r={width:e-de,height:t-ge};P.width===r.width&&P.height===r.height||G(r)}),[de,ge,P]),Ue=e.useCallback(((e,t)=>{const r={width:e,height:t};J.width===r.width&&J.height===r.height||K(r)}),[J]);let Ze;const _e=e.useCallback(((e,t)=>{const r=C.current;if(!r)return null;const n=r.scrollTop,s=performance.now(),o=l=>{const i=l-s,c=Math.min(i/U.duration,1);null!=e&&(r.scrollTop=n+(e-n)*c),i<U.duration?requestAnimationFrame(o):null==t||t()};return Ze=requestAnimationFrame(o),()=>cancelAnimationFrame(Ze)}),[C]);e.useEffect((()=>{function e(e,r,n=!1){console.warn(`You are using the ${e} ${n?"with":"without"} ${r}${t?` in ${t}`:""} 👺`)}!m&&p&&g&&e("rootMargin","lazyRender"),v&&m&&g&&e("lazyRender","infiniteScroll",!0),"hidden"===h&&(g&&e("progressReverse","progressVisibility `hidden`",!0),d.progressElement&&e("progressTrigger [`scrollThumb`]","progressVisibility `hidden`",!0),d.arrows&&e("progressTrigger [`arrows`]","progressVisibility `hidden`",!0)),!f&&b&&g&&e("fallback","suspending"),v&&z(),Xe()}),[]),e.useEffect((()=>{if(C.current&&ee.length>0){let e;return"end"===U.value?(q.current||(q.current=te),e=q.current===te?_e(Be):null,q.current=te):e=_e(Be),()=>{e&&e(),D.current=[],V.current&&clearTimeout(V.current)}}}),[Be,Te]),e.useEffect((()=>{if(R){const e=document.querySelectorAll(`[wrap-id^="${Q}-"]`),t=Array.from(e,(e=>e.getAttribute("wrap-id")));D.current=t}}),[F]);const et=e.createElement("div",{className:"objectsWrapper",ref:N,onMouseDown:()=>{d.content&&(Je("wrapp"),Ie(N.current))},style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({padding:`${le}px ${ie}px ${ce}px ${ae}px`,height:v&&ze?`${ze}px`:"fit-content",width:Re?`${Re}px`:""},d.content&&{cursor:"grab"}),v&&{position:"relative"}),!v&&{display:"flex"}),!v&&Ee>1&&{flexWrap:"wrap"}),!v&&Ee<=1&&{flexDirection:"column"}),a&&!v&&{gap:`${he}px ${me}px`}),E&&!v&&{justifyContent:"start"===E?"flex-start":"center"===E?"center":"flex-end"}),j&&{minHeight:we-ge+"px"})},ee.map(((t,s)=>{var o,l;const a=t.key,u={scrollElementRef:C,xyObjectReverse:be,xyObject:fe,rootMargin:p,suspending:f,fallback:b,mRootLocal:ye,objectsSizeLocal:pe},g=R&&!D.current.includes(`${Q}-${a}`)&&F?b:t,d="number"==typeof i[0]&&"number"==typeof i[1]||"firstChild"!==i[0]&&"firstChild"!==i[1]||0!==s?g:e.createElement(r,{onResize:Ue},(()=>g));if(!v)return e.createElement(n,Object.assign({key:a},u,{lazyRender:m,objectsPerDirection:Ee,objectsSize:i,direction:c,attribute:R?`${Q}-${a}`:""}),d);{const{elementTop:t,elementBottom:r,left:g}=Le[s];if(("x"===c?null!==(o=je[0])&&void 0!==o?o:0:null!==(l=je[1])&&void 0!==l?l:0)+ve>t-Se&&r-Se>0-xe)return e.createElement(n,Object.assign({key:a},u,{elementTop:t,left:g,infiniteScroll:v,attribute:R?`${Q}-${a}`:"",objectsPerDirection:Ee,objectsSize:i,direction:c}),d)}}))),tt=e.createElement("div",{"m-s":"〈♦〉",className:"customScroll"+(o?` ${o}`:""),ref:k,style:{width:`${je[2]}px`,height:`${je[3]}px`}},e.createElement("div",{className:"scrollContent",ref:S,onMouseEnter:()=>"hover"===h&&((e,t)=>{if(e){const r=e.querySelector(`.${t}`);r&&(r.style.opacity="1")}})(S.current,"scroll"===s?"scrollBar":"sliderBar"),onMouseLeave:()=>"hover"===h&&"thumb"!==Y.current&&"slider"!==Y.current&&Fe(S.current,"scroll"===s?"scrollBar":"sliderBar"),style:Object.assign(Object.assign({position:"relative",width:`${Oe}px`,height:`${we}px`},"x"===c&&{transform:`rotate(-90deg) translate(${Ye}px, ${Ye}px) scaleX(-1)`}),d.arrows&&re.size&&("x"===c?{left:`${re.size}px`}:{top:`${re.size}px`}))},e.createElement("div",{className:"scrollElement",ref:C,onScroll:He,style:Object.assign(Object.assign(Object.assign({display:"flex",width:"100%",height:"100%"},De),d.wheel?{overflow:"hidden scroll"}:{overflow:"hidden hidden"}),"boolean"!=typeof d.progressElement||!1===d.progressElement?{scrollbarWidth:"none"}:{})},"string"!=typeof i[0]||"string"!=typeof i[1]||v?et:e.createElement(r,{onResize:Qe},(()=>et))),x&&e.createElement("div",{className:"edge",style:Object.assign(Object.assign({},se),{top:0,opacity:Se>1?1:0})}),x&&e.createElement("div",{className:"edge",style:Object.assign(Object.assign({},se),{bottom:0,opacity:Ce?1:0,transform:"scaleY(-1)"})}),d.arrows&&e.createElement(e.Fragment,null,e.createElement("div",{className:"arrowBox"+(Se>1?" active":""),style:Object.assign(Object.assign({},Z),{top:0,transform:"translateY(-100%)",height:`${re.size}px`}),onClick:()=>We("first")},re.element),e.createElement("div",{className:"arrowBox"+(Ce?" active":""),style:Object.assign(Object.assign({},Z),{bottom:0,transform:"translateY(100%) scaleY(-1)",height:`${re.size}px`}),onClick:()=>We("last")},re.element)),"hidden"!==h&&Ne<we&&"boolean"!=typeof d.progressElement&&e.createElement(e.Fragment,null,"slider"!==s?e.createElement("div",{className:"scrollBar",style:Object.assign(Object.assign(Object.assign(Object.assign({position:"absolute",top:0},g?{left:0}:{right:0}),{width:"fit-content",height:"100%"}),!1!=!d.progressElement&&{pointerEvents:"none"}),"hover"===h&&{opacity:0,transition:"opacity 0.1s ease-in-out"})},e.createElement("div",{ref:A,className:"scrollBarThumb",onMouseDown:()=>{d.progressElement&&(Je("thumb"),Ie(A.current))},style:Object.assign({height:`${Ne}px`,willChange:"transform",transform:`translateY(${I.current}px)`},d.progressElement&&{cursor:"grab"})},d.progressElement)):e.createElement("div",{className:"sliderBar",style:Object.assign(Object.assign(Object.assign({position:"absolute",top:"50%",transform:"translateY(-50%)"},g?{left:0}:{right:0}),!d.progressElement&&{pointerEvents:"none"}),"hover"===h&&{opacity:0,transition:"opacity 0.1s ease-in-out"}),ref:B,onMouseDown:()=>Je("slider")},Array.from({length:qe()||0},((t,r)=>e.createElement("div",{key:r,className:"sliderElem",style:{width:"fit-content"}},d.progressElement)))))));return l?tt:e.createElement(r,{measure:"outer",onResize:Ke},(()=>tt))},exports.ResizeTracker=r;
1
+ "use strict";var e=require("react");const t=({measure:t="inner",style:r,onResize:n,children:s})=>{const l=e.useRef(null),[o,i]=e.useState({width:0,height:0});e.useEffect((()=>{const e=l.current;if(!e)return;const t=new ResizeObserver((e=>{for(const t of e){const e=t.contentRect.width,r=t.contentRect.height;i({width:e,height:r}),n&&n(e,r)}}));return t.observe(e),()=>{t.unobserve(e),t.disconnect()}}),[t,n]);const a={minWidth:"100%",minHeight:"100%"},c={width:"max-content",height:"max-content"},u={inner:Object.assign({},c),outer:Object.assign({},a),all:Object.assign(Object.assign({},a),c)};return e.createElement("div",{ref:l,"resize-tracker":"〈—〉",style:Object.assign(Object.assign({},u[t]),r)},s(o.width,o.height))},r=(e,t)=>{if(void 0!==e)return"number"==typeof e?[e,e,e,e]:2===e.length?t?[e[0],e[1],e[0],e[1]]:[e[1],e[0],e[1],e[0]]:4===e.length?t?[e[1],e[0],e[3],e[2]]:e:void 0},n=({style:t,root:n,children:s,threshold:l,rootMargin:o,visibleContent:i=!1,onVisible:a,intersectionDelay:c})=>{const[u,d]=e.useState(!1),p=e.useRef(null),m=e.useRef(null),h=r(o),g=h?`${h[0]}px ${h[1]}px ${h[2]}px ${h[3]}px`:"",f=e.useCallback((([e])=>{d(e.isIntersecting)}),[]),b=()=>{m.current&&(clearTimeout(m.current),m.current=null)};e.useEffect((()=>{const e=new IntersectionObserver(f,{root:n,threshold:l,rootMargin:g});return p.current&&e.observe(p.current),()=>{e.disconnect()}}),[n,l,g]),e.useEffect((()=>{if(u&&a)return b(),c?m.current=setTimeout((()=>{u&&a&&a()}),c):u&&a&&a(),()=>b()}),[u,c,a]);const y=i||u?s:null;return e.createElement("div",{ref:p,"intersection-tracker":"〈•〉",style:t},y)};exports.IntersectionTracker=n,exports.MorphScroll=({type:s="scroll",className:l="",size:o,objectsSize:i,direction:a="y",gap:c,padding:u,progressReverse:d=!1,progressTrigger:p={wheel:!0},progressVisibility:m="visible",suspending:h=!1,fallback:g=null,scrollTop:f,edgeGradient:b,objectsWrapFullMinSize:y=!1,children:v,onScrollValue:x,elementsAlign:w=!1,contentAlign:j,isScrolling:E,stopLoadOnScroll:O=!1,render:M={type:"default"},emptyElements:$})=>{var k;const C=e.useReducer((()=>({})),{})[1],T=e.useRef(null),R=e.useRef(null),z=e.useRef(null),A=e.useRef(null),S=e.useRef(null),B=e.useRef(null),N=e.useRef(null),Y=e.useRef("none"),q=e.useRef(0),F=e.useRef([]),I=e.useRef(0),L=e.useRef(null),V=e.useRef(""),[D,W]=e.useState(!1),[X,H]=e.useState({width:0,height:0}),[G,P]=e.useState({width:0,height:0}),[J,K]=e.useState({width:0,height:0}),Q=`${e.useId()}`.replace(/^(.{2})(.*).$/,"$2"),U=Object.assign({duration:200},f),Z={position:"absolute",width:"100%",display:"flex",justifyContent:"center",alignItems:"center",cursor:"pointer"},_={color:"rgba(0,0,0,0.4)",size:40},ee=e.useCallback((t=>{if(null==t)return[];if(e.isValidElement(t)){const r=t;return r.type===e.Fragment?e.Children.toArray(r.props.children).flatMap(ee):[r]}return[t]}),[]),te="clear"===(null==$?void 0:$.mode),re=e.useMemo((()=>te?V.current:""),[te,V.current]),ne=e.useMemo((()=>e.Children.toArray(v).flatMap(ee).filter(Boolean).filter((t=>!te||!e.isValidElement(t)||!V.current.includes(t.key)))),[v,te,re]),se=e.useMemo((()=>{if("end"!==U.value)return null;if(ne.length>0){const t=ne[0];if(e.isValidElement(t))return t.key}return null}),[ne]),le=Object.assign(Object.assign({},{size:40}),"object"==typeof p.arrows?p.arrows:{}),oe="object"==typeof b?Object.assign(Object.assign({},_),b):_,ie={position:"absolute",left:0,width:"100%",pointerEvents:"none",transition:"opacity 0.1s ease-in-out",background:`linear-gradient(${oe.color}, transparent)`,height:`${oe.size}px`},[ae,ce,ue,de]=r(u,"x"===a)||[0,0,0,0],pe=ae+ue,me=de+ce,[he,ge]=e.useMemo((()=>{var e,t,r,n;return"number"==typeof c?[c,c]:"x"===a?[null!==(e=null==c?void 0:c[0])&&void 0!==e?e:0,null!==(t=null==c?void 0:c[1])&&void 0!==t?t:0]:[null!==(r=null==c?void 0:c[1])&&void 0!==r?r:0,null!==(n=null==c?void 0:c[0])&&void 0!==n?n:0]}),[c,a]),fe=e.useMemo((()=>["number"==typeof i[0]?i[0]:"none"===i[0]?null:"firstChild"===i[0]?J.width:null,"number"==typeof i[1]?i[1]:"none"===i[1]?null:"firstChild"===i[1]?J.height:null]),[i,J]),be="x"===a?fe[0]:fe[1],ye="x"===a?fe[1]:fe[0],ve=e.useMemo((()=>r("lazy"===M.type&&M.rootMargin||0,"x"===a)),[M,a]),[xe,we]=ve?[ve[2],ve[0]]:[0,0],je=e.useMemo((()=>{const[e,t]=o&&Array.isArray(o)?o:[X.width,X.height];return p.arrows&&le.size?"x"===a?[e?e-2*le.size:e,t,e,t]:[e,t?t-2*le.size:t,e,t]:[e,t,e,t]}),[o,a,le.size,X]),Ee="x"===a?je[0]:je[1],Oe="x"===a?je[1]:je[0],Me=e.useMemo((()=>{const e=ye?ye+he:null;return e?Math.floor((Oe-me)/e):1}),[ye,Oe,he,me]),$e=e.useMemo((()=>{if("virtual"!==M.type||Me<=1)return[];const e=ne.map(((e,t)=>t));if(!e)return[];const t=Array.from({length:Me},(()=>[]));return e.forEach((e=>{t[e%Me].push(e)})),t}),[v,Me,M.type]),ke=e.useMemo((()=>Me>1?Math.ceil(ne.length/Me):ne.length),[ne.length,Me]),Ce=e.useMemo((()=>{const e=Me||1;return ye?ye*e+(e-1)*ge:"virtual"!==M.type?G.width:(J.width+ge)*e-ge}),[ye,Me,ge,G,J,M.type]),Te=e.useMemo((()=>be?be*ke+(ke-1)*he:"virtual"!==M.type?G.height:(J.height+he)*ke-he),[be,ke,he,G,J,M.type]),Re=e.useMemo((()=>Te?Te+pe:0),[Te,pe]),ze=e.useMemo((()=>Ce?Ce+me:0),[Ce,me]),Ae=(null===(k=z.current)||void 0===k?void 0:k.scrollTop)||0,Se=Math.round(Ae+Ee)!==Re,Be=e.useMemo((()=>"hidden"===m&&Re||0===Te?0:Ee?Math.round(Ee/Re*Ee):0),[Ee,Re,m]),Ne=e.useMemo((()=>Ee?Re-Ee:Re),[Re,Ee]),Ye=e.useMemo((()=>"number"==typeof U.value?U.value:"end"===U.value&&Re>Ee?Ne:0),[f,Re,Ne]),qe=e.useMemo((()=>je[0]&&je[1]?je[0]/2-je[1]/2:0),[je]),Fe=e.useMemo((()=>{let e=[],t=0;if("virtual"===M.type&&w){const r=Array.from({length:ne.length},((e,t)=>t)),n=Math.abs(Math.floor(ne.length/Me)*Me-ne.length);e=n?r.slice(-n):[],"center"===w?t=((null!=ye?ye:0)+ge)*(Me-n)/2:"end"===w&&(t=((null!=ye?ye:0)+ge)*(Me-n))}return ne.map(((r,n)=>{const s=function(e,t){if(!t)return[0,e];for(let r=0;r<t.length;r++){const n=t[r].indexOf(e);if(-1!==n)return[r,n]}return[0,0]}(n,$e),l=function(e){return 0!==e?((null!=be?be:0)+he)*e+ae:ae}("virtual"===M.type?Me>1?s[1]:n:0),o="virtual"===M.type&&fe[1]?l+fe[1]:0,i="virtual"===M.type&&ye?ye*s[0]+ge*s[0]+de+(w&&e.length>0&&e.includes(n)?t:0):0;return{elementTop:l,elementBottom:o,left:i}}))}),[v,$e,fe,c,M.type,Me]),Ie=e.useMemo((()=>{var e,t;if(!j)return{};const[r,n="start"]=j,s="start"===r?"flex-start":"center"===r?"center":"flex-end",l="start"===n?"flex-start":"center"===n?"center":"flex-end",o=null!==(e=je[0])&&void 0!==e?e:0,i=null!==(t=je[1])&&void 0!==t?t:0,c="x"===a?o>Re:i>Re,u={};return("x"===a?i>ze:o>ze)&&(u.justifyContent="x"===a?l:s),c&&(u.alignItems="x"===a?s:l),u}),[j,a,je,Re,ze]),Le=e.useCallback((e=>(e?Math.ceil:Math.floor)(Re/Ee)),[Ee,Re]),Ve=e=>{e&&(e.style.cursor="grabbing")},De=e=>{e&&"grabbing"===e.style.cursor&&(e.style.cursor="grab")},We=(e,t)=>{if(e){const r=e.querySelector(`.${t}`);r&&(r.style.opacity="0")}},Xe=e.useCallback((e=>{const t=z.current,r=A.current;if(!t||!r)return;const n=r.clientHeight,s=Le(),l=e=>et(e);"first"===e&&t.scrollTop>0&&l(t.scrollTop<=Ee?0:t.scrollTop-Ee),"last"===e&&s&&t.scrollTop+Ee!==n&&l(t.scrollTop+Ee>=Ee*s?n:t.scrollTop+Ee)}),[z,A,Le]),He=e.useCallback((()=>{const e=z.current;if(e&&R.current&&B.current){function t(){var t;const r=null===(t=B.current)||void 0===t?void 0:t.querySelectorAll(".sliderElem");r&&r.forEach(((t,r)=>{var n,s;const l=(null!==(n=null==e?void 0:e.scrollTop)&&void 0!==n?n:0)>=Ee*r&&(null!==(s=null==e?void 0:e.scrollTop)&&void 0!==s?s:0)<Ee*(r+1);t.classList.toggle("active",l)}))}t()}}),[Ee,Re]),Ge=e.useCallback((()=>{const e=z.current;if(!e)return;const t=O||E;if(!D&&(null==E||E(!0)),t&&W(!0),L.current&&clearTimeout(L.current),L.current=setTimeout((()=>{t&&W(!1),null==E||E(!1),"default"!==M.type&&nt(),C()}),200),0!==Be&&"hidden"!==m){const t=Math.abs(Math.round(e.scrollTop/Ne*(Ee-Be)));t!==I.current&&"slider"!==s&&(I.current=Be+t>Ee?Ee-Be:t),x&&x(e.scrollTop)}b&&He(),"default"!==M.type&&nt(),C()}),[Ee,Be,I,m,x,He,b,E]),Pe=e.useCallback((e=>{const t=z.current,r=Le();if(t&&r){if(["thumb","wrapp"].includes(Y.current)){const n="thumb"===Y.current?1:-1;t.scrollTop+=("x"===a?e.movementX:e.movementY)*r*n}if("slider"===Y.current){const r=A.current;if(!r)return;const n=r.clientHeight,s=e=>et(e,(()=>{q.current=0,C()})),l=e=>{const r=t.scrollTop+e*Ee;s(e>0?Math.min(r,n-Ee):Math.max(r,0))};e.movementY>0&&q.current<1?(q.current+=e.movementY,q.current>=1&&t.scrollTop+Ee!=n&&l(1)):e.movementY<0&&q.current>-1&&(q.current-=Math.abs(e.movementY),q.current<=-1&&0!=t.scrollTop&&l(-1))}}}),[a,z,Le]),Je=e.useCallback((e=>{if(window.removeEventListener("mousemove",Pe),window.removeEventListener("mouseup",Je),document.body.style.removeProperty("cursor"),De(A.current),De(S.current),Y.current="none","hover"===m){let t=e.target,r=!1;for(;t&&t!==document.body;){if(t===R.current){r=!0;break}t=t.parentNode}r||We(R.current,"scroll"===s?"scrollBar":"sliderBar")}C()}),[Pe,T,m,s]),Ke=e.useCallback((e=>{Y.current=e,C(),window.addEventListener("mousemove",Pe),window.addEventListener("mouseup",Je),document.body.style.cursor="grabbing"}),[Pe,Je,T]),Qe=e.useCallback(((e,t)=>{const r={width:e,height:t-pe};X.width===r.width&&X.height===r.height||H(r)}),[pe,X]),Ue=e.useCallback(((e,t)=>{const r={width:e-me,height:t-pe};G.width===r.width&&G.height===r.height||P(r)}),[me,pe,G]),Ze=e.useCallback(((e,t)=>{const r={width:e,height:t};J.width===r.width&&J.height===r.height||K(r)}),[J]);let _e;const et=e.useCallback(((e,t)=>{const r=z.current;if(!r)return null;const n=r.scrollTop,s=performance.now(),l=o=>{const i=o-s,a=Math.min(i/U.duration,1);null!=e&&(r.scrollTop=n+(e-n)*a),i<U.duration?requestAnimationFrame(l):null==t||t()};return _e=requestAnimationFrame(l),()=>cancelAnimationFrame(_e)}),[z]),tt=(t,r,s,l,o)=>{const i=h?e.createElement(e.Suspense,{fallback:g},l):l,c=Object.assign({width:ye?`${ye}px`:"",height:be?`${be}px`:""},"x"===a&&{display:"flex"}),u=Object.assign({width:fe[0]?`${fe[0]}px`:""},"x"===a&&{transform:"rotate(-90deg) scaleX(-1)"}),d={root:z.current,rootMargin:"lazy"===M.type?M.rootMargin:ve,style:"virtual"===M.type?Object.assign(Object.assign(Object.assign(Object.assign({},c),{position:"absolute",top:`${t}px`}),r&&{left:`${r}px`}),!ye&&1===Me&&{transform:"translateX(-50%)"}):c},p=e.createElement("div",Object.assign({},s?{"wrap-id":s}:{},{style:u}),i);return"virtual"===M.type?e.createElement("div",{key:o,style:Object.assign(Object.assign(Object.assign({position:"absolute",top:`${t}px`},r&&{left:`${r}px`}),!ye&&1===Me&&{transform:"translateX(-50%)"}),c)},p):"lazy"===M.type?e.createElement(n,Object.assign({key:o},d),p):e.createElement("div",{key:o,style:c},p)},rt=e.useCallback((()=>document.querySelectorAll(`[wrap-id^="${Q}-"]`)),[]),nt=e.useCallback((()=>{const e=Array.from(rt()).filter((e=>0===e.children.length)).map((e=>{var t;return null===(t=e.getAttribute("wrap-id"))||void 0===t?void 0:t.split("-")[1]})).filter(Boolean).join("/");V.current?e&&V.current!==e&&(V.current=e):V.current=e}),[]);e.useEffect((()=>{"virtual"===M.type&&C(),He(),nt()}),[]),e.useEffect((()=>{if(z.current&&ne.length>0){let e;return"end"===U.value?(N.current||(N.current=se),e=N.current===se?et(Ye):null,N.current=se):e=et(Ye),()=>{e&&e(),L.current&&clearTimeout(L.current),F.current=[]}}}),[Ye,Te]),e.useEffect((()=>{if(O){const e=Array.from(rt(),(e=>e.getAttribute("wrap-id")));F.current=e}}),[D]);const st=e.createElement("div",{className:"objectsWrapper",ref:A,onMouseDown:()=>{p.content&&(Ke("wrapp"),Ve(A.current))},style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({height:"virtual"===M.type&&Re||"none"!==i[1]?`${Re}px`:"fit-content",width:ze?`${ze}px`:""},p.content&&{cursor:"grab"}),"virtual"===M.type&&{position:"relative"}),"virtual"!==M.type&&{display:"flex",alignContent:"center"}),"virtual"!==M.type&&"y"===a&&{alignItems:"center"}),"virtual"!==M.type&&Me>1&&{flexWrap:"wrap"}),"virtual"!==M.type&&Me<=1&&{flexDirection:"column"}),c&&"virtual"!==M.type&&{gap:`${he}px ${ge}px`}),w&&"virtual"!==M.type&&{justifyContent:"start"===w?"flex-start":"center"===w?"center":"flex-end"}),y&&{minHeight:Ee-pe+"px"})},ne.map(((r,n)=>{var s,l,o;const c=r.key||"",u=O&&!F.current.includes(`${Q}-${c}`)&&D?g:"fallback"===(null==$?void 0:$.mode)&&V.current.includes(c)?null!==(s=$.element)&&void 0!==s?s:g:r,d="number"==typeof i[0]&&"number"==typeof i[1]||"firstChild"!==i[0]&&"firstChild"!==i[1]||0!==n?u:e.createElement(t,{onResize:Ze},(()=>u));if("virtual"!==M.type)return tt(0,0,`${Q}-${c}`,d,c);{const{elementTop:e,elementBottom:t,left:r}=Fe[n];if(("x"===a?null!==(l=je[0])&&void 0!==l?l:0:null!==(o=je[1])&&void 0!==o?o:0)+xe>e-Ae&&t-Ae>0-we)return tt(e,r,`${Q}-${c}`,d,c)}}))),lt=e.createElement("div",{"morph-scroll":"〈♦〉",className:`${l&&l}`,ref:T,style:{width:`${je[2]}px`,height:`${je[3]}px`}},e.createElement("div",{className:"scrollContent",ref:R,onMouseEnter:()=>"hover"===m&&((e,t)=>{if(e){const r=e.querySelector(`.${t}`);r&&(r.style.opacity="1")}})(R.current,"scroll"===s?"scrollBar":"sliderBar"),onMouseLeave:()=>"hover"===m&&"thumb"!==Y.current&&"slider"!==Y.current&&We(R.current,"scroll"===s?"scrollBar":"sliderBar"),style:Object.assign(Object.assign({position:"relative",width:`${Oe}px`,height:`${Ee}px`},"x"===a&&{transform:`rotate(-90deg) translate(${qe}px, ${qe}px) scaleX(-1)`}),p.arrows&&le.size&&("x"===a?{left:`${le.size}px`}:{top:`${le.size}px`}))},e.createElement("div",{className:"scrollElement",ref:z,onScroll:Ge,style:Object.assign(Object.assign(Object.assign({display:"flex",width:"100%",height:"100%"},Ie),p.wheel?{overflow:"hidden scroll"}:{overflow:"hidden hidden"}),"boolean"!=typeof p.progressElement||!1===p.progressElement?{scrollbarWidth:"none"}:{})},"none"!==i[0]&&"none"!==i[1]?st:e.createElement(t,{onResize:Ue},(()=>st))),b&&e.createElement("div",{className:"edge",style:Object.assign(Object.assign({},ie),{top:0,opacity:Ae>1?1:0})}),b&&e.createElement("div",{className:"edge",style:Object.assign(Object.assign({},ie),{bottom:0,opacity:Se?1:0,transform:"scaleY(-1)"})}),p.arrows&&e.createElement(e.Fragment,null,e.createElement("div",{className:"arrowBox"+(Ae>1?" active":""),style:Object.assign(Object.assign({},Z),{top:0,transform:"translateY(-100%)",height:`${le.size}px`}),onClick:()=>Xe("first")},le.element),e.createElement("div",{className:"arrowBox"+(Se?" active":""),style:Object.assign(Object.assign({},Z),{bottom:0,transform:"translateY(100%) scaleY(-1)",height:`${le.size}px`}),onClick:()=>Xe("last")},le.element)),"hidden"!==m&&Be<Ee&&"boolean"!=typeof p.progressElement&&e.createElement(e.Fragment,null,"slider"!==s?e.createElement("div",{className:"scrollBar",style:Object.assign(Object.assign(Object.assign(Object.assign({position:"absolute",top:0},d?{left:0}:{right:0}),{width:"fit-content",height:"100%"}),!1!=!p.progressElement&&{pointerEvents:"none"}),"hover"===m&&{opacity:0,transition:"opacity 0.1s ease-in-out"})},e.createElement("div",{ref:S,className:"scrollBarThumb",onMouseDown:()=>{p.progressElement&&(Ke("thumb"),Ve(S.current))},style:Object.assign({height:`${Be}px`,willChange:"transform",transform:`translateY(${I.current}px)`},p.progressElement&&{cursor:"grab"})},p.progressElement)):e.createElement("div",{className:"sliderBar",style:Object.assign(Object.assign(Object.assign({position:"absolute",top:"50%",transform:"translateY(-50%)"},d?{left:0}:{right:0}),!p.progressElement&&{pointerEvents:"none"}),"hover"===m&&{opacity:0,transition:"opacity 0.1s ease-in-out"}),ref:B,onMouseDown:()=>Ke("slider")},Array.from({length:Le()||0},((t,r)=>e.createElement("div",{key:r,className:"sliderElem",style:{width:"fit-content"}},p.progressElement)))))));return o?lt:e.createElement(t,{measure:"outer",onResize:Qe},(()=>lt))},exports.ResizeTracker=t;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "morphing-scroll",
3
- "version": "1.1.7",
3
+ "version": "1.1.8",
4
4
  "description": "Library for using various methods of scrolling objects〈♦〉",
5
5
  "author": "Georg Schilin",
6
6
  "license": "MIT",
@@ -14,6 +14,10 @@
14
14
  "scroller"
15
15
  ],
16
16
  "peerDependencies": {
17
- "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
17
+ "react": ">=16 <20"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/voodoofugu/morphing-scroll.git"
18
22
  }
19
23
  }