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 +21 -0
- package/README.md +619 -0
- package/index.d.ts +253 -69
- package/index.js +1 -1
- package/package.json +6 -2
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
|
-
|
|
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
|
-
|
|
17
|
-
|
|
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
|
-
|
|
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
|
-
|
|
27
|
-
|
|
137
|
+
/**---
|
|
138
|
+
* ✨ *Additional class for the component.*
|
|
139
|
+
*/
|
|
28
140
|
className?: string;
|
|
141
|
+
/**---
|
|
142
|
+
* ✨ *Child elements.*
|
|
143
|
+
*/
|
|
29
144
|
children?: React.ReactNode;
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
*
|
|
262
|
+
* ## *MorphScroll component*〈♦〉
|
|
69
263
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
264
|
+
* ---
|
|
265
|
+
* ## PROPS:
|
|
266
|
+
* #### • GENERAL SETTINGS:
|
|
267
|
+
* - `className`
|
|
268
|
+
* - `children`
|
|
74
269
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
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
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
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
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* `
|
|
105
|
-
*
|
|
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
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
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
|
-
*
|
|
119
|
-
*
|
|
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.
|
|
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": "
|
|
17
|
+
"react": ">=16 <20"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/voodoofugu/morphing-scroll.git"
|
|
18
22
|
}
|
|
19
23
|
}
|