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