react-loadly 1.0.1 → 1.1.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.
Files changed (59) hide show
  1. package/README.md +529 -62
  2. package/dist/index.cjs.js +1 -1701
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.d.ts +146 -79
  5. package/dist/index.esm.js +1 -1662
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/styles.css +1 -1
  8. package/dist/styles.css.map +1 -1
  9. package/dist/styles.js +1 -0
  10. package/dist/types/@types/index.d.ts +3 -1
  11. package/dist/types/@types/index.d.ts.map +1 -1
  12. package/dist/types/@types/interfaces/IBaseLoaderProps.d.ts +4 -0
  13. package/dist/types/@types/interfaces/IBaseLoaderProps.d.ts.map +1 -1
  14. package/dist/types/@types/interfaces/IShimmerLoaderProps.d.ts +20 -0
  15. package/dist/types/@types/interfaces/IShimmerLoaderProps.d.ts.map +1 -0
  16. package/dist/types/@types/interfaces/ISkeletonLoaderProps.d.ts +22 -0
  17. package/dist/types/@types/interfaces/ISkeletonLoaderProps.d.ts.map +1 -0
  18. package/dist/types/@types/interfaces/index.d.ts +14 -0
  19. package/dist/types/@types/interfaces/index.d.ts.map +1 -0
  20. package/dist/types/@types/types/index.d.ts +3 -3
  21. package/dist/types/@types/types/index.d.ts.map +1 -1
  22. package/dist/types/components/organisms/BarsLoader.d.ts.map +1 -1
  23. package/dist/types/components/organisms/BlobLoader.d.ts.map +1 -1
  24. package/dist/types/components/organisms/BounceLoader.d.ts.map +1 -1
  25. package/dist/types/components/organisms/DotsLoader.d.ts.map +1 -1
  26. package/dist/types/components/organisms/ElementLoader.d.ts +0 -23
  27. package/dist/types/components/organisms/ElementLoader.d.ts.map +1 -1
  28. package/dist/types/components/organisms/FallbackLoader.d.ts +1 -1
  29. package/dist/types/components/organisms/FallbackLoader.d.ts.map +1 -1
  30. package/dist/types/components/organisms/FlowLoader.d.ts.map +1 -1
  31. package/dist/types/components/organisms/GridLoader.d.ts.map +1 -1
  32. package/dist/types/components/organisms/LiquidLoader.d.ts.map +1 -1
  33. package/dist/types/components/organisms/LogoSpinLoader.d.ts +1 -1
  34. package/dist/types/components/organisms/LogoSpinLoader.d.ts.map +1 -1
  35. package/dist/types/components/organisms/PulseLoader.d.ts.map +1 -1
  36. package/dist/types/components/organisms/RingLoader.d.ts.map +1 -1
  37. package/dist/types/components/organisms/RotateLoader.d.ts.map +1 -1
  38. package/dist/types/components/organisms/ShimmerLoader.d.ts +4 -0
  39. package/dist/types/components/organisms/ShimmerLoader.d.ts.map +1 -0
  40. package/dist/types/components/organisms/SkeletonLoader.d.ts +4 -0
  41. package/dist/types/components/organisms/SkeletonLoader.d.ts.map +1 -0
  42. package/dist/types/components/organisms/SpinLoader.d.ts.map +1 -1
  43. package/dist/types/components/organisms/TypingLoader.d.ts.map +1 -1
  44. package/dist/types/components/organisms/WaveLoader.d.ts.map +1 -1
  45. package/dist/types/components/organisms/index.d.ts +3 -1
  46. package/dist/types/components/organisms/index.d.ts.map +1 -1
  47. package/dist/types/index.d.ts +2 -2
  48. package/dist/types/index.d.ts.map +1 -1
  49. package/dist/types/styles.d.ts +2 -0
  50. package/dist/types/styles.d.ts.map +1 -0
  51. package/dist/types/utils/animationUtils.d.ts +24 -1
  52. package/dist/types/utils/animationUtils.d.ts.map +1 -1
  53. package/dist/types/utils/classNameGen.d.ts +4 -0
  54. package/dist/types/utils/classNameGen.d.ts.map +1 -0
  55. package/dist/types/utils/index.d.ts +3 -1
  56. package/dist/types/utils/index.d.ts.map +1 -1
  57. package/package.json +41 -6
  58. package/dist/types/@types/interfaces/ILoaderTheme.d.ts +0 -20
  59. package/dist/types/@types/interfaces/ILoaderTheme.d.ts.map +0 -1
package/dist/index.esm.js CHANGED
@@ -1,1663 +1,2 @@
1
- import React, { useMemo, useRef, useState, useEffect, useCallback } from 'react';
2
-
3
- /**
4
- * Merges default props with user props, handling undefined values gracefully
5
- * @param defaultProps - The default props to merge
6
- * @param userProps - The user provided props
7
- * @returns Merged props object
8
- */
9
- function mergeProps(defaultProps, userProps) {
10
- return { ...defaultProps, ...userProps };
11
- }
12
- /**
13
- * Converts size prop to CSS value
14
- * @param size - The size value (number or string)
15
- * @param fallback - The fallback value if size is undefined
16
- * @returns CSS size value as string
17
- */
18
- function getSizeValue(size, fallback = "40px") {
19
- if (size === undefined)
20
- return fallback;
21
- if (typeof size === "number")
22
- return `${size}px`;
23
- return size;
24
- }
25
- /**
26
- * Generates CSS custom properties object from loader variables
27
- * @param variables - The loader CSS variables object
28
- * @returns React CSS properties object
29
- */
30
- function generateCSSVariables(variables) {
31
- const cssProps = {};
32
- Object.entries(variables).forEach(([key, value]) => {
33
- if (value !== undefined) {
34
- cssProps[key] = value;
35
- }
36
- });
37
- return cssProps;
38
- }
39
-
40
- /**
41
- * Calculates animation duration based on speed multiplier
42
- * @param baseMs - The base duration in milliseconds
43
- * @param speed - The speed multiplier (default: 1)
44
- * @returns Formatted duration string
45
- */
46
- function getAnimationDuration(baseMs, speed = 1) {
47
- const duration = baseMs / Math.max(speed, 0.1); // Prevent division by zero
48
- return `${duration}ms`;
49
- }
50
- /**
51
- * Creates a CSS animation name with prefix
52
- * @param name - The base name for the animation
53
- * @returns Prefixed animation name
54
- */
55
- function createAnimationName(name) {
56
- return `react-loadly-${name}`;
57
- }
58
- /**
59
- * Check if reduced motion is preferred
60
- * @returns Boolean indicating if reduced motion is preferred
61
- */
62
- function prefersReducedMotion() {
63
- // Check if we're in a browser environment
64
- if (typeof window === "undefined" || !window.matchMedia)
65
- return false;
66
- try {
67
- return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
68
- }
69
- catch (e) {
70
- return false;
71
- }
72
- }
73
- /**
74
- * Get optimized animation settings based on user preferences
75
- * @param speed - The animation speed multiplier (default: 1)
76
- * @returns Object with optimized animation settings
77
- */
78
- function getOptimizedAnimationSettings(speed = 1) {
79
- // In test environments, disable animations to prevent test failures
80
- if (typeof process !== "undefined" && process.env.NODE_ENV === "test") {
81
- return {
82
- duration: "0ms",
83
- playState: "paused",
84
- iterationCount: 1,
85
- };
86
- }
87
- const reducedMotion = prefersReducedMotion();
88
- return {
89
- duration: reducedMotion ? "0ms" : getAnimationDuration(1000, speed),
90
- playState: reducedMotion ? "paused" : "running",
91
- iterationCount: reducedMotion ? 1 : "infinite",
92
- };
93
- }
94
-
95
- /**
96
- * Converts hex color to RGB values
97
- * @param hex - The hex color string
98
- * @returns Object with r, g, b values or null if invalid
99
- */
100
- function hexToRgb(hex) {
101
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
102
- return result
103
- ? {
104
- r: parseInt(result[1], 16),
105
- g: parseInt(result[2], 16),
106
- b: parseInt(result[3], 16),
107
- }
108
- : null;
109
- }
110
- /**
111
- * Generates rgba color with opacity
112
- * @param color - The hex color string
113
- * @param opacity - The opacity value (0-1)
114
- * @returns RGBA color string
115
- */
116
- function rgba(color, opacity) {
117
- const rgb = hexToRgb(color);
118
- if (!rgb)
119
- return color;
120
- return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${clamp(opacity, 0, 1)})`;
121
- }
122
-
123
- /**
124
- * Clamps a value between min and max
125
- * @param value - The value to clamp
126
- * @param min - The minimum value
127
- * @param max - The maximum value
128
- * @returns The clamped value
129
- */
130
- function clamp(value, min, max) {
131
- return Math.min(Math.max(value, min), max);
132
- }
133
-
134
- /**
135
- * Generates unique IDs for accessibility
136
- * @param prefix - The prefix for the ID (default: "loader")
137
- * @returns A unique ID string
138
- */
139
- function generateId(prefix = "loader") {
140
- return `${prefix}-${Math.random().toString(36).substr(2, 9)}`;
141
- }
142
- /**
143
- * Validates and sanitizes CSS values
144
- * @param value - The CSS value to sanitize
145
- * @returns Sanitized CSS value or undefined
146
- */
147
- function sanitizeCSSValue(value) {
148
- if (value === undefined || value === null)
149
- return undefined;
150
- if (typeof value === "number")
151
- return `${value}px`;
152
- if (typeof value === "string") {
153
- // Basic sanitization - remove potentially dangerous CSS
154
- return value.replace(/[<>'"]/g, "");
155
- }
156
- return undefined;
157
- }
158
-
159
- const Dot = ({ size = 8, color = "var(--react-loadly-color)", opacity = 1, className = "", style = {}, animation, animationDuration, animationDelay, glowIntensity = 0, "data-testid": dataTestId, ...props }) => {
160
- const sizeValue = getSizeValue(size);
161
- const dotStyle = {
162
- width: sizeValue,
163
- height: sizeValue,
164
- borderRadius: "50%",
165
- backgroundColor: color,
166
- opacity,
167
- animation: animation ? `${animation} ${animationDuration || "1s"} infinite` : undefined,
168
- animationDelay,
169
- display: "inline-block",
170
- boxShadow: glowIntensity > 0 ? `0 0 ${glowIntensity * 10}px ${color}` : undefined,
171
- ...style,
172
- };
173
- return React.createElement("div", { className: `react-loadly-dot ${className}`.trim(), style: dotStyle, "data-testid": dataTestId, ...props });
174
- };
175
-
176
- const Line = ({ width = 30, height = 4, color = "var(--react-loadly-color)", opacity = 1, borderRadius = 2, className = "", style = {}, animation, animationDuration, animationDelay, orientation = "horizontal", "data-testid": dataTestId, ...props }) => {
177
- const widthValue = getSizeValue(width);
178
- const heightValue = getSizeValue(height);
179
- const borderRadiusValue = sanitizeCSSValue(borderRadius);
180
- const lineStyle = {
181
- width: orientation === "vertical" ? heightValue : widthValue,
182
- height: orientation === "vertical" ? widthValue : heightValue,
183
- backgroundColor: color,
184
- opacity,
185
- borderRadius: borderRadiusValue,
186
- animation: animation ? `${animation} ${animationDuration || "1s"} infinite` : undefined,
187
- animationDelay,
188
- display: "inline-block",
189
- ...style,
190
- };
191
- return (React.createElement("div", { className: `react-loadly-line react-loadly-line-${orientation} ${className}`.trim(), style: lineStyle, "data-testid": dataTestId, ...props }));
192
- };
193
-
194
- const Rectangle = ({ width = 20, height = 20, color = "var(--react-loadly-color)", borderColor, borderWidth = 0, borderRadius = 0, opacity = 1, className = "", style = {}, animation, animationDuration, animationDelay, "data-testid": dataTestId, ...props }) => {
195
- const widthValue = getSizeValue(width);
196
- const heightValue = getSizeValue(height);
197
- const borderWidthValue = sanitizeCSSValue(borderWidth);
198
- const borderRadiusValue = sanitizeCSSValue(borderRadius);
199
- const rectangleStyle = {
200
- width: widthValue,
201
- height: heightValue,
202
- backgroundColor: borderColor ? "transparent" : color,
203
- border: borderColor ? `${borderWidthValue} solid ${borderColor}` : undefined,
204
- borderRadius: borderRadiusValue,
205
- opacity,
206
- animation: animation ? `${animation} ${animationDuration || "1s"} infinite` : undefined,
207
- animationDelay,
208
- display: "inline-block",
209
- ...style,
210
- };
211
- return React.createElement("div", { className: `react-loadly-rectangle ${className}`.trim(), style: rectangleStyle, "data-testid": dataTestId, ...props });
212
- };
213
-
214
- const Circle = ({ size = 20, color = "var(--react-loadly-color)", borderColor, borderWidth = 0, opacity = 1, className = "", style = {}, animation, animationDuration, animationDelay, "data-testid": dataTestId, ...props }) => {
215
- const sizeValue = getSizeValue(size);
216
- const borderWidthValue = sanitizeCSSValue(borderWidth);
217
- const circleStyle = {
218
- width: sizeValue,
219
- height: sizeValue,
220
- borderRadius: "50%",
221
- backgroundColor: borderColor ? "transparent" : color,
222
- border: borderColor ? `${borderWidthValue} solid ${borderColor}` : undefined,
223
- opacity,
224
- animation: animation ? `${animation} ${animationDuration || "1s"} infinite` : undefined,
225
- animationDelay,
226
- display: "inline-block",
227
- ...style,
228
- };
229
- return React.createElement("div", { className: `react-loadly-circle ${className}`.trim(), style: circleStyle, "data-testid": dataTestId, ...props });
230
- };
231
-
232
- const DotCluster = ({ count = 3, dotSize = 8, color = "var(--react-loadly-color)", secondaryColor, spacing = 8, speed = 1, arrangement = "linear", className = "", style = {}, animationType = "wave", "data-testid": dataTestId, ...props }) => {
233
- const spacingValue = getSizeValue(spacing);
234
- const animationDuration = getAnimationDuration(1200, speed);
235
- const getArrangementStyle = () => {
236
- switch (arrangement) {
237
- case "circular":
238
- return {
239
- display: "flex",
240
- alignItems: "center",
241
- justifyContent: "center",
242
- position: "relative",
243
- width: `${(parseInt(getSizeValue(dotSize)) + parseInt(spacingValue)) * 2}px`,
244
- height: `${(parseInt(getSizeValue(dotSize)) + parseInt(spacingValue)) * 2}px`,
245
- };
246
- case "grid": {
247
- const gridSize = Math.ceil(Math.sqrt(count));
248
- return {
249
- display: "grid",
250
- gridTemplateColumns: `repeat(${gridSize}, 1fr)`,
251
- gap: spacingValue,
252
- };
253
- }
254
- default: // linear
255
- return {
256
- display: "flex",
257
- alignItems: "center",
258
- gap: spacingValue,
259
- };
260
- }
261
- };
262
- const getDotPosition = (index) => {
263
- if (arrangement === "circular") {
264
- const angle = (index / count) * 2 * Math.PI;
265
- const radius = parseInt(spacingValue);
266
- return {
267
- position: "absolute",
268
- left: "50%",
269
- top: "50%",
270
- transform: `translate(-50%, -50%) translate(${Math.cos(angle) * radius}px, ${Math.sin(angle) * radius}px)`,
271
- };
272
- }
273
- return {};
274
- };
275
- const getDotAnimationDelay = (index) => {
276
- return `${(index * 0.1) / speed}s`;
277
- };
278
- const containerStyle = {
279
- ...getArrangementStyle(),
280
- ...style,
281
- };
282
- return (React.createElement("div", { className: `react-loadly-dot-cluster react-loadly-dot-cluster-${arrangement} ${className}`.trim(), style: containerStyle, "data-testid": dataTestId, ...props }, Array.from({ length: count }, (_, index) => (React.createElement(Dot, { key: index, size: dotSize, color: secondaryColor && index % 2 === 1 ? secondaryColor : color, animation: `react-loadly-${animationType}`, animationDuration: animationDuration, animationDelay: getDotAnimationDelay(index), style: getDotPosition(index), "data-testid": dataTestId ? `${dataTestId}-dot-${index}` : undefined })))));
283
- };
284
-
285
- const LineGroup = ({ count = 5, lineWidth = 4, lineHeight = 35, color = "var(--react-loadly-color)", secondaryColor, spacing = 6, speed = 1, arrangement = "parallel", orientation = "vertical", className = "", style = {}, animationType = "wave", "data-testid": dataTestId, ...props }) => {
286
- const spacingValue = getSizeValue(spacing);
287
- const animationDuration = getAnimationDuration(1000, speed);
288
- const getArrangementStyle = () => {
289
- switch (arrangement) {
290
- case "radial":
291
- return {
292
- display: "flex",
293
- alignItems: "center",
294
- justifyContent: "center",
295
- position: "relative",
296
- width: `${parseInt(getSizeValue(lineHeight)) * 1.5}px`,
297
- height: `${parseInt(getSizeValue(lineHeight)) * 1.5}px`,
298
- };
299
- case "staggered":
300
- return {
301
- display: "flex",
302
- alignItems: "flex-end",
303
- justifyContent: "center",
304
- gap: spacingValue,
305
- };
306
- default: // parallel
307
- return {
308
- display: "flex",
309
- alignItems: "center",
310
- justifyContent: "center",
311
- gap: spacingValue,
312
- };
313
- }
314
- };
315
- const getLinePosition = (index) => {
316
- if (arrangement === "radial") {
317
- const angle = (index / count) * 2 * Math.PI;
318
- return {
319
- position: "absolute",
320
- left: "50%",
321
- top: "50%",
322
- transformOrigin: "center",
323
- transform: `translate(-50%, -50%) rotate(${angle}rad)`,
324
- };
325
- }
326
- if (arrangement === "staggered") {
327
- const heightMultiplier = 0.3 + 0.7 * Math.sin((index / count) * Math.PI);
328
- return {
329
- height: orientation === "vertical" ? `${parseInt(getSizeValue(lineHeight)) * heightMultiplier}px` : getSizeValue(lineHeight),
330
- };
331
- }
332
- return {};
333
- };
334
- const getLineAnimationDelay = (index) => {
335
- return `${(index * 0.1) / speed}s`;
336
- };
337
- const containerStyle = {
338
- ...getArrangementStyle(),
339
- ...style,
340
- };
341
- return (React.createElement("div", { className: `react-loadly-line-group react-loadly-line-group-${arrangement} ${className}`.trim(), style: containerStyle, "data-testid": dataTestId, ...props }, Array.from({ length: count }, (_, index) => (React.createElement(Line, { key: index, width: orientation === "horizontal" ? lineWidth : lineHeight, height: orientation === "horizontal" ? lineHeight : lineWidth, color: secondaryColor && index % 2 === 1 ? secondaryColor : color, orientation: orientation, animation: `react-loadly-${animationType}`, animationDuration: animationDuration, animationDelay: getLineAnimationDelay(index), style: getLinePosition(index), "data-testid": dataTestId ? `${dataTestId}-line-${index}` : undefined })))));
342
- };
343
-
344
- const ShapeGroup = ({ count = 4, shapeSize = 16, color = "var(--react-loadly-color)", secondaryColor, spacing = 8, speed = 1, arrangement = "linear", shapeTypes = ["circle", "rectangle"], className = "", style = {}, animationType = "pulse", borderWidth = 0, "data-testid": dataTestId, ...props }) => {
345
- const spacingValue = getSizeValue(spacing);
346
- const animationDuration = getAnimationDuration(800, speed);
347
- const getArrangementStyle = () => {
348
- switch (arrangement) {
349
- case "circular":
350
- return {
351
- display: "flex",
352
- alignItems: "center",
353
- justifyContent: "center",
354
- position: "relative",
355
- width: `${(parseInt(getSizeValue(shapeSize)) + parseInt(spacingValue)) * 2.5}px`,
356
- height: `${(parseInt(getSizeValue(shapeSize)) + parseInt(spacingValue)) * 2.5}px`,
357
- };
358
- case "spiral":
359
- return {
360
- display: "flex",
361
- alignItems: "center",
362
- justifyContent: "center",
363
- position: "relative",
364
- width: `${(parseInt(getSizeValue(shapeSize)) + parseInt(spacingValue)) * 3}px`,
365
- height: `${(parseInt(getSizeValue(shapeSize)) + parseInt(spacingValue)) * 3}px`,
366
- };
367
- default: // linear
368
- return {
369
- display: "flex",
370
- alignItems: "center",
371
- gap: spacingValue,
372
- };
373
- }
374
- };
375
- const getShapePosition = (index) => {
376
- if (arrangement === "circular") {
377
- const angle = (index / count) * 2 * Math.PI;
378
- const radius = parseInt(spacingValue) * 2;
379
- return {
380
- position: "absolute",
381
- left: "50%",
382
- top: "50%",
383
- transform: `translate(-50%, -50%) translate(${Math.cos(angle) * radius}px, ${Math.sin(angle) * radius}px)`,
384
- };
385
- }
386
- if (arrangement === "spiral") {
387
- const angle = (index / count) * 4 * Math.PI;
388
- const radius = ((index + 1) * parseInt(spacingValue)) / 2;
389
- return {
390
- position: "absolute",
391
- left: "50%",
392
- top: "50%",
393
- transform: `translate(-50%, -50%) translate(${Math.cos(angle) * radius}px, ${Math.sin(angle) * radius}px)`,
394
- };
395
- }
396
- return {};
397
- };
398
- const getShapeAnimationDelay = (index) => {
399
- return `${(index * 0.15) / speed}s`;
400
- };
401
- const getShapeType = (index) => {
402
- return shapeTypes[index % shapeTypes.length];
403
- };
404
- const containerStyle = {
405
- ...getArrangementStyle(),
406
- ...style,
407
- };
408
- const renderShape = (index) => {
409
- const shapeType = getShapeType(index);
410
- const shapeColor = secondaryColor && index % 2 === 1 ? secondaryColor : color;
411
- const commonProps = {
412
- key: index,
413
- color: borderWidth > 0 ? undefined : shapeColor,
414
- borderColor: borderWidth > 0 ? shapeColor : undefined,
415
- borderWidth: borderWidth > 0 ? borderWidth : undefined,
416
- animation: `react-loadly-${animationType}`,
417
- animationDuration,
418
- animationDelay: getShapeAnimationDelay(index),
419
- style: getShapePosition(index),
420
- "data-testid": dataTestId ? `${dataTestId}-shape-${index}` : undefined,
421
- };
422
- if (shapeType === "circle") {
423
- return React.createElement(Circle, { ...commonProps, size: shapeSize });
424
- }
425
- else {
426
- return React.createElement(Rectangle, { ...commonProps, width: shapeSize, height: shapeSize });
427
- }
428
- };
429
- return (React.createElement("div", { className: `react-loadly-shape-group react-loadly-shape-group-${arrangement} ${className}`.trim(), style: containerStyle, "data-testid": dataTestId, ...props }, Array.from({ length: count }, (_, index) => renderShape(index))));
430
- };
431
-
432
- const defaultProps$e = {
433
- size: 20,
434
- color: "var(--react-loadly-color)",
435
- speed: 1,
436
- loading: true,
437
- count: 5,
438
- "aria-label": "Loading...",
439
- };
440
- const BarsLoader = (userProps) => {
441
- const props = mergeProps(defaultProps$e, userProps);
442
- const { size, color, speed, loading, className = "", style = {}, count = 5, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
443
- const id = useMemo(() => generateId("bars-loader"), []);
444
- const sizeValue = getSizeValue(size);
445
- const animationSettings = getOptimizedAnimationSettings(speed);
446
- if (!loading)
447
- return null;
448
- const containerStyle = {
449
- display: "inline-flex",
450
- flexDirection: "column",
451
- alignItems: "center",
452
- ...style,
453
- ...(fullscreen && {
454
- position: "fixed",
455
- top: 0,
456
- left: 0,
457
- width: screenWidth || "100vw",
458
- height: screenHeight || "100vh",
459
- backgroundColor: screenBackground || "var(--react-loadly-background)",
460
- zIndex: 9999,
461
- justifyContent: loaderCenter ? "center" : style.justifyContent,
462
- }),
463
- };
464
- const barsContainerStyle = {
465
- display: "flex",
466
- justifyContent: "center",
467
- alignItems: "center",
468
- gap: "4px",
469
- };
470
- const barStyle = {
471
- width: "4px",
472
- height: sizeValue,
473
- backgroundColor: color,
474
- borderRadius: "2px",
475
- animation: `react-loadly-bars ${animationSettings.duration} ease-in-out infinite`,
476
- animationPlayState: animationSettings.playState,
477
- };
478
- // Create bars with different animation delays
479
- const bars = Array.from({ length: count }).map((_, index) => {
480
- const delay = `${index * 0.1}s`;
481
- const heightFactor = 0.5 + (index % 3) * 0.25; // Vary heights for visual interest
482
- return (React.createElement("div", { key: index, style: {
483
- ...barStyle,
484
- animationDelay: delay,
485
- height: `${parseFloat(sizeValue) * heightFactor}px`,
486
- }, "data-testid": dataTestId ? `${dataTestId}-bar-${index}` : undefined }));
487
- });
488
- return (React.createElement("div", { className: `react-loadly react-loadly-bars ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
489
- React.createElement("div", { style: barsContainerStyle }, bars),
490
- showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
491
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
492
- };
493
-
494
- const defaultProps$d = {
495
- size: 60,
496
- color: "var(--react-loadly-color)",
497
- speed: 1,
498
- loading: true,
499
- fluidity: 1,
500
- amplitude: 1,
501
- "aria-label": "Loading...",
502
- };
503
- const BlobLoader = (userProps) => {
504
- const props = mergeProps(defaultProps$d, userProps);
505
- const { size, color, secondaryColor, speed, loading, fluidity, amplitude, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
506
- const id = useMemo(() => generateId("blob-loader"), []);
507
- const sizeValue = getSizeValue(size);
508
- const animationDuration = getAnimationDuration(2500, speed);
509
- if (!loading)
510
- return null;
511
- const containerStyle = {
512
- display: "inline-flex",
513
- flexDirection: "column",
514
- alignItems: "center",
515
- ...style,
516
- };
517
- const blobStyle = {
518
- width: sizeValue,
519
- height: sizeValue,
520
- background: `linear-gradient(45deg, ${color}, ${secondaryColor || color})`,
521
- borderRadius: "30% 70% 70% 30% / 30% 30% 70% 70%",
522
- animation: `blob-morph ${animationDuration} ease-in-out infinite`,
523
- filter: "blur(1px)",
524
- position: "relative",
525
- };
526
- const innerBlobStyle = {
527
- position: "absolute",
528
- top: "20%",
529
- left: "20%",
530
- width: "60%",
531
- height: "60%",
532
- background: `radial-gradient(circle, ${secondaryColor || color}, transparent)`,
533
- borderRadius: "40% 60% 60% 40% / 40% 40% 60% 60%",
534
- animation: `blob-inner ${animationDuration} ease-in-out infinite reverse`,
535
- opacity: 0.7,
536
- };
537
- return (React.createElement(React.Fragment, null,
538
- React.createElement("style", null, `
539
- @keyframes blob-morph {
540
- 0%, 100% {
541
- border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
542
- transform: scale(1) rotate(0deg);
543
- }
544
- 25% {
545
- border-radius: 58% 42% 75% 25% / 76% 46% 54% 24%;
546
- transform: scale(${1 + (amplitude ?? 1) * 0.1}) rotate(90deg);
547
- }
548
- 50% {
549
- border-radius: 50% 50% 33% 67% / 55% 27% 73% 45%;
550
- transform: scale(${1 - (amplitude ?? 1) * 0.05}) rotate(180deg);
551
- }
552
- 75% {
553
- border-radius: 33% 67% 58% 42% / 63% 68% 32% 37%;
554
- transform: scale(${1 + (amplitude ?? 1) * 0.08}) rotate(270deg);
555
- }
556
- }
557
-
558
- @keyframes blob-inner {
559
- 0%, 100% {
560
- border-radius: 40% 60% 60% 40% / 40% 40% 60% 60%;
561
- transform: scale(1) rotate(0deg);
562
- }
563
- 33% {
564
- border-radius: 70% 30% 50% 50% / 30% 70% 30% 70%;
565
- transform: scale(${1.1 + (fluidity ?? 1) * 0.1}) rotate(-120deg);
566
- }
567
- 66% {
568
- border-radius: 30% 70% 40% 60% / 70% 30% 70% 30%;
569
- transform: scale(${0.9 + (fluidity ?? 1) * 0.05}) rotate(-240deg);
570
- }
571
- }
572
- `),
573
- React.createElement("div", { className: `react-loadly react-loadly-blob ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
574
- React.createElement("div", { style: blobStyle, "data-testid": dataTestId ? `${dataTestId}-blob` : undefined },
575
- React.createElement("div", { style: innerBlobStyle })),
576
- showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
577
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel))));
578
- };
579
-
580
- const defaultProps$c = {
581
- size: 15,
582
- color: "var(--react-loadly-color)",
583
- speed: 1,
584
- loading: true,
585
- count: 3,
586
- "aria-label": "Loading...",
587
- };
588
- const BounceLoader = (userProps) => {
589
- const props = mergeProps(defaultProps$c, userProps);
590
- const { size, color, speed, loading, className = "", style = {}, count = 3, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
591
- const id = useMemo(() => generateId("bounce-loader"), []);
592
- const sizeValue = getSizeValue(size);
593
- const animationSettings = getOptimizedAnimationSettings(speed);
594
- if (!loading)
595
- return null;
596
- const containerStyle = {
597
- display: "inline-flex",
598
- flexDirection: "column",
599
- alignItems: "center",
600
- ...style,
601
- ...(fullscreen && {
602
- position: "fixed",
603
- top: 0,
604
- left: 0,
605
- width: screenWidth || "100vw",
606
- height: screenHeight || "100vh",
607
- backgroundColor: screenBackground || "var(--react-loadly-background)",
608
- zIndex: 9999,
609
- justifyContent: loaderCenter ? "center" : style.justifyContent,
610
- }),
611
- };
612
- const bounceContainerStyle = {
613
- display: "flex",
614
- justifyContent: "center",
615
- alignItems: "center",
616
- gap: "8px",
617
- };
618
- const bounceBallStyle = {
619
- width: sizeValue,
620
- height: sizeValue,
621
- borderRadius: "50%",
622
- backgroundColor: color,
623
- animation: `react-loadly-bounce ${animationSettings.duration} ease-in-out infinite`,
624
- animationPlayState: animationSettings.playState,
625
- };
626
- // Create bounce animation delays for each ball
627
- const balls = Array.from({ length: count }).map((_, index) => {
628
- const delay = `${index * 0.1}s`;
629
- return (React.createElement("div", { key: index, style: {
630
- ...bounceBallStyle,
631
- animationDelay: delay,
632
- }, "data-testid": dataTestId ? `${dataTestId}-ball-${index}` : undefined }));
633
- });
634
- return (React.createElement("div", { className: `react-loadly react-loadly-bounce ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
635
- React.createElement("div", { style: bounceContainerStyle }, balls),
636
- showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
637
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
638
- };
639
-
640
- const defaultProps$b = {
641
- size: 12,
642
- color: "var(--react-loadly-color)",
643
- speed: 1,
644
- loading: true,
645
- count: 3,
646
- "aria-label": "Loading...",
647
- };
648
- const DotsLoader = (userProps) => {
649
- const props = mergeProps(defaultProps$b, userProps);
650
- const { size, color, speed, loading, className = "", style = {}, count = 3, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
651
- const id = useMemo(() => generateId("dots-loader"), []);
652
- const sizeValue = getSizeValue(size);
653
- const animationSettings = getOptimizedAnimationSettings(speed);
654
- if (!loading)
655
- return null;
656
- const containerStyle = {
657
- display: "inline-flex",
658
- flexDirection: "column",
659
- alignItems: "center",
660
- ...style,
661
- ...(fullscreen && {
662
- position: "fixed",
663
- top: 0,
664
- left: 0,
665
- width: screenWidth || "100vw",
666
- height: screenHeight || "100vh",
667
- backgroundColor: screenBackground || "var(--react-loadly-background)",
668
- zIndex: 9999,
669
- justifyContent: loaderCenter ? "center" : style.justifyContent,
670
- }),
671
- };
672
- const dotsContainerStyle = {
673
- display: "flex",
674
- justifyContent: "center",
675
- alignItems: "center",
676
- gap: "6px",
677
- };
678
- const dotStyle = {
679
- width: sizeValue,
680
- height: sizeValue,
681
- borderRadius: "50%",
682
- backgroundColor: color,
683
- animation: `react-loadly-dots ${animationSettings.duration} ease-in-out infinite`,
684
- animationPlayState: animationSettings.playState,
685
- };
686
- // Create dots with different animation delays
687
- const dots = Array.from({ length: count }).map((_, index) => {
688
- const delay = `${index * 0.2}s`;
689
- return (React.createElement("div", { key: index, style: {
690
- ...dotStyle,
691
- animationDelay: delay,
692
- }, "data-testid": dataTestId ? `${dataTestId}-dot-${index}` : undefined }));
693
- });
694
- return (React.createElement("div", { className: `react-loadly react-loadly-dots ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
695
- React.createElement("div", { style: dotsContainerStyle }, dots),
696
- showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
697
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
698
- };
699
-
700
- const defaultProps$a = {
701
- size: 60,
702
- speed: 1,
703
- loading: true,
704
- animationType: "spin",
705
- glowIntensity: 0.3,
706
- "aria-label": "Loading...",
707
- };
708
- const ElementLoader = (userProps) => {
709
- const props = mergeProps(defaultProps$a, userProps);
710
- const { size, width, height, speed = 1, loading, animationType, glowIntensity, className = "", style = {}, color = "var(--react-loadly-color)", "aria-label": ariaLabel, loadingText, showText, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, children, ...restProps } = props;
711
- if (!loading)
712
- return null;
713
- const containerStyle = {
714
- display: "inline-flex",
715
- flexDirection: "column",
716
- alignItems: "center",
717
- ...style,
718
- ...(fullscreen && {
719
- position: "fixed",
720
- top: 0,
721
- left: 0,
722
- width: screenWidth || "100vw",
723
- height: screenHeight || "100vh",
724
- backgroundColor: screenBackground || "var(--react-loadly-background)",
725
- zIndex: 9999,
726
- justifyContent: loaderCenter ? "center" : style.justifyContent,
727
- }),
728
- };
729
- // Enhanced animation variants for ElementLoader
730
- const getAnimation = () => {
731
- switch (animationType) {
732
- case "pulse":
733
- return `react-loadly-pulse ${getAnimationDuration(2000, speed)} infinite`;
734
- case "glow":
735
- return `react-loadly-glow ${getAnimationDuration(2000, speed)} infinite`;
736
- case "bounce":
737
- return `react-loadly-bounce ${getAnimationDuration(2000, speed)} infinite`;
738
- case "flip":
739
- return `react-loadly-flip ${getAnimationDuration(2000, speed)} infinite`;
740
- case "spin":
741
- default:
742
- return `react-loadly-spin ${getAnimationDuration(2000, speed)} infinite`;
743
- }
744
- };
745
- // Calculate dimensions, prioritizing width/height props over size
746
- const elementWidth = width || size;
747
- const elementHeight = height || size;
748
- const elementStyle = {
749
- width: typeof elementWidth === "number" ? `${elementWidth}px` : elementWidth,
750
- height: typeof elementHeight === "number" ? `${elementHeight}px` : elementHeight,
751
- animation: getAnimation(),
752
- filter: (glowIntensity ?? 0) > 0 ? `drop-shadow(0 0 ${(glowIntensity ?? 0) * 20}px ${color})` : undefined,
753
- transformStyle: "preserve-3d",
754
- willChange: "transform",
755
- display: "flex",
756
- alignItems: "center",
757
- justifyContent: "center",
758
- };
759
- // Add additional animated elements for enhanced visual effect
760
- const innerElementStyle = {
761
- position: "absolute",
762
- top: "50%",
763
- left: "50%",
764
- width: "60%",
765
- height: "60%",
766
- borderRadius: "50%",
767
- backgroundColor: color,
768
- opacity: 0.3,
769
- transform: "translate(-50%, -50%)",
770
- animation: `react-loadly-pulse ${getAnimationDuration(1500, speed * 1.5)} infinite`,
771
- zIndex: -1,
772
- };
773
- const outerElementStyle = {
774
- position: "absolute",
775
- top: "50%",
776
- left: "50%",
777
- width: "120%",
778
- height: "120%",
779
- borderRadius: "50%",
780
- border: `2px solid ${color}`,
781
- opacity: 0.2,
782
- transform: "translate(-50%, -50%)",
783
- animation: `react-loadly-spin ${getAnimationDuration(3000, speed * 0.8)} infinite reverse`,
784
- zIndex: -2,
785
- };
786
- return (React.createElement("div", { className: `react-loadly react-loadly-element-loader ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
787
- React.createElement("div", { style: { position: "relative", display: "flex", alignItems: "center", justifyContent: "center" } },
788
- React.createElement("div", { style: outerElementStyle }),
789
- React.createElement("div", { style: innerElementStyle }),
790
- React.createElement("div", { style: elementStyle, className: "react-loadly-element", "data-testid": dataTestId ? `${dataTestId}-element` : undefined }, children)),
791
- showText && (React.createElement("div", { className: "react-loadly-text", "aria-live": "polite" }, loadingText || ariaLabel)),
792
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
793
- };
794
-
795
- const ErrorIcon = ({ className = "" }) => (React.createElement("svg", { className: className, fill: "currentColor", viewBox: "0 0 20 20", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" },
796
- React.createElement("path", { clipRule: "evenodd", fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z" })));
797
- const NetworkIcon = ({ className = "" }) => (React.createElement("svg", { className: className, fill: "currentColor", viewBox: "0 0 20 20", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" },
798
- React.createElement("path", { fillRule: "evenodd", d: "M9.243 3.03a1 1 0 01.727 1.213L9.53 6h2.94l.56-2.243a1 1 0 111.94.486L14.53 6H16a1 1 0 110 2h-1.97l-1 4H15a1 1 0 110 2h-2.47l-.56 2.242a1 1 0 11-1.94-.485L10.47 14H7.53l-.56 2.242a1 1 0 11-1.94-.485L5.47 14H4a1 1 0 110-2h1.97l1-4H5a1 1 0 110-2h2.47l.56-2.243a1 1 0 011.213-.727zM9.03 8l-1 4h2.94l1-4H9.03z", clipRule: "evenodd" })));
799
- const TimeoutIcon = ({ className = "" }) => (React.createElement("svg", { className: className, fill: "currentColor", viewBox: "0 0 20 20", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" },
800
- React.createElement("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z", clipRule: "evenodd" })));
801
- const FallbackLoader = ({ error = "Something went wrong", onRetry, showRetry = true, children, type = "error", className = "", style = {}, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps }) => {
802
- const getIcon = () => {
803
- switch (type) {
804
- case "network":
805
- return React.createElement(NetworkIcon, { className: "react-loadly-error-icon" });
806
- case "timeout":
807
- return React.createElement(TimeoutIcon, { className: "react-loadly-error-icon" });
808
- default:
809
- return React.createElement(ErrorIcon, { className: "react-loadly-error-icon" });
810
- }
811
- };
812
- const getMessage = () => {
813
- switch (type) {
814
- case "network":
815
- return error || "Network connection failed. Please check your internet connection.";
816
- case "timeout":
817
- return error || "Loading timeout. The operation took too long to complete.";
818
- default:
819
- return error || "Something went wrong. Please try again.";
820
- }
821
- };
822
- const containerStyle = {
823
- ...style,
824
- ...(fullscreen && {
825
- position: "fixed",
826
- top: 0,
827
- left: 0,
828
- width: screenWidth || "100vw",
829
- height: screenHeight || "100vh",
830
- backgroundColor: screenBackground || "var(--react-loadly-error-background)",
831
- zIndex: 9999,
832
- display: "flex",
833
- flexDirection: "column",
834
- alignItems: "center",
835
- justifyContent: loaderCenter ? "center" : style.justifyContent,
836
- }),
837
- };
838
- if (children) {
839
- return React.createElement("div", { className: `react-loadly-fallback ${className}`.trim(), style: containerStyle, ...restProps }, children);
840
- }
841
- return (React.createElement("div", { className: `react-loadly-error ${className}`.trim(), style: containerStyle, role: "alert", "aria-live": "polite", ...restProps },
842
- getIcon(),
843
- React.createElement("p", { className: "react-loadly-error-message" }, getMessage()),
844
- showRetry && onRetry && (React.createElement("button", { className: "react-loadly-retry-button", onClick: onRetry, type: "button", "aria-label": "Retry loading" }, "Try Again"))));
845
- };
846
-
847
- const defaultProps$9 = {
848
- size: 60,
849
- color: "var(--react-loadly-color)",
850
- speed: 1,
851
- loading: true,
852
- fluidity: 1,
853
- amplitude: 1,
854
- "aria-label": "Loading...",
855
- };
856
- const FlowLoader = (userProps) => {
857
- const props = mergeProps(defaultProps$9, userProps);
858
- const { size, color, secondaryColor, speed, loading, amplitude, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
859
- const id = useMemo(() => generateId("flow-loader"), []);
860
- const sizeValue = getSizeValue(size);
861
- const numericSize = parseInt(sizeValue);
862
- const containerHeight = Math.max(numericSize * 0.4, 10); // Minimum height of 10px
863
- const animationDuration = getAnimationDuration(1500, speed);
864
- if (!loading)
865
- return null;
866
- const containerStyle = {
867
- display: "inline-flex",
868
- flexDirection: "column",
869
- alignItems: "center",
870
- ...style,
871
- ...(fullscreen && {
872
- position: "fixed",
873
- top: 0,
874
- left: 0,
875
- width: screenWidth || "100vw",
876
- height: screenHeight || "100vh",
877
- backgroundColor: screenBackground || "var(--react-loadly-background)",
878
- zIndex: 9999,
879
- justifyContent: loaderCenter ? "center" : style.justifyContent,
880
- }),
881
- };
882
- const flowContainerStyle = {
883
- width: sizeValue,
884
- height: `${containerHeight}px`,
885
- position: "relative",
886
- overflow: "hidden",
887
- borderRadius: `${Math.max(numericSize * 0.2, 4)}px`, // Minimum radius of 4px
888
- backgroundColor: "rgba(0, 0, 0, 0.1)",
889
- };
890
- // Ensure minimum particle count even for small sizes
891
- const particleCount = Math.max(Math.floor(numericSize / 15), 3);
892
- const createParticle = (index) => {
893
- const delay = (index * 0.2) / (speed ?? 1);
894
- const duration = parseFloat(animationDuration) + index * 100;
895
- // Scale particle size based on container size
896
- const minParticleSize = Math.max(numericSize / 10, 4); // Minimum 4px
897
- const particleSize = minParticleSize + (index % 3) * (minParticleSize / 2);
898
- return (React.createElement("div", { key: index, style: {
899
- position: "absolute",
900
- width: `${particleSize}px`,
901
- height: `${particleSize}px`,
902
- borderRadius: "50%",
903
- background: index % 2 === 0 ? color : secondaryColor || color,
904
- animation: `flow-particle-${id} ${duration}ms ease-in-out infinite`,
905
- animationDelay: `${delay}s`,
906
- opacity: 0.8 - index * 0.1,
907
- left: "0px", // Start at the beginning of the container
908
- top: `${(containerHeight - particleSize) / 2 + (index % 3) * (containerHeight / (particleCount + 1))}px`, // Distribute vertically
909
- }, "data-testid": dataTestId ? `${dataTestId}-particle-${index}` : undefined }));
910
- };
911
- return (React.createElement(React.Fragment, null,
912
- React.createElement("style", null, `
913
- @keyframes flow-particle-${id} {
914
- 0% {
915
- transform: translateX(0) translateY(0) scale(0);
916
- opacity: 0;
917
- }
918
- 10% {
919
- transform: translateX(${Math.min(numericSize * 0.1, 10)}px) translateY(${Math.sin(0.1) * (amplitude ?? Math.min(5, containerHeight / 4))}px) scale(1);
920
- opacity: 0.8;
921
- }
922
- 50% {
923
- transform: translateX(${Math.min(numericSize * 0.5, numericSize * 0.7)}px) translateY(${Math.sin(0.5) * (amplitude ?? Math.min(5, containerHeight / 4))}px) scale(1);
924
- opacity: 0.8;
925
- }
926
- 90% {
927
- transform: translateX(${Math.min(numericSize * 0.9, numericSize - 10)}px) translateY(${Math.sin(0.9) * (amplitude ?? Math.min(5, containerHeight / 4))}px) scale(1);
928
- opacity: 0.8;
929
- }
930
- 100% {
931
- transform: translateX(${numericSize}px) translateY(${Math.sin(1) * (amplitude ?? Math.min(5, containerHeight / 4))}px) scale(0);
932
- opacity: 0;
933
- }
934
- }
935
- `),
936
- React.createElement("div", { className: `react-loadly react-loadly-flow ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
937
- React.createElement("div", { style: flowContainerStyle, "data-testid": dataTestId ? `${dataTestId}-container` : undefined }, Array.from({ length: particleCount }, (_, index) => createParticle(index))),
938
- showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
939
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel))));
940
- };
941
-
942
- const defaultProps$8 = {
943
- size: 40,
944
- color: "var(--react-loadly-color)",
945
- speed: 1,
946
- loading: true,
947
- count: 4,
948
- "aria-label": "Loading...",
949
- };
950
- const GridLoader = (userProps) => {
951
- const props = mergeProps(defaultProps$8, userProps);
952
- const { size, color, secondaryColor, speed = 1, loading, count, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
953
- const id = useMemo(() => generateId("grid-loader"), []);
954
- const shapeSize = useMemo(() => {
955
- const sizeNum = typeof size === "number" ? size : parseInt(getSizeValue(size));
956
- const gridSize = Math.ceil(Math.sqrt(count || 4));
957
- return Math.max(sizeNum / (gridSize * 1.5), 8);
958
- }, [size, count]);
959
- if (!loading)
960
- return null;
961
- const containerStyle = {
962
- display: "inline-flex",
963
- flexDirection: "column",
964
- alignItems: "center",
965
- ...style,
966
- ...(fullscreen && {
967
- position: "fixed",
968
- top: 0,
969
- left: 0,
970
- width: screenWidth || "100vw",
971
- height: screenHeight || "100vh",
972
- backgroundColor: screenBackground || "var(--react-loadly-background)",
973
- zIndex: 9999,
974
- justifyContent: loaderCenter ? "center" : style.justifyContent,
975
- }),
976
- };
977
- return (React.createElement("div", { className: `react-loadly react-loadly-grid ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
978
- React.createElement("div", { className: "react-loadly-grid-container", style: {
979
- display: "grid",
980
- gridTemplateColumns: `repeat(${Math.ceil(Math.sqrt(count || 4))}, 1fr)`,
981
- gap: `${shapeSize / 3}px`,
982
- }, "data-testid": dataTestId ? `${dataTestId}-grid` : undefined }, Array.from({ length: count || 4 }).map((_, index) => (React.createElement("div", { key: index, className: "react-loadly-grid-item", style: {
983
- width: `${shapeSize}px`,
984
- height: `${shapeSize}px`,
985
- backgroundColor: index % 2 === 0 ? color : secondaryColor || color,
986
- borderRadius: "20%",
987
- animation: `react-loadly-scale ${1.2 / (speed || 1)}s ease-in-out infinite`,
988
- animationDelay: `${(index * 0.1) / (speed || 1)}s`,
989
- } })))),
990
- showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
991
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
992
- };
993
-
994
- const defaultProps$7 = {
995
- size: 60,
996
- color: "var(--react-loadly-color)",
997
- speed: 1,
998
- loading: true,
999
- fluidity: 1,
1000
- amplitude: 1,
1001
- "aria-label": "Loading...",
1002
- };
1003
- const LiquidLoader = (userProps) => {
1004
- const props = mergeProps(defaultProps$7, userProps);
1005
- const { size, color, secondaryColor, speed, loading, amplitude, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
1006
- const id = useMemo(() => generateId("liquid-loader"), []);
1007
- const sizeValue = getSizeValue(size);
1008
- const animationDuration = getAnimationDuration(2000, speed);
1009
- if (!loading)
1010
- return null;
1011
- const containerStyle = {
1012
- display: "inline-flex",
1013
- flexDirection: "column",
1014
- alignItems: "center",
1015
- ...style,
1016
- ...(fullscreen && {
1017
- position: "fixed",
1018
- top: 0,
1019
- left: 0,
1020
- width: screenWidth || "100vw",
1021
- height: screenHeight || "100vh",
1022
- backgroundColor: screenBackground || "var(--react-loadly-background)",
1023
- zIndex: 9999,
1024
- justifyContent: loaderCenter ? "center" : style.justifyContent,
1025
- }),
1026
- };
1027
- const liquidStyle = {
1028
- width: sizeValue,
1029
- height: sizeValue,
1030
- position: "relative",
1031
- overflow: "hidden",
1032
- borderRadius: "50%",
1033
- backgroundColor: "rgba(0, 0, 0, 0.1)",
1034
- };
1035
- // Calculate the translateY value based on amplitude
1036
- const translateY = 50 - (amplitude ?? 1) * 10;
1037
- const waveStyle = {
1038
- position: "absolute",
1039
- bottom: 0,
1040
- left: 0,
1041
- width: "200%",
1042
- height: "200%",
1043
- background: `linear-gradient(180deg, ${color} 0%, ${secondaryColor || color} 100%)`,
1044
- borderRadius: "40%",
1045
- animation: `react-loadly-liquid-wave ${animationDuration} ease-in-out infinite`,
1046
- transform: "translate(-25%, 50%) rotate(0deg)",
1047
- animationTimingFunction: `cubic-bezier(0.36, 0.45, 0.63, 0.53)`,
1048
- };
1049
- const wave2Style = {
1050
- ...waveStyle,
1051
- background: `linear-gradient(180deg, ${secondaryColor || color} 0%, ${color} 100%)`,
1052
- animation: `react-loadly-liquid-wave ${animationDuration} ease-in-out infinite reverse`,
1053
- animationDelay: `${ -0.5 / (speed ?? 1)}s`,
1054
- opacity: 0.8,
1055
- };
1056
- return (React.createElement(React.Fragment, null,
1057
- React.createElement("style", null, `
1058
- @keyframes react-loadly-liquid-wave {
1059
- 0%, 100% {
1060
- transform: translate(-25%, 50%) rotate(0deg);
1061
- }
1062
- 50% {
1063
- transform: translate(-25%, ${translateY}%) rotate(180deg);
1064
- }
1065
- }
1066
- `),
1067
- React.createElement("div", { className: `react-loadly react-loadly-liquid ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1068
- React.createElement("div", { style: liquidStyle, "data-testid": dataTestId ? `${dataTestId}-container` : undefined },
1069
- React.createElement("div", { style: waveStyle }),
1070
- React.createElement("div", { style: wave2Style })),
1071
- showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
1072
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel))));
1073
- };
1074
-
1075
- const defaultProps$6 = {
1076
- size: 60,
1077
- speed: 1,
1078
- loading: true,
1079
- animationType: "spin",
1080
- glowIntensity: 0.3,
1081
- "aria-label": "Loading...",
1082
- alt: "Loading",
1083
- };
1084
- const LogoSpinLoader = (userProps) => {
1085
- const props = mergeProps(defaultProps$6, userProps);
1086
- const { src, alt, size, speed, loading, animationType, glowIntensity, className = "", style = {}, color = "var(--react-loadly-color)", "aria-label": ariaLabel, loadingText, showText, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
1087
- if (!loading)
1088
- return null;
1089
- const containerStyle = {
1090
- display: "inline-flex",
1091
- flexDirection: "column",
1092
- alignItems: "center",
1093
- ...style,
1094
- ...(fullscreen && {
1095
- position: "fixed",
1096
- top: 0,
1097
- left: 0,
1098
- width: screenWidth || "100vw",
1099
- height: screenHeight || "100vh",
1100
- backgroundColor: screenBackground || "var(--react-loadly-background)",
1101
- zIndex: 9999,
1102
- justifyContent: loaderCenter ? "center" : style.justifyContent,
1103
- }),
1104
- };
1105
- const logoStyle = {
1106
- width: typeof size === "number" ? `${size}px` : size,
1107
- height: typeof size === "number" ? `${size}px` : size,
1108
- animation: `react-loadly-${animationType} ${getAnimationDuration(2000, speed)} infinite`,
1109
- filter: (glowIntensity ?? 0) > 0 ? `drop-shadow(0 0 ${(glowIntensity ?? 0) * 20}px ${color})` : undefined,
1110
- };
1111
- return (React.createElement("div", { className: `react-loadly react-loadly-logo-spin ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1112
- React.createElement("img", { src: src, alt: alt, style: logoStyle, className: "react-loadly-logo", "data-testid": dataTestId ? `${dataTestId}-logo` : undefined }),
1113
- showText && (React.createElement("div", { className: "react-loadly-text", "aria-live": "polite" }, loadingText || ariaLabel)),
1114
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
1115
- };
1116
-
1117
- const defaultProps$5 = {
1118
- size: 40,
1119
- color: "var(--react-loadly-color)",
1120
- speed: 1,
1121
- loading: true,
1122
- count: 3,
1123
- "aria-label": "Loading...",
1124
- };
1125
- const PulseLoader = (userProps) => {
1126
- const props = mergeProps(defaultProps$5, userProps);
1127
- const { size, color, secondaryColor, speed, loading, count, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
1128
- const id = useMemo(() => generateId("pulse-loader"), []);
1129
- const dotSize = useMemo(() => {
1130
- const sizeNum = typeof size === "number" ? size : parseInt(getSizeValue(size));
1131
- return Math.max(sizeNum / 5, 6); // Ensure minimum dot size
1132
- }, [size]);
1133
- if (!loading)
1134
- return null;
1135
- const containerStyle = {
1136
- display: "inline-flex",
1137
- flexDirection: "column",
1138
- alignItems: "center",
1139
- ...style,
1140
- ...(fullscreen && {
1141
- position: "fixed",
1142
- top: 0,
1143
- left: 0,
1144
- width: screenWidth || "100vw",
1145
- height: screenHeight || "100vh",
1146
- backgroundColor: screenBackground || "var(--react-loadly-background)",
1147
- zIndex: 9999,
1148
- justifyContent: loaderCenter ? "center" : style.justifyContent,
1149
- }),
1150
- };
1151
- return (React.createElement("div", { className: `react-loadly react-loadly-pulse ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1152
- React.createElement(DotCluster, { count: count, dotSize: dotSize, color: color, secondaryColor: secondaryColor, speed: speed, arrangement: "linear", animationType: "pulse", spacing: dotSize / 2, "data-testid": dataTestId ? `${dataTestId}-dots` : undefined }),
1153
- showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
1154
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
1155
- };
1156
-
1157
- const defaultProps$4 = {
1158
- size: 60,
1159
- color: "var(--react-loadly-color)",
1160
- speed: 1,
1161
- loading: true,
1162
- borderWidth: 4,
1163
- "aria-label": "Loading...",
1164
- };
1165
- const RingLoader = (userProps) => {
1166
- const props = mergeProps(defaultProps$4, userProps);
1167
- const { size, color, speed, loading, className = "", style = {}, borderWidth, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
1168
- // Use useRef instead of useMemo for better compatibility
1169
- const idRef = useRef(generateId("ring-loader"));
1170
- const sizeValue = getSizeValue(size);
1171
- const animationSettings = getOptimizedAnimationSettings(speed);
1172
- // Don't render anything if not loading
1173
- if (!loading)
1174
- return null;
1175
- const containerStyle = {
1176
- display: "inline-flex",
1177
- flexDirection: "column",
1178
- alignItems: "center",
1179
- ...style,
1180
- ...(fullscreen && {
1181
- position: "fixed",
1182
- top: 0,
1183
- left: 0,
1184
- width: screenWidth || "100vw",
1185
- height: screenHeight || "100vh",
1186
- backgroundColor: screenBackground || "var(--react-loadly-background)",
1187
- zIndex: 9999,
1188
- justifyContent: loaderCenter ? "center" : style.justifyContent,
1189
- }),
1190
- };
1191
- const ringStyle = {
1192
- position: "relative",
1193
- width: sizeValue,
1194
- height: sizeValue,
1195
- };
1196
- const ringSegmentStyle = {
1197
- boxSizing: "border-box",
1198
- display: "block",
1199
- position: "absolute",
1200
- width: sizeValue,
1201
- height: sizeValue,
1202
- border: `${borderWidth}px solid transparent`,
1203
- borderTop: `${borderWidth}px solid ${color}`,
1204
- borderBottom: `${borderWidth}px solid ${color}`,
1205
- borderRadius: "50%",
1206
- animation: `react-loadly-ring ${animationSettings.duration} cubic-bezier(0.5, 0, 0.5, 1) infinite`,
1207
- animationPlayState: animationSettings.playState,
1208
- };
1209
- // Create the 4 ring segments with their specific styles
1210
- const segments = Array.from({ length: 4 }).map((_, index) => {
1211
- const rotation = `${index * 90}deg`;
1212
- const delay = `${index * -0.15}s`;
1213
- return (React.createElement("div", { key: index, style: {
1214
- ...ringSegmentStyle,
1215
- transform: `rotate(${rotation})`,
1216
- animationDelay: delay,
1217
- }, "data-testid": dataTestId ? `${dataTestId}-segment-${index}` : undefined }));
1218
- });
1219
- return (React.createElement("div", { className: `react-loadly react-loadly-ring ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1220
- React.createElement("div", { style: ringStyle }, segments),
1221
- showText && (React.createElement("div", { className: "react-loadly-text", id: `${idRef.current}-text`, "aria-live": "polite" }, loadingText)),
1222
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
1223
- };
1224
-
1225
- const defaultProps$3 = {
1226
- size: 15,
1227
- color: "var(--react-loadly-color)",
1228
- speed: 1,
1229
- loading: true,
1230
- count: 2,
1231
- "aria-label": "Loading...",
1232
- };
1233
- const RotateLoader = (userProps) => {
1234
- const props = mergeProps(defaultProps$3, userProps);
1235
- const { size, color, speed, loading, className = "", style = {}, count = 2, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
1236
- const id = useMemo(() => generateId("rotate-loader"), []);
1237
- const sizeValue = getSizeValue(size);
1238
- const animationSettings = getOptimizedAnimationSettings(speed);
1239
- if (!loading)
1240
- return null;
1241
- const containerStyle = {
1242
- display: "inline-flex",
1243
- flexDirection: "column",
1244
- alignItems: "center",
1245
- ...style,
1246
- ...(fullscreen && {
1247
- position: "fixed",
1248
- top: 0,
1249
- left: 0,
1250
- width: screenWidth || "100vw",
1251
- height: screenHeight || "100vh",
1252
- backgroundColor: screenBackground || "var(--react-loadly-background)",
1253
- zIndex: 9999,
1254
- justifyContent: loaderCenter ? "center" : style.justifyContent,
1255
- }),
1256
- };
1257
- const rotateContainerStyle = {
1258
- position: "relative",
1259
- width: sizeValue,
1260
- height: sizeValue,
1261
- };
1262
- const rotateElementStyle = {
1263
- position: "absolute",
1264
- width: sizeValue,
1265
- height: sizeValue,
1266
- border: "2px solid transparent",
1267
- borderTopColor: color,
1268
- borderBottomColor: color,
1269
- borderRadius: "50%",
1270
- animation: `react-loadly-ring ${animationSettings.duration} cubic-bezier(0.5, 0, 0.5, 1) infinite`,
1271
- animationPlayState: animationSettings.playState,
1272
- transform: "rotate(0deg)",
1273
- };
1274
- // Create rotating elements
1275
- const elements = Array.from({ length: count }).map((_, index) => {
1276
- const sizeFactor = 1 - index * 0.2;
1277
- const borderWidth = 2 + index;
1278
- const delay = `${index * -0.15}s`;
1279
- return (React.createElement("div", { key: index, style: {
1280
- ...rotateElementStyle,
1281
- width: `${parseFloat(sizeValue) * sizeFactor}px`,
1282
- height: `${parseFloat(sizeValue) * sizeFactor}px`,
1283
- borderWidth: `${borderWidth}px`,
1284
- animationDuration: `${parseFloat(animationSettings.duration) * (1 + index * 0.5)}ms`,
1285
- animationDelay: delay,
1286
- }, "data-testid": dataTestId ? `${dataTestId}-element-${index}` : undefined }));
1287
- });
1288
- return (React.createElement("div", { className: `react-loadly react-loadly-ring ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1289
- React.createElement("div", { style: rotateContainerStyle }, elements),
1290
- showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
1291
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
1292
- };
1293
-
1294
- const defaultProps$2 = {
1295
- size: 40,
1296
- color: "var(--react-loadly-color)",
1297
- speed: 1,
1298
- loading: true,
1299
- borderWidth: 4,
1300
- "aria-label": "Loading...",
1301
- };
1302
- const SpinLoader = (userProps) => {
1303
- const props = mergeProps(defaultProps$2, userProps);
1304
- const { size, color, speed, loading, className = "", style = {}, borderWidth, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
1305
- // Use useRef instead of useMemo for better compatibility
1306
- const idRef = useRef(generateId("spin-loader"));
1307
- const sizeValue = getSizeValue(size);
1308
- const animationSettings = getOptimizedAnimationSettings(speed);
1309
- if (!loading)
1310
- return null;
1311
- const containerStyle = {
1312
- display: "inline-flex",
1313
- flexDirection: "column",
1314
- alignItems: "center",
1315
- ...style,
1316
- ...(fullscreen && {
1317
- position: "fixed",
1318
- top: 0,
1319
- left: 0,
1320
- width: screenWidth || "100vw",
1321
- height: screenHeight || "100vh",
1322
- backgroundColor: screenBackground || "var(--react-loadly-background)",
1323
- zIndex: 9999,
1324
- justifyContent: loaderCenter ? "center" : style.justifyContent,
1325
- }),
1326
- };
1327
- const spinnerStyle = {
1328
- width: sizeValue,
1329
- height: sizeValue,
1330
- border: `${borderWidth}px solid transparent`,
1331
- borderTop: `${borderWidth}px solid ${color}`,
1332
- borderRadius: "50%",
1333
- animation: `react-loadly-spin ${animationSettings.duration} linear infinite`,
1334
- animationPlayState: animationSettings.playState,
1335
- };
1336
- return (React.createElement("div", { className: `react-loadly react-loadly-spin ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1337
- React.createElement("div", { style: spinnerStyle, "data-testid": dataTestId ? `${dataTestId}-spinner` : undefined }),
1338
- showText && (React.createElement("div", { className: "react-loadly-text", id: `${idRef.current}-text`, "aria-live": "polite" }, loadingText)),
1339
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
1340
- };
1341
-
1342
- const defaultProps$1 = {
1343
- speed: 1,
1344
- loading: true,
1345
- charDelay: 100,
1346
- "aria-label": "Loading...",
1347
- loop: true,
1348
- };
1349
- const TypingLoader = (userProps) => {
1350
- const props = mergeProps(defaultProps$1, userProps);
1351
- const { loadingText, speed = 1, loading, charDelay = 100, loop, className = "", style = {}, color = "var(--react-loadly-text-color)", fontFamily, fontWeight = 500, "aria-label": ariaLabel, "data-testid": dataTestId, showText, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
1352
- const [displayText, setDisplayText] = useState("");
1353
- const [isTyping, setIsTyping] = useState(false);
1354
- const timeoutRef = useRef(null);
1355
- useEffect(() => {
1356
- // Clear any existing timeout
1357
- if (timeoutRef.current) {
1358
- clearTimeout(timeoutRef.current);
1359
- timeoutRef.current = null;
1360
- }
1361
- if (!loading || !loadingText) {
1362
- setDisplayText("");
1363
- return;
1364
- }
1365
- setIsTyping(true);
1366
- setDisplayText("");
1367
- const typeText = (index = 0) => {
1368
- if (index < loadingText.length) {
1369
- setDisplayText(loadingText.substring(0, index + 1));
1370
- timeoutRef.current = setTimeout(() => typeText(index + 1), charDelay / speed);
1371
- }
1372
- else if (loop) {
1373
- // Reset and start over if looping
1374
- timeoutRef.current = setTimeout(() => {
1375
- setDisplayText("");
1376
- typeText(0);
1377
- }, charDelay * 2);
1378
- }
1379
- else {
1380
- setIsTyping(false);
1381
- }
1382
- };
1383
- typeText(0);
1384
- // Cleanup timeouts on unmount or when dependencies change
1385
- return () => {
1386
- if (timeoutRef.current) {
1387
- clearTimeout(timeoutRef.current);
1388
- }
1389
- };
1390
- }, [loading, loadingText, charDelay, speed, loop]);
1391
- if (!loading)
1392
- return null;
1393
- const containerStyle = {
1394
- display: "inline-flex",
1395
- flexDirection: "column",
1396
- alignItems: "center",
1397
- ...style,
1398
- ...(fullscreen && {
1399
- position: "fixed",
1400
- top: 0,
1401
- left: 0,
1402
- width: screenWidth || "100vw",
1403
- height: screenHeight || "100vh",
1404
- backgroundColor: screenBackground || "var(--react-loadly-background)",
1405
- zIndex: 9999,
1406
- justifyContent: loaderCenter ? "center" : style.justifyContent,
1407
- }),
1408
- };
1409
- const textStyle = {
1410
- color,
1411
- fontFamily,
1412
- fontWeight,
1413
- fontSize: "1.2em",
1414
- whiteSpace: "pre",
1415
- };
1416
- return (React.createElement("div", { className: `react-loadly react-loadly-typing ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1417
- React.createElement("div", { style: textStyle, "data-testid": dataTestId ? `${dataTestId}-text` : undefined },
1418
- displayText,
1419
- React.createElement("span", { className: "react-loadly-typing-cursor", style: {
1420
- display: isTyping ? "inline-block" : "none",
1421
- animation: `react-loadly-blink ${1 / speed}s step-end infinite`,
1422
- marginLeft: "2px",
1423
- verticalAlign: "baseline",
1424
- } }, "|")),
1425
- showText && (React.createElement("div", { className: "react-loadly-text", "aria-live": "polite" }, loadingText)),
1426
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
1427
- };
1428
-
1429
- const defaultProps = {
1430
- size: 40,
1431
- color: "var(--react-loadly-color)",
1432
- speed: 1,
1433
- loading: true,
1434
- count: 5,
1435
- "aria-label": "Loading...",
1436
- };
1437
- const WaveLoader = (userProps) => {
1438
- const props = mergeProps(defaultProps, userProps);
1439
- const { size, color, secondaryColor, speed, loading, count, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
1440
- const id = useMemo(() => generateId("wave-loader"), []);
1441
- const lineSpecs = useMemo(() => {
1442
- const sizeNum = typeof size === "number" ? size : parseInt(getSizeValue(size));
1443
- return {
1444
- width: Math.max(sizeNum / 10, 3), // Line thickness
1445
- height: sizeNum, // Line height
1446
- spacing: Math.max(sizeNum / 8, 4), // Spacing between lines
1447
- };
1448
- }, [size]);
1449
- if (!loading)
1450
- return null;
1451
- const containerStyle = {
1452
- display: "inline-flex",
1453
- flexDirection: "column",
1454
- alignItems: "center",
1455
- ...style,
1456
- ...(fullscreen && {
1457
- position: "fixed",
1458
- top: 0,
1459
- left: 0,
1460
- width: screenWidth || "100vw",
1461
- height: screenHeight || "100vh",
1462
- backgroundColor: screenBackground || "var(--react-loadly-background)",
1463
- zIndex: 9999,
1464
- justifyContent: loaderCenter ? "center" : style.justifyContent,
1465
- }),
1466
- };
1467
- return (React.createElement("div", { className: `react-loadly react-loadly-wave ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1468
- React.createElement(LineGroup, { count: count, lineWidth: lineSpecs.width, lineHeight: lineSpecs.height, color: color, secondaryColor: secondaryColor, speed: speed, arrangement: "staggered", orientation: "vertical", animationType: "wave", spacing: lineSpecs.spacing, "data-testid": dataTestId ? `${dataTestId}-lines` : undefined }),
1469
- showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
1470
- React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
1471
- };
1472
-
1473
- /**
1474
- * Custom React hook for managing loader state with advanced features
1475
- * Provides centralized loading state management with timeout, retry, and progress tracking
1476
- *
1477
- * @param options - Configuration options for the loader state
1478
- * @returns Object containing state and methods to control the loader
1479
- */
1480
- const useLoaderState = (options = {}) => {
1481
- const { initialLoading = false, timeout, maxRetries = 3, onLoadingChange, onError, onProgress } = options;
1482
- const [state, setState] = useState({
1483
- isLoading: initialLoading,
1484
- progress: 0,
1485
- error: null,
1486
- retryCount: 0,
1487
- });
1488
- const timeoutRef = useRef(null);
1489
- const retryTimeoutRef = useRef(null);
1490
- // Clear timeouts on unmount
1491
- useEffect(() => {
1492
- return () => {
1493
- if (timeoutRef.current) {
1494
- clearTimeout(timeoutRef.current);
1495
- }
1496
- if (retryTimeoutRef.current) {
1497
- clearTimeout(retryTimeoutRef.current);
1498
- }
1499
- };
1500
- }, []);
1501
- // Handle timeout
1502
- useEffect(() => {
1503
- if (state.isLoading && timeout) {
1504
- timeoutRef.current = setTimeout(() => {
1505
- setState((prev) => ({
1506
- ...prev,
1507
- isLoading: false,
1508
- error: "Loading timeout exceeded",
1509
- }));
1510
- onError?.("Loading timeout exceeded");
1511
- }, timeout);
1512
- }
1513
- else if (timeoutRef.current) {
1514
- clearTimeout(timeoutRef.current);
1515
- }
1516
- return () => {
1517
- if (timeoutRef.current) {
1518
- clearTimeout(timeoutRef.current);
1519
- }
1520
- };
1521
- }, [state.isLoading, timeout, onError]);
1522
- // Call onLoadingChange when loading state changes
1523
- useEffect(() => {
1524
- onLoadingChange?.(state.isLoading);
1525
- }, [state.isLoading, onLoadingChange]);
1526
- // Call onProgress when progress changes
1527
- useEffect(() => {
1528
- if (state.progress !== undefined) {
1529
- onProgress?.(state.progress);
1530
- }
1531
- }, [state.progress, onProgress]);
1532
- const setLoading = useCallback((loading) => {
1533
- setState((prev) => ({
1534
- ...prev,
1535
- isLoading: loading,
1536
- error: loading ? null : prev.error, // Clear error when starting new loading
1537
- progress: loading ? 0 : prev.progress, // Reset progress when starting
1538
- }));
1539
- }, []);
1540
- const setProgress = useCallback((progress) => {
1541
- const clampedProgress = Math.min(Math.max(progress, 0), 100);
1542
- setState((prev) => ({
1543
- ...prev,
1544
- progress: clampedProgress,
1545
- // Auto-complete when progress reaches 100%
1546
- isLoading: clampedProgress >= 100 ? false : prev.isLoading,
1547
- }));
1548
- }, []);
1549
- const setError = useCallback((error) => {
1550
- setState((prev) => ({
1551
- ...prev,
1552
- error,
1553
- isLoading: false,
1554
- }));
1555
- if (error) {
1556
- onError?.(error);
1557
- }
1558
- }, [onError]);
1559
- const retry = useCallback(() => {
1560
- setState((prev) => {
1561
- const newRetryCount = (prev.retryCount || 0) + 1;
1562
- if (newRetryCount > maxRetries) {
1563
- onError?.("Maximum retry attempts exceeded");
1564
- return {
1565
- ...prev,
1566
- error: "Maximum retry attempts exceeded",
1567
- isLoading: false,
1568
- };
1569
- }
1570
- return {
1571
- ...prev,
1572
- retryCount: newRetryCount,
1573
- isLoading: true,
1574
- error: null,
1575
- progress: 0,
1576
- };
1577
- });
1578
- // Add exponential backoff for retries
1579
- const backoffDelay = Math.min(1000 * Math.pow(2, state.retryCount || 0), 30000);
1580
- retryTimeoutRef.current = setTimeout(() => {
1581
- setState((prev) => ({ ...prev, isLoading: true }));
1582
- }, backoffDelay);
1583
- }, [state.retryCount, maxRetries, onError]);
1584
- const reset = useCallback(() => {
1585
- setState({
1586
- isLoading: false,
1587
- progress: 0,
1588
- error: null,
1589
- retryCount: 0,
1590
- });
1591
- if (timeoutRef.current) {
1592
- clearTimeout(timeoutRef.current);
1593
- }
1594
- if (retryTimeoutRef.current) {
1595
- clearTimeout(retryTimeoutRef.current);
1596
- }
1597
- }, []);
1598
- return {
1599
- state,
1600
- setLoading,
1601
- setProgress,
1602
- setError,
1603
- retry,
1604
- reset,
1605
- };
1606
- };
1607
-
1608
- /**
1609
- * Hook for managing multiple loader states with shared options
1610
- * Useful when you need to control multiple loaders with the same configuration
1611
- *
1612
- * @param keys - Array of string keys representing each loader state
1613
- * @param options - Shared configuration options for all loader states
1614
- * @returns Record mapping each key to its corresponding loader state methods
1615
- */
1616
- const useMultipleLoaderStates = (keys, options = {}) => {
1617
- return keys.reduce((acc, key) => {
1618
- // eslint-disable-next-line react-hooks/rules-of-hooks
1619
- acc[key] = useLoaderState(options);
1620
- return acc;
1621
- }, {});
1622
- };
1623
-
1624
- /**
1625
- * Hook for tracking async operations with automatic loading state management
1626
- * Automatically handles loading states during async operations and provides error handling
1627
- *
1628
- * @param asyncFn - Async function to execute and track
1629
- * @param dependencies - Dependency array to trigger re-execution (similar to useEffect)
1630
- * @param options - Configuration options for the loader state
1631
- * @returns Object containing loader state, data result, and execution method
1632
- */
1633
- const useAsyncLoader = (asyncFn, dependencies = [], options = {}) => {
1634
- const loaderState = useLoaderState(options);
1635
- const [data, setData] = useState(null);
1636
- const execute = useCallback(async () => {
1637
- try {
1638
- loaderState.setLoading(true);
1639
- loaderState.setError(null);
1640
- const result = await asyncFn();
1641
- setData(result);
1642
- loaderState.setProgress(100);
1643
- return result;
1644
- }
1645
- catch (error) {
1646
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
1647
- loaderState.setError(errorMessage);
1648
- return null;
1649
- }
1650
- }, [asyncFn, loaderState]);
1651
- // Auto-execute on dependency changes
1652
- useEffect(() => {
1653
- execute();
1654
- }, dependencies);
1655
- return {
1656
- ...loaderState,
1657
- data,
1658
- execute,
1659
- };
1660
- };
1661
-
1662
- export { BarsLoader, BlobLoader, BounceLoader, Circle, Dot, DotCluster, DotsLoader, ElementLoader, FallbackLoader, FlowLoader, GridLoader, Line, LineGroup, LiquidLoader, LogoSpinLoader, PulseLoader, Rectangle, RingLoader, RotateLoader, ShapeGroup, SpinLoader, TypingLoader, WaveLoader, clamp, createAnimationName, generateCSSVariables, generateId, getAnimationDuration, getOptimizedAnimationSettings, getSizeValue, hexToRgb, mergeProps, prefersReducedMotion, rgba, sanitizeCSSValue, useAsyncLoader, useLoaderState, useMultipleLoaderStates };
1
+ import e,{useMemo as t,useRef as a,useState as r,useEffect as i,useCallback as n}from"react";function l(e,t){return{...e,...t}}function o(e,t="40px"){return void 0===e?t:"number"==typeof e?`${e}px`:e}function s(e){const t={};return Object.entries(e).forEach(([e,a])=>{void 0!==a&&(t[e]=a)}),t}function d(e,t=1){return`${e/Math.max(t,.1)}ms`}function c(e){return`react-loadly-${e}`}function u(){if("undefined"==typeof window||!window.matchMedia)return!1;try{return window.matchMedia("(prefers-reduced-motion: reduce)").matches}catch(e){return!1}}function m(e=1,t=!0){if("undefined"!=typeof process&&"test"===process.env.NODE_ENV)return{duration:"0ms",playState:"paused",iterationCount:1};const a=t&&u();return{duration:a?"0ms":d(1e3,e),playState:a?"paused":"running",iterationCount:a?1:"infinite"}}function y(e="normal"){return e}function p(e="ease"){return e}function g(e,t,a="ease",r="normal",i="infinite"){return`${e} ${t} ${a} ${r} ${i}`}function h(e,t,a){return Math.min(Math.max(e,t),a)}function f(e){const t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return t?{r:parseInt(t[1],16),g:parseInt(t[2],16),b:parseInt(t[3],16)}:null}function v(e,t){const a=f(e);return a?`rgba(${a.r}, ${a.g}, ${a.b}, ${h(t,0,1)})`:e}function b(e="loader"){return`${e}-${Math.random().toString(36).substr(2,9)}`}function x(e){if(null!=e)return"number"==typeof e?`${e}px`:"string"==typeof e?e.replace(/[<>'"]/g,""):void 0}function $(...e){return e.flat().filter(e=>"string"==typeof e&&e.trim()).join(" ")}const w=({size:t=8,color:a="var(--react-loadly-color)",opacity:r=1,className:i="",style:n={},animation:l,animationDuration:s,animationDelay:d,glowIntensity:c=0,"data-testid":u,...m})=>{const y=o(t),p={width:y,height:y,borderRadius:"50%",backgroundColor:a,opacity:r,animation:l?`${l} ${s||"1s"} infinite`:void 0,animationDelay:d,display:"inline-block",boxShadow:c>0?`0 0 ${10*c}px ${a}`:void 0,...n};return e.createElement("div",{className:`react-loadly-dot ${i}`.trim(),style:p,"data-testid":u,...m})},E=({width:t=30,height:a=4,color:r="var(--react-loadly-color)",opacity:i=1,borderRadius:n=2,className:l="",style:s={},animation:d,animationDuration:c,animationDelay:u,orientation:m="horizontal","data-testid":y,...p})=>{const g=o(t),h=o(a),f={width:"vertical"===m?h:g,height:"vertical"===m?g:h,backgroundColor:r,opacity:i,borderRadius:x(n),animation:d?`${d} ${c||"1s"} infinite`:void 0,animationDelay:u,display:"inline-block",...s};return e.createElement("div",{className:`react-loadly-line react-loadly-line-${m} ${l}`.trim(),style:f,"data-testid":y,...p})},C=({width:t=20,height:a=20,color:r="var(--react-loadly-color)",borderColor:i,borderWidth:n=0,borderRadius:l=0,opacity:s=1,className:d="",style:c={},animation:u,animationDuration:m,animationDelay:y,"data-testid":p,...g})=>{const h=o(t),f=o(a),v=x(n),b={width:h,height:f,backgroundColor:i?"transparent":r,border:i?`${v} solid ${i}`:void 0,borderRadius:x(l),opacity:s,animation:u?`${u} ${m||"1s"} infinite`:void 0,animationDelay:y,display:"inline-block",...c};return e.createElement("div",{className:`react-loadly-rectangle ${d}`.trim(),style:b,"data-testid":p,...g})},k=({size:t=20,color:a="var(--react-loadly-color)",borderColor:r,borderWidth:i=0,opacity:n=1,className:l="",style:s={},animation:d,animationDuration:c,animationDelay:u,"data-testid":m,...y})=>{const p=o(t),g=x(i),h={width:p,height:p,borderRadius:"50%",backgroundColor:r?"transparent":a,border:r?`${g} solid ${r}`:void 0,opacity:n,animation:d?`${d} ${c||"1s"} infinite`:void 0,animationDelay:u,display:"inline-block",...s};return e.createElement("div",{className:`react-loadly-circle ${l}`.trim(),style:h,"data-testid":m,...y})},N=({count:t=3,dotSize:a=8,color:r="var(--react-loadly-color)",secondaryColor:i,spacing:n=8,speed:l=1,arrangement:s="linear",className:c="",style:u={},animationType:m="wave","data-testid":y,...p})=>{const g=o(n),h=d(1200,l),f=e=>{if("circular"===s){const a=e/t*2*Math.PI,r=parseInt(g);return{position:"absolute",left:"50%",top:"50%",transform:`translate(-50%, -50%) translate(${Math.cos(a)*r}px, ${Math.sin(a)*r}px)`}}return{}},v=e=>.1*e/l+"s",b={...(()=>{switch(s){case"circular":return{display:"flex",alignItems:"center",justifyContent:"center",position:"relative",width:2*(parseInt(o(a))+parseInt(g))+"px",height:2*(parseInt(o(a))+parseInt(g))+"px"};case"grid":return{display:"grid",gridTemplateColumns:`repeat(${Math.ceil(Math.sqrt(t))}, 1fr)`,gap:g};default:return{display:"flex",alignItems:"center",gap:g}}})(),...u};return e.createElement("div",{className:`react-loadly-dot-cluster react-loadly-dot-cluster-${s} ${c}`.trim(),style:b,"data-testid":y,...p},Array.from({length:t},(t,n)=>e.createElement(w,{key:n,size:a,color:i&&n%2==1?i:r,animation:`react-loadly-${m}`,animationDuration:h,animationDelay:v(n),style:f(n),"data-testid":y?`${y}-dot-${n}`:void 0})))},I=({count:t=5,lineWidth:a=4,lineHeight:r=35,color:i="var(--react-loadly-color)",secondaryColor:n,spacing:l=6,speed:s=1,arrangement:c="parallel",orientation:u="vertical",className:m="",style:y={},animationType:p="wave","data-testid":g,...h})=>{const f=o(l),v=d(1e3,s),b=e=>{if("radial"===c){return{position:"absolute",left:"50%",top:"50%",transformOrigin:"center",transform:`translate(-50%, -50%) rotate(${e/t*2*Math.PI}rad)`}}if("staggered"===c){const a=.3+.7*Math.sin(e/t*Math.PI);return{height:"vertical"===u?parseInt(o(r))*a+"px":o(r)}}return{}},x=e=>.1*e/s+"s",$={...(()=>{switch(c){case"radial":return{display:"flex",alignItems:"center",justifyContent:"center",position:"relative",width:1.5*parseInt(o(r))+"px",height:1.5*parseInt(o(r))+"px"};case"staggered":return{display:"flex",alignItems:"flex-end",justifyContent:"center",gap:f};default:return{display:"flex",alignItems:"center",justifyContent:"center",gap:f}}})(),...y};return e.createElement("div",{className:`react-loadly-line-group react-loadly-line-group-${c} ${m}`.trim(),style:$,"data-testid":g,...h},Array.from({length:t},(t,l)=>e.createElement(E,{key:l,width:"horizontal"===u?a:r,height:"horizontal"===u?r:a,color:n&&l%2==1?n:i,orientation:u,animation:`react-loadly-${p}`,animationDuration:v,animationDelay:x(l),style:b(l),"data-testid":g?`${g}-line-${l}`:void 0})))},z=({count:t=4,shapeSize:a=16,color:r="var(--react-loadly-color)",secondaryColor:i,spacing:n=8,speed:l=1,arrangement:s="linear",shapeTypes:c=["circle","rectangle"],className:u="",style:m={},animationType:y="pulse",borderWidth:p=0,"data-testid":g,...h})=>{const f=o(n),v=d(800,l),b=e=>{if("circular"===s){const a=e/t*2*Math.PI,r=2*parseInt(f);return{position:"absolute",left:"50%",top:"50%",transform:`translate(-50%, -50%) translate(${Math.cos(a)*r}px, ${Math.sin(a)*r}px)`}}if("spiral"===s){const a=e/t*4*Math.PI,r=(e+1)*parseInt(f)/2;return{position:"absolute",left:"50%",top:"50%",transform:`translate(-50%, -50%) translate(${Math.cos(a)*r}px, ${Math.sin(a)*r}px)`}}return{}},x=e=>.15*e/l+"s",$={...(()=>{switch(s){case"circular":return{display:"flex",alignItems:"center",justifyContent:"center",position:"relative",width:2.5*(parseInt(o(a))+parseInt(f))+"px",height:2.5*(parseInt(o(a))+parseInt(f))+"px"};case"spiral":return{display:"flex",alignItems:"center",justifyContent:"center",position:"relative",width:3*(parseInt(o(a))+parseInt(f))+"px",height:3*(parseInt(o(a))+parseInt(f))+"px"};default:return{display:"flex",alignItems:"center",gap:f}}})(),...m},w=t=>{const n=(e=>c[e%c.length])(t),l=i&&t%2==1?i:r,o={key:t,color:p>0?void 0:l,borderColor:p>0?l:void 0,borderWidth:p>0?p:void 0,animation:`react-loadly-${y}`,animationDuration:v,animationDelay:x(t),style:b(t),"data-testid":g?`${g}-shape-${t}`:void 0};return"circle"===n?e.createElement(k,{...o,size:a}):e.createElement(C,{...o,width:a,height:a})};return e.createElement("div",{className:`react-loadly-shape-group react-loadly-shape-group-${s} ${u}`.trim(),style:$,"data-testid":g,...h},Array.from({length:t},(e,t)=>w(t)))},T={size:20,color:"var(--react-loadly-color)",speed:1,loading:!0,count:5,"aria-label":"Loading..."},L=a=>{const r=l(T,a),{size:i,color:n,speed:s,loading:d,className:c="",style:u={},count:y=5,showText:p,loadingText:g="Loading...","aria-label":h,"data-testid":f,fullscreen:v,screenWidth:x,screenHeight:w,loaderCenter:E,screenBackground:C,...k}=r,N=t(()=>b("bars-loader"),[]),I=o(i),z=m(s);if(!d)return null;const L={display:"inline-flex",flexDirection:"column",alignItems:"center",...u,...v&&{position:"fixed",top:0,left:0,width:x||"100vw",height:w||"100vh",backgroundColor:C||"var(--react-loadly-background)",zIndex:9999,justifyContent:E?"center":u.justifyContent}},D={width:"4px",height:I,backgroundColor:n,borderRadius:"2px",animation:`react-loadly-bars ${z.duration} ease-in-out infinite`,animationPlayState:z.playState},M=Array.from({length:y}).map((t,a)=>{const r=.1*a+"s",i=.5+a%3*.25;return e.createElement("div",{key:a,style:{...D,animationDelay:r,height:parseFloat(I)*i+"px"},"data-testid":f?`${f}-bar-${a}`:void 0})});return e.createElement("div",{className:$("react-loadly react-loadly-bars",c),style:L,role:"status","aria-label":h,"aria-live":"polite","aria-busy":d,"data-testid":f,...k},e.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",gap:"4px"}},M),p&&e.createElement("div",{className:"react-loadly-text",id:`${N}-text`,"aria-live":"polite"},g),e.createElement("span",{className:"react-loadly-sr-only"},h))},D={size:60,color:"var(--react-loadly-color)",speed:1,loading:!0,fluidity:1,amplitude:1,"aria-label":"Loading..."},M=a=>{const r=l(D,a),{size:i,color:n,secondaryColor:s,speed:c,loading:u,fluidity:m,amplitude:y,className:p="",style:g={},showText:h,loadingText:f="Loading...","aria-label":v,"data-testid":x,...w}=r,E=t(()=>b("blob-loader"),[]),C=o(i),k=d(2500,c);if(!u)return null;const N={display:"inline-flex",flexDirection:"column",alignItems:"center",...g},I={width:C,height:C,background:`linear-gradient(45deg, ${n}, ${s||n})`,borderRadius:"30% 70% 70% 30% / 30% 30% 70% 70%",animation:`blob-morph ${k} ease-in-out infinite`,filter:"blur(1px)",position:"relative"},z={position:"absolute",top:"20%",left:"20%",width:"60%",height:"60%",background:`radial-gradient(circle, ${s||n}, transparent)`,borderRadius:"40% 60% 60% 40% / 40% 40% 60% 60%",animation:`blob-inner ${k} ease-in-out infinite reverse`,opacity:.7};return e.createElement(e.Fragment,null,e.createElement("style",null,`\n @keyframes blob-morph {\n 0%, 100% {\n border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;\n transform: scale(1) rotate(0deg);\n }\n 25% {\n border-radius: 58% 42% 75% 25% / 76% 46% 54% 24%;\n transform: scale(${1+.1*(y??1)}) rotate(90deg);\n }\n 50% {\n border-radius: 50% 50% 33% 67% / 55% 27% 73% 45%;\n transform: scale(${1-.05*(y??1)}) rotate(180deg);\n }\n 75% {\n border-radius: 33% 67% 58% 42% / 63% 68% 32% 37%;\n transform: scale(${1+.08*(y??1)}) rotate(270deg);\n }\n }\n \n @keyframes blob-inner {\n 0%, 100% {\n border-radius: 40% 60% 60% 40% / 40% 40% 60% 60%;\n transform: scale(1) rotate(0deg);\n }\n 33% {\n border-radius: 70% 30% 50% 50% / 30% 70% 30% 70%;\n transform: scale(${1.1+.1*(m??1)}) rotate(-120deg);\n }\n 66% {\n border-radius: 30% 70% 40% 60% / 70% 30% 70% 30%;\n transform: scale(${.9+.05*(m??1)}) rotate(-240deg);\n }\n }\n `),e.createElement("div",{className:$("react-loadly react-loadly-blob",p),style:N,role:"status","aria-label":v,"aria-live":"polite","aria-busy":u,"data-testid":x,...w},e.createElement("div",{style:I,"data-testid":x?`${x}-blob`:void 0},e.createElement("div",{style:z})),h&&e.createElement("div",{className:"react-loadly-text",id:`${E}-text`,"aria-live":"polite"},f),e.createElement("span",{className:"react-loadly-sr-only"},v)))},R={size:15,color:"var(--react-loadly-color)",speed:1,loading:!0,count:3,"aria-label":"Loading..."},j=a=>{const r=l(R,a),{size:i,color:n,speed:s,loading:d,className:c="",style:u={},count:y=3,showText:p,loadingText:g="Loading...","aria-label":h,"data-testid":f,fullscreen:v,screenWidth:x,screenHeight:w,loaderCenter:E,screenBackground:C,...k}=r,N=t(()=>b("bounce-loader"),[]),I=o(i),z=m(s);if(!d)return null;const T={display:"inline-flex",flexDirection:"column",alignItems:"center",...u,...v&&{position:"fixed",top:0,left:0,width:x||"100vw",height:w||"100vh",backgroundColor:C||"var(--react-loadly-background)",zIndex:9999,justifyContent:E?"center":u.justifyContent}},L={width:I,height:I,borderRadius:"50%",backgroundColor:n,animation:`react-loadly-bounce ${z.duration} ease-in-out infinite`,animationPlayState:z.playState},D=Array.from({length:y}).map((t,a)=>{const r=.1*a+"s";return e.createElement("div",{key:a,style:{...L,animationDelay:r},"data-testid":f?`${f}-ball-${a}`:void 0})});return e.createElement("div",{className:$("react-loadly react-loadly-bounce",c),style:T,role:"status","aria-label":h,"aria-live":"polite","aria-busy":d,"data-testid":f,...k},e.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",gap:"8px"}},D),p&&e.createElement("div",{className:"react-loadly-text",id:`${N}-text`,"aria-live":"polite"},g),e.createElement("span",{className:"react-loadly-sr-only"},h))},W={size:12,color:"var(--react-loadly-color)",speed:1,loading:!0,count:3,"aria-label":"Loading..."},S=a=>{const r=l(W,a),{size:i,color:n,speed:s,loading:d,className:c="",style:u={},count:y=3,showText:p,loadingText:g="Loading...","aria-label":h,"data-testid":f,fullscreen:v,screenWidth:x,screenHeight:w,loaderCenter:E,screenBackground:C,...k}=r,N=t(()=>b("dots-loader"),[]),I=o(i),z=m(s);if(!d)return null;const T={display:"inline-flex",flexDirection:"column",alignItems:"center",...u,...v&&{position:"fixed",top:0,left:0,width:x||"100vw",height:w||"100vh",backgroundColor:C||"var(--react-loadly-background)",zIndex:9999,justifyContent:E?"center":u.justifyContent}},L={width:I,height:I,borderRadius:"50%",backgroundColor:n,animation:`react-loadly-dots ${z.duration} ease-in-out infinite`,animationPlayState:z.playState},D=Array.from({length:y}).map((t,a)=>{const r=.2*a+"s";return e.createElement("div",{key:a,style:{...L,animationDelay:r},"data-testid":f?`${f}-dot-${a}`:void 0})});return e.createElement("div",{className:$("`react-loadly react-loadly-dots",c),style:T,role:"status","aria-label":h,"aria-live":"polite","aria-busy":d,"data-testid":f,...k},e.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",gap:"6px"}},D),p&&e.createElement("div",{className:"react-loadly-text",id:`${N}-text`,"aria-live":"polite"},g),e.createElement("span",{className:"react-loadly-sr-only"},h))},H={size:60,speed:1,loading:!0,animationType:"spin",glowIntensity:.3,"aria-label":"Loading..."},B=t=>{const a=l(H,t),{size:r,width:i,height:n,speed:o=1,loading:s,animationType:c,glowIntensity:u,className:m="",style:y={},color:p="var(--react-loadly-color)","aria-label":g,loadingText:h,showText:f,"data-testid":v,fullscreen:b,screenWidth:x,screenHeight:w,loaderCenter:E,screenBackground:C,children:k,...N}=a;if(!s)return null;const I={display:"inline-flex",flexDirection:"column",alignItems:"center",...y,...b&&{position:"fixed",top:0,left:0,width:x||"100vw",height:w||"100vh",backgroundColor:C||"var(--react-loadly-background)",zIndex:9999,justifyContent:E?"center":y.justifyContent}},z=i||r,T=n||r,L={width:"number"==typeof z?`${z}px`:z,height:"number"==typeof T?`${T}px`:T,animation:(()=>{switch(c){case"pulse":return`react-loadly-pulse ${d(2e3,o)} infinite`;case"glow":return`react-loadly-glow ${d(2e3,o)} infinite`;case"bounce":return`react-loadly-bounce ${d(2e3,o)} infinite`;case"flip":return`react-loadly-flip ${d(2e3,o)} infinite`;default:return`react-loadly-spin ${d(2e3,o)} infinite`}})(),filter:(u??0)>0?`drop-shadow(0 0 ${20*(u??0)}px ${p})`:void 0,transformStyle:"preserve-3d",willChange:"transform",display:"flex",alignItems:"center",justifyContent:"center"},D={position:"absolute",top:"50%",left:"50%",width:"60%",height:"60%",borderRadius:"50%",backgroundColor:p,opacity:.3,transform:"translate(-50%, -50%)",animation:`react-loadly-pulse ${d(1500,1.5*o)} infinite`,zIndex:-1},M={position:"absolute",top:"50%",left:"50%",width:"120%",height:"120%",borderRadius:"50%",border:`2px solid ${p}`,opacity:.2,transform:"translate(-50%, -50%)",animation:`react-loadly-spin ${d(3e3,.8*o)} infinite reverse`,zIndex:-2};return e.createElement("div",{className:$("`react-loadly react-loadly-element-loader",m),style:I,role:"status","aria-label":g,"aria-live":"polite","aria-busy":s,"data-testid":v,...N},e.createElement("div",{style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center"}},e.createElement("div",{style:M}),e.createElement("div",{style:D}),e.createElement("div",{style:L,className:"react-loadly-element","data-testid":v?`${v}-element`:void 0},k)),f&&e.createElement("div",{className:"react-loadly-text","aria-live":"polite"},h||g),e.createElement("span",{className:"react-loadly-sr-only"},g))},P=({className:t=""})=>e.createElement("svg",{className:t,fill:"currentColor",viewBox:"0 0 20 20",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true"},e.createElement("path",{clipRule:"evenodd",fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z"})),A=({className:t=""})=>e.createElement("svg",{className:t,fill:"currentColor",viewBox:"0 0 20 20",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true"},e.createElement("path",{fillRule:"evenodd",d:"M9.243 3.03a1 1 0 01.727 1.213L9.53 6h2.94l.56-2.243a1 1 0 111.94.486L14.53 6H16a1 1 0 110 2h-1.97l-1 4H15a1 1 0 110 2h-2.47l-.56 2.242a1 1 0 11-1.94-.485L10.47 14H7.53l-.56 2.242a1 1 0 11-1.94-.485L5.47 14H4a1 1 0 110-2h1.97l1-4H5a1 1 0 110-2h2.47l.56-2.243a1 1 0 011.213-.727zM9.03 8l-1 4h2.94l1-4H9.03z",clipRule:"evenodd"})),F=({className:t=""})=>e.createElement("svg",{className:t,fill:"currentColor",viewBox:"0 0 20 20",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true"},e.createElement("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z",clipRule:"evenodd"})),q=({error:t="Something went wrong",onRetry:a,showRetry:r=!0,children:i,type:n="error",className:l="",style:o={},fullscreen:s,screenWidth:d,screenHeight:c,loaderCenter:u,screenBackground:m,...y})=>{const p={...o,...s&&{position:"fixed",top:0,left:0,width:d||"100vw",height:c||"100vh",backgroundColor:m||"var(--react-loadly-error-background)",zIndex:9999,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:u?"center":o.justifyContent}};return i?e.createElement("div",{className:`react-loadly-fallback ${l}`.trim(),style:p,...y},i):e.createElement("div",{className:`react-loadly-error ${l}`.trim(),style:p,role:"alert","aria-live":"polite",...y},(()=>{switch(n){case"network":return e.createElement(A,{className:"react-loadly-error-icon"});case"timeout":return e.createElement(F,{className:"react-loadly-error-icon"});default:return e.createElement(P,{className:"react-loadly-error-icon"})}})(),e.createElement("p",{className:"react-loadly-error-message"},(()=>{switch(n){case"network":return t||"Network connection failed. Please check your internet connection.";case"timeout":return t||"Loading timeout. The operation took too long to complete.";default:return t||"Something went wrong. Please try again."}})()),r&&a&&e.createElement("button",{className:"react-loadly-retry-button",onClick:a,type:"button","aria-label":"Retry loading"},"Try Again"))},X={size:60,color:"var(--react-loadly-color)",speed:1,loading:!0,fluidity:1,amplitude:1,"aria-label":"Loading..."},Y=a=>{const r=l(X,a),{size:i,color:n,secondaryColor:s,speed:c,loading:u,amplitude:m,className:y="",style:p={},showText:g,loadingText:h="Loading...","aria-label":f,"data-testid":v,fullscreen:x,screenWidth:w,screenHeight:E,loaderCenter:C,screenBackground:k,...N}=r,I=t(()=>b("flow-loader"),[]),z=o(i),T=parseInt(z),L=Math.max(.4*T,10),D=d(1500,c);if(!u)return null;const M={display:"inline-flex",flexDirection:"column",alignItems:"center",...p,...x&&{position:"fixed",top:0,left:0,width:w||"100vw",height:E||"100vh",backgroundColor:k||"var(--react-loadly-background)",zIndex:9999,justifyContent:C?"center":p.justifyContent}},R={width:z,height:`${L}px`,position:"relative",overflow:"hidden",borderRadius:`${Math.max(.2*T,4)}px`,backgroundColor:"rgba(0, 0, 0, 0.1)"},j=Math.max(Math.floor(T/15),3);return e.createElement(e.Fragment,null,e.createElement("style",null,`\n @keyframes flow-particle-${I} {\n 0% {\n transform: translateX(0) translateY(0) scale(0);\n opacity: 0;\n }\n 10% {\n transform: translateX(${Math.min(.1*T,10)}px) translateY(${Math.sin(.1)*(m??Math.min(5,L/4))}px) scale(1);\n opacity: 0.8;\n }\n 50% {\n transform: translateX(${Math.min(.5*T,.7*T)}px) translateY(${Math.sin(.5)*(m??Math.min(5,L/4))}px) scale(1);\n opacity: 0.8;\n }\n 90% {\n transform: translateX(${Math.min(.9*T,T-10)}px) translateY(${Math.sin(.9)*(m??Math.min(5,L/4))}px) scale(1);\n opacity: 0.8;\n }\n 100% {\n transform: translateX(${T}px) translateY(${Math.sin(1)*(m??Math.min(5,L/4))}px) scale(0);\n opacity: 0;\n }\n }\n `),e.createElement("div",{className:$("react-loadly react-loadly-flow",y),style:M,role:"status","aria-label":f,"aria-live":"polite","aria-busy":u,"data-testid":v,...N},e.createElement("div",{style:R,"data-testid":v?`${v}-container`:void 0},Array.from({length:j},(t,a)=>(t=>{const a=.2*t/(c??1),r=parseFloat(D)+100*t,i=Math.max(T/10,4),l=i+t%3*(i/2);return e.createElement("div",{key:t,style:{position:"absolute",width:`${l}px`,height:`${l}px`,borderRadius:"50%",background:t%2==0?n:s||n,animation:`flow-particle-${I} ${r}ms ease-in-out infinite`,animationDelay:`${a}s`,opacity:.8-.1*t,left:"0px",top:(L-l)/2+t%3*(L/(j+1))+"px"},"data-testid":v?`${v}-particle-${t}`:void 0})})(a))),g&&e.createElement("div",{className:"react-loadly-text",id:`${I}-text`,"aria-live":"polite"},h),e.createElement("span",{className:"react-loadly-sr-only"},f)))},O={size:40,color:"var(--react-loadly-color)",speed:1,loading:!0,count:4,"aria-label":"Loading..."},V=a=>{const r=l(O,a),{size:i,color:n,secondaryColor:s,speed:d=1,loading:c,count:u,className:m="",style:y={},showText:p,loadingText:g="Loading...","aria-label":h,"data-testid":f,fullscreen:v,screenWidth:x,screenHeight:w,loaderCenter:E,screenBackground:C,...k}=r,N=t(()=>b("grid-loader"),[]),I=t(()=>{const e="number"==typeof i?i:parseInt(o(i)),t=Math.ceil(Math.sqrt(u||4));return Math.max(e/(1.5*t),8)},[i,u]);if(!c)return null;const z={display:"inline-flex",flexDirection:"column",alignItems:"center",...y,...v&&{position:"fixed",top:0,left:0,width:x||"100vw",height:w||"100vh",backgroundColor:C||"var(--react-loadly-background)",zIndex:9999,justifyContent:E?"center":y.justifyContent}};return e.createElement("div",{className:$("react-loadly react-loadly-grid",m),style:z,role:"status","aria-label":h,"aria-live":"polite","aria-busy":c,"data-testid":f,...k},e.createElement("div",{className:"react-loadly-grid-container",style:{display:"grid",gridTemplateColumns:`repeat(${Math.ceil(Math.sqrt(u||4))}, 1fr)`,gap:I/3+"px"},"data-testid":f?`${f}-grid`:void 0},Array.from({length:u||4}).map((t,a)=>e.createElement("div",{key:a,className:"react-loadly-grid-item",style:{width:`${I}px`,height:`${I}px`,backgroundColor:a%2==0?n:s||n,borderRadius:"20%",animation:`react-loadly-scale ${1.2/(d||1)}s ease-in-out infinite`,animationDelay:.1*a/(d||1)+"s"}}))),p&&e.createElement("div",{className:"react-loadly-text",id:`${N}-text`,"aria-live":"polite"},g),e.createElement("span",{className:"react-loadly-sr-only"},h))},U={size:60,color:"var(--react-loadly-color)",speed:1,loading:!0,fluidity:1,amplitude:1,"aria-label":"Loading..."},_=a=>{const r=l(U,a),{size:i,color:n,secondaryColor:s,speed:c,loading:u,amplitude:m,className:y="",style:p={},showText:g,loadingText:h="Loading...","aria-label":f,"data-testid":v,fullscreen:x,screenWidth:w,screenHeight:E,loaderCenter:C,screenBackground:k,...N}=r,I=t(()=>b("liquid-loader"),[]),z=o(i),T=d(2e3,c);if(!u)return null;const L={display:"inline-flex",flexDirection:"column",alignItems:"center",...p,...x&&{position:"fixed",top:0,left:0,width:w||"100vw",height:E||"100vh",backgroundColor:k||"var(--react-loadly-background)",zIndex:9999,justifyContent:C?"center":p.justifyContent}},D={width:z,height:z,position:"relative",overflow:"hidden",borderRadius:"50%",backgroundColor:"rgba(0, 0, 0, 0.1)"},M=50-10*(m??1),R={position:"absolute",bottom:0,left:0,width:"200%",height:"200%",background:`linear-gradient(180deg, ${n} 0%, ${s||n} 100%)`,borderRadius:"40%",animation:`react-loadly-liquid-wave ${T} ease-in-out infinite`,transform:"translate(-25%, 50%) rotate(0deg)",animationTimingFunction:"cubic-bezier(0.36, 0.45, 0.63, 0.53)"},j={...R,background:`linear-gradient(180deg, ${s||n} 0%, ${n} 100%)`,animation:`react-loadly-liquid-wave ${T} ease-in-out infinite reverse`,animationDelay:-.5/(c??1)+"s",opacity:.8};return e.createElement(e.Fragment,null,e.createElement("style",null,`\n @keyframes react-loadly-liquid-wave {\n 0%, 100% {\n transform: translate(-25%, 50%) rotate(0deg);\n }\n 50% {\n transform: translate(-25%, ${M}%) rotate(180deg);\n }\n }\n `),e.createElement("div",{className:$("react-loadly react-loadly-liquid",y),style:L,role:"status","aria-label":f,"aria-live":"polite","aria-busy":u,"data-testid":v,...N},e.createElement("div",{style:D,"data-testid":v?`${v}-container`:void 0},e.createElement("div",{style:R}),e.createElement("div",{style:j})),g&&e.createElement("div",{className:"react-loadly-text",id:`${I}-text`,"aria-live":"polite"},h),e.createElement("span",{className:"react-loadly-sr-only"},f)))},G={size:60,speed:1,loading:!0,animationType:"spin",glowIntensity:.3,"aria-label":"Loading...",alt:"Loading"},J=t=>{const a=l(G,t),{src:r,alt:i,size:n,speed:o,loading:s,animationType:c,glowIntensity:u,className:m="",style:y={},color:p="var(--react-loadly-color)","aria-label":g,loadingText:h,showText:f,"data-testid":v,fullscreen:b,screenWidth:x,screenHeight:w,loaderCenter:E,screenBackground:C,...k}=a;if(!s)return null;const N={display:"inline-flex",flexDirection:"column",alignItems:"center",...y,...b&&{position:"fixed",top:0,left:0,width:x||"100vw",height:w||"100vh",backgroundColor:C||"var(--react-loadly-background)",zIndex:9999,justifyContent:E?"center":y.justifyContent}},I={width:"number"==typeof n?`${n}px`:n,height:"number"==typeof n?`${n}px`:n,animation:`react-loadly-${c} ${d(2e3,o)} infinite`,filter:(u??0)>0?`drop-shadow(0 0 ${20*(u??0)}px ${p})`:void 0};return e.createElement("div",{className:$("`react-loadly react-loadly-logo-spin",m),style:N,role:"status","aria-label":g,"aria-live":"polite","aria-busy":s,"data-testid":v,...k},e.createElement("img",{src:r,alt:i,style:I,className:"react-loadly-logo","data-testid":v?`${v}-logo`:void 0}),f&&e.createElement("div",{className:"react-loadly-text","aria-live":"polite"},h||g),e.createElement("span",{className:"react-loadly-sr-only"},g))},K={size:40,color:"var(--react-loadly-color)",speed:1,loading:!0,count:3,"aria-label":"Loading..."},Q=a=>{const r=l(K,a),{size:i,color:n,secondaryColor:s,speed:d,loading:c,count:u,className:m="",style:y={},showText:p,loadingText:g="Loading...","aria-label":h,"data-testid":f,fullscreen:v,screenWidth:x,screenHeight:w,loaderCenter:E,screenBackground:C,...k}=r,I=t(()=>b("pulse-loader"),[]),z=t(()=>{const e="number"==typeof i?i:parseInt(o(i));return Math.max(e/5,6)},[i]);if(!c)return null;const T={display:"inline-flex",flexDirection:"column",alignItems:"center",...y,...v&&{position:"fixed",top:0,left:0,width:x||"100vw",height:w||"100vh",backgroundColor:C||"var(--react-loadly-background)",zIndex:9999,justifyContent:E?"center":y.justifyContent}};return e.createElement("div",{className:$("react-loadly react-loadly-pulse",m),style:T,role:"status","aria-label":h,"aria-live":"polite","aria-busy":c,"data-testid":f,...k},e.createElement(N,{count:u,dotSize:z,color:n,secondaryColor:s,speed:d,arrangement:"linear",animationType:"pulse",spacing:z/2,"data-testid":f?`${f}-dots`:void 0}),p&&e.createElement("div",{className:"react-loadly-text",id:`${I}-text`,"aria-live":"polite"},g),e.createElement("span",{className:"react-loadly-sr-only"},h))},Z={size:60,color:"var(--react-loadly-color)",speed:1,loading:!0,borderWidth:4,"aria-label":"Loading..."},ee=t=>{const r=l(Z,t),{size:i,color:n,speed:s,loading:d,className:c="",style:u={},borderWidth:y,showText:p,loadingText:g="Loading...","aria-label":h,"data-testid":f,fullscreen:v,screenWidth:x,screenHeight:w,loaderCenter:E,screenBackground:C,...k}=r,N=a(b("ring-loader")),I=o(i),z=m(s);if(!d)return null;const T={display:"inline-flex",flexDirection:"column",alignItems:"center",...u,...v&&{position:"fixed",top:0,left:0,width:x||"100vw",height:w||"100vh",backgroundColor:C||"var(--react-loadly-background)",zIndex:9999,justifyContent:E?"center":u.justifyContent}},L={position:"relative",width:I,height:I},D={boxSizing:"border-box",display:"block",position:"absolute",width:I,height:I,border:`${y}px solid transparent`,borderTop:`${y}px solid ${n}`,borderBottom:`${y}px solid ${n}`,borderRadius:"50%",animation:`react-loadly-ring ${z.duration} cubic-bezier(0.5, 0, 0.5, 1) infinite`,animationPlayState:z.playState},M=Array.from({length:4}).map((t,a)=>{const r=90*a+"deg",i=-.15*a+"s";return e.createElement("div",{key:a,style:{...D,transform:`rotate(${r})`,animationDelay:i},"data-testid":f?`${f}-segment-${a}`:void 0})});return e.createElement("div",{className:$("react-loadly react-loadly-ring",c),style:T,role:"status","aria-label":h,"aria-live":"polite","aria-busy":d,"data-testid":f,...k},e.createElement("div",{style:L},M),p&&e.createElement("div",{className:"react-loadly-text",id:`${N.current}-text`,"aria-live":"polite"},g),e.createElement("span",{className:"react-loadly-sr-only"},h))},te={size:15,color:"var(--react-loadly-color)",speed:1,loading:!0,count:2,"aria-label":"Loading..."},ae=a=>{const r=l(te,a),{size:i,color:n,speed:s,loading:d,className:c="",style:u={},count:y=2,showText:p,loadingText:g="Loading...","aria-label":h,"data-testid":f,fullscreen:v,screenWidth:x,screenHeight:w,loaderCenter:E,screenBackground:C,...k}=r,N=t(()=>b("rotate-loader"),[]),I=o(i),z=m(s);if(!d)return null;const T={display:"inline-flex",flexDirection:"column",alignItems:"center",...u,...v&&{position:"fixed",top:0,left:0,width:x||"100vw",height:w||"100vh",backgroundColor:C||"var(--react-loadly-background)",zIndex:9999,justifyContent:E?"center":u.justifyContent}},L={position:"relative",width:I,height:I},D={position:"absolute",width:I,height:I,border:"2px solid transparent",borderTopColor:n,borderBottomColor:n,borderRadius:"50%",animation:`react-loadly-ring ${z.duration} cubic-bezier(0.5, 0, 0.5, 1) infinite`,animationPlayState:z.playState,transform:"rotate(0deg)"},M=Array.from({length:y}).map((t,a)=>{const r=1-.2*a,i=2+a,n=-.15*a+"s";return e.createElement("div",{key:a,style:{...D,width:parseFloat(I)*r+"px",height:parseFloat(I)*r+"px",borderWidth:`${i}px`,animationDuration:parseFloat(z.duration)*(1+.5*a)+"ms",animationDelay:n},"data-testid":f?`${f}-element-${a}`:void 0})});return e.createElement("div",{className:$("react-loadly react-loadly-rotate",c),style:T,role:"status","aria-label":h,"aria-live":"polite","aria-busy":d,"data-testid":f,...k},e.createElement("div",{style:L},M),p&&e.createElement("div",{className:"react-loadly-text",id:`${N}-text`,"aria-live":"polite"},g),e.createElement("span",{className:"react-loadly-sr-only"},h))},re={size:40,speed:1,loading:!0,lines:1,variant:"card",color:"#f1f5f9",highlightColor:"#e2e8f0",shimmerColor:"rgba(255, 255, 255, 0.8)",borderRadius:"4px",spacing:"8px",waveWidth:"200px",waveDirection:"left-to-right","aria-label":"Loading content..."},ie=t=>{const a=l(re,t),{size:r,width:i,height:n,speed:s,loading:d,className:c="",style:u={},lines:m=1,variant:y,borderRadius:p,spacing:g,waveWidth:h,color:f,highlightColor:v,shimmerColor:b,waveDirection:x,showText:w,loadingText:E="Loading content...","aria-label":C,"data-testid":k,fullscreen:N,screenWidth:I,screenHeight:z,loaderCenter:T,screenBackground:L,...D}=a;if(!d)return null;const M={display:"inline-flex",flexDirection:"column",alignItems:"center",...u,...N&&{position:"fixed",top:0,left:0,width:I||"100vw",height:z||"100vh",backgroundColor:L||"var(--react-loadly-background)",zIndex:9999,justifyContent:T?"center":u.justifyContent}},R=(()=>{switch(y){case"avatar":return{width:i||r||"40px",height:n||r||"40px",borderRadius:p||"50%"};case"card":return{width:i||"300px",height:n||"200px",borderRadius:p||"8px"};case"text":return{width:i||"100%",height:n||"16px",borderRadius:p||"4px"};case"wave":return{width:i||"100%",height:n||"20px",borderRadius:p||"10px"};default:return{width:i||r||"100%",height:n||"16px",borderRadius:p||"4px"}}})(),j=o(g,"8px"),W=o(h,"200px"),S={width:o(R.width),height:o(R.height),background:`linear-gradient(${"left-to-right"===x?"90deg":"right-to-left"===x?"270deg":"top-to-bottom"===x?"180deg":"0deg"}, ${f} 0%, ${v} 50%, ${f} 100%)`,backgroundSize:`${W} 100%`,borderRadius:o(R.borderRadius),position:"relative",overflow:"hidden",animation:`react-loadly-shimmer-wave ${2/(s||1)}s ease-in-out infinite`};return e.createElement("div",{className:$("react-loadly react-loadly-shimmer",c),style:M,role:"status","aria-label":C,"aria-live":"polite","aria-busy":d,"data-testid":k,...D},e.createElement("div",{style:{display:"flex",flexDirection:"column",width:"100%"}},"card"===y?e.createElement("div",{style:S,"data-testid":k?`${k}-shimmer`:void 0},e.createElement("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,background:`linear-gradient(90deg, transparent, ${b}, transparent)`,animation:`react-loadly-shimmer-overlay ${2/(s||1)}s ease-in-out infinite`}})):"avatar"===y?e.createElement("div",{style:S,"data-testid":k?`${k}-shimmer`:void 0},e.createElement("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,borderRadius:"50%",background:`linear-gradient(90deg, transparent, ${b}, transparent)`,animation:`react-loadly-shimmer-overlay ${2/(s||1)}s ease-in-out infinite`}})):"wave"===y?e.createElement("div",{style:S,"data-testid":k?`${k}-shimmer`:void 0},e.createElement("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,background:`linear-gradient(90deg, transparent, ${b}, transparent)`,animation:`react-loadly-shimmer-wave-overlay ${2/(s||1)}s ease-in-out infinite`}})):Array.from({length:m},(t,a)=>{const r=a===m-1&&m>1?"60%":"100%";return e.createElement("div",{key:a,style:{...S,width:r,marginBottom:a<m-1?j:0},"data-testid":k?`${k}-shimmer-${a}`:void 0},e.createElement("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,background:`linear-gradient(90deg, transparent, ${b}, transparent)`,animation:`react-loadly-shimmer-overlay ${2/(s||1)}s ease-in-out infinite`,animationDelay:.1*a+"s"}}))})),w&&e.createElement("div",{className:"react-loadly-text","aria-live":"polite"},E),e.createElement("span",{className:"react-loadly-sr-only"},C))},ne={size:40,speed:1,loading:!0,lines:1,variant:"line",shimmer:!0,color:"#e2e8f0",highlightColor:"#f1f5f9",shimmerColor:"rgba(255, 255, 255, 0.6)",borderRadius:"4px",spacing:"8px","aria-label":"Loading content..."},le=t=>{const a=l(ne,t),{size:r,width:i,height:n,speed:s,loading:d,className:c="",style:u={},lines:m=1,variant:y,borderRadius:p,spacing:g,shimmer:h,color:f,highlightColor:v,shimmerColor:b,showText:x,loadingText:w="Loading content...","aria-label":E,"data-testid":C,fullscreen:k,screenWidth:N,screenHeight:I,loaderCenter:z,screenBackground:T,...L}=a;if(!d)return null;const D={display:"inline-flex",flexDirection:"column",alignItems:"center",...u,...k&&{position:"fixed",top:0,left:0,width:N||"100vw",height:I||"100vh",backgroundColor:T||"var(--react-loadly-background)",zIndex:9999,justifyContent:z?"center":u.justifyContent}},M=(()=>{switch(y){case"avatar":return{width:i||r||"40px",height:n||r||"40px",borderRadius:p||"50%"};case"card":return{width:i||"300px",height:n||"200px",borderRadius:p||"8px"};case"text":return{width:i||"100%",height:n||"16px",borderRadius:p||"4px"};default:return{width:i||r||"100%",height:n||"16px",borderRadius:p||"4px"}}})(),R=o(g,"8px"),j={width:o(M.width),height:o(M.height),backgroundColor:f,borderRadius:o(M.borderRadius),position:"relative",overflow:"hidden",...h&&{background:`linear-gradient(90deg, ${f} 25%, ${v} 50%, ${f} 75%)`,backgroundSize:"200% 100%",animation:`react-loadly-shimmer ${1.5/(s||1)}s ease-in-out infinite`}};return e.createElement("div",{className:$("react-loadly react-loadly-skeleton",c),style:D,role:"status","aria-label":E,"aria-live":"polite","aria-busy":d,"data-testid":C,...L},e.createElement("div",{style:{display:"flex",flexDirection:"column",width:"100%"}},"card"===y?e.createElement("div",{style:j,"data-testid":C?`${C}-skeleton`:void 0},h&&e.createElement("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,background:`linear-gradient(90deg, transparent, ${b}, transparent)`,animation:`react-loadly-shimmer-overlay ${1.5/(s||1)}s ease-in-out infinite`}})):"avatar"===y?e.createElement("div",{style:j,"data-testid":C?`${C}-skeleton`:void 0},h&&e.createElement("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,borderRadius:"50%",background:`linear-gradient(90deg, transparent, ${b}, transparent)`,animation:`react-loadly-shimmer-overlay ${1.5/(s||1)}s ease-in-out infinite`}})):Array.from({length:m},(t,a)=>{const r=a===m-1&&m>1?"60%":"100%";return e.createElement("div",{key:a,style:{...j,width:r,marginBottom:a<m-1?R:0},"data-testid":C?`${C}-skeleton-${a}`:void 0},h&&e.createElement("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,background:`linear-gradient(90deg, transparent, ${b}, transparent)`,animation:`react-loadly-shimmer-overlay ${1.5/(s||1)}s ease-in-out infinite`,animationDelay:.1*a+"s"}}))})),x&&e.createElement("div",{className:"react-loadly-text","aria-live":"polite"},w),e.createElement("span",{className:"react-loadly-sr-only"},E))},oe={size:40,color:"var(--react-loadly-color)",speed:1,loading:!0,borderWidth:4,"aria-label":"Loading..."},se=t=>{const r=l(oe,t),{size:i,color:n,speed:s,loading:d,className:c="",style:u={},borderWidth:y,showText:p,loadingText:g="Loading...","aria-label":h,"data-testid":f,fullscreen:v,screenWidth:x,screenHeight:w,loaderCenter:E,screenBackground:C,...k}=r,N=a(b("spin-loader")),I=o(i),z=m(s);if(!d)return null;const T={display:"inline-flex",flexDirection:"column",alignItems:"center",...u,...v&&{position:"fixed",top:0,left:0,width:x||"100vw",height:w||"100vh",backgroundColor:C||"var(--react-loadly-background)",zIndex:9999,justifyContent:E?"center":u.justifyContent}},L={width:I,height:I,border:`${y}px solid transparent`,borderTop:`${y}px solid ${n}`,borderRadius:"50%",animation:`react-loadly-spin ${z.duration} linear infinite`,animationPlayState:z.playState};return e.createElement("div",{className:$("react-loadly react-loadly-spin",c),style:T,role:"status","aria-label":h,"aria-live":"polite","aria-busy":d,"data-testid":f,...k},e.createElement("div",{style:L,"data-testid":f?`${f}-spinner`:void 0}),p&&e.createElement("div",{className:"react-loadly-text",id:`${N.current}-text`,"aria-live":"polite"},g),e.createElement("span",{className:"react-loadly-sr-only"},h))},de={speed:1,loading:!0,charDelay:100,"aria-label":"Loading...",loop:!0},ce=t=>{const n=l(de,t),{loadingText:o,speed:s=1,loading:d,charDelay:c=100,loop:u,className:m="",style:y={},color:p="var(--react-loadly-text-color)",fontFamily:g,fontWeight:h=500,"aria-label":f,"data-testid":v,showText:b,fullscreen:x,screenWidth:w,screenHeight:E,loaderCenter:C,screenBackground:k,size:N=18,...I}=n,[z,T]=r(""),[L,D]=r(!1),M=a(null);if(i(()=>{if(M.current&&(clearTimeout(M.current),M.current=null),!d||!o)return void T("");D(!0),T("");const e=(t=0)=>{t<o.length?(T(o.substring(0,t+1)),M.current=setTimeout(()=>e(t+1),c/s)):u?M.current=setTimeout(()=>{T(""),e(0)},2*c):D(!1)};return e(0),()=>{M.current&&clearTimeout(M.current)}},[d,o,c,s,u]),!d)return null;const R={display:"inline-flex",flexDirection:"column",alignItems:"center",...y,...x&&{position:"fixed",top:0,left:0,width:w||"100vw",height:E||"100vh",backgroundColor:k||"var(--react-loadly-background)",zIndex:9999,justifyContent:C?"center":y.justifyContent}},j={color:p,fontFamily:g,fontWeight:h,fontSize:N,whiteSpace:"pre"};return e.createElement("div",{className:$("react-loadly react-loadly-typing",m),style:R,role:"status","aria-label":f,"aria-live":"polite","aria-busy":d,"data-testid":v,...I},e.createElement("div",{style:j,"data-testid":v?`${v}-text`:void 0},z,e.createElement("span",{className:"react-loadly-typing-cursor",style:{display:L?"inline-block":"none",animation:`react-loadly-blink ${1/s}s step-end infinite`,marginLeft:"2px",verticalAlign:"baseline"}},"|")),b&&e.createElement("div",{className:"react-loadly-text","aria-live":"polite"},o),e.createElement("span",{className:"react-loadly-sr-only"},f))},ue={size:40,color:"var(--react-loadly-color)",speed:1,loading:!0,count:5,"aria-label":"Loading..."},me=a=>{const r=l(ue,a),{size:i,color:n,secondaryColor:s,speed:d,loading:c,count:u,className:m="",style:y={},showText:p,loadingText:g="Loading...","aria-label":h,"data-testid":f,fullscreen:v,screenWidth:x,screenHeight:w,loaderCenter:E,screenBackground:C,...k}=r,N=t(()=>b("wave-loader"),[]),z=t(()=>{const e="number"==typeof i?i:parseInt(o(i));return{width:Math.max(e/10,3),height:e,spacing:Math.max(e/8,4)}},[i]);if(!c)return null;const T={display:"inline-flex",flexDirection:"column",alignItems:"center",...y,...v&&{position:"fixed",top:0,left:0,width:x||"100vw",height:w||"100vh",backgroundColor:C||"var(--react-loadly-background)",zIndex:9999,justifyContent:E?"center":y.justifyContent}};return e.createElement("div",{className:$("react-loadly react-loadly-wave",m),style:T,role:"status","aria-label":h,"aria-live":"polite","aria-busy":c,"data-testid":f,...k},e.createElement(I,{count:u,lineWidth:z.width,lineHeight:z.height,color:n,secondaryColor:s,speed:d,arrangement:"staggered",orientation:"vertical",animationType:"wave",spacing:z.spacing,"data-testid":f?`${f}-lines`:void 0}),p&&e.createElement("div",{className:"react-loadly-text",id:`${N}-text`,"aria-live":"polite"},g),e.createElement("span",{className:"react-loadly-sr-only"},h))},ye=(e={})=>{const{initialLoading:t=!1,timeout:l,maxRetries:o=3,onLoadingChange:s,onError:d,onProgress:c}=e,[u,m]=r({isLoading:t,progress:0,error:null,retryCount:0}),y=a(null),p=a(null);i(()=>()=>{y.current&&clearTimeout(y.current),p.current&&clearTimeout(p.current)},[]),i(()=>(u.isLoading&&l?y.current=setTimeout(()=>{m(e=>({...e,isLoading:!1,error:"Loading timeout exceeded"})),d?.("Loading timeout exceeded")},l):y.current&&clearTimeout(y.current),()=>{y.current&&clearTimeout(y.current)}),[u.isLoading,l,d]),i(()=>{s?.(u.isLoading)},[u.isLoading,s]),i(()=>{void 0!==u.progress&&c?.(u.progress)},[u.progress,c]);const g=n(e=>{m(t=>({...t,isLoading:e,error:e?null:t.error,progress:e?0:t.progress}))},[]),h=n(e=>{const t=Math.min(Math.max(e,0),100);m(e=>({...e,progress:t,isLoading:!(t>=100)&&e.isLoading}))},[]),f=n(e=>{m(t=>({...t,error:e,isLoading:!1})),e&&d?.(e)},[d]),v=n(()=>{m(e=>{const t=(e.retryCount||0)+1;return t>o?(d?.("Maximum retry attempts exceeded"),{...e,error:"Maximum retry attempts exceeded",isLoading:!1}):{...e,retryCount:t,isLoading:!0,error:null,progress:0}});const e=Math.min(1e3*Math.pow(2,u.retryCount||0),3e4);p.current=setTimeout(()=>{m(e=>({...e,isLoading:!0}))},e)},[u.retryCount,o,d]),b=n(()=>{m({isLoading:!1,progress:0,error:null,retryCount:0}),y.current&&clearTimeout(y.current),p.current&&clearTimeout(p.current)},[]);return{state:u,setLoading:g,setProgress:h,setError:f,retry:v,reset:b}},pe=(e,t={})=>e.reduce((e,a)=>(e[a]=ye(t),e),{}),ge=(e,t=[],a={})=>{const l=ye(a),[o,s]=r(null),d=n(async()=>{try{l.setLoading(!0),l.setError(null);const t=await e();return s(t),l.setProgress(100),t}catch(t){const e=t instanceof Error?t.message:"Unknown error occurred";return l.setError(e),null}},[e,l]);return i(()=>{d()},t),{...l,data:o,execute:d}};export{L as BarsLoader,M as BlobLoader,j as BounceLoader,k as Circle,w as Dot,N as DotCluster,S as DotsLoader,B as ElementLoader,q as FallbackLoader,Y as FlowLoader,V as GridLoader,E as Line,I as LineGroup,_ as LiquidLoader,J as LogoSpinLoader,Q as PulseLoader,C as Rectangle,ee as RingLoader,ae as RotateLoader,z as ShapeGroup,ie as ShimmerLoader,le as SkeletonLoader,se as SpinLoader,ce as TypingLoader,me as WaveLoader,h as clamp,$ as classNameGen,c as createAnimationName,g as createAnimationString,s as generateCSSVariables,b as generateId,y as getAnimationDirection,d as getAnimationDuration,p as getAnimationEasing,m as getOptimizedAnimationSettings,o as getSizeValue,f as hexToRgb,l as mergeProps,u as prefersReducedMotion,v as rgba,x as sanitizeCSSValue,ge as useAsyncLoader,ye as useLoaderState,pe as useMultipleLoaderStates};
1663
2
  //# sourceMappingURL=index.esm.js.map