morphing-scroll 1.3.2 → 1.4.1
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 +136 -59
- package/index.d.ts +9 -5
- package/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ npm install morphing-scroll
|
|
|
34
34
|
|
|
35
35
|
- **`className`:** _Additional classes for the component._
|
|
36
36
|
<details>
|
|
37
|
-
<summary><strong><em>
|
|
37
|
+
<summary><strong><em>more</em></strong></summary>
|
|
38
38
|
<br />
|
|
39
39
|
<strong>• Type:</strong> string<br />
|
|
40
40
|
<br />
|
|
@@ -57,7 +57,7 @@ npm install morphing-scroll
|
|
|
57
57
|
|
|
58
58
|
- **`children` (required):** _Custom user content._
|
|
59
59
|
<details>
|
|
60
|
-
<summary><strong><em>
|
|
60
|
+
<summary><strong><em>more</em></strong></summary>
|
|
61
61
|
<br />
|
|
62
62
|
<strong>• Type:</strong> React.ReactNode<br />
|
|
63
63
|
<br />
|
|
@@ -78,11 +78,13 @@ npm install morphing-scroll
|
|
|
78
78
|
|
|
79
79
|
</details>
|
|
80
80
|
|
|
81
|
+
<h2>
|
|
82
|
+
|
|
81
83
|
##### - SCROLL SETTINGS:
|
|
82
84
|
|
|
83
85
|
- **`type`:** _Type of progress element._
|
|
84
86
|
<details>
|
|
85
|
-
<summary><strong><em>
|
|
87
|
+
<summary><strong><em>more</em></strong></summary>
|
|
86
88
|
<br />
|
|
87
89
|
<strong>• Type:</strong> "scroll" | "slider"<br />
|
|
88
90
|
<br />
|
|
@@ -109,7 +111,7 @@ npm install morphing-scroll
|
|
|
109
111
|
|
|
110
112
|
- **`direction`:** _Scrolling direction._
|
|
111
113
|
<details>
|
|
112
|
-
<summary><strong><em>
|
|
114
|
+
<summary><strong><em>more</em></strong></summary>
|
|
113
115
|
<br />
|
|
114
116
|
<strong>• Type:</strong> "x" | "y"<br />
|
|
115
117
|
<br />
|
|
@@ -135,16 +137,26 @@ npm install morphing-scroll
|
|
|
135
137
|
|
|
136
138
|
- **`scrollTop`:** _Scroll position and animation duration._
|
|
137
139
|
<details>
|
|
138
|
-
<summary><strong><em>
|
|
140
|
+
<summary><strong><em>more</em></strong></summary>
|
|
139
141
|
<br />
|
|
140
|
-
<strong>• Type:</strong> {
|
|
142
|
+
<strong>• Type:</strong> {<br />
|
|
143
|
+
value: number | "end";<br />
|
|
144
|
+
duration?: number;<br />
|
|
145
|
+
updater?: boolean;<br />
|
|
146
|
+
}<br />
|
|
141
147
|
<br />
|
|
142
|
-
<strong>• Default:</strong> { value:
|
|
148
|
+
<strong>• Default:</strong> { value: 0; duration: 200; updater: false }<br />
|
|
143
149
|
<br />
|
|
144
150
|
<strong>• Description:</strong> <em><br />
|
|
145
|
-
This parameter
|
|
146
|
-
|
|
147
|
-
The <code>
|
|
151
|
+
This parameter allows you to set custom scroll values.<br />
|
|
152
|
+
<br />
|
|
153
|
+
The <code>value</code> property accepts numerical pixel values.<br />
|
|
154
|
+
The <code>"end"</code> option scrolls to the bottom of the list upon loading, which is useful for scenarios like chat message lists. When new elements are appended to the list, the scroll position will update automatically. However, to prevent unwanted scrolling when adding elements to the beginning of the list, this property will not trigger.<br />
|
|
155
|
+
<br />
|
|
156
|
+
The <code>duration</code> property determines the animation speed for scrolling in ms.</em><br />
|
|
157
|
+
<br />
|
|
158
|
+
The <code>updater</code> property is a helper for the <code>value</code> property. When setting the same scroll value repeatedly (e.g., clicking a button to scroll to the top), React does not register the update. To force an update, toggle updater within setState, e.g.,<br />
|
|
159
|
+
<code>setScroll((prev) => ({ ...prev, value: 0, updater: !prev.updater }))</code></em><br />
|
|
148
160
|
<br />
|
|
149
161
|
<strong>• Example:</strong>
|
|
150
162
|
|
|
@@ -162,7 +174,7 @@ npm install morphing-scroll
|
|
|
162
174
|
|
|
163
175
|
- **`stopLoadOnScroll`:** _Stop loading when scrolling._
|
|
164
176
|
<details>
|
|
165
|
-
<summary><strong><em>
|
|
177
|
+
<summary><strong><em>more</em></strong></summary>
|
|
166
178
|
<br />
|
|
167
179
|
<strong>• Type:</strong> boolean<br />
|
|
168
180
|
<br />
|
|
@@ -187,7 +199,7 @@ npm install morphing-scroll
|
|
|
187
199
|
|
|
188
200
|
- **`onScrollValue`:** _Callback for scroll value._
|
|
189
201
|
<details>
|
|
190
|
-
<summary><strong><em>
|
|
202
|
+
<summary><strong><em>more</em></strong></summary>
|
|
191
203
|
<br />
|
|
192
204
|
<strong>• Type:</strong> (scroll: number) => void<br />
|
|
193
205
|
<br />
|
|
@@ -215,7 +227,7 @@ npm install morphing-scroll
|
|
|
215
227
|
|
|
216
228
|
- **`isScrolling`:** _Callback function for scroll status._
|
|
217
229
|
<details>
|
|
218
|
-
<summary><strong><em>
|
|
230
|
+
<summary><strong><em>more</em></strong></summary>
|
|
219
231
|
<br />
|
|
220
232
|
<strong>• Type:</strong> (motion: boolean) => void<br />
|
|
221
233
|
<br />
|
|
@@ -237,11 +249,13 @@ npm install morphing-scroll
|
|
|
237
249
|
|
|
238
250
|
</details>
|
|
239
251
|
|
|
252
|
+
<h2>
|
|
253
|
+
|
|
240
254
|
##### - VISUAL SETTINGS:
|
|
241
255
|
|
|
242
256
|
- **`size`:** _MorphScroll width and height._
|
|
243
257
|
<details>
|
|
244
|
-
<summary><strong><em>
|
|
258
|
+
<summary><strong><em>more</em></strong></summary>
|
|
245
259
|
<br />
|
|
246
260
|
<strong>• Type:</strong> number[]<br />
|
|
247
261
|
<br />
|
|
@@ -268,7 +282,7 @@ npm install morphing-scroll
|
|
|
268
282
|
|
|
269
283
|
- **`objectsSize` (required):** _Required: Size of cells for each object._
|
|
270
284
|
<details>
|
|
271
|
-
<summary><strong><em>
|
|
285
|
+
<summary><strong><em>more</em></strong></summary>
|
|
272
286
|
<br />
|
|
273
287
|
<strong>• Type:</strong> (number | "none" | "firstChild")[]<br />
|
|
274
288
|
<br />
|
|
@@ -298,7 +312,7 @@ npm install morphing-scroll
|
|
|
298
312
|
|
|
299
313
|
- **`gap`:** _Gap between cells._
|
|
300
314
|
<details>
|
|
301
|
-
<summary><strong><em>
|
|
315
|
+
<summary><strong><em>more</em></strong></summary>
|
|
302
316
|
<br />
|
|
303
317
|
<strong>• Type:</strong> number[] | number<br />
|
|
304
318
|
<br />
|
|
@@ -323,14 +337,17 @@ npm install morphing-scroll
|
|
|
323
337
|
|
|
324
338
|
- **`padding`:** _Padding for the `objectsWrapper`._
|
|
325
339
|
<details>
|
|
326
|
-
<summary><strong><em>
|
|
340
|
+
<summary><strong><em>more</em></strong></summary>
|
|
327
341
|
<br />
|
|
328
342
|
<strong>• Type:</strong> number[] | number<br />
|
|
329
343
|
<br />
|
|
330
344
|
<strong>• Description:</strong> <em><br />
|
|
331
345
|
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
346
|
<br />
|
|
333
|
-
*
|
|
347
|
+
*This parameter accepts either a single number or an array of numbers.<br />
|
|
348
|
+
If a two-number array is provided, the values follow the <code>horizontal/vertical</code> rule.<br />
|
|
349
|
+
If a four-number array is provided, the values follow the <code>top/right/bottom/left</code> rule.<br />
|
|
350
|
+
All values are in pixels and apply regardless of the <code>direction</code>.<br />
|
|
334
351
|
<br />
|
|
335
352
|
*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
353
|
<br />
|
|
@@ -352,18 +369,25 @@ npm install morphing-scroll
|
|
|
352
369
|
|
|
353
370
|
- **`contentAlign`:** _Aligns the content when it is smaller than the MorphScroll `size`._
|
|
354
371
|
<details>
|
|
355
|
-
<summary><strong><em>
|
|
356
|
-
<br />
|
|
357
|
-
<strong>• Type:</strong> ["start" | "center" | "end", "start" | "center" | "end"]<br />
|
|
372
|
+
<summary><strong><em>more</em></strong></summary>
|
|
358
373
|
<br />
|
|
374
|
+
<strong>• Type:</strong> [<br />
|
|
375
|
+
"start" | "center" | "end",<br />
|
|
376
|
+
"start" | "center" | "end"<br />
|
|
377
|
+
]<br />
|
|
359
378
|
<strong>• Description:</strong> <em><br />
|
|
360
|
-
|
|
379
|
+
This parameter aligns the `objectsWrapper`, which contains all the provided elements, relative to the scroll or the `size`.<br />
|
|
380
|
+
<br />
|
|
381
|
+
*Important: only takes effect when `objectsWrapper` is smaller than the scroll container.<br />
|
|
382
|
+
<br />
|
|
383
|
+
*The values are specified following the horizontal/vertical rule, regardless of the direction.</em><br />
|
|
361
384
|
<br />
|
|
362
385
|
<strong>• Example:</strong>
|
|
363
386
|
|
|
364
387
|
```tsx
|
|
365
388
|
<MorphScroll
|
|
366
|
-
|
|
389
|
+
contentAlign={["center", "center"]}
|
|
390
|
+
// another props
|
|
367
391
|
>
|
|
368
392
|
{children}
|
|
369
393
|
</MorphScroll>
|
|
@@ -374,18 +398,19 @@ npm install morphing-scroll
|
|
|
374
398
|
|
|
375
399
|
- **`elementsAlign`:** _Aligns the objects within the `objectsWrapper`._
|
|
376
400
|
<details>
|
|
377
|
-
<summary><strong><em>
|
|
401
|
+
<summary><strong><em>more</em></strong></summary>
|
|
378
402
|
<br />
|
|
379
403
|
<strong>• Type:</strong> "start" | "center" | "end"<br />
|
|
380
404
|
<br />
|
|
381
405
|
<strong>• Description:</strong> <em><br />
|
|
382
|
-
|
|
406
|
+
This parameter aligns the provided custom objects within the `objectsWrapper`.</em><br />
|
|
383
407
|
<br />
|
|
384
408
|
<strong>• Example:</strong>
|
|
385
409
|
|
|
386
410
|
```tsx
|
|
387
411
|
<MorphScroll
|
|
388
|
-
|
|
412
|
+
elementsAlign="center"
|
|
413
|
+
// another props
|
|
389
414
|
>
|
|
390
415
|
{children}
|
|
391
416
|
</MorphScroll>
|
|
@@ -396,20 +421,27 @@ npm install morphing-scroll
|
|
|
396
421
|
|
|
397
422
|
- **`edgeGradient`:** _Edge gradient._
|
|
398
423
|
<details>
|
|
399
|
-
<summary><strong><em>
|
|
424
|
+
<summary><strong><em>more</em></strong></summary>
|
|
400
425
|
<br />
|
|
401
426
|
<strong>• Type:</strong> boolean | { color?: string; size?: number }<br />
|
|
402
427
|
<br />
|
|
403
|
-
<strong>• Default:</strong>
|
|
428
|
+
<strong>• Default:</strong> When using true or color, the default size will be 40<br />
|
|
404
429
|
<br />
|
|
405
430
|
<strong>• Description:</strong> <em><br />
|
|
406
|
-
|
|
431
|
+
This parameter creates two edge elements responsible for darkening the edges of the scroll when it overflows.<br />
|
|
432
|
+
<br />
|
|
433
|
+
The color property accepts any valid color format. If specified, the library will generate a gradient transitioning from the custom color to transparent. If omitted, the edge elements will have no color, allowing for custom styling via CSS classes.<br />
|
|
434
|
+
<br />
|
|
435
|
+
The size property, measured in pixels, adjusts the dimensions of the edge elements.</em><br />
|
|
407
436
|
<br />
|
|
408
437
|
<strong>• Example:</strong>
|
|
409
438
|
|
|
410
439
|
```tsx
|
|
411
440
|
<MorphScroll
|
|
412
|
-
|
|
441
|
+
edgeGradient={{ color: "rgba(0, 0, 0, 0.5)" }}
|
|
442
|
+
// edgeGradient={{ color: "rgba(0, 0, 0, 0.5)", size: 20 }}
|
|
443
|
+
// edgeGradient
|
|
444
|
+
// another props
|
|
413
445
|
>
|
|
414
446
|
{children}
|
|
415
447
|
</MorphScroll>
|
|
@@ -418,22 +450,27 @@ npm install morphing-scroll
|
|
|
418
450
|
</details>
|
|
419
451
|
<h2>
|
|
420
452
|
|
|
421
|
-
- **`progressReverse`:** _Reverse the progress bar
|
|
453
|
+
- **`progressReverse`:** _Reverse the progress bar position._
|
|
422
454
|
<details>
|
|
423
|
-
<summary><strong><em>
|
|
455
|
+
<summary><strong><em>more</em></strong></summary>
|
|
424
456
|
<br />
|
|
425
457
|
<strong>• Type:</strong> boolean<br />
|
|
426
458
|
<br />
|
|
427
459
|
<strong>• Default:</strong> false<br />
|
|
428
460
|
<br />
|
|
429
461
|
<strong>• Description:</strong> <em><br />
|
|
430
|
-
|
|
462
|
+
This parameter changes the position of the progress bar based on the direction property.<br />
|
|
463
|
+
<br />
|
|
464
|
+
If direction="x", the progress bar will be positioned on the left by default or on the right when progressReverse is active.<br />
|
|
465
|
+
<br />
|
|
466
|
+
If direction="y", the progress bar will be positioned at the top by default or at the bottom when progressReverse is active.</em><br />
|
|
431
467
|
<br />
|
|
432
468
|
<strong>• Example:</strong>
|
|
433
469
|
|
|
434
470
|
```tsx
|
|
435
471
|
<MorphScroll
|
|
436
|
-
|
|
472
|
+
progressReverse
|
|
473
|
+
// another props
|
|
437
474
|
>
|
|
438
475
|
{children}
|
|
439
476
|
</MorphScroll>
|
|
@@ -444,20 +481,21 @@ npm install morphing-scroll
|
|
|
444
481
|
|
|
445
482
|
- **`progressVisibility`:** _Visibility of the progress bar._
|
|
446
483
|
<details>
|
|
447
|
-
<summary><strong><em>
|
|
484
|
+
<summary><strong><em>more</em></strong></summary>
|
|
448
485
|
<br />
|
|
449
486
|
<strong>• Type:</strong> "visible" | "hover" | "hidden"<br />
|
|
450
487
|
<br />
|
|
451
488
|
<strong>• Default:</strong> "visible"<br />
|
|
452
489
|
<br />
|
|
453
490
|
<strong>• Description:</strong> <em><br />
|
|
454
|
-
.</em><br />
|
|
491
|
+
This parameter controls the visibility of the progress bar regardless of the <code>type</code> value.</em><br />
|
|
455
492
|
<br />
|
|
456
493
|
<strong>• Example:</strong>
|
|
457
494
|
|
|
458
495
|
```tsx
|
|
459
496
|
<MorphScroll
|
|
460
|
-
|
|
497
|
+
progressVisibility="hover"
|
|
498
|
+
// another props
|
|
461
499
|
>
|
|
462
500
|
{children}
|
|
463
501
|
</MorphScroll>
|
|
@@ -468,7 +506,7 @@ npm install morphing-scroll
|
|
|
468
506
|
|
|
469
507
|
- **`objectsWrapFullMinSize`:** _Sets the `min-height` CSS property of the `objectsWrapper` to match the height of the MorphScroll._
|
|
470
508
|
<details>
|
|
471
|
-
<summary><strong><em>
|
|
509
|
+
<summary><strong><em>more</em></strong></summary>
|
|
472
510
|
<br />
|
|
473
511
|
<strong>• Type:</strong> boolean<br />
|
|
474
512
|
<br />
|
|
@@ -489,11 +527,13 @@ npm install morphing-scroll
|
|
|
489
527
|
|
|
490
528
|
</details>
|
|
491
529
|
|
|
530
|
+
<h2>
|
|
531
|
+
|
|
492
532
|
##### - PROGRESS AND RENDERING:
|
|
493
533
|
|
|
494
534
|
- **`progressTrigger`:** _Triggers for the progress bar._
|
|
495
535
|
<details>
|
|
496
|
-
<summary><strong><em>
|
|
536
|
+
<summary><strong><em>more</em></strong></summary>
|
|
497
537
|
<br />
|
|
498
538
|
<strong>• Type:</strong> {<br />
|
|
499
539
|
wheel?: boolean;<br />
|
|
@@ -505,13 +545,22 @@ npm install morphing-scroll
|
|
|
505
545
|
<strong>• Default:</strong> { wheel: true }<br />
|
|
506
546
|
<br />
|
|
507
547
|
<strong>• Description:</strong> <em><br />
|
|
508
|
-
|
|
548
|
+
This is one of the most important parameters, allowing you to define how users interact with the progress bar and customize its appearance.<br />
|
|
549
|
+
<br />
|
|
550
|
+
The <code>wheel</code> property determines whether the progress bar responds to mouse wheel scrolling.<br />
|
|
551
|
+
The <code>content</code> property enables interaction by clicking and dragging anywhere within the scrollable content to move it.<br />
|
|
552
|
+
The <code>progressElement</code> property defines whether the progress bar is controlled by a custom element. If your custom scroll element is not ready yet, you can simply pass <code>true</code>, which will display the browser's default scrollbar when <code>type="scroll"</code> is used. Alternatively, if <code>type="slider"</code> is set, a <code>sliderBar</code> element will be created, containing multiple <code>sliderElem</code> elements representing progress. Depending on the position, one of these elements will always have the <code>active</code> class.<br />
|
|
553
|
+
</em><br />
|
|
509
554
|
<br />
|
|
510
555
|
<strong>• Example:</strong>
|
|
511
556
|
|
|
512
557
|
```tsx
|
|
513
558
|
<MorphScroll
|
|
514
|
-
|
|
559
|
+
progressTrigger={{
|
|
560
|
+
wheel: true,
|
|
561
|
+
progressElement: <div className="your-scroll-thumb" />,
|
|
562
|
+
}}
|
|
563
|
+
// another props
|
|
515
564
|
>
|
|
516
565
|
{children}
|
|
517
566
|
</MorphScroll>
|
|
@@ -522,23 +571,36 @@ npm install morphing-scroll
|
|
|
522
571
|
|
|
523
572
|
- **`render`:** _Types of rendering for optimization._
|
|
524
573
|
<details>
|
|
525
|
-
<summary><strong><em>
|
|
574
|
+
<summary><strong><em>more</em></strong></summary>
|
|
526
575
|
<br />
|
|
527
576
|
<strong>• Type:</strong><br />
|
|
528
577
|
| { type: "default" }<br />
|
|
529
|
-
| { type: "lazy"; rootMargin?: number }<br />
|
|
530
|
-
| { type: "virtual" }<br />
|
|
578
|
+
| { type: "lazy"; rootMargin?: number | number[]; onVisible?: () => void }<br />
|
|
579
|
+
| { type: "virtual"; rootMargin?: number | number[] }<br />
|
|
531
580
|
<br />
|
|
532
|
-
<strong>• Default:</strong>
|
|
581
|
+
<strong>• Default:</strong> { type: "default" }<br />
|
|
533
582
|
<br />
|
|
534
583
|
<strong>• Description:</strong> <em><br />
|
|
535
|
-
|
|
584
|
+
This parameter defines the rendering type for optimization.<br />
|
|
585
|
+
The <code>type</code> property can be set to <code>default</code>, <code>lazy</code> or <code>virtual</code>.<br />
|
|
586
|
+
<br />
|
|
587
|
+
With <code>default</code>, no optimizations are applied.<br />
|
|
588
|
+
With <code>lazy</code>, containers are created but do not load content until they enter the viewport. The <code>rootMargin</code> property controls the threshold for loading, and the <code>onVisible</code>callback function can be used to trigger actions when a container becomes visible for each scrollable object.<br />
|
|
589
|
+
<br />
|
|
590
|
+
With <code>virtual</code>, a container is created for each scrollable object, and its absolute positioning is calculated based on <code>scrollTop</code> and scroll area dimensions. Rendering is dynamically adjusted according to the scroll position. The <code>rootMargin</code> property can also be used to extend the rendering area.<br />
|
|
591
|
+
<br />
|
|
592
|
+
*The <code>rootMargin</code> property accepts either a single number or an array of numbers.<br />
|
|
593
|
+
If a two-number array is provided, the values follow the <code>horizontal/vertical</code> rule.<br />
|
|
594
|
+
If a four-number array is provided, the values follow the <code>top/right/bottom/left</code> rule.<br />
|
|
595
|
+
All values are in pixels and apply regardless of the <code>direction</code>.<br /></em><br />
|
|
536
596
|
<br />
|
|
537
597
|
<strong>• Example:</strong>
|
|
538
598
|
|
|
539
599
|
```tsx
|
|
540
600
|
<MorphScroll
|
|
541
|
-
|
|
601
|
+
render={{ type: "virtual" }}
|
|
602
|
+
// render={{ type: "lazy", rootMargin: [0, 100], onVisible: () => console.log("visible")) }}
|
|
603
|
+
// another props
|
|
542
604
|
>
|
|
543
605
|
{children}
|
|
544
606
|
</MorphScroll>
|
|
@@ -547,31 +609,46 @@ npm install morphing-scroll
|
|
|
547
609
|
</details>
|
|
548
610
|
<h2>
|
|
549
611
|
|
|
550
|
-
- **`emptyElements`:**
|
|
612
|
+
- **`emptyElements`:** _Handling of empty scroll elements._
|
|
551
613
|
<details>
|
|
552
|
-
<summary><strong><em>
|
|
614
|
+
<summary><strong><em>more</em></strong></summary>
|
|
553
615
|
<br />
|
|
554
616
|
<strong>• Type:</strong><br />
|
|
555
617
|
| {
|
|
556
|
-
mode: "clear"
|
|
557
|
-
|
|
618
|
+
mode: "clear";
|
|
619
|
+
clickTrigger?: { selector: string; delay?: number };
|
|
558
620
|
}<br />
|
|
559
621
|
| {
|
|
560
622
|
mode: "fallback";
|
|
561
|
-
|
|
562
|
-
|
|
623
|
+
element?: React.ReactNode;
|
|
624
|
+
clickTrigger?: { selector: string; delay?: number };
|
|
563
625
|
}<br />
|
|
564
626
|
<br />
|
|
565
|
-
<strong>• Default:</strong> false<br />
|
|
566
|
-
<br />
|
|
567
627
|
<strong>• Description:</strong> <em><br />
|
|
568
|
-
|
|
628
|
+
If certain components might return nothing during rendering, this parameter helps manage them. The check and subsequent replacement with a fallback element or removal occur after the scroll elements are rendered. Due to this, when dynamically displaying elements in different <code>render</code> modes, you may notice slight position shifts during fast scrolling, as empty elements are removed, causing subsequent elements to reposition.<br />
|
|
629
|
+
<br />
|
|
630
|
+
<code>mode: "clear"</code> – automatically removes empty elements, eliminating unnecessary gaps in the scroll list.<br />
|
|
631
|
+
<br />
|
|
632
|
+
<code>clickTrigger</code> – if elements are removed via a click action, this property ensures cleanup is triggered accordingly. It accepts an object with a <code>selector</code> (such as a delete button’s class) and an optional <code>delay</code> (a delay in milliseconds to accommodate animations or complex removals).<br />
|
|
633
|
+
<br />
|
|
634
|
+
<code>mode: "fallback"</code> – replaces empty elements with a specified fallback component. By default, it uses the <code>fallback</code> props value, but you can also pass a separate placeholder element via the <code>element</code> property.</em><br />
|
|
569
635
|
<br />
|
|
570
636
|
<strong>• Example:</strong>
|
|
571
637
|
|
|
572
638
|
```tsx
|
|
573
639
|
<MorphScroll
|
|
574
|
-
|
|
640
|
+
emptyElements={{
|
|
641
|
+
mode: "clear",
|
|
642
|
+
clickTrigger: { selector: ".close-button" },
|
|
643
|
+
}}
|
|
644
|
+
// emptyElements={{
|
|
645
|
+
// mode: "fallback",
|
|
646
|
+
// clickTrigger: {
|
|
647
|
+
// selector: ".close-button",
|
|
648
|
+
// delay: 100,
|
|
649
|
+
// },
|
|
650
|
+
// }}
|
|
651
|
+
// another props
|
|
575
652
|
>
|
|
576
653
|
{children}
|
|
577
654
|
</MorphScroll>
|
|
@@ -582,7 +659,7 @@ npm install morphing-scroll
|
|
|
582
659
|
|
|
583
660
|
- **`suspending`:** _Adds React Suspense._
|
|
584
661
|
<details>
|
|
585
|
-
<summary><strong><em>
|
|
662
|
+
<summary><strong><em>more</em></strong></summary>
|
|
586
663
|
<br />
|
|
587
664
|
<strong>• Type:</strong> boolean<br />
|
|
588
665
|
<br />
|
|
@@ -606,7 +683,7 @@ npm install morphing-scroll
|
|
|
606
683
|
|
|
607
684
|
- **`fallback`:** _Fallback element for error handling._
|
|
608
685
|
<details>
|
|
609
|
-
<summary><strong><em>
|
|
686
|
+
<summary><strong><em>more</em></strong></summary>
|
|
610
687
|
<br />
|
|
611
688
|
<strong>• Type:</strong> React.ReactNode<br />
|
|
612
689
|
<br />
|
package/index.d.ts
CHANGED
|
@@ -155,7 +155,11 @@ export type MorphScrollT = {
|
|
|
155
155
|
/**---
|
|
156
156
|
* ✨ *Scroll position and animation duration.*
|
|
157
157
|
*/
|
|
158
|
-
scrollTop?: {
|
|
158
|
+
scrollTop?: {
|
|
159
|
+
value: number | "end" | null;
|
|
160
|
+
duration?: number;
|
|
161
|
+
updater?: boolean;
|
|
162
|
+
};
|
|
159
163
|
/**---
|
|
160
164
|
* ✨ *Stop loading when scrolling.*
|
|
161
165
|
* @default-false
|
|
@@ -240,20 +244,20 @@ export type MorphScrollT = {
|
|
|
240
244
|
*/
|
|
241
245
|
render?:
|
|
242
246
|
| { type: "default" }
|
|
243
|
-
| { type: "lazy"; rootMargin?: number }
|
|
247
|
+
| { type: "lazy"; rootMargin?: number | number[] }
|
|
244
248
|
| { type: "virtual" };
|
|
245
249
|
/**---
|
|
246
|
-
* ✨ *
|
|
250
|
+
* ✨ *Handling of empty scroll elements.*
|
|
247
251
|
*/
|
|
248
252
|
emptyElements?:
|
|
249
253
|
| {
|
|
250
254
|
mode: "clear";
|
|
251
|
-
|
|
255
|
+
clickTrigger?: { selector: string; delay?: number };
|
|
252
256
|
}
|
|
253
257
|
| {
|
|
254
258
|
mode: "fallback";
|
|
255
|
-
closeSelector?: string;
|
|
256
259
|
element?: React.ReactNode;
|
|
260
|
+
clickTrigger?: { selector: string; delay?: number };
|
|
257
261
|
};
|
|
258
262
|
/**---
|
|
259
263
|
* ✨ *Adds React Suspense.*
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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 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",{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:c,intersectionDelay:a})=>{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&&c)return b(),a?m.current=setTimeout((()=>{u&&c&&c()}),a):u&&c&&c(),()=>b()}),[u,a,c]);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:c="y",gap:a,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),S=e.useRef(null),A=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`},[ce,ae,ue,de]=r(u,"x"===c)||[0,0,0,0],pe=ce+ue,me=de+ae,[he,ge]=e.useMemo((()=>{var e,t,r,n;return"number"==typeof a?[a,a]:Array.isArray(a)?"x"===c?[null!==(e=a[0])&&void 0!==e?e:0,null!==(t=a[1])&&void 0!==t?t:0]:[null!==(r=a[1])&&void 0!==r?r:0,null!==(n=a[0])&&void 0!==n?n:0]:[0,0]}),[a,c]),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"===c?fe[0]:fe[1],ye="x"===c?fe[1]:fe[0],ve=e.useMemo((()=>r("lazy"===M.type&&M.rootMargin||0,"x"===c)),[M,c]),[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"===c?[e?e-2*le.size:e,t,e,t]:[e,t?t-2*le.size:t,e,t]:[e,t,e,t]}),[o,c,le.size,X]),Ee="x"===c?je[0]:je[1],Oe="x"===c?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]),Se=(null===(k=z.current)||void 0===k?void 0:k.scrollTop)||0,Ae=Math.round(Se+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:null),[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+ce:ce}("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,a,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,a="x"===c?o>Re:i>Re,u={};return("x"===c?i>ze:o>ze)&&(u.justifyContent="x"===c?l:s),a&&(u.alignItems="x"===c?s:l),u}),[j,c,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=S.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,S,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,O,$,M]),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"===c?e.movementX:e.movementY)*r*n}if("slider"===Y.current){const r=S.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))}}}),[c,z,Le]),Je=e.useCallback((e=>{if(window.removeEventListener("mousemove",Pe),window.removeEventListener("mouseup",Je),document.body.style.removeProperty("cursor"),De(S.current),De(A.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,c=Math.min(i/U.duration,1);r.scrollTop=n+((null!=e?e:0)-n)*c,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,a=Object.assign({width:ye?`${ye}px`:"",height:be?`${be}px`:""},"x"===c&&{display:"flex"}),u=Object.assign({width:fe[0]?`${fe[0]}px`:""},"x"===c&&{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({},a),{position:"absolute",top:`${t}px`}),r&&{left:`${r}px`}),!ye&&1===Me&&{transform:"translateX(-50%)"}):a},p=e.createElement("div",Object.assign({},s?{"wrap-id":s}:{},{onClick:st,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%)"}),a)},p):"lazy"===M.type?e.createElement(n,Object.assign({key:o},d),p):e.createElement("div",{key:o,style:a},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.includes(e)&&(V.current=`${V.current}/${e}`):V.current=e}),[V.current]),st=e.useCallback((e=>{if(!(null==$?void 0:$.closeSelector))return;const t=e.target.closest(null==$?void 0:$.closeSelector);console.log("closeSelector",t),t&&(L.current=setTimeout((()=>{nt(),C()})))}),[$]);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]),e.useEffect((()=>{if(O){const e=Array.from(rt(),(e=>e.getAttribute("wrap-id")));F.current=e}}),[O]);const lt=e.createElement("div",{className:"objectsWrapper",ref:S,onMouseDown:()=>{p.content&&(Ke("wrapp"),Ve(S.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"===c&&{alignItems:"center"}),"virtual"!==M.type&&Me>1&&{flexWrap:"wrap"}),"virtual"!==M.type&&Me<=1&&{flexDirection:"column"}),a&&"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 a=r.key||"",u=O&&!F.current.includes(`${Q}-${a}`)&&D?g:"fallback"===(null==$?void 0:$.mode)&&V.current.includes(a)?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}-${a}`,d,a);{const{elementTop:e,elementBottom:t,left:r}=Fe[n];if(("x"===c?null!==(l=je[0])&&void 0!==l?l:0:null!==(o=je[1])&&void 0!==o?o:0)+xe>e-Se&&t-Se>0-we)return tt(e,r,`${Q}-${a}`,d,a)}}))),ot=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"===c&&{transform:`rotate(-90deg) translate(${qe}px, ${qe}px) scaleX(-1)`}),p.arrows&&le.size&&("x"===c?{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]?lt:e.createElement(t,{onResize:Ue},(()=>lt))),b&&e.createElement("div",{className:"edge",style:Object.assign(Object.assign({},ie),{top:0,opacity:Se>1?1:0})}),b&&e.createElement("div",{className:"edge",style:Object.assign(Object.assign({},ie),{bottom:0,opacity:Ae?1:0,transform:"scaleY(-1)"})}),p.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:`${le.size}px`}),onClick:()=>Xe("first")},le.element),e.createElement("div",{className:"arrowBox"+(Ae?" 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:A,className:"scrollBarThumb",onMouseDown:()=>{p.progressElement&&(Ke("thumb"),Ve(A.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?ot:e.createElement(t,{measure:"outer",onResize:Qe},(()=>ot))},exports.ResizeTracker=t;
|
|
1
|
+
"use strict";var e=require("react");const t=(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},r=({style:r,root:n,children:l,threshold:s,rootMargin:o,visibleContent:i=!1,onVisible:a,intersectionDelay:c})=>{const[u,d]=e.useState(!1),p=e.useRef(null),m=e.useRef(null),h=t(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:s,rootMargin:g});return p.current&&e.observe(p.current),()=>{e.disconnect()}}),[n,s,g]),e.useEffect((()=>{if(u&&a)return b(),c?m.current=setTimeout((()=>{u&&a&&a()}),c):u&&a&&a(),()=>b()}),[u,c,a]);const v=i||u?l:null;return e.createElement("div",{ref:p,"intersection-tracker":"〈•〉",style:r},v)},n=({measure:t="inner",style:r,onResize:n,children:l})=>{const s=e.useRef(null),[o,i]=e.useState({width:0,height:0});e.useEffect((()=>{const e=s.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:s,"resize-tracker":"〈—〉",style:Object.assign(Object.assign({},u[t]),r)},l(o.width,o.height))};exports.IntersectionTracker=r,exports.MorphScroll=({type:l="scroll",className:s="",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:v=!1,children:y,onScrollValue:x,elementsAlign:w=!1,contentAlign:j,isScrolling:E,stopLoadOnScroll:O=!1,render:M={type:"default"},emptyElements:$})=>{var k,T,C;const R=e.useReducer((()=>({})),{})[1],z=e.useRef(null),A=e.useRef(null),S=e.useRef(null),B=e.useRef(null),N=e.useRef(null),Y=e.useRef(null),V=e.useRef(null),q=e.useRef("none"),F=e.useRef(0),I=e.useRef([]),L=e.useRef(0),D=e.useRef(null),W=e.useRef(""),[X,H]=e.useState(!1),[G,P]=e.useState({width:0,height:0}),[J,K]=e.useState({width:0,height:0}),[Q,U]=e.useState({width:0,height:0}),Z=`${e.useId()}`.replace(/^(.{2})(.*).$/,"$2"),_={value:null!==(k=null==f?void 0:f.value)&&void 0!==k?k:null,duration:null!==(T=null==f?void 0:f.duration)&&void 0!==T?T:200},ee={position:"absolute",width:"100%",display:"flex",justifyContent:"center",alignItems:"center",cursor:"pointer"},te={color:null,size:40},re=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(re):[r]}return[t]}),[]),ne="clear"===(null==$?void 0:$.mode),le=e.useMemo((()=>ne?W.current:""),[ne,W.current]),se=e.useMemo((()=>e.Children.toArray(y).flatMap(re).filter(Boolean).filter((t=>!ne||!e.isValidElement(t)||!W.current.includes(t.key)))),[y,ne,le]),oe=e.useMemo((()=>{if("end"!==_.value)return null;if(se.length>0){const t=se[0];if(e.isValidElement(t))return t.key}return null}),[se,_.value]),ie=Object.assign(Object.assign({},{size:40}),"object"==typeof p.arrows?p.arrows:{}),ae="object"==typeof b?Object.assign(Object.assign({},te),b):te,ce=Object.assign({position:"absolute",left:0,width:"100%",pointerEvents:"none",transition:"opacity 0.1s ease-in-out",height:`${ae.size}px`},ae.color&&{background:`linear-gradient(${ae.color}, transparent)`}),[ue,de,pe,me]=t(u,"x"===a)||[0,0,0,0],he=ue+pe,ge=me+de,[fe,be]=e.useMemo((()=>{var e,t,r,n;return"number"==typeof c?[c,c]:Array.isArray(c)?"x"===a?[null!==(e=c[0])&&void 0!==e?e:0,null!==(t=c[1])&&void 0!==t?t:0]:[null!==(r=c[1])&&void 0!==r?r:0,null!==(n=c[0])&&void 0!==n?n:0]:[0,0]}),[c,a]),ve=e.useMemo((()=>["number"==typeof i[0]?i[0]:"none"===i[0]?null:"firstChild"===i[0]?Q.width:null,"number"==typeof i[1]?i[1]:"none"===i[1]?null:"firstChild"===i[1]?Q.height:null]),[i,Q]),ye="x"===a?ve[0]:ve[1],xe="x"===a?ve[1]:ve[0],we=e.useMemo((()=>t("default"!==M.type&&M.rootMargin||0,"x"===a)),[M,a]),[je,Ee]=we?[we[2],we[0]]:[0,0],Oe=e.useMemo((()=>{const[e,t]=o&&Array.isArray(o)?o:[G.width,G.height];return p.arrows&&ie.size?"x"===a?[e?e-2*ie.size:e,t,e,t]:[e,t?t-2*ie.size:t,e,t]:[e,t,e,t]}),[o,a,ie.size,G]),Me="x"===a?Oe[0]:Oe[1],$e="x"===a?Oe[1]:Oe[0],ke=e.useMemo((()=>{const e=xe?xe+fe:null;return e?Math.floor(($e-ge)/e):1}),[xe,$e,fe,ge]),Te=e.useMemo((()=>{if("virtual"!==M.type||ke<=1)return[];const e=se.map(((e,t)=>t));if(!e)return[];const t=Array.from({length:ke},(()=>[]));return e.forEach((e=>{t[e%ke].push(e)})),t}),[y,ke,M.type]),Ce=e.useMemo((()=>ke>1?Math.ceil(se.length/ke):se.length),[se.length,ke]),Re=e.useMemo((()=>{const e=ke||1;return xe?xe*e+(e-1)*be:"virtual"!==M.type?J.width:(Q.width+be)*e-be}),[xe,ke,be,J,Q,M.type]),ze=e.useMemo((()=>{const e=Ce-1,t=e<=0?0:e*fe;return ye?ye*Ce+t:"virtual"!==M.type?J.height:Q.height+t}),[ye,Ce,fe,J,Q,M.type]),Ae=e.useMemo((()=>ze?ze+he:0),[ze,he]),Se=e.useMemo((()=>Re?Re+ge:0),[Re,ge]),Be=(null===(C=S.current)||void 0===C?void 0:C.scrollTop)||0,Ne=Math.round(Be+Me)!==Ae,Ye=e.useMemo((()=>"hidden"===m&&Ae||0===ze?0:Me?Math.round(Me/Ae*Me):0),[Me,Ae,m]),Ve=e.useMemo((()=>Me?Ae-Me:Ae),[Ae,Me]),qe=e.useMemo((()=>Oe[0]&&Oe[1]?Oe[0]/2-Oe[1]/2:0),[Oe]),Fe=e.useMemo((()=>{let e=[],t=0;if("virtual"===M.type&&w){const r=Array.from({length:se.length},((e,t)=>t)),n=Math.abs(Math.floor(se.length/ke)*ke-se.length);e=n?r.slice(-n):[],"center"===w?t=((null!=xe?xe:0)+be)*(ke-n)/2:"end"===w&&(t=((null!=xe?xe:0)+be)*(ke-n))}return se.map(((r,n)=>{const l=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,Te),s=function(e){return 0!==e?((null!=ye?ye:0)+fe)*e+ue:ue}("virtual"===M.type?ke>1?l[1]:n:0),o="virtual"===M.type&&ve[1]?s+ve[1]:0,i="virtual"===M.type&&xe?xe*l[0]+be*l[0]+me+(w&&e.length>0&&e.includes(n)?t:0):0;return{elementTop:s,elementBottom:o,left:i}}))}),[y,Te,ve,c,M.type,ke]),Ie=e.useMemo((()=>{var e,t;if(!j)return{};const[r,n="start"]=j,l="start"===r?"flex-start":"center"===r?"center":"flex-end",s="start"===n?"flex-start":"center"===n?"center":"flex-end",o=null!==(e=Oe[0])&&void 0!==e?e:0,i=null!==(t=Oe[1])&&void 0!==t?t:0,c="x"===a?o>Ae:i>Ae,u={};return("x"===a?i>Se:o>Se)&&(u.justifyContent="x"===a?s:l),c&&(u.alignItems="x"===a?l:s),u}),[j,a,Oe,Ae,Se]),Le=e.useCallback((e=>(e?Math.ceil:Math.floor)(Ae/Me)),[Me,Ae]),De=e=>{e&&(e.style.cursor="grabbing")},We=e=>{e&&"grabbing"===e.style.cursor&&(e.style.cursor="grab")},Xe=(e,t)=>{if(e){const r=e.querySelector(`.${t}`);r&&(r.style.opacity="0")}},He=e.useCallback((e=>{const t=S.current,r=B.current;if(!t||!r)return;const n=r.clientHeight,l=Le(),s=e=>tt(e);"first"===e&&t.scrollTop>0&&s(t.scrollTop<=Me?0:t.scrollTop-Me),"last"===e&&l&&t.scrollTop+Me!==n&&s(t.scrollTop+Me>=Me*l?n:t.scrollTop+Me)}),[S,B,Le]),Ge=e.useCallback((()=>{const e=S.current;if(e&&A.current&&Y.current){function t(){var t;const r=null===(t=Y.current)||void 0===t?void 0:t.querySelectorAll(".sliderElem");r&&r.forEach(((t,r)=>{var n,l;const s=(null!==(n=null==e?void 0:e.scrollTop)&&void 0!==n?n:0)>=Me*r&&(null!==(l=null==e?void 0:e.scrollTop)&&void 0!==l?l:0)<Me*(r+1);t.classList.toggle("active",s)}))}t()}}),[Me,Ae]),Pe=e.useCallback((()=>{const e=S.current;if(!e)return;const t=O||E;if(!X&&(null==E||E(!0)),t&&H(!0),D.current&&clearTimeout(D.current),D.current=setTimeout((()=>{t&&H(!1),null==E||E(!1),"default"!==M.type&&st()}),200),0!==Ye&&"hidden"!==m){const t=Math.abs(Math.round(e.scrollTop/Ve*(Me-Ye)));t!==L.current&&"slider"!==l&&(L.current=Ye+t>Me?Me-Ye:t),x&&x(e.scrollTop)}b&&Ge(),"default"!==M.type&&st(!1),R()}),[Me,Ye,L,m,x,Ge,b,E,O,$,M]),Je=e.useCallback((e=>{const t=S.current,r=Le();if(t&&r){if(["thumb","wrapp"].includes(q.current)){const n="thumb"===q.current?1:-1;t.scrollTop+=("x"===a?e.movementX:e.movementY)*r*n}if("slider"===q.current){const r=B.current;if(!r)return;const n=r.clientHeight,l=e=>tt(e,(()=>{F.current=0,R()})),s=e=>{const r=t.scrollTop+e*Me;l(e>0?Math.min(r,n-Me):Math.max(r,0))};e.movementY>0&&F.current<1?(F.current+=e.movementY,F.current>=1&&t.scrollTop+Me!=n&&s(1)):e.movementY<0&&F.current>-1&&(F.current-=Math.abs(e.movementY),F.current<=-1&&0!=t.scrollTop&&s(-1))}}}),[a,S,Le]),Ke=e.useCallback((e=>{if(window.removeEventListener("mousemove",Je),window.removeEventListener("mouseup",Ke),document.body.style.removeProperty("cursor"),We(B.current),We(N.current),q.current="none","hover"===m){let t=e.target,r=!1;for(;t&&t!==document.body;){if(t===A.current){r=!0;break}t=t.parentNode}r||Xe(A.current,"scroll"===l?"scrollBar":"sliderBar")}R()}),[Je,z,m,l]),Qe=e.useCallback((e=>{q.current=e,R(),window.addEventListener("mousemove",Je),window.addEventListener("mouseup",Ke),document.body.style.cursor="grabbing"}),[Je,Ke,z]),Ue=e.useCallback(((e,t)=>{const r={width:e,height:t-he};G.width===r.width&&G.height===r.height||P(r)}),[he,G]),Ze=e.useCallback(((e,t)=>{const r={width:e-ge,height:t-he};J.width===r.width&&J.height===r.height||K(r)}),[ge,he,J]),_e=e.useCallback(((e,t)=>{const r={width:e,height:t};Q.width===r.width&&Q.height===r.height||U(r)}),[Q]);let et;const tt=e.useCallback(((e,t)=>{const r=S.current;if(!r)return null;const n=r.scrollTop;let l=null;const s=o=>{null===l&&(l=o);const i=Math.round(o-l),a=Math.min(i/_.duration,1)||0;r.scrollTop=n+(e-n)*a,i<=_.duration?et=requestAnimationFrame(s):null==t||t()};return et=requestAnimationFrame(s),()=>cancelAnimationFrame(et)}),[S,_.duration,_.value]),rt=e.useCallback((()=>{"lazy"===M.type&&M.onVisible?(M.onVisible(),st()):st()}),[M]),nt=(t,n,l,s,o)=>{const i=h?e.createElement(e.Suspense,{fallback:g},s):s,c=Object.assign({width:xe?`${xe}px`:"",height:ye?`${ye}px`:""},"x"===a&&{display:"flex"}),u=Object.assign({width:ve[0]?`${ve[0]}px`:""},"x"===a&&{transform:"rotate(-90deg) scaleX(-1)"}),d={root:S.current,rootMargin:"lazy"===M.type?M.rootMargin:we,style:"virtual"===M.type?Object.assign(Object.assign(Object.assign(Object.assign({},c),{position:"absolute",top:`${t}px`}),n&&{left:`${n}px`}),!xe&&1===ke&&{transform:"translateX(-50%)"}):c,onVisible:rt},p=e.createElement("div",Object.assign({},l?{"wrap-id":l}:{},{onClick:ot,style:u}),i);return"virtual"===M.type?e.createElement("div",{key:o,style:Object.assign(Object.assign(Object.assign({position:"absolute",top:`${t}px`},n&&{left:`${n}px`}),!xe&&1===ke&&{transform:"translateX(-50%)"}),c)},p):"lazy"===M.type?e.createElement(r,Object.assign({key:o},d),p):e.createElement("div",{key:o,style:c},p)},lt=e.useCallback((()=>document.querySelectorAll(`[wrap-id^="${Z}-"]`)),[]),st=e.useCallback(((e=!0)=>{if(!$)return;const t=Array.from(lt()).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("/");W.current?t&&!W.current.includes(t)&&(W.current=`${W.current}/${t}`):W.current=t,e&&R()}),[W.current]),ot=e.useCallback((e=>{var t;if(!(null===(t=null==$?void 0:$.clickTrigger)||void 0===t?void 0:t.selector))return;e.target.closest(null==$?void 0:$.clickTrigger.selector)&&(D.current&&clearTimeout(D.current),D.current=setTimeout((()=>{st()}),$.clickTrigger.delay))}),[$]);e.useEffect((()=>{st()}),[se.length]),e.useEffect((()=>{"virtual"===M.type&&R(),Ge()}),[]),e.useEffect((()=>{if(S.current&&se.length>0){let e;return"end"===_.value&&Ae>Me?(V.current||(V.current=oe),e=V.current===oe?tt(Ve):null,V.current=oe):"number"==typeof _.value&&(e=tt(_.value)),()=>{e&&e(),D.current&&clearTimeout(D.current),I.current=[]}}}),[null==f?void 0:f.updater,_.value,tt,Ve]),e.useEffect((()=>{if(O){const e=Array.from(lt(),(e=>e.getAttribute("wrap-id")));I.current=e}}),[O]);const it=e.createElement("div",{className:"objectsWrapper",ref:B,onMouseDown:()=>{p.content&&(Qe("wrapp"),De(B.current))},style:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({height:"virtual"===M.type&&Ae||"none"!==i[1]?`${Ae}px`:"fit-content",width:Se?`${Se}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&&ke>1&&{flexWrap:"wrap"}),"virtual"!==M.type&&ke<=1&&{flexDirection:"column"}),c&&"virtual"!==M.type&&{gap:`${fe}px ${be}px`}),w&&"virtual"!==M.type&&{justifyContent:"start"===w?"flex-start":"center"===w?"center":"flex-end"}),v&&{minHeight:Me-he+"px"})},se.map(((t,r)=>{var l,s,o;const c=t.key||"",u=O&&!I.current.includes(`${Z}-${c}`)&&X?g:"fallback"===(null==$?void 0:$.mode)&&W.current.includes(c)?null!==(l=$.element)&&void 0!==l?l:g:t,d="number"==typeof i[0]&&"number"==typeof i[1]||"firstChild"!==i[0]&&"firstChild"!==i[1]||0!==r?u:e.createElement(n,{onResize:_e},(()=>u));if("virtual"!==M.type)return nt(0,0,`${Z}-${c}`,d,c);{const{elementTop:e,elementBottom:t,left:n}=Fe[r];if(("x"===a?null!==(s=Oe[0])&&void 0!==s?s:0:null!==(o=Oe[1])&&void 0!==o?o:0)+je>e-Be&&t-Be>0-Ee)return nt(e,n,`${Z}-${c}`,d,c)}}))),at=e.createElement("div",{"morph-scroll":"〈♦〉",className:`${s&&s}`,ref:z,style:{width:`${Oe[2]}px`,height:`${Oe[3]}px`}},e.createElement("div",{className:"scrollContent",ref:A,onMouseEnter:()=>"hover"===m&&((e,t)=>{if(e){const r=e.querySelector(`.${t}`);r&&(r.style.opacity="1")}})(A.current,"scroll"===l?"scrollBar":"sliderBar"),onMouseLeave:()=>"hover"===m&&"thumb"!==q.current&&"slider"!==q.current&&Xe(A.current,"scroll"===l?"scrollBar":"sliderBar"),style:Object.assign(Object.assign({position:"relative",width:`${$e}px`,height:`${Me}px`},"x"===a&&{transform:`rotate(-90deg) translate(${qe}px, ${qe}px) scaleX(-1)`}),p.arrows&&ie.size&&("x"===a?{left:`${ie.size}px`}:{top:`${ie.size}px`}))},e.createElement("div",{className:"scrollElement",ref:S,onScroll:Pe,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]?it:e.createElement(n,{onResize:Ze},(()=>it))),b&&e.createElement("div",{className:"edge",style:Object.assign(Object.assign({},ce),{top:0,opacity:Be>1?1:0})}),b&&e.createElement("div",{className:"edge",style:Object.assign(Object.assign({},ce),{bottom:0,opacity:Ne?1:0,transform:"scaleY(-1)"})}),p.arrows&&e.createElement(e.Fragment,null,e.createElement("div",{className:"arrowBox"+(Be>1?" active":""),style:Object.assign(Object.assign({},ee),{top:0,transform:"translateY(-100%)",height:`${ie.size}px`}),onClick:()=>He("first")},ie.element),e.createElement("div",{className:"arrowBox"+(Ne?" active":""),style:Object.assign(Object.assign({},ee),{bottom:0,transform:"translateY(100%) scaleY(-1)",height:`${ie.size}px`}),onClick:()=>He("last")},ie.element)),"hidden"!==m&&Ye<ze&&"boolean"!=typeof p.progressElement&&e.createElement(e.Fragment,null,"slider"!==l?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:N,className:"scrollBarThumb",onMouseDown:()=>{p.progressElement&&(Qe("thumb"),De(N.current))},style:Object.assign({height:`${Ye}px`,willChange:"transform",transform:`translateY(${L.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:Y,onMouseDown:()=>Qe("slider")},Array.from({length:Le()||0},((t,r)=>e.createElement("div",{key:r,className:"sliderElem",style:{width:"fit-content"}},p.progressElement)))))));return o?at:e.createElement(n,{measure:"outer",onResize:Ue},(()=>at))},exports.ResizeTracker=n;
|