premium-react-loaders 4.0.0 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/README.md +21 -6
  2. package/dist/components/index.d.ts +1 -0
  3. package/dist/components/index.d.ts.map +1 -1
  4. package/dist/components/neon/NeonPulse.d.ts +12 -0
  5. package/dist/components/neon/NeonPulse.d.ts.map +1 -0
  6. package/dist/components/neon/NeonSpinner.d.ts +12 -0
  7. package/dist/components/neon/NeonSpinner.d.ts.map +1 -0
  8. package/dist/components/neon/NeonText.d.ts +12 -0
  9. package/dist/components/neon/NeonText.d.ts.map +1 -0
  10. package/dist/components/neon/index.d.ts +4 -0
  11. package/dist/components/neon/index.d.ts.map +1 -0
  12. package/dist/components/particle/ParticleField.d.ts +3 -0
  13. package/dist/components/particle/ParticleField.d.ts.map +1 -0
  14. package/dist/components/particle/ParticleTrail.d.ts +12 -0
  15. package/dist/components/particle/ParticleTrail.d.ts.map +1 -0
  16. package/dist/components/particle/index.d.ts +2 -0
  17. package/dist/components/particle/index.d.ts.map +1 -1
  18. package/dist/components/status/InfoIndicator.d.ts +29 -0
  19. package/dist/components/status/InfoIndicator.d.ts.map +1 -0
  20. package/dist/components/status/WarningIndicator.d.ts +29 -0
  21. package/dist/components/status/WarningIndicator.d.ts.map +1 -0
  22. package/dist/components/status/index.d.ts +2 -0
  23. package/dist/components/status/index.d.ts.map +1 -1
  24. package/dist/index.cjs +41 -27
  25. package/dist/index.js +41 -27
  26. package/dist/index10.cjs +1 -1
  27. package/dist/index10.js +1 -1
  28. package/dist/index11.cjs +1 -1
  29. package/dist/index11.js +1 -1
  30. package/dist/index12.cjs +1 -1
  31. package/dist/index12.js +1 -1
  32. package/dist/index13.cjs +1 -1
  33. package/dist/index13.js +1 -1
  34. package/dist/index14.cjs +1 -1
  35. package/dist/index14.js +1 -1
  36. package/dist/index15.cjs +1 -1
  37. package/dist/index15.js +1 -1
  38. package/dist/index17.cjs +1 -1
  39. package/dist/index17.js +1 -1
  40. package/dist/index18.cjs +1 -1
  41. package/dist/index18.js +1 -1
  42. package/dist/index19.cjs +1 -1
  43. package/dist/index19.js +1 -1
  44. package/dist/index20.cjs +1 -1
  45. package/dist/index20.js +1 -1
  46. package/dist/index21.cjs +1 -1
  47. package/dist/index21.js +1 -1
  48. package/dist/index22.cjs +1 -1
  49. package/dist/index22.js +1 -1
  50. package/dist/index23.cjs +1 -1
  51. package/dist/index23.js +1 -1
  52. package/dist/index24.cjs +1 -1
  53. package/dist/index24.js +1 -1
  54. package/dist/index25.cjs +1 -1
  55. package/dist/index25.js +1 -1
  56. package/dist/index26.cjs +1 -1
  57. package/dist/index26.js +1 -1
  58. package/dist/index27.cjs +1 -1
  59. package/dist/index27.js +1 -1
  60. package/dist/index28.cjs +1 -1
  61. package/dist/index28.js +1 -1
  62. package/dist/index29.cjs +1 -1
  63. package/dist/index29.js +1 -1
  64. package/dist/index30.cjs +1 -1
  65. package/dist/index30.js +1 -1
  66. package/dist/index31.cjs +1 -1
  67. package/dist/index31.js +1 -1
  68. package/dist/index32.cjs +1 -1
  69. package/dist/index32.js +1 -1
  70. package/dist/index33.cjs +1 -1
  71. package/dist/index33.js +1 -1
  72. package/dist/index34.cjs +1 -1
  73. package/dist/index34.js +1 -1
  74. package/dist/index35.cjs +1 -1
  75. package/dist/index35.js +1 -1
  76. package/dist/index36.cjs +1 -1
  77. package/dist/index36.js +1 -1
  78. package/dist/index37.cjs +59 -145
  79. package/dist/index37.js +61 -147
  80. package/dist/index38.cjs +32 -53
  81. package/dist/index38.js +33 -54
  82. package/dist/index39.cjs +138 -84
  83. package/dist/index39.js +140 -86
  84. package/dist/index40.cjs +33 -106
  85. package/dist/index40.js +34 -107
  86. package/dist/index41.cjs +66 -50
  87. package/dist/index41.js +66 -50
  88. package/dist/index42.cjs +123 -44
  89. package/dist/index42.js +124 -45
  90. package/dist/index43.cjs +43 -85
  91. package/dist/index43.js +44 -86
  92. package/dist/index44.cjs +35 -27
  93. package/dist/index44.js +35 -27
  94. package/dist/index45.cjs +87 -58
  95. package/dist/index45.js +87 -58
  96. package/dist/index46.cjs +35 -88
  97. package/dist/index46.js +36 -89
  98. package/dist/index47.cjs +62 -58
  99. package/dist/index47.js +63 -59
  100. package/dist/index48.cjs +87 -110
  101. package/dist/index48.js +88 -111
  102. package/dist/index49.cjs +48 -109
  103. package/dist/index49.js +49 -110
  104. package/dist/index50.cjs +110 -62
  105. package/dist/index50.js +111 -63
  106. package/dist/index51.cjs +104 -49
  107. package/dist/index51.js +104 -49
  108. package/dist/index52.cjs +43 -77
  109. package/dist/index52.js +44 -78
  110. package/dist/index53.cjs +56 -56
  111. package/dist/index53.js +56 -56
  112. package/dist/index54.cjs +104 -149
  113. package/dist/index54.js +106 -151
  114. package/dist/index55.cjs +97 -38
  115. package/dist/index55.js +99 -40
  116. package/dist/index56.cjs +161 -27
  117. package/dist/index56.js +162 -28
  118. package/dist/index57.cjs +36 -102
  119. package/dist/index57.js +38 -104
  120. package/dist/index58.cjs +19 -34
  121. package/dist/index58.js +20 -35
  122. package/dist/index59.cjs +87 -34
  123. package/dist/index59.js +89 -36
  124. package/dist/index60.cjs +25 -23
  125. package/dist/index60.js +25 -23
  126. package/dist/index61.cjs +32 -65
  127. package/dist/index61.js +34 -67
  128. package/dist/index62.cjs +29 -36
  129. package/dist/index62.js +30 -37
  130. package/dist/index63.cjs +66 -59
  131. package/dist/index63.js +69 -62
  132. package/dist/index64.cjs +71 -121
  133. package/dist/index64.js +72 -122
  134. package/dist/index65.cjs +92 -0
  135. package/dist/index65.js +92 -0
  136. package/dist/index66.cjs +76 -0
  137. package/dist/index66.js +76 -0
  138. package/dist/index67.cjs +76 -0
  139. package/dist/index67.js +76 -0
  140. package/dist/index68.cjs +64 -0
  141. package/dist/index68.js +64 -0
  142. package/dist/index69.cjs +60 -0
  143. package/dist/index69.js +60 -0
  144. package/dist/index7.cjs +1 -1
  145. package/dist/index7.js +1 -1
  146. package/dist/index70.cjs +57 -0
  147. package/dist/index70.js +57 -0
  148. package/dist/index71.cjs +125 -0
  149. package/dist/index71.js +125 -0
  150. package/dist/index8.cjs +1 -1
  151. package/dist/index8.js +1 -1
  152. package/dist/index9.cjs +1 -1
  153. package/dist/index9.js +1 -1
  154. package/dist/premium-react-loaders.css +85 -0
  155. package/dist/types/index.d.ts +1 -0
  156. package/dist/types/index.d.ts.map +1 -1
  157. package/dist/types/neon.d.ts +26 -0
  158. package/dist/types/neon.d.ts.map +1 -0
  159. package/dist/types/particle.d.ts +18 -0
  160. package/dist/types/particle.d.ts.map +1 -1
  161. package/dist/types/status.d.ts +30 -0
  162. package/dist/types/status.d.ts.map +1 -1
  163. package/package.json +1 -1
package/dist/index63.cjs CHANGED
@@ -2,15 +2,17 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const react = require("react");
5
- const hooks = require("./index64.cjs");
5
+ const hooks = require("./index71.cjs");
6
6
  const colors = require("./index4.cjs");
7
7
  const classNames = require("./index3.cjs");
8
- const ParticleOrbit = react.forwardRef(
8
+ const GradientBar = react.forwardRef(
9
9
  ({
10
- size = 80,
11
- count = 5,
10
+ value,
11
+ width = "100%",
12
+ height = 8,
12
13
  color = "#3b82f6",
13
- centerColor,
14
+ secondaryColor = "#8b5cf6",
15
+ onComplete,
14
16
  speed = "normal",
15
17
  respectMotionPreference = true,
16
18
  delay = 0,
@@ -18,75 +20,80 @@ const ParticleOrbit = react.forwardRef(
18
20
  transition,
19
21
  className,
20
22
  style,
21
- testId = "particle-orbit",
23
+ testId = "gradient-bar",
22
24
  visible = true,
23
- ariaLabel = "Loading...",
25
+ ariaLabel,
24
26
  ...rest
25
27
  }, ref) => {
26
28
  const prefersReducedMotion = hooks.useReducedMotion();
27
29
  const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
28
30
  const { shouldRender, opacity, transitionStyle } = hooks.useLoaderVisibility(visible, delay, minDuration, transition);
31
+ const onCompleteRef = react.useRef(onComplete);
32
+ onCompleteRef.current = onComplete;
33
+ const hasCompletedRef = react.useRef(false);
34
+ const isIndeterminate = value === void 0;
35
+ const clampedValue = isIndeterminate ? 0 : Math.min(100, Math.max(0, value));
36
+ react.useEffect(() => {
37
+ if (clampedValue < 100) {
38
+ hasCompletedRef.current = false;
39
+ }
40
+ }, [clampedValue]);
41
+ react.useEffect(() => {
42
+ if (!isIndeterminate && clampedValue === 100 && !hasCompletedRef.current && onCompleteRef.current) {
43
+ hasCompletedRef.current = true;
44
+ onCompleteRef.current();
45
+ }
46
+ }, [clampedValue, isIndeterminate]);
29
47
  if (!shouldRender) return null;
30
- const clampedCount = Math.min(8, Math.max(3, count));
31
- const orbitRadius = size * 0.35;
32
- const particleSize = size * 0.1;
33
- const centerSize = size * 0.15;
34
- const dotColor = centerColor || color;
35
- const durationMs = colors.parseDurationMs(effectiveDuration);
36
- return /* @__PURE__ */ jsxRuntime.jsxs(
48
+ const gradient = `linear-gradient(90deg, ${color}, ${secondaryColor}, ${color})`;
49
+ const progressLabel = ariaLabel || (isIndeterminate ? "Loading..." : `Loading ${clampedValue}%`);
50
+ return /* @__PURE__ */ jsxRuntime.jsx(
37
51
  "div",
38
52
  {
39
53
  ref,
40
54
  "data-testid": testId,
41
- className: classNames.cn("relative inline-flex items-center justify-center", className),
42
- style: { width: size, height: size, opacity, transition: transitionStyle, ...style },
43
- role: "status",
44
- "aria-label": ariaLabel,
55
+ className: classNames.cn("relative overflow-hidden rounded-full", className),
56
+ style: {
57
+ width: colors.normalizeSize(width),
58
+ height,
59
+ backgroundColor: `${color}20`,
60
+ opacity,
61
+ transition: transitionStyle,
62
+ ...style
63
+ },
64
+ role: "progressbar",
65
+ "aria-label": progressLabel,
66
+ "aria-valuenow": isIndeterminate ? void 0 : clampedValue,
67
+ "aria-valuemin": 0,
68
+ "aria-valuemax": 100,
45
69
  "aria-busy": "true",
46
70
  ...rest,
47
- children: [
48
- /* @__PURE__ */ jsxRuntime.jsx(
49
- "div",
50
- {
51
- className: "absolute rounded-full z-10",
52
- style: {
53
- width: centerSize,
54
- height: centerSize,
55
- backgroundColor: dotColor,
56
- top: "50%",
57
- left: "50%",
58
- transform: "translate(-50%, -50%)"
59
- }
71
+ children: isIndeterminate ? /* @__PURE__ */ jsxRuntime.jsx(
72
+ "div",
73
+ {
74
+ className: "absolute h-full rounded-full",
75
+ style: {
76
+ background: gradient,
77
+ backgroundSize: "200% 100%",
78
+ animation: `gradient-flow ${effectiveDuration} linear infinite, progress-indeterminate ${effectiveDuration} ease-in-out infinite`
79
+ }
80
+ }
81
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
82
+ "div",
83
+ {
84
+ className: "h-full rounded-full",
85
+ style: {
86
+ width: `${clampedValue}%`,
87
+ background: gradient,
88
+ backgroundSize: "200% 100%",
89
+ animation: `gradient-flow ${effectiveDuration} linear infinite`,
90
+ transition: "width 0.3s ease-in-out"
60
91
  }
61
- ),
62
- Array.from({ length: clampedCount }, (_, i) => {
63
- const startAngle = `${i / clampedCount * 360}deg`;
64
- const staggerDelay = `-${i / clampedCount * durationMs}ms`;
65
- return /* @__PURE__ */ jsxRuntime.jsx(
66
- "div",
67
- {
68
- className: "absolute rounded-full",
69
- style: {
70
- width: particleSize,
71
- height: particleSize,
72
- backgroundColor: color,
73
- top: "50%",
74
- left: "50%",
75
- marginTop: -particleSize / 2,
76
- marginLeft: -particleSize / 2,
77
- animation: `particle-orbit ${effectiveDuration} linear infinite`,
78
- animationDelay: staggerDelay,
79
- ["--start-angle"]: startAngle,
80
- ["--orbit-radius"]: `${orbitRadius}px`
81
- }
82
- },
83
- i
84
- );
85
- })
86
- ]
92
+ }
93
+ )
87
94
  }
88
95
  );
89
96
  }
90
97
  );
91
- ParticleOrbit.displayName = "ParticleOrbit";
92
- exports.ParticleOrbit = ParticleOrbit;
98
+ GradientBar.displayName = "GradientBar";
99
+ exports.GradientBar = GradientBar;
package/dist/index63.js CHANGED
@@ -1,14 +1,16 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { forwardRef } from "react";
3
- import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index64.js";
4
- import { parseDurationMs } from "./index4.js";
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { forwardRef, useRef, useEffect } from "react";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index71.js";
4
+ import { normalizeSize } from "./index4.js";
5
5
  import { cn } from "./index3.js";
6
- const ParticleOrbit = forwardRef(
6
+ const GradientBar = forwardRef(
7
7
  ({
8
- size = 80,
9
- count = 5,
8
+ value,
9
+ width = "100%",
10
+ height = 8,
10
11
  color = "#3b82f6",
11
- centerColor,
12
+ secondaryColor = "#8b5cf6",
13
+ onComplete,
12
14
  speed = "normal",
13
15
  respectMotionPreference = true,
14
16
  delay = 0,
@@ -16,77 +18,82 @@ const ParticleOrbit = forwardRef(
16
18
  transition,
17
19
  className,
18
20
  style,
19
- testId = "particle-orbit",
21
+ testId = "gradient-bar",
20
22
  visible = true,
21
- ariaLabel = "Loading...",
23
+ ariaLabel,
22
24
  ...rest
23
25
  }, ref) => {
24
26
  const prefersReducedMotion = useReducedMotion();
25
27
  const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
26
28
  const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(visible, delay, minDuration, transition);
29
+ const onCompleteRef = useRef(onComplete);
30
+ onCompleteRef.current = onComplete;
31
+ const hasCompletedRef = useRef(false);
32
+ const isIndeterminate = value === void 0;
33
+ const clampedValue = isIndeterminate ? 0 : Math.min(100, Math.max(0, value));
34
+ useEffect(() => {
35
+ if (clampedValue < 100) {
36
+ hasCompletedRef.current = false;
37
+ }
38
+ }, [clampedValue]);
39
+ useEffect(() => {
40
+ if (!isIndeterminate && clampedValue === 100 && !hasCompletedRef.current && onCompleteRef.current) {
41
+ hasCompletedRef.current = true;
42
+ onCompleteRef.current();
43
+ }
44
+ }, [clampedValue, isIndeterminate]);
27
45
  if (!shouldRender) return null;
28
- const clampedCount = Math.min(8, Math.max(3, count));
29
- const orbitRadius = size * 0.35;
30
- const particleSize = size * 0.1;
31
- const centerSize = size * 0.15;
32
- const dotColor = centerColor || color;
33
- const durationMs = parseDurationMs(effectiveDuration);
34
- return /* @__PURE__ */ jsxs(
46
+ const gradient = `linear-gradient(90deg, ${color}, ${secondaryColor}, ${color})`;
47
+ const progressLabel = ariaLabel || (isIndeterminate ? "Loading..." : `Loading ${clampedValue}%`);
48
+ return /* @__PURE__ */ jsx(
35
49
  "div",
36
50
  {
37
51
  ref,
38
52
  "data-testid": testId,
39
- className: cn("relative inline-flex items-center justify-center", className),
40
- style: { width: size, height: size, opacity, transition: transitionStyle, ...style },
41
- role: "status",
42
- "aria-label": ariaLabel,
53
+ className: cn("relative overflow-hidden rounded-full", className),
54
+ style: {
55
+ width: normalizeSize(width),
56
+ height,
57
+ backgroundColor: `${color}20`,
58
+ opacity,
59
+ transition: transitionStyle,
60
+ ...style
61
+ },
62
+ role: "progressbar",
63
+ "aria-label": progressLabel,
64
+ "aria-valuenow": isIndeterminate ? void 0 : clampedValue,
65
+ "aria-valuemin": 0,
66
+ "aria-valuemax": 100,
43
67
  "aria-busy": "true",
44
68
  ...rest,
45
- children: [
46
- /* @__PURE__ */ jsx(
47
- "div",
48
- {
49
- className: "absolute rounded-full z-10",
50
- style: {
51
- width: centerSize,
52
- height: centerSize,
53
- backgroundColor: dotColor,
54
- top: "50%",
55
- left: "50%",
56
- transform: "translate(-50%, -50%)"
57
- }
69
+ children: isIndeterminate ? /* @__PURE__ */ jsx(
70
+ "div",
71
+ {
72
+ className: "absolute h-full rounded-full",
73
+ style: {
74
+ background: gradient,
75
+ backgroundSize: "200% 100%",
76
+ animation: `gradient-flow ${effectiveDuration} linear infinite, progress-indeterminate ${effectiveDuration} ease-in-out infinite`
77
+ }
78
+ }
79
+ ) : /* @__PURE__ */ jsx(
80
+ "div",
81
+ {
82
+ className: "h-full rounded-full",
83
+ style: {
84
+ width: `${clampedValue}%`,
85
+ background: gradient,
86
+ backgroundSize: "200% 100%",
87
+ animation: `gradient-flow ${effectiveDuration} linear infinite`,
88
+ transition: "width 0.3s ease-in-out"
58
89
  }
59
- ),
60
- Array.from({ length: clampedCount }, (_, i) => {
61
- const startAngle = `${i / clampedCount * 360}deg`;
62
- const staggerDelay = `-${i / clampedCount * durationMs}ms`;
63
- return /* @__PURE__ */ jsx(
64
- "div",
65
- {
66
- className: "absolute rounded-full",
67
- style: {
68
- width: particleSize,
69
- height: particleSize,
70
- backgroundColor: color,
71
- top: "50%",
72
- left: "50%",
73
- marginTop: -particleSize / 2,
74
- marginLeft: -particleSize / 2,
75
- animation: `particle-orbit ${effectiveDuration} linear infinite`,
76
- animationDelay: staggerDelay,
77
- ["--start-angle"]: startAngle,
78
- ["--orbit-radius"]: `${orbitRadius}px`
79
- }
80
- },
81
- i
82
- );
83
- })
84
- ]
90
+ }
91
+ )
85
92
  }
86
93
  );
87
94
  }
88
95
  );
89
- ParticleOrbit.displayName = "ParticleOrbit";
96
+ GradientBar.displayName = "GradientBar";
90
97
  export {
91
- ParticleOrbit
98
+ GradientBar
92
99
  };
package/dist/index64.cjs CHANGED
@@ -1,125 +1,75 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
3
4
  const react = require("react");
4
- function useReducedMotion() {
5
- const [prefersReducedMotion, setPrefersReducedMotion] = react.useState(false);
6
- react.useEffect(() => {
7
- if (typeof window === "undefined" || !window.matchMedia) {
8
- return;
9
- }
10
- const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
11
- setPrefersReducedMotion(mediaQuery.matches);
12
- const handleChange = (event) => {
13
- setPrefersReducedMotion(event.matches);
14
- };
15
- if (mediaQuery.addEventListener) {
16
- mediaQuery.addEventListener("change", handleChange);
17
- return () => mediaQuery.removeEventListener("change", handleChange);
18
- } else {
19
- mediaQuery.addListener(handleChange);
20
- return () => mediaQuery.removeListener(handleChange);
21
- }
22
- }, []);
23
- return prefersReducedMotion;
24
- }
25
- function getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion) {
26
- if (respectMotionPreference && prefersReducedMotion) {
27
- return "0.01ms";
28
- }
29
- if (typeof speed === "number") {
30
- const validSpeed = !isNaN(speed) && speed > 0 ? Math.max(50, Math.min(1e4, speed)) : 1e3;
31
- return `${validSpeed}ms`;
32
- }
33
- const speedMap = {
34
- slow: "2s",
35
- normal: "1s",
36
- fast: "0.5s"
37
- };
38
- return speedMap[speed] || speedMap.normal;
39
- }
40
- function useLoaderVisibility(visible = true, delay = 0, minDuration = 0, transition) {
41
- const transitionDuration = transition === true ? 150 : typeof transition === "number" ? transition : 0;
42
- const hasTransition = transitionDuration > 0;
43
- const [shouldRender, setShouldRender] = react.useState(visible && delay === 0);
44
- const [isTransitioning, setIsTransitioning] = react.useState(visible && delay === 0 && hasTransition);
45
- const showTimeRef = react.useRef(visible && delay === 0 ? Date.now() : null);
46
- const delayTimerRef = react.useRef(null);
47
- const minDurationTimerRef = react.useRef(null);
48
- const transitionTimerRef = react.useRef(null);
49
- react.useEffect(() => {
50
- if (delayTimerRef.current) {
51
- clearTimeout(delayTimerRef.current);
52
- delayTimerRef.current = null;
53
- }
54
- if (minDurationTimerRef.current) {
55
- clearTimeout(minDurationTimerRef.current);
56
- minDurationTimerRef.current = null;
57
- }
58
- if (transitionTimerRef.current) {
59
- clearTimeout(transitionTimerRef.current);
60
- transitionTimerRef.current = null;
61
- }
62
- if (visible) {
63
- if (delay > 0) {
64
- delayTimerRef.current = setTimeout(() => {
65
- setShouldRender(true);
66
- showTimeRef.current = Date.now();
67
- if (hasTransition) {
68
- setIsTransitioning(true);
69
- }
70
- }, delay);
71
- } else {
72
- setShouldRender(true);
73
- showTimeRef.current = Date.now();
74
- if (hasTransition) {
75
- setIsTransitioning(true);
76
- }
77
- }
78
- } else {
79
- const hideLoader = () => {
80
- if (hasTransition) {
81
- setIsTransitioning(false);
82
- transitionTimerRef.current = setTimeout(() => {
83
- setShouldRender(false);
84
- showTimeRef.current = null;
85
- }, transitionDuration);
86
- } else {
87
- setShouldRender(false);
88
- showTimeRef.current = null;
89
- }
90
- };
91
- if (showTimeRef.current !== null && minDuration > 0) {
92
- const elapsedTime = Date.now() - showTimeRef.current;
93
- const remainingTime = minDuration - elapsedTime;
94
- if (remainingTime > 0) {
95
- minDurationTimerRef.current = setTimeout(hideLoader, remainingTime);
96
- } else {
97
- hideLoader();
98
- }
99
- } else {
100
- hideLoader();
101
- }
102
- }
103
- return () => {
104
- if (delayTimerRef.current) {
105
- clearTimeout(delayTimerRef.current);
5
+ const hooks = require("./index71.cjs");
6
+ const colors = require("./index4.cjs");
7
+ const classNames = require("./index3.cjs");
8
+ const ParticleBurst = react.forwardRef(
9
+ ({
10
+ size = 60,
11
+ count = 8,
12
+ color = "#3b82f6",
13
+ particleSize = 6,
14
+ speed = "normal",
15
+ respectMotionPreference = true,
16
+ delay = 0,
17
+ minDuration = 0,
18
+ transition,
19
+ className,
20
+ style,
21
+ testId = "particle-burst",
22
+ visible = true,
23
+ ariaLabel = "Loading...",
24
+ ...rest
25
+ }, ref) => {
26
+ const prefersReducedMotion = hooks.useReducedMotion();
27
+ const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
28
+ const { shouldRender, opacity, transitionStyle } = hooks.useLoaderVisibility(visible, delay, minDuration, transition);
29
+ if (!shouldRender) return null;
30
+ const clampedCount = Math.min(20, Math.max(4, count));
31
+ const radius = size / 2;
32
+ const durationMs = colors.parseDurationMs(effectiveDuration);
33
+ return /* @__PURE__ */ jsxRuntime.jsx(
34
+ "div",
35
+ {
36
+ ref,
37
+ "data-testid": testId,
38
+ className: classNames.cn("relative inline-flex items-center justify-center", className),
39
+ style: { width: size, height: size, opacity, transition: transitionStyle, ...style },
40
+ role: "status",
41
+ "aria-label": ariaLabel,
42
+ "aria-busy": "true",
43
+ ...rest,
44
+ children: Array.from({ length: clampedCount }, (_, i) => {
45
+ const angle = i / clampedCount * 2 * Math.PI;
46
+ const tx = Math.cos(angle) * radius;
47
+ const ty = Math.sin(angle) * radius;
48
+ const animationDelay = `${i / clampedCount * durationMs}ms`;
49
+ return /* @__PURE__ */ jsxRuntime.jsx(
50
+ "div",
51
+ {
52
+ className: "absolute rounded-full",
53
+ style: {
54
+ width: particleSize,
55
+ height: particleSize,
56
+ backgroundColor: color,
57
+ top: "50%",
58
+ left: "50%",
59
+ marginTop: -particleSize / 2,
60
+ marginLeft: -particleSize / 2,
61
+ animation: `particle-burst ${effectiveDuration} ease-out infinite`,
62
+ animationDelay,
63
+ ["--tx"]: `${tx}px`,
64
+ ["--ty"]: `${ty}px`
65
+ }
66
+ },
67
+ i
68
+ );
69
+ })
106
70
  }
107
- if (minDurationTimerRef.current) {
108
- clearTimeout(minDurationTimerRef.current);
109
- }
110
- if (transitionTimerRef.current) {
111
- clearTimeout(transitionTimerRef.current);
112
- }
113
- };
114
- }, [visible, delay, minDuration, hasTransition, transitionDuration]);
115
- const opacity = hasTransition ? isTransitioning ? 1 : 0 : 1;
116
- const transitionStyle = hasTransition ? `opacity ${transitionDuration}ms ease-in-out` : "none";
117
- return {
118
- shouldRender,
119
- opacity,
120
- transitionStyle
121
- };
122
- }
123
- exports.getEffectiveDuration = getEffectiveDuration;
124
- exports.useLoaderVisibility = useLoaderVisibility;
125
- exports.useReducedMotion = useReducedMotion;
71
+ );
72
+ }
73
+ );
74
+ ParticleBurst.displayName = "ParticleBurst";
75
+ exports.ParticleBurst = ParticleBurst;