react-loadly 1.0.0 → 1.1.0

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