react-loadly 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +142 -34
  2. package/dist/{index.js → index.cjs.js} +660 -367
  3. package/dist/index.cjs.js.map +1 -0
  4. package/dist/index.d.ts +84 -30
  5. package/dist/index.esm.js +644 -352
  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/types/@types/interfaces/IBaseLoaderProps.d.ts +10 -0
  10. package/dist/types/@types/interfaces/IBaseLoaderProps.d.ts.map +1 -1
  11. package/dist/types/@types/interfaces/IElementLoaderProps.d.ts +11 -0
  12. package/dist/types/@types/interfaces/IElementLoaderProps.d.ts.map +1 -0
  13. package/dist/types/@types/interfaces/IFallbackLoaderProps.d.ts +2 -1
  14. package/dist/types/@types/interfaces/IFallbackLoaderProps.d.ts.map +1 -1
  15. package/dist/types/@types/interfaces/ILogoLoaderProps.d.ts +1 -1
  16. package/dist/types/@types/interfaces/ILogoLoaderProps.d.ts.map +1 -1
  17. package/dist/types/@types/interfaces/ITextLoaderProps.d.ts +1 -2
  18. package/dist/types/@types/interfaces/ITextLoaderProps.d.ts.map +1 -1
  19. package/dist/types/__tests__/ElementLoader.example.d.ts +4 -0
  20. package/dist/types/__tests__/ElementLoader.example.d.ts.map +1 -0
  21. package/dist/types/components/atoms/Circle.d.ts +2 -1
  22. package/dist/types/components/atoms/Circle.d.ts.map +1 -1
  23. package/dist/types/components/atoms/Dot.d.ts +1 -1
  24. package/dist/types/components/atoms/Dot.d.ts.map +1 -1
  25. package/dist/types/components/atoms/Line.d.ts +1 -1
  26. package/dist/types/components/atoms/Line.d.ts.map +1 -1
  27. package/dist/types/components/atoms/Rectangle.d.ts +1 -0
  28. package/dist/types/components/atoms/Rectangle.d.ts.map +1 -1
  29. package/dist/types/components/molecules/DotCluster.d.ts +1 -0
  30. package/dist/types/components/molecules/DotCluster.d.ts.map +1 -1
  31. package/dist/types/components/molecules/LineGroup.d.ts +1 -0
  32. package/dist/types/components/molecules/LineGroup.d.ts.map +1 -1
  33. package/dist/types/components/molecules/ShapeGroup.d.ts +1 -0
  34. package/dist/types/components/molecules/ShapeGroup.d.ts.map +1 -1
  35. package/dist/types/components/organisms/BarsLoader.d.ts.map +1 -1
  36. package/dist/types/components/organisms/BlobLoader.d.ts.map +1 -1
  37. package/dist/types/components/organisms/BounceLoader.d.ts.map +1 -1
  38. package/dist/types/components/organisms/DotsLoader.d.ts.map +1 -1
  39. package/dist/types/components/organisms/ElementLoader.d.ts +27 -0
  40. package/dist/types/components/organisms/ElementLoader.d.ts.map +1 -0
  41. package/dist/types/components/organisms/FallbackLoader.d.ts.map +1 -1
  42. package/dist/types/components/organisms/FlowLoader.d.ts.map +1 -1
  43. package/dist/types/components/organisms/GridLoader.d.ts.map +1 -1
  44. package/dist/types/components/organisms/LiquidLoader.d.ts.map +1 -1
  45. package/dist/types/components/organisms/LogoSpinLoader.d.ts.map +1 -1
  46. package/dist/types/components/organisms/PulseLoader.d.ts.map +1 -1
  47. package/dist/types/components/organisms/RingLoader.d.ts.map +1 -1
  48. package/dist/types/components/organisms/RotateLoader.d.ts.map +1 -1
  49. package/dist/types/components/organisms/SpinLoader.d.ts.map +1 -1
  50. package/dist/types/components/organisms/TypingLoader.d.ts.map +1 -1
  51. package/dist/types/components/organisms/WaveLoader.d.ts.map +1 -1
  52. package/dist/types/components/organisms/index.d.ts +6 -5
  53. package/dist/types/components/organisms/index.d.ts.map +1 -1
  54. package/dist/types/hooks/useLoaderState.d.ts.map +1 -1
  55. package/package.json +11 -21
  56. package/dist/index.js.map +0 -1
package/dist/index.esm.js CHANGED
@@ -1,5 +1,4 @@
1
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { useMemo, useRef, useState, useEffect, useCallback } from 'react';
1
+ import React, { useMemo, useRef, useState, useEffect, useCallback } from 'react';
3
2
 
4
3
  /**
5
4
  * Merges default props with user props, handling undefined values gracefully
@@ -171,7 +170,7 @@ const Dot = ({ size = 8, color = "var(--react-loadly-color)", opacity = 1, class
171
170
  boxShadow: glowIntensity > 0 ? `0 0 ${glowIntensity * 10}px ${color}` : undefined,
172
171
  ...style,
173
172
  };
174
- return jsx("div", { className: `react-loadly-dot ${className}`.trim(), style: dotStyle, "data-testid": dataTestId, ...props });
173
+ return React.createElement("div", { className: `react-loadly-dot ${className}`.trim(), style: dotStyle, "data-testid": dataTestId, ...props });
175
174
  };
176
175
 
177
176
  const Line = ({ width = 30, height = 4, color = "var(--react-loadly-color)", opacity = 1, borderRadius = 2, className = "", style = {}, animation, animationDuration, animationDelay, orientation = "horizontal", "data-testid": dataTestId, ...props }) => {
@@ -189,7 +188,7 @@ const Line = ({ width = 30, height = 4, color = "var(--react-loadly-color)", opa
189
188
  display: "inline-block",
190
189
  ...style,
191
190
  };
192
- return (jsx("div", { className: `react-loadly-line react-loadly-line-${orientation} ${className}`.trim(), style: lineStyle, "data-testid": dataTestId, ...props }));
191
+ return (React.createElement("div", { className: `react-loadly-line react-loadly-line-${orientation} ${className}`.trim(), style: lineStyle, "data-testid": dataTestId, ...props }));
193
192
  };
194
193
 
195
194
  const Rectangle = ({ width = 20, height = 20, color = "var(--react-loadly-color)", borderColor, borderWidth = 0, borderRadius = 0, opacity = 1, className = "", style = {}, animation, animationDuration, animationDelay, "data-testid": dataTestId, ...props }) => {
@@ -209,7 +208,7 @@ const Rectangle = ({ width = 20, height = 20, color = "var(--react-loadly-color)
209
208
  display: "inline-block",
210
209
  ...style,
211
210
  };
212
- return jsx("div", { className: `react-loadly-rectangle ${className}`.trim(), style: rectangleStyle, "data-testid": dataTestId, ...props });
211
+ return React.createElement("div", { className: `react-loadly-rectangle ${className}`.trim(), style: rectangleStyle, "data-testid": dataTestId, ...props });
213
212
  };
214
213
 
215
214
  const Circle = ({ size = 20, color = "var(--react-loadly-color)", borderColor, borderWidth = 0, opacity = 1, className = "", style = {}, animation, animationDuration, animationDelay, "data-testid": dataTestId, ...props }) => {
@@ -227,7 +226,7 @@ const Circle = ({ size = 20, color = "var(--react-loadly-color)", borderColor, b
227
226
  display: "inline-block",
228
227
  ...style,
229
228
  };
230
- return jsx("div", { className: `react-loadly-circle ${className}`.trim(), style: circleStyle, "data-testid": dataTestId, ...props });
229
+ return React.createElement("div", { className: `react-loadly-circle ${className}`.trim(), style: circleStyle, "data-testid": dataTestId, ...props });
231
230
  };
232
231
 
233
232
  const DotCluster = ({ count = 3, dotSize = 8, color = "var(--react-loadly-color)", secondaryColor, spacing = 8, speed = 1, arrangement = "linear", className = "", style = {}, animationType = "wave", "data-testid": dataTestId, ...props }) => {
@@ -280,7 +279,7 @@ const DotCluster = ({ count = 3, dotSize = 8, color = "var(--react-loadly-color)
280
279
  ...getArrangementStyle(),
281
280
  ...style,
282
281
  };
283
- return (jsx("div", { className: `react-loadly-dot-cluster react-loadly-dot-cluster-${arrangement} ${className}`.trim(), style: containerStyle, "data-testid": dataTestId, ...props, children: Array.from({ length: count }, (_, index) => (jsx(Dot, { size: dotSize, color: secondaryColor && index % 2 === 1 ? secondaryColor : color, animation: `react-loadly-${animationType}`, animationDuration: animationDuration, animationDelay: getDotAnimationDelay(index), style: getDotPosition(index), "data-testid": dataTestId ? `${dataTestId}-dot-${index}` : undefined }, index))) }));
282
+ return (React.createElement("div", { className: `react-loadly-dot-cluster react-loadly-dot-cluster-${arrangement} ${className}`.trim(), style: containerStyle, "data-testid": dataTestId, ...props }, Array.from({ length: count }, (_, index) => (React.createElement(Dot, { key: index, size: dotSize, color: secondaryColor && index % 2 === 1 ? secondaryColor : color, animation: `react-loadly-${animationType}`, animationDuration: animationDuration, animationDelay: getDotAnimationDelay(index), style: getDotPosition(index), "data-testid": dataTestId ? `${dataTestId}-dot-${index}` : undefined })))));
284
283
  };
285
284
 
286
285
  const LineGroup = ({ count = 5, lineWidth = 4, lineHeight = 35, color = "var(--react-loadly-color)", secondaryColor, spacing = 6, speed = 1, arrangement = "parallel", orientation = "vertical", className = "", style = {}, animationType = "wave", "data-testid": dataTestId, ...props }) => {
@@ -339,7 +338,7 @@ const LineGroup = ({ count = 5, lineWidth = 4, lineHeight = 35, color = "var(--r
339
338
  ...getArrangementStyle(),
340
339
  ...style,
341
340
  };
342
- return (jsx("div", { className: `react-loadly-line-group react-loadly-line-group-${arrangement} ${className}`.trim(), style: containerStyle, "data-testid": dataTestId, ...props, children: Array.from({ length: count }, (_, index) => (jsx(Line, { width: orientation === "horizontal" ? lineWidth : lineHeight, height: orientation === "horizontal" ? lineHeight : lineWidth, color: secondaryColor && index % 2 === 1 ? secondaryColor : color, orientation: orientation, animation: `react-loadly-${animationType}`, animationDuration: animationDuration, animationDelay: getLineAnimationDelay(index), style: getLinePosition(index), "data-testid": dataTestId ? `${dataTestId}-line-${index}` : undefined }, index))) }));
341
+ return (React.createElement("div", { className: `react-loadly-line-group react-loadly-line-group-${arrangement} ${className}`.trim(), style: containerStyle, "data-testid": dataTestId, ...props }, Array.from({ length: count }, (_, index) => (React.createElement(Line, { key: index, width: orientation === "horizontal" ? lineWidth : lineHeight, height: orientation === "horizontal" ? lineHeight : lineWidth, color: secondaryColor && index % 2 === 1 ? secondaryColor : color, orientation: orientation, animation: `react-loadly-${animationType}`, animationDuration: animationDuration, animationDelay: getLineAnimationDelay(index), style: getLinePosition(index), "data-testid": dataTestId ? `${dataTestId}-line-${index}` : undefined })))));
343
342
  };
344
343
 
345
344
  const ShapeGroup = ({ count = 4, shapeSize = 16, color = "var(--react-loadly-color)", secondaryColor, spacing = 8, speed = 1, arrangement = "linear", shapeTypes = ["circle", "rectangle"], className = "", style = {}, animationType = "pulse", borderWidth = 0, "data-testid": dataTestId, ...props }) => {
@@ -421,13 +420,75 @@ const ShapeGroup = ({ count = 4, shapeSize = 16, color = "var(--react-loadly-col
421
420
  "data-testid": dataTestId ? `${dataTestId}-shape-${index}` : undefined,
422
421
  };
423
422
  if (shapeType === "circle") {
424
- return jsx(Circle, { ...commonProps, size: shapeSize });
423
+ return React.createElement(Circle, { ...commonProps, size: shapeSize });
425
424
  }
426
425
  else {
427
- return jsx(Rectangle, { ...commonProps, width: shapeSize, height: shapeSize });
426
+ return React.createElement(Rectangle, { ...commonProps, width: shapeSize, height: shapeSize });
428
427
  }
429
428
  };
430
- return (jsx("div", { className: `react-loadly-shape-group react-loadly-shape-group-${arrangement} ${className}`.trim(), style: containerStyle, "data-testid": dataTestId, ...props, children: Array.from({ length: count }, (_, index) => renderShape(index)) }));
429
+ return (React.createElement("div", { className: `react-loadly-shape-group react-loadly-shape-group-${arrangement} ${className}`.trim(), style: containerStyle, "data-testid": dataTestId, ...props }, Array.from({ length: count }, (_, index) => renderShape(index))));
430
+ };
431
+
432
+ const defaultProps$e = {
433
+ size: 20,
434
+ color: "var(--react-loadly-color)",
435
+ speed: 1,
436
+ loading: true,
437
+ count: 5,
438
+ "aria-label": "Loading...",
439
+ };
440
+ const BarsLoader = (userProps) => {
441
+ const props = mergeProps(defaultProps$e, userProps);
442
+ const { size, color, speed, loading, className = "", style = {}, count = 5, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
443
+ const id = useMemo(() => generateId("bars-loader"), []);
444
+ const sizeValue = getSizeValue(size);
445
+ const animationSettings = getOptimizedAnimationSettings(speed);
446
+ if (!loading)
447
+ return null;
448
+ const containerStyle = {
449
+ display: "inline-flex",
450
+ flexDirection: "column",
451
+ alignItems: "center",
452
+ ...style,
453
+ ...(fullscreen && {
454
+ position: "fixed",
455
+ top: 0,
456
+ left: 0,
457
+ width: screenWidth || "100vw",
458
+ height: screenHeight || "100vh",
459
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
460
+ zIndex: 9999,
461
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
462
+ }),
463
+ };
464
+ const barsContainerStyle = {
465
+ display: "flex",
466
+ justifyContent: "center",
467
+ alignItems: "center",
468
+ gap: "4px",
469
+ };
470
+ const barStyle = {
471
+ width: "4px",
472
+ height: sizeValue,
473
+ backgroundColor: color,
474
+ borderRadius: "2px",
475
+ animation: `react-loadly-bars ${animationSettings.duration} ease-in-out infinite`,
476
+ animationPlayState: animationSettings.playState,
477
+ };
478
+ // Create bars with different animation delays
479
+ const bars = Array.from({ length: count }).map((_, index) => {
480
+ const delay = `${index * 0.1}s`;
481
+ const heightFactor = 0.5 + (index % 3) * 0.25; // Vary heights for visual interest
482
+ return (React.createElement("div", { key: index, style: {
483
+ ...barStyle,
484
+ animationDelay: delay,
485
+ height: `${parseFloat(sizeValue) * heightFactor}px`,
486
+ }, "data-testid": dataTestId ? `${dataTestId}-bar-${index}` : undefined }));
487
+ });
488
+ return (React.createElement("div", { className: `react-loadly react-loadly-bars ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
489
+ React.createElement("div", { style: barsContainerStyle }, bars),
490
+ showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
491
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
431
492
  };
432
493
 
433
494
  const defaultProps$d = {
@@ -473,7 +534,8 @@ const BlobLoader = (userProps) => {
473
534
  animation: `blob-inner ${animationDuration} ease-in-out infinite reverse`,
474
535
  opacity: 0.7,
475
536
  };
476
- return (jsxs(Fragment, { children: [jsx("style", { children: `
537
+ return (React.createElement(React.Fragment, null,
538
+ React.createElement("style", null, `
477
539
  @keyframes blob-morph {
478
540
  0%, 100% {
479
541
  border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
@@ -507,21 +569,244 @@ const BlobLoader = (userProps) => {
507
569
  transform: scale(${0.9 + (fluidity ?? 1) * 0.05}) rotate(-240deg);
508
570
  }
509
571
  }
510
- ` }), jsxs("div", { className: `react-loadly react-loadly-blob ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx("div", { style: blobStyle, "data-testid": dataTestId ? `${dataTestId}-blob` : undefined, children: jsx("div", { style: innerBlobStyle }) }), showText && (jsx("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite", children: loadingText })), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] })] }));
572
+ `),
573
+ React.createElement("div", { className: `react-loadly react-loadly-blob ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
574
+ React.createElement("div", { style: blobStyle, "data-testid": dataTestId ? `${dataTestId}-blob` : undefined },
575
+ React.createElement("div", { style: innerBlobStyle })),
576
+ showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
577
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel))));
578
+ };
579
+
580
+ const defaultProps$c = {
581
+ size: 15,
582
+ color: "var(--react-loadly-color)",
583
+ speed: 1,
584
+ loading: true,
585
+ count: 3,
586
+ "aria-label": "Loading...",
587
+ };
588
+ const BounceLoader = (userProps) => {
589
+ const props = mergeProps(defaultProps$c, userProps);
590
+ const { size, color, speed, loading, className = "", style = {}, count = 3, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
591
+ const id = useMemo(() => generateId("bounce-loader"), []);
592
+ const sizeValue = getSizeValue(size);
593
+ const animationSettings = getOptimizedAnimationSettings(speed);
594
+ if (!loading)
595
+ return null;
596
+ const containerStyle = {
597
+ display: "inline-flex",
598
+ flexDirection: "column",
599
+ alignItems: "center",
600
+ ...style,
601
+ ...(fullscreen && {
602
+ position: "fixed",
603
+ top: 0,
604
+ left: 0,
605
+ width: screenWidth || "100vw",
606
+ height: screenHeight || "100vh",
607
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
608
+ zIndex: 9999,
609
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
610
+ }),
611
+ };
612
+ const bounceContainerStyle = {
613
+ display: "flex",
614
+ justifyContent: "center",
615
+ alignItems: "center",
616
+ gap: "8px",
617
+ };
618
+ const bounceBallStyle = {
619
+ width: sizeValue,
620
+ height: sizeValue,
621
+ borderRadius: "50%",
622
+ backgroundColor: color,
623
+ animation: `react-loadly-bounce ${animationSettings.duration} ease-in-out infinite`,
624
+ animationPlayState: animationSettings.playState,
625
+ };
626
+ // Create bounce animation delays for each ball
627
+ const balls = Array.from({ length: count }).map((_, index) => {
628
+ const delay = `${index * 0.1}s`;
629
+ return (React.createElement("div", { key: index, style: {
630
+ ...bounceBallStyle,
631
+ animationDelay: delay,
632
+ }, "data-testid": dataTestId ? `${dataTestId}-ball-${index}` : undefined }));
633
+ });
634
+ return (React.createElement("div", { className: `react-loadly react-loadly-bounce ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
635
+ React.createElement("div", { style: bounceContainerStyle }, balls),
636
+ showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
637
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
638
+ };
639
+
640
+ const defaultProps$b = {
641
+ size: 12,
642
+ color: "var(--react-loadly-color)",
643
+ speed: 1,
644
+ loading: true,
645
+ count: 3,
646
+ "aria-label": "Loading...",
647
+ };
648
+ const DotsLoader = (userProps) => {
649
+ const props = mergeProps(defaultProps$b, userProps);
650
+ const { size, color, speed, loading, className = "", style = {}, count = 3, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
651
+ const id = useMemo(() => generateId("dots-loader"), []);
652
+ const sizeValue = getSizeValue(size);
653
+ const animationSettings = getOptimizedAnimationSettings(speed);
654
+ if (!loading)
655
+ return null;
656
+ const containerStyle = {
657
+ display: "inline-flex",
658
+ flexDirection: "column",
659
+ alignItems: "center",
660
+ ...style,
661
+ ...(fullscreen && {
662
+ position: "fixed",
663
+ top: 0,
664
+ left: 0,
665
+ width: screenWidth || "100vw",
666
+ height: screenHeight || "100vh",
667
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
668
+ zIndex: 9999,
669
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
670
+ }),
671
+ };
672
+ const dotsContainerStyle = {
673
+ display: "flex",
674
+ justifyContent: "center",
675
+ alignItems: "center",
676
+ gap: "6px",
677
+ };
678
+ const dotStyle = {
679
+ width: sizeValue,
680
+ height: sizeValue,
681
+ borderRadius: "50%",
682
+ backgroundColor: color,
683
+ animation: `react-loadly-dots ${animationSettings.duration} ease-in-out infinite`,
684
+ animationPlayState: animationSettings.playState,
685
+ };
686
+ // Create dots with different animation delays
687
+ const dots = Array.from({ length: count }).map((_, index) => {
688
+ const delay = `${index * 0.2}s`;
689
+ return (React.createElement("div", { key: index, style: {
690
+ ...dotStyle,
691
+ animationDelay: delay,
692
+ }, "data-testid": dataTestId ? `${dataTestId}-dot-${index}` : undefined }));
693
+ });
694
+ return (React.createElement("div", { className: `react-loadly react-loadly-dots ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
695
+ React.createElement("div", { style: dotsContainerStyle }, dots),
696
+ showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
697
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
698
+ };
699
+
700
+ const defaultProps$a = {
701
+ size: 60,
702
+ speed: 1,
703
+ loading: true,
704
+ animationType: "spin",
705
+ glowIntensity: 0.3,
706
+ "aria-label": "Loading...",
707
+ };
708
+ const ElementLoader = (userProps) => {
709
+ const props = mergeProps(defaultProps$a, userProps);
710
+ const { size, width, height, speed = 1, loading, animationType, glowIntensity, className = "", style = {}, color = "var(--react-loadly-color)", "aria-label": ariaLabel, loadingText, showText, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, children, ...restProps } = props;
711
+ if (!loading)
712
+ return null;
713
+ const containerStyle = {
714
+ display: "inline-flex",
715
+ flexDirection: "column",
716
+ alignItems: "center",
717
+ ...style,
718
+ ...(fullscreen && {
719
+ position: "fixed",
720
+ top: 0,
721
+ left: 0,
722
+ width: screenWidth || "100vw",
723
+ height: screenHeight || "100vh",
724
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
725
+ zIndex: 9999,
726
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
727
+ }),
728
+ };
729
+ // Enhanced animation variants for ElementLoader
730
+ const getAnimation = () => {
731
+ switch (animationType) {
732
+ case "pulse":
733
+ return `react-loadly-pulse ${getAnimationDuration(2000, speed)} infinite`;
734
+ case "glow":
735
+ return `react-loadly-glow ${getAnimationDuration(2000, speed)} infinite`;
736
+ case "bounce":
737
+ return `react-loadly-bounce ${getAnimationDuration(2000, speed)} infinite`;
738
+ case "flip":
739
+ return `react-loadly-flip ${getAnimationDuration(2000, speed)} infinite`;
740
+ case "spin":
741
+ default:
742
+ return `react-loadly-spin ${getAnimationDuration(2000, speed)} infinite`;
743
+ }
744
+ };
745
+ // Calculate dimensions, prioritizing width/height props over size
746
+ const elementWidth = width || size;
747
+ const elementHeight = height || size;
748
+ const elementStyle = {
749
+ width: typeof elementWidth === "number" ? `${elementWidth}px` : elementWidth,
750
+ height: typeof elementHeight === "number" ? `${elementHeight}px` : elementHeight,
751
+ animation: getAnimation(),
752
+ filter: (glowIntensity ?? 0) > 0 ? `drop-shadow(0 0 ${(glowIntensity ?? 0) * 20}px ${color})` : undefined,
753
+ transformStyle: "preserve-3d",
754
+ willChange: "transform",
755
+ display: "flex",
756
+ alignItems: "center",
757
+ justifyContent: "center",
758
+ };
759
+ // Add additional animated elements for enhanced visual effect
760
+ const innerElementStyle = {
761
+ position: "absolute",
762
+ top: "50%",
763
+ left: "50%",
764
+ width: "60%",
765
+ height: "60%",
766
+ borderRadius: "50%",
767
+ backgroundColor: color,
768
+ opacity: 0.3,
769
+ transform: "translate(-50%, -50%)",
770
+ animation: `react-loadly-pulse ${getAnimationDuration(1500, speed * 1.5)} infinite`,
771
+ zIndex: -1,
772
+ };
773
+ const outerElementStyle = {
774
+ position: "absolute",
775
+ top: "50%",
776
+ left: "50%",
777
+ width: "120%",
778
+ height: "120%",
779
+ borderRadius: "50%",
780
+ border: `2px solid ${color}`,
781
+ opacity: 0.2,
782
+ transform: "translate(-50%, -50%)",
783
+ animation: `react-loadly-spin ${getAnimationDuration(3000, speed * 0.8)} infinite reverse`,
784
+ zIndex: -2,
785
+ };
786
+ return (React.createElement("div", { className: `react-loadly react-loadly-element-loader ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
787
+ React.createElement("div", { style: { position: "relative", display: "flex", alignItems: "center", justifyContent: "center" } },
788
+ React.createElement("div", { style: outerElementStyle }),
789
+ React.createElement("div", { style: innerElementStyle }),
790
+ React.createElement("div", { style: elementStyle, className: "react-loadly-element", "data-testid": dataTestId ? `${dataTestId}-element` : undefined }, children)),
791
+ showText && (React.createElement("div", { className: "react-loadly-text", "aria-live": "polite" }, loadingText || ariaLabel)),
792
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
511
793
  };
512
794
 
513
- const ErrorIcon = ({ className = "" }) => (jsx("svg", { className: className, fill: "currentColor", viewBox: "0 0 20 20", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: jsx("path", { clipRule: "evenodd", fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z" }) }));
514
- const NetworkIcon = ({ className = "" }) => (jsx("svg", { className: className, fill: "currentColor", viewBox: "0 0 20 20", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: jsx("path", { fillRule: "evenodd", d: "M9.243 3.03a1 1 0 01.727 1.213L9.53 6h2.94l.56-2.243a1 1 0 111.94.486L14.53 6H16a1 1 0 110 2h-1.97l-1 4H15a1 1 0 110 2h-2.47l-.56 2.242a1 1 0 11-1.94-.485L10.47 14H7.53l-.56 2.242a1 1 0 11-1.94-.485L5.47 14H4a1 1 0 110-2h1.97l1-4H5a1 1 0 110-2h2.47l.56-2.243a1 1 0 011.213-.727zM9.03 8l-1 4h2.94l1-4H9.03z", clipRule: "evenodd" }) }));
515
- const TimeoutIcon = ({ className = "" }) => (jsx("svg", { className: className, fill: "currentColor", viewBox: "0 0 20 20", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z", clipRule: "evenodd" }) }));
516
- const FallbackLoader = ({ error = "Something went wrong", onRetry, showRetry = true, children, type = "error" }) => {
795
+ const ErrorIcon = ({ className = "" }) => (React.createElement("svg", { className: className, fill: "currentColor", viewBox: "0 0 20 20", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" },
796
+ React.createElement("path", { clipRule: "evenodd", fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z" })));
797
+ const NetworkIcon = ({ className = "" }) => (React.createElement("svg", { className: className, fill: "currentColor", viewBox: "0 0 20 20", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" },
798
+ React.createElement("path", { fillRule: "evenodd", d: "M9.243 3.03a1 1 0 01.727 1.213L9.53 6h2.94l.56-2.243a1 1 0 111.94.486L14.53 6H16a1 1 0 110 2h-1.97l-1 4H15a1 1 0 110 2h-2.47l-.56 2.242a1 1 0 11-1.94-.485L10.47 14H7.53l-.56 2.242a1 1 0 11-1.94-.485L5.47 14H4a1 1 0 110-2h1.97l1-4H5a1 1 0 110-2h2.47l.56-2.243a1 1 0 011.213-.727zM9.03 8l-1 4h2.94l1-4H9.03z", clipRule: "evenodd" })));
799
+ const TimeoutIcon = ({ className = "" }) => (React.createElement("svg", { className: className, fill: "currentColor", viewBox: "0 0 20 20", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" },
800
+ React.createElement("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z", clipRule: "evenodd" })));
801
+ const FallbackLoader = ({ error = "Something went wrong", onRetry, showRetry = true, children, type = "error", className = "", style = {}, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps }) => {
517
802
  const getIcon = () => {
518
803
  switch (type) {
519
804
  case "network":
520
- return jsx(NetworkIcon, { className: "react-loadly-error-icon" });
805
+ return React.createElement(NetworkIcon, { className: "react-loadly-error-icon" });
521
806
  case "timeout":
522
- return jsx(TimeoutIcon, { className: "react-loadly-error-icon" });
807
+ return React.createElement(TimeoutIcon, { className: "react-loadly-error-icon" });
523
808
  default:
524
- return jsx(ErrorIcon, { className: "react-loadly-error-icon" });
809
+ return React.createElement(ErrorIcon, { className: "react-loadly-error-icon" });
525
810
  }
526
811
  };
527
812
  const getMessage = () => {
@@ -534,13 +819,32 @@ const FallbackLoader = ({ error = "Something went wrong", onRetry, showRetry = t
534
819
  return error || "Something went wrong. Please try again.";
535
820
  }
536
821
  };
822
+ const containerStyle = {
823
+ ...style,
824
+ ...(fullscreen && {
825
+ position: "fixed",
826
+ top: 0,
827
+ left: 0,
828
+ width: screenWidth || "100vw",
829
+ height: screenHeight || "100vh",
830
+ backgroundColor: screenBackground || "var(--react-loadly-error-background)",
831
+ zIndex: 9999,
832
+ display: "flex",
833
+ flexDirection: "column",
834
+ alignItems: "center",
835
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
836
+ }),
837
+ };
537
838
  if (children) {
538
- return jsx("div", { className: "react-loadly-fallback", children: children });
839
+ return React.createElement("div", { className: `react-loadly-fallback ${className}`.trim(), style: containerStyle, ...restProps }, children);
539
840
  }
540
- return (jsxs("div", { className: "react-loadly-error", role: "alert", "aria-live": "polite", children: [getIcon(), jsx("p", { className: "react-loadly-error-message", children: getMessage() }), showRetry && onRetry && (jsx("button", { className: "react-loadly-retry-button", onClick: onRetry, type: "button", "aria-label": "Retry loading", children: "Try Again" }))] }));
841
+ return (React.createElement("div", { className: `react-loadly-error ${className}`.trim(), style: containerStyle, role: "alert", "aria-live": "polite", ...restProps },
842
+ getIcon(),
843
+ React.createElement("p", { className: "react-loadly-error-message" }, getMessage()),
844
+ showRetry && onRetry && (React.createElement("button", { className: "react-loadly-retry-button", onClick: onRetry, type: "button", "aria-label": "Retry loading" }, "Try Again"))));
541
845
  };
542
846
 
543
- const defaultProps$c = {
847
+ const defaultProps$9 = {
544
848
  size: 60,
545
849
  color: "var(--react-loadly-color)",
546
850
  speed: 1,
@@ -550,8 +854,8 @@ const defaultProps$c = {
550
854
  "aria-label": "Loading...",
551
855
  };
552
856
  const FlowLoader = (userProps) => {
553
- const props = mergeProps(defaultProps$c, userProps);
554
- const { size, color, secondaryColor, speed, loading, amplitude, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
857
+ const props = mergeProps(defaultProps$9, userProps);
858
+ const { size, color, secondaryColor, speed, loading, amplitude, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
555
859
  const id = useMemo(() => generateId("flow-loader"), []);
556
860
  const sizeValue = getSizeValue(size);
557
861
  const numericSize = parseInt(sizeValue);
@@ -564,6 +868,16 @@ const FlowLoader = (userProps) => {
564
868
  flexDirection: "column",
565
869
  alignItems: "center",
566
870
  ...style,
871
+ ...(fullscreen && {
872
+ position: "fixed",
873
+ top: 0,
874
+ left: 0,
875
+ width: screenWidth || "100vw",
876
+ height: screenHeight || "100vh",
877
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
878
+ zIndex: 9999,
879
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
880
+ }),
567
881
  };
568
882
  const flowContainerStyle = {
569
883
  width: sizeValue,
@@ -581,7 +895,7 @@ const FlowLoader = (userProps) => {
581
895
  // Scale particle size based on container size
582
896
  const minParticleSize = Math.max(numericSize / 10, 4); // Minimum 4px
583
897
  const particleSize = minParticleSize + (index % 3) * (minParticleSize / 2);
584
- return (jsx("div", { style: {
898
+ return (React.createElement("div", { key: index, style: {
585
899
  position: "absolute",
586
900
  width: `${particleSize}px`,
587
901
  height: `${particleSize}px`,
@@ -592,9 +906,10 @@ const FlowLoader = (userProps) => {
592
906
  opacity: 0.8 - index * 0.1,
593
907
  left: "0px", // Start at the beginning of the container
594
908
  top: `${(containerHeight - particleSize) / 2 + (index % 3) * (containerHeight / (particleCount + 1))}px`, // Distribute vertically
595
- }, "data-testid": dataTestId ? `${dataTestId}-particle-${index}` : undefined }, index));
909
+ }, "data-testid": dataTestId ? `${dataTestId}-particle-${index}` : undefined }));
596
910
  };
597
- return (jsxs(Fragment, { children: [jsx("style", { children: `
911
+ return (React.createElement(React.Fragment, null,
912
+ React.createElement("style", null, `
598
913
  @keyframes flow-particle-${id} {
599
914
  0% {
600
915
  transform: translateX(0) translateY(0) scale(0);
@@ -617,10 +932,14 @@ const FlowLoader = (userProps) => {
617
932
  opacity: 0;
618
933
  }
619
934
  }
620
- ` }), jsxs("div", { className: `react-loadly react-loadly-flow ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx("div", { style: flowContainerStyle, "data-testid": dataTestId ? `${dataTestId}-container` : undefined, children: Array.from({ length: particleCount }, (_, index) => createParticle(index)) }), showText && (jsx("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite", children: loadingText })), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] })] }));
935
+ `),
936
+ React.createElement("div", { className: `react-loadly react-loadly-flow ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
937
+ React.createElement("div", { style: flowContainerStyle, "data-testid": dataTestId ? `${dataTestId}-container` : undefined }, Array.from({ length: particleCount }, (_, index) => createParticle(index))),
938
+ showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
939
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel))));
621
940
  };
622
941
 
623
- const defaultProps$b = {
942
+ const defaultProps$8 = {
624
943
  size: 40,
625
944
  color: "var(--react-loadly-color)",
626
945
  speed: 1,
@@ -629,8 +948,8 @@ const defaultProps$b = {
629
948
  "aria-label": "Loading...",
630
949
  };
631
950
  const GridLoader = (userProps) => {
632
- const props = mergeProps(defaultProps$b, userProps);
633
- const { size, color, secondaryColor, speed, loading, count, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
951
+ const props = mergeProps(defaultProps$8, userProps);
952
+ const { size, color, secondaryColor, speed = 1, loading, count, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
634
953
  const id = useMemo(() => generateId("grid-loader"), []);
635
954
  const shapeSize = useMemo(() => {
636
955
  const sizeNum = typeof size === "number" ? size : parseInt(getSizeValue(size));
@@ -644,22 +963,35 @@ const GridLoader = (userProps) => {
644
963
  flexDirection: "column",
645
964
  alignItems: "center",
646
965
  ...style,
966
+ ...(fullscreen && {
967
+ position: "fixed",
968
+ top: 0,
969
+ left: 0,
970
+ width: screenWidth || "100vw",
971
+ height: screenHeight || "100vh",
972
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
973
+ zIndex: 9999,
974
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
975
+ }),
647
976
  };
648
- return (jsxs("div", { className: `react-loadly react-loadly-grid ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx("div", { style: {
649
- display: "grid",
650
- gridTemplateColumns: `repeat(${Math.ceil(Math.sqrt(count || 4))}, 1fr)`,
651
- gap: `${shapeSize / 4}px`,
652
- }, children: Array.from({ length: count || 4 }, (_, index) => (jsx("div", { style: {
653
- width: shapeSize,
654
- height: shapeSize,
655
- backgroundColor: index % 2 === 0 ? color : secondaryColor || color,
656
- borderRadius: "2px",
657
- animation: `react-loadly-scale ${1.2 / (speed || 1)}s ease-in-out infinite`,
658
- animationDelay: `${(index * 0.1) / (speed || 1)}s`,
659
- }, "data-testid": dataTestId ? `${dataTestId}-shape-${index}` : undefined }, index))) }), showText && (jsx("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite", children: loadingText })), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] }));
977
+ return (React.createElement("div", { className: `react-loadly react-loadly-grid ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
978
+ React.createElement("div", { className: "react-loadly-grid-container", style: {
979
+ display: "grid",
980
+ gridTemplateColumns: `repeat(${Math.ceil(Math.sqrt(count || 4))}, 1fr)`,
981
+ gap: `${shapeSize / 3}px`,
982
+ }, "data-testid": dataTestId ? `${dataTestId}-grid` : undefined }, Array.from({ length: count || 4 }).map((_, index) => (React.createElement("div", { key: index, className: "react-loadly-grid-item", style: {
983
+ width: `${shapeSize}px`,
984
+ height: `${shapeSize}px`,
985
+ backgroundColor: index % 2 === 0 ? color : secondaryColor || color,
986
+ borderRadius: "20%",
987
+ animation: `react-loadly-scale ${1.2 / (speed || 1)}s ease-in-out infinite`,
988
+ animationDelay: `${(index * 0.1) / (speed || 1)}s`,
989
+ } })))),
990
+ showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
991
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
660
992
  };
661
993
 
662
- const defaultProps$a = {
994
+ const defaultProps$7 = {
663
995
  size: 60,
664
996
  color: "var(--react-loadly-color)",
665
997
  speed: 1,
@@ -669,8 +1001,8 @@ const defaultProps$a = {
669
1001
  "aria-label": "Loading...",
670
1002
  };
671
1003
  const LiquidLoader = (userProps) => {
672
- const props = mergeProps(defaultProps$a, userProps);
673
- const { size, color, secondaryColor, speed, loading, amplitude, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
1004
+ const props = mergeProps(defaultProps$7, userProps);
1005
+ const { size, color, secondaryColor, speed, loading, amplitude, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
674
1006
  const id = useMemo(() => generateId("liquid-loader"), []);
675
1007
  const sizeValue = getSizeValue(size);
676
1008
  const animationDuration = getAnimationDuration(2000, speed);
@@ -681,6 +1013,16 @@ const LiquidLoader = (userProps) => {
681
1013
  flexDirection: "column",
682
1014
  alignItems: "center",
683
1015
  ...style,
1016
+ ...(fullscreen && {
1017
+ position: "fixed",
1018
+ top: 0,
1019
+ left: 0,
1020
+ width: screenWidth || "100vw",
1021
+ height: screenHeight || "100vh",
1022
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
1023
+ zIndex: 9999,
1024
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
1025
+ }),
684
1026
  };
685
1027
  const liquidStyle = {
686
1028
  width: sizeValue,
@@ -711,7 +1053,8 @@ const LiquidLoader = (userProps) => {
711
1053
  animationDelay: `${ -0.5 / (speed ?? 1)}s`,
712
1054
  opacity: 0.8,
713
1055
  };
714
- return (jsxs(Fragment, { children: [jsx("style", { children: `
1056
+ return (React.createElement(React.Fragment, null,
1057
+ React.createElement("style", null, `
715
1058
  @keyframes react-loadly-liquid-wave {
716
1059
  0%, 100% {
717
1060
  transform: translate(-25%, 50%) rotate(0deg);
@@ -720,20 +1063,27 @@ const LiquidLoader = (userProps) => {
720
1063
  transform: translate(-25%, ${translateY}%) rotate(180deg);
721
1064
  }
722
1065
  }
723
- ` }), jsxs("div", { className: `react-loadly react-loadly-liquid ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsxs("div", { style: liquidStyle, "data-testid": dataTestId ? `${dataTestId}-container` : undefined, children: [jsx("div", { style: waveStyle }), jsx("div", { style: wave2Style })] }), showText && (jsx("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite", children: loadingText })), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] })] }));
1066
+ `),
1067
+ React.createElement("div", { className: `react-loadly react-loadly-liquid ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1068
+ React.createElement("div", { style: liquidStyle, "data-testid": dataTestId ? `${dataTestId}-container` : undefined },
1069
+ React.createElement("div", { style: waveStyle }),
1070
+ React.createElement("div", { style: wave2Style })),
1071
+ showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
1072
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel))));
724
1073
  };
725
1074
 
726
- const defaultProps$9 = {
1075
+ const defaultProps$6 = {
727
1076
  size: 60,
728
1077
  speed: 1,
729
1078
  loading: true,
730
1079
  animationType: "spin",
731
1080
  glowIntensity: 0.3,
732
1081
  "aria-label": "Loading...",
1082
+ alt: "Loading",
733
1083
  };
734
1084
  const LogoSpinLoader = (userProps) => {
735
- const props = mergeProps(defaultProps$9, userProps);
736
- const { src, alt = "Loading", size, speed, loading, animationType, glowIntensity, className = "", style = {}, color = "var(--react-loadly-color)", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
1085
+ const props = mergeProps(defaultProps$6, userProps);
1086
+ const { src, alt, size, speed, loading, animationType, glowIntensity, className = "", style = {}, color = "var(--react-loadly-color)", "aria-label": ariaLabel, loadingText, showText, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
737
1087
  if (!loading)
738
1088
  return null;
739
1089
  const containerStyle = {
@@ -741,6 +1091,16 @@ const LogoSpinLoader = (userProps) => {
741
1091
  flexDirection: "column",
742
1092
  alignItems: "center",
743
1093
  ...style,
1094
+ ...(fullscreen && {
1095
+ position: "fixed",
1096
+ top: 0,
1097
+ left: 0,
1098
+ width: screenWidth || "100vw",
1099
+ height: screenHeight || "100vh",
1100
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
1101
+ zIndex: 9999,
1102
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
1103
+ }),
744
1104
  };
745
1105
  const logoStyle = {
746
1106
  width: typeof size === "number" ? `${size}px` : size,
@@ -748,19 +1108,13 @@ const LogoSpinLoader = (userProps) => {
748
1108
  animation: `react-loadly-${animationType} ${getAnimationDuration(2000, speed)} infinite`,
749
1109
  filter: (glowIntensity ?? 0) > 0 ? `drop-shadow(0 0 ${(glowIntensity ?? 0) * 20}px ${color})` : undefined,
750
1110
  };
751
- // If no src provided, show a default loading circle
752
- if (!src) {
753
- return (jsxs("div", { className: `react-loadly react-loadly-logo ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx("div", { style: {
754
- ...logoStyle,
755
- borderRadius: "50%",
756
- backgroundColor: color,
757
- opacity: 0.8,
758
- }, "data-testid": dataTestId ? `${dataTestId}-default` : undefined }), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] }));
759
- }
760
- return (jsxs("div", { className: `react-loadly react-loadly-logo ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx("img", { src: src, alt: alt, style: logoStyle, "data-testid": dataTestId ? `${dataTestId}-image` : undefined }), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] }));
1111
+ return (React.createElement("div", { className: `react-loadly react-loadly-logo-spin ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1112
+ React.createElement("img", { src: src, alt: alt, style: logoStyle, className: "react-loadly-logo", "data-testid": dataTestId ? `${dataTestId}-logo` : undefined }),
1113
+ showText && (React.createElement("div", { className: "react-loadly-text", "aria-live": "polite" }, loadingText || ariaLabel)),
1114
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
761
1115
  };
762
1116
 
763
- const defaultProps$8 = {
1117
+ const defaultProps$5 = {
764
1118
  size: 40,
765
1119
  color: "var(--react-loadly-color)",
766
1120
  speed: 1,
@@ -769,8 +1123,8 @@ const defaultProps$8 = {
769
1123
  "aria-label": "Loading...",
770
1124
  };
771
1125
  const PulseLoader = (userProps) => {
772
- const props = mergeProps(defaultProps$8, userProps);
773
- const { size, color, secondaryColor, speed, loading, count, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
1126
+ const props = mergeProps(defaultProps$5, userProps);
1127
+ const { size, color, secondaryColor, speed, loading, count, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
774
1128
  const id = useMemo(() => generateId("pulse-loader"), []);
775
1129
  const dotSize = useMemo(() => {
776
1130
  const sizeNum = typeof size === "number" ? size : parseInt(getSizeValue(size));
@@ -783,25 +1137,39 @@ const PulseLoader = (userProps) => {
783
1137
  flexDirection: "column",
784
1138
  alignItems: "center",
785
1139
  ...style,
1140
+ ...(fullscreen && {
1141
+ position: "fixed",
1142
+ top: 0,
1143
+ left: 0,
1144
+ width: screenWidth || "100vw",
1145
+ height: screenHeight || "100vh",
1146
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
1147
+ zIndex: 9999,
1148
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
1149
+ }),
786
1150
  };
787
- return (jsxs("div", { className: `react-loadly react-loadly-pulse ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx(DotCluster, { count: count, dotSize: dotSize, color: color, secondaryColor: secondaryColor, speed: speed, arrangement: "linear", animationType: "pulse", spacing: dotSize / 2, "data-testid": dataTestId ? `${dataTestId}-dots` : undefined }), showText && (jsx("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite", children: loadingText })), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] }));
1151
+ return (React.createElement("div", { className: `react-loadly react-loadly-pulse ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1152
+ React.createElement(DotCluster, { count: count, dotSize: dotSize, color: color, secondaryColor: secondaryColor, speed: speed, arrangement: "linear", animationType: "pulse", spacing: dotSize / 2, "data-testid": dataTestId ? `${dataTestId}-dots` : undefined }),
1153
+ showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
1154
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
788
1155
  };
789
1156
 
790
- const defaultProps$7 = {
791
- size: 40,
1157
+ const defaultProps$4 = {
1158
+ size: 60,
792
1159
  color: "var(--react-loadly-color)",
793
1160
  speed: 1,
794
1161
  loading: true,
795
1162
  borderWidth: 4,
796
1163
  "aria-label": "Loading...",
797
1164
  };
798
- const SpinLoader = (userProps) => {
799
- const props = mergeProps(defaultProps$7, userProps);
800
- const { size, color, speed, loading, className = "", style = {}, borderWidth, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
1165
+ const RingLoader = (userProps) => {
1166
+ const props = mergeProps(defaultProps$4, userProps);
1167
+ const { size, color, speed, loading, className = "", style = {}, borderWidth, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
801
1168
  // Use useRef instead of useMemo for better compatibility
802
- const idRef = useRef(generateId("spin-loader"));
1169
+ const idRef = useRef(generateId("ring-loader"));
803
1170
  const sizeValue = getSizeValue(size);
804
1171
  const animationSettings = getOptimizedAnimationSettings(speed);
1172
+ // Don't render anything if not loading
805
1173
  if (!loading)
806
1174
  return null;
807
1175
  const containerStyle = {
@@ -809,182 +1177,63 @@ const SpinLoader = (userProps) => {
809
1177
  flexDirection: "column",
810
1178
  alignItems: "center",
811
1179
  ...style,
1180
+ ...(fullscreen && {
1181
+ position: "fixed",
1182
+ top: 0,
1183
+ left: 0,
1184
+ width: screenWidth || "100vw",
1185
+ height: screenHeight || "100vh",
1186
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
1187
+ zIndex: 9999,
1188
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
1189
+ }),
812
1190
  };
813
- const spinnerStyle = {
1191
+ const ringStyle = {
1192
+ position: "relative",
1193
+ width: sizeValue,
1194
+ height: sizeValue,
1195
+ };
1196
+ const ringSegmentStyle = {
1197
+ boxSizing: "border-box",
1198
+ display: "block",
1199
+ position: "absolute",
814
1200
  width: sizeValue,
815
1201
  height: sizeValue,
816
1202
  border: `${borderWidth}px solid transparent`,
817
1203
  borderTop: `${borderWidth}px solid ${color}`,
1204
+ borderBottom: `${borderWidth}px solid ${color}`,
818
1205
  borderRadius: "50%",
819
- animation: `react-loadly-spin ${animationSettings.duration} linear infinite`,
1206
+ animation: `react-loadly-ring ${animationSettings.duration} cubic-bezier(0.5, 0, 0.5, 1) infinite`,
820
1207
  animationPlayState: animationSettings.playState,
821
1208
  };
822
- return (jsxs("div", { className: `react-loadly react-loadly-spin ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx("div", { style: spinnerStyle, "data-testid": dataTestId ? `${dataTestId}-spinner` : undefined }), showText && (jsx("div", { className: "react-loadly-text", id: `${idRef.current}-text`, "aria-live": "polite", children: loadingText })), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] }));
1209
+ // Create the 4 ring segments with their specific styles
1210
+ const segments = Array.from({ length: 4 }).map((_, index) => {
1211
+ const rotation = `${index * 90}deg`;
1212
+ const delay = `${index * -0.15}s`;
1213
+ return (React.createElement("div", { key: index, style: {
1214
+ ...ringSegmentStyle,
1215
+ transform: `rotate(${rotation})`,
1216
+ animationDelay: delay,
1217
+ }, "data-testid": dataTestId ? `${dataTestId}-segment-${index}` : undefined }));
1218
+ });
1219
+ return (React.createElement("div", { className: `react-loadly react-loadly-ring ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1220
+ React.createElement("div", { style: ringStyle }, segments),
1221
+ showText && (React.createElement("div", { className: "react-loadly-text", id: `${idRef.current}-text`, "aria-live": "polite" }, loadingText)),
1222
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
823
1223
  };
824
1224
 
825
- const defaultProps$6 = {
826
- text: "Loading...",
1225
+ const defaultProps$3 = {
1226
+ size: 15,
1227
+ color: "var(--react-loadly-color)",
827
1228
  speed: 1,
828
1229
  loading: true,
829
- charDelay: 100,
1230
+ count: 2,
830
1231
  "aria-label": "Loading...",
831
1232
  };
832
- const TypingLoader = (userProps) => {
833
- const props = mergeProps(defaultProps$6, userProps);
834
- const { text, speed, loading, charDelay, className = "", style = {}, color = "var(--react-loadly-text-color)", fontFamily, fontWeight = 500, "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
835
- const [displayText, setDisplayText] = useState("");
836
- const [isTyping, setIsTyping] = useState(false);
837
- const timeoutRef = useRef(null);
838
- useEffect(() => {
839
- // Clear any existing timeout
840
- if (timeoutRef.current) {
841
- clearTimeout(timeoutRef.current);
842
- timeoutRef.current = null;
843
- }
844
- if (!loading || !text) {
845
- setDisplayText("");
846
- return;
847
- }
848
- setIsTyping(true);
849
- setDisplayText("");
850
- let currentIndex = 0;
851
- const typeChar = () => {
852
- if (currentIndex < text.length) {
853
- setDisplayText(text.slice(0, currentIndex + 1));
854
- currentIndex++;
855
- timeoutRef.current = setTimeout(typeChar, (charDelay ?? 100) / (speed ?? 1));
856
- }
857
- else {
858
- setIsTyping(false);
859
- // Reset and start over
860
- timeoutRef.current = setTimeout(() => {
861
- currentIndex = 0;
862
- setDisplayText("");
863
- if (loading)
864
- typeChar();
865
- }, 1000 / (speed ?? 1));
866
- }
867
- };
868
- typeChar();
869
- return () => {
870
- setIsTyping(false);
871
- if (timeoutRef.current) {
872
- clearTimeout(timeoutRef.current);
873
- timeoutRef.current = null;
874
- }
875
- };
876
- }, [text, loading, charDelay, speed]);
877
- if (!loading)
878
- return null;
879
- const containerStyle = {
880
- display: "inline-flex",
881
- alignItems: "center",
882
- fontFamily: fontFamily || "var(--react-loadly-font-family)",
883
- fontSize: "var(--react-loadly-font-size)",
884
- fontWeight,
885
- color,
886
- ...style,
887
- };
888
- const cursorStyle = {
889
- marginLeft: "2px",
890
- animation: isTyping ? "none" : "react-loadly-fade 1s infinite",
891
- opacity: isTyping ? 1 : 0.5,
892
- };
893
- return (jsxs("div", { className: `react-loadly react-loadly-typing ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx("span", { children: displayText }), jsx("span", { style: cursorStyle, children: "|" }), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] }));
894
- };
895
-
896
- const defaultProps$5 = {
897
- size: 40,
898
- color: "var(--react-loadly-color)",
899
- speed: 1,
900
- loading: true,
901
- count: 5,
902
- "aria-label": "Loading...",
903
- };
904
- const WaveLoader = (userProps) => {
905
- const props = mergeProps(defaultProps$5, userProps);
906
- const { size, color, secondaryColor, speed, loading, count, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
907
- const id = useMemo(() => generateId("wave-loader"), []);
908
- const lineSpecs = useMemo(() => {
909
- const sizeNum = typeof size === "number" ? size : parseInt(getSizeValue(size));
910
- return {
911
- width: Math.max(sizeNum / 10, 3), // Line thickness
912
- height: sizeNum, // Line height
913
- spacing: Math.max(sizeNum / 8, 4), // Spacing between lines
914
- };
915
- }, [size]);
916
- if (!loading)
917
- return null;
918
- const containerStyle = {
919
- display: "inline-flex",
920
- flexDirection: "column",
921
- alignItems: "center",
922
- ...style,
923
- };
924
- return (jsxs("div", { className: `react-loadly react-loadly-wave ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx(LineGroup, { count: count, lineWidth: lineSpecs.width, lineHeight: lineSpecs.height, color: color, secondaryColor: secondaryColor, speed: speed, arrangement: "staggered", orientation: "vertical", animationType: "wave", spacing: lineSpecs.spacing, "data-testid": dataTestId ? `${dataTestId}-lines` : undefined }), showText && (jsx("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite", children: loadingText })), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] }));
925
- };
926
-
927
- const defaultProps$4 = {
928
- size: 20,
929
- color: "var(--react-loadly-color)",
930
- speed: 1,
931
- loading: true,
932
- count: 5,
933
- "aria-label": "Loading...",
934
- };
935
- const BarsLoader = (userProps) => {
936
- const props = mergeProps(defaultProps$4, userProps);
937
- const { size, color, speed, loading, className = "", style = {}, count = 5, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
938
- const id = useMemo(() => generateId("bars-loader"), []);
939
- const sizeValue = getSizeValue(size);
940
- const animationSettings = getOptimizedAnimationSettings(speed);
941
- if (!loading)
942
- return null;
943
- const containerStyle = {
944
- display: "inline-flex",
945
- flexDirection: "column",
946
- alignItems: "center",
947
- ...style,
948
- };
949
- const barsContainerStyle = {
950
- display: "flex",
951
- justifyContent: "center",
952
- alignItems: "center",
953
- gap: "4px",
954
- };
955
- const barStyle = {
956
- width: "4px",
957
- height: sizeValue,
958
- backgroundColor: color,
959
- borderRadius: "2px",
960
- animation: `react-loadly-bars ${animationSettings.duration} ease-in-out infinite`,
961
- animationPlayState: animationSettings.playState,
962
- };
963
- // Create bars with different animation delays
964
- const bars = Array.from({ length: count }).map((_, index) => {
965
- const delay = `${index * 0.1}s`;
966
- const heightFactor = 0.5 + (index % 3) * 0.25; // Vary heights for visual interest
967
- return (jsx("div", { style: {
968
- ...barStyle,
969
- animationDelay: delay,
970
- height: `${parseFloat(sizeValue) * heightFactor}px`,
971
- }, "data-testid": dataTestId ? `${dataTestId}-bar-${index}` : undefined }, index));
972
- });
973
- return (jsxs("div", { className: `react-loadly react-loadly-bars ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx("div", { style: barsContainerStyle, children: bars }), showText && (jsx("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite", children: loadingText })), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] }));
974
- };
975
-
976
- const defaultProps$3 = {
977
- size: 15,
978
- color: "var(--react-loadly-color)",
979
- speed: 1,
980
- loading: true,
981
- count: 3,
982
- "aria-label": "Loading...",
983
- };
984
- const BounceLoader = (userProps) => {
1233
+ const RotateLoader = (userProps) => {
985
1234
  const props = mergeProps(defaultProps$3, userProps);
986
- const { size, color, speed, loading, className = "", style = {}, count = 3, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
987
- const id = useMemo(() => generateId("bounce-loader"), []);
1235
+ const { size, color, speed, loading, className = "", style = {}, count = 2, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
1236
+ const id = useMemo(() => generateId("rotate-loader"), []);
988
1237
  const sizeValue = getSizeValue(size);
989
1238
  const animationSettings = getOptimizedAnimationSettings(speed);
990
1239
  if (!loading)
@@ -994,44 +1243,67 @@ const BounceLoader = (userProps) => {
994
1243
  flexDirection: "column",
995
1244
  alignItems: "center",
996
1245
  ...style,
1246
+ ...(fullscreen && {
1247
+ position: "fixed",
1248
+ top: 0,
1249
+ left: 0,
1250
+ width: screenWidth || "100vw",
1251
+ height: screenHeight || "100vh",
1252
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
1253
+ zIndex: 9999,
1254
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
1255
+ }),
997
1256
  };
998
- const bounceContainerStyle = {
999
- display: "flex",
1000
- justifyContent: "center",
1001
- alignItems: "center",
1002
- gap: "8px",
1257
+ const rotateContainerStyle = {
1258
+ position: "relative",
1259
+ width: sizeValue,
1260
+ height: sizeValue,
1003
1261
  };
1004
- const bounceBallStyle = {
1262
+ const rotateElementStyle = {
1263
+ position: "absolute",
1005
1264
  width: sizeValue,
1006
1265
  height: sizeValue,
1266
+ border: "2px solid transparent",
1267
+ borderTopColor: color,
1268
+ borderBottomColor: color,
1007
1269
  borderRadius: "50%",
1008
- backgroundColor: color,
1009
- animation: `react-loadly-bounce ${animationSettings.duration} ease-in-out infinite`,
1270
+ animation: `react-loadly-ring ${animationSettings.duration} cubic-bezier(0.5, 0, 0.5, 1) infinite`,
1010
1271
  animationPlayState: animationSettings.playState,
1272
+ transform: "rotate(0deg)",
1011
1273
  };
1012
- // Create bounce animation delays for each ball
1013
- const balls = Array.from({ length: count }).map((_, index) => {
1014
- const delay = `${index * 0.1}s`;
1015
- return (jsx("div", { style: {
1016
- ...bounceBallStyle,
1274
+ // Create rotating elements
1275
+ const elements = Array.from({ length: count }).map((_, index) => {
1276
+ const sizeFactor = 1 - index * 0.2;
1277
+ const borderWidth = 2 + index;
1278
+ const delay = `${index * -0.15}s`;
1279
+ return (React.createElement("div", { key: index, style: {
1280
+ ...rotateElementStyle,
1281
+ width: `${parseFloat(sizeValue) * sizeFactor}px`,
1282
+ height: `${parseFloat(sizeValue) * sizeFactor}px`,
1283
+ borderWidth: `${borderWidth}px`,
1284
+ animationDuration: `${parseFloat(animationSettings.duration) * (1 + index * 0.5)}ms`,
1017
1285
  animationDelay: delay,
1018
- }, "data-testid": dataTestId ? `${dataTestId}-ball-${index}` : undefined }, index));
1286
+ }, "data-testid": dataTestId ? `${dataTestId}-element-${index}` : undefined }));
1019
1287
  });
1020
- return (jsxs("div", { className: `react-loadly react-loadly-bounce ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx("div", { style: bounceContainerStyle, children: balls }), showText && (jsx("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite", children: loadingText })), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] }));
1288
+ return (React.createElement("div", { className: `react-loadly react-loadly-ring ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1289
+ React.createElement("div", { style: rotateContainerStyle }, elements),
1290
+ showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
1291
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
1021
1292
  };
1022
1293
 
1023
1294
  const defaultProps$2 = {
1024
- size: 12,
1295
+ size: 40,
1025
1296
  color: "var(--react-loadly-color)",
1026
1297
  speed: 1,
1027
1298
  loading: true,
1028
- count: 3,
1299
+ borderWidth: 4,
1029
1300
  "aria-label": "Loading...",
1030
1301
  };
1031
- const DotsLoader = (userProps) => {
1302
+ const SpinLoader = (userProps) => {
1032
1303
  const props = mergeProps(defaultProps$2, userProps);
1033
- const { size, color, speed, loading, className = "", style = {}, count = 3, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
1034
- const id = useMemo(() => generateId("dots-loader"), []);
1304
+ const { size, color, speed, loading, className = "", style = {}, borderWidth, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
1305
+ // Use useRef instead of useMemo for better compatibility
1306
+ const idRef = useRef(generateId("spin-loader"));
1035
1307
  const sizeValue = getSizeValue(size);
1036
1308
  const animationSettings = getOptimizedAnimationSettings(speed);
1037
1309
  if (!loading)
@@ -1041,48 +1313,81 @@ const DotsLoader = (userProps) => {
1041
1313
  flexDirection: "column",
1042
1314
  alignItems: "center",
1043
1315
  ...style,
1316
+ ...(fullscreen && {
1317
+ position: "fixed",
1318
+ top: 0,
1319
+ left: 0,
1320
+ width: screenWidth || "100vw",
1321
+ height: screenHeight || "100vh",
1322
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
1323
+ zIndex: 9999,
1324
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
1325
+ }),
1044
1326
  };
1045
- const dotsContainerStyle = {
1046
- display: "flex",
1047
- justifyContent: "center",
1048
- alignItems: "center",
1049
- gap: "6px",
1050
- };
1051
- const dotStyle = {
1327
+ const spinnerStyle = {
1052
1328
  width: sizeValue,
1053
1329
  height: sizeValue,
1330
+ border: `${borderWidth}px solid transparent`,
1331
+ borderTop: `${borderWidth}px solid ${color}`,
1054
1332
  borderRadius: "50%",
1055
- backgroundColor: color,
1056
- animation: `react-loadly-dots ${animationSettings.duration} ease-in-out infinite`,
1333
+ animation: `react-loadly-spin ${animationSettings.duration} linear infinite`,
1057
1334
  animationPlayState: animationSettings.playState,
1058
1335
  };
1059
- // Create dots with different animation delays
1060
- const dots = Array.from({ length: count }).map((_, index) => {
1061
- const delay = `${index * 0.2}s`;
1062
- return (jsx("div", { style: {
1063
- ...dotStyle,
1064
- animationDelay: delay,
1065
- }, "data-testid": dataTestId ? `${dataTestId}-dot-${index}` : undefined }, index));
1066
- });
1067
- return (jsxs("div", { className: `react-loadly react-loadly-dots ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx("div", { style: dotsContainerStyle, children: dots }), showText && (jsx("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite", children: loadingText })), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] }));
1336
+ return (React.createElement("div", { className: `react-loadly react-loadly-spin ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1337
+ React.createElement("div", { style: spinnerStyle, "data-testid": dataTestId ? `${dataTestId}-spinner` : undefined }),
1338
+ showText && (React.createElement("div", { className: "react-loadly-text", id: `${idRef.current}-text`, "aria-live": "polite" }, loadingText)),
1339
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
1068
1340
  };
1069
1341
 
1070
1342
  const defaultProps$1 = {
1071
- size: 60,
1072
- color: "var(--react-loadly-color)",
1073
1343
  speed: 1,
1074
1344
  loading: true,
1075
- borderWidth: 4,
1345
+ charDelay: 100,
1076
1346
  "aria-label": "Loading...",
1347
+ loop: true,
1077
1348
  };
1078
- const RingLoader = (userProps) => {
1349
+ const TypingLoader = (userProps) => {
1079
1350
  const props = mergeProps(defaultProps$1, userProps);
1080
- const { size, color, speed, loading, className = "", style = {}, borderWidth, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
1081
- // Use useRef instead of useMemo for better compatibility
1082
- const idRef = useRef(generateId("ring-loader"));
1083
- const sizeValue = getSizeValue(size);
1084
- const animationSettings = getOptimizedAnimationSettings(speed);
1085
- // Don't render anything if not loading
1351
+ const { loadingText, speed = 1, loading, charDelay = 100, loop, className = "", style = {}, color = "var(--react-loadly-text-color)", fontFamily, fontWeight = 500, "aria-label": ariaLabel, "data-testid": dataTestId, showText, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
1352
+ const [displayText, setDisplayText] = useState("");
1353
+ const [isTyping, setIsTyping] = useState(false);
1354
+ const timeoutRef = useRef(null);
1355
+ useEffect(() => {
1356
+ // Clear any existing timeout
1357
+ if (timeoutRef.current) {
1358
+ clearTimeout(timeoutRef.current);
1359
+ timeoutRef.current = null;
1360
+ }
1361
+ if (!loading || !loadingText) {
1362
+ setDisplayText("");
1363
+ return;
1364
+ }
1365
+ setIsTyping(true);
1366
+ setDisplayText("");
1367
+ const typeText = (index = 0) => {
1368
+ if (index < loadingText.length) {
1369
+ setDisplayText(loadingText.substring(0, index + 1));
1370
+ timeoutRef.current = setTimeout(() => typeText(index + 1), charDelay / speed);
1371
+ }
1372
+ else if (loop) {
1373
+ // Reset and start over if looping
1374
+ timeoutRef.current = setTimeout(() => {
1375
+ setDisplayText("");
1376
+ typeText(0);
1377
+ }, charDelay * 2);
1378
+ }
1379
+ else {
1380
+ setIsTyping(false);
1381
+ }
1382
+ };
1383
+ typeText(0);
1384
+ // Cleanup timeouts on unmount or when dependencies change
1385
+ return () => {
1386
+ if (timeoutRef.current) {
1387
+ clearTimeout(timeoutRef.current);
1388
+ }
1389
+ };
1390
+ }, [loading, loadingText, charDelay, speed, loop]);
1086
1391
  if (!loading)
1087
1392
  return null;
1088
1393
  const containerStyle = {
@@ -1090,52 +1395,57 @@ const RingLoader = (userProps) => {
1090
1395
  flexDirection: "column",
1091
1396
  alignItems: "center",
1092
1397
  ...style,
1398
+ ...(fullscreen && {
1399
+ position: "fixed",
1400
+ top: 0,
1401
+ left: 0,
1402
+ width: screenWidth || "100vw",
1403
+ height: screenHeight || "100vh",
1404
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
1405
+ zIndex: 9999,
1406
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
1407
+ }),
1093
1408
  };
1094
- const ringStyle = {
1095
- position: "relative",
1096
- width: sizeValue,
1097
- height: sizeValue,
1098
- };
1099
- const ringSegmentStyle = {
1100
- boxSizing: "border-box",
1101
- display: "block",
1102
- position: "absolute",
1103
- width: sizeValue,
1104
- height: sizeValue,
1105
- border: `${borderWidth}px solid transparent`,
1106
- borderTop: `${borderWidth}px solid ${color}`,
1107
- borderBottom: `${borderWidth}px solid ${color}`,
1108
- borderRadius: "50%",
1109
- animation: `react-loadly-ring ${animationSettings.duration} cubic-bezier(0.5, 0, 0.5, 1) infinite`,
1110
- animationPlayState: animationSettings.playState,
1409
+ const textStyle = {
1410
+ color,
1411
+ fontFamily,
1412
+ fontWeight,
1413
+ fontSize: "1.2em",
1414
+ whiteSpace: "pre",
1111
1415
  };
1112
- // Create the 4 ring segments with their specific styles
1113
- const segments = Array.from({ length: 4 }).map((_, index) => {
1114
- const rotation = `${index * 90}deg`;
1115
- const delay = `${index * -0.15}s`;
1116
- return (jsx("div", { style: {
1117
- ...ringSegmentStyle,
1118
- transform: `rotate(${rotation})`,
1119
- animationDelay: delay,
1120
- }, "data-testid": dataTestId ? `${dataTestId}-segment-${index}` : undefined }, index));
1121
- });
1122
- return (jsxs("div", { className: `react-loadly react-loadly-ring ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx("div", { style: ringStyle, children: segments }), showText && (jsx("div", { className: "react-loadly-text", id: `${idRef.current}-text`, "aria-live": "polite", children: loadingText })), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] }));
1416
+ return (React.createElement("div", { className: `react-loadly react-loadly-typing ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1417
+ React.createElement("div", { style: textStyle, "data-testid": dataTestId ? `${dataTestId}-text` : undefined },
1418
+ displayText,
1419
+ React.createElement("span", { className: "react-loadly-typing-cursor", style: {
1420
+ display: isTyping ? "inline-block" : "none",
1421
+ animation: `react-loadly-blink ${1 / speed}s step-end infinite`,
1422
+ marginLeft: "2px",
1423
+ verticalAlign: "baseline",
1424
+ } }, "|")),
1425
+ showText && (React.createElement("div", { className: "react-loadly-text", "aria-live": "polite" }, loadingText)),
1426
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
1123
1427
  };
1124
1428
 
1125
1429
  const defaultProps = {
1126
- size: 15,
1430
+ size: 40,
1127
1431
  color: "var(--react-loadly-color)",
1128
1432
  speed: 1,
1129
1433
  loading: true,
1130
- count: 2,
1434
+ count: 5,
1131
1435
  "aria-label": "Loading...",
1132
1436
  };
1133
- const RotateLoader = (userProps) => {
1437
+ const WaveLoader = (userProps) => {
1134
1438
  const props = mergeProps(defaultProps, userProps);
1135
- const { size, color, speed, loading, className = "", style = {}, count = 2, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, ...restProps } = props;
1136
- const id = useMemo(() => generateId("rotate-loader"), []);
1137
- const sizeValue = getSizeValue(size);
1138
- const animationSettings = getOptimizedAnimationSettings(speed);
1439
+ const { size, color, secondaryColor, speed, loading, count, className = "", style = {}, showText, loadingText = "Loading...", "aria-label": ariaLabel, "data-testid": dataTestId, fullscreen, screenWidth, screenHeight, loaderCenter, screenBackground, ...restProps } = props;
1440
+ const id = useMemo(() => generateId("wave-loader"), []);
1441
+ const lineSpecs = useMemo(() => {
1442
+ const sizeNum = typeof size === "number" ? size : parseInt(getSizeValue(size));
1443
+ return {
1444
+ width: Math.max(sizeNum / 10, 3), // Line thickness
1445
+ height: sizeNum, // Line height
1446
+ spacing: Math.max(sizeNum / 8, 4), // Spacing between lines
1447
+ };
1448
+ }, [size]);
1139
1449
  if (!loading)
1140
1450
  return null;
1141
1451
  const containerStyle = {
@@ -1143,39 +1453,21 @@ const RotateLoader = (userProps) => {
1143
1453
  flexDirection: "column",
1144
1454
  alignItems: "center",
1145
1455
  ...style,
1456
+ ...(fullscreen && {
1457
+ position: "fixed",
1458
+ top: 0,
1459
+ left: 0,
1460
+ width: screenWidth || "100vw",
1461
+ height: screenHeight || "100vh",
1462
+ backgroundColor: screenBackground || "var(--react-loadly-background)",
1463
+ zIndex: 9999,
1464
+ justifyContent: loaderCenter ? "center" : style.justifyContent,
1465
+ }),
1146
1466
  };
1147
- const rotateContainerStyle = {
1148
- position: "relative",
1149
- width: sizeValue,
1150
- height: sizeValue,
1151
- };
1152
- const rotateElementStyle = {
1153
- position: "absolute",
1154
- width: sizeValue,
1155
- height: sizeValue,
1156
- border: "2px solid transparent",
1157
- borderTopColor: color,
1158
- borderBottomColor: color,
1159
- borderRadius: "50%",
1160
- animation: `react-loadly-ring ${animationSettings.duration} cubic-bezier(0.5, 0, 0.5, 1) infinite`,
1161
- animationPlayState: animationSettings.playState,
1162
- transform: "rotate(0deg)",
1163
- };
1164
- // Create rotating elements
1165
- const elements = Array.from({ length: count }).map((_, index) => {
1166
- const sizeFactor = 1 - index * 0.2;
1167
- const borderWidth = 2 + index;
1168
- const delay = `${index * -0.15}s`;
1169
- return (jsx("div", { style: {
1170
- ...rotateElementStyle,
1171
- width: `${parseFloat(sizeValue) * sizeFactor}px`,
1172
- height: `${parseFloat(sizeValue) * sizeFactor}px`,
1173
- borderWidth: `${borderWidth}px`,
1174
- animationDuration: `${parseFloat(animationSettings.duration) * (1 + index * 0.5)}ms`,
1175
- animationDelay: delay,
1176
- }, "data-testid": dataTestId ? `${dataTestId}-element-${index}` : undefined }, index));
1177
- });
1178
- return (jsxs("div", { className: `react-loadly react-loadly-ring ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps, children: [jsx("div", { style: rotateContainerStyle, children: elements }), showText && (jsx("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite", children: loadingText })), jsx("span", { className: "react-loadly-sr-only", children: ariaLabel })] }));
1467
+ return (React.createElement("div", { className: `react-loadly react-loadly-wave ${className}`.trim(), style: containerStyle, role: "status", "aria-label": ariaLabel, "aria-live": "polite", "aria-busy": loading, "data-testid": dataTestId, ...restProps },
1468
+ React.createElement(LineGroup, { count: count, lineWidth: lineSpecs.width, lineHeight: lineSpecs.height, color: color, secondaryColor: secondaryColor, speed: speed, arrangement: "staggered", orientation: "vertical", animationType: "wave", spacing: lineSpecs.spacing, "data-testid": dataTestId ? `${dataTestId}-lines` : undefined }),
1469
+ showText && (React.createElement("div", { className: "react-loadly-text", id: `${id}-text`, "aria-live": "polite" }, loadingText)),
1470
+ React.createElement("span", { className: "react-loadly-sr-only" }, ariaLabel)));
1179
1471
  };
1180
1472
 
1181
1473
  /**
@@ -1186,15 +1478,15 @@ const RotateLoader = (userProps) => {
1186
1478
  * @returns Object containing state and methods to control the loader
1187
1479
  */
1188
1480
  const useLoaderState = (options = {}) => {
1189
- const { initialLoading = false, timeout, maxRetries = 3, onLoadingChange, onError, onProgress, } = options;
1481
+ const { initialLoading = false, timeout, maxRetries = 3, onLoadingChange, onError, onProgress } = options;
1190
1482
  const [state, setState] = useState({
1191
1483
  isLoading: initialLoading,
1192
1484
  progress: 0,
1193
1485
  error: null,
1194
1486
  retryCount: 0,
1195
1487
  });
1196
- const timeoutRef = useRef();
1197
- const retryTimeoutRef = useRef();
1488
+ const timeoutRef = useRef(null);
1489
+ const retryTimeoutRef = useRef(null);
1198
1490
  // Clear timeouts on unmount
1199
1491
  useEffect(() => {
1200
1492
  return () => {
@@ -1367,5 +1659,5 @@ const useAsyncLoader = (asyncFn, dependencies = [], options = {}) => {
1367
1659
  };
1368
1660
  };
1369
1661
 
1370
- export { BarsLoader, BlobLoader, BounceLoader, Circle, Dot, DotCluster, DotsLoader, FallbackLoader, FlowLoader, GridLoader, Line, LineGroup, LiquidLoader, LogoSpinLoader, PulseLoader, Rectangle, RingLoader, RotateLoader, ShapeGroup, SpinLoader, TypingLoader, WaveLoader, clamp, createAnimationName, generateCSSVariables, generateId, getAnimationDuration, getOptimizedAnimationSettings, getSizeValue, hexToRgb, mergeProps, prefersReducedMotion, rgba, sanitizeCSSValue, useAsyncLoader, useLoaderState, useMultipleLoaderStates };
1662
+ export { BarsLoader, BlobLoader, BounceLoader, Circle, Dot, DotCluster, DotsLoader, ElementLoader, FallbackLoader, FlowLoader, GridLoader, Line, LineGroup, LiquidLoader, LogoSpinLoader, PulseLoader, Rectangle, RingLoader, RotateLoader, ShapeGroup, SpinLoader, TypingLoader, WaveLoader, clamp, createAnimationName, generateCSSVariables, generateId, getAnimationDuration, getOptimizedAnimationSettings, getSizeValue, hexToRgb, mergeProps, prefersReducedMotion, rgba, sanitizeCSSValue, useAsyncLoader, useLoaderState, useMultipleLoaderStates };
1371
1663
  //# sourceMappingURL=index.esm.js.map