premium-react-loaders 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/dist/components/index.d.ts +1 -0
  2. package/dist/components/index.d.ts.map +1 -1
  3. package/dist/components/neon/NeonPulse.d.ts +12 -0
  4. package/dist/components/neon/NeonPulse.d.ts.map +1 -0
  5. package/dist/components/neon/NeonSpinner.d.ts +12 -0
  6. package/dist/components/neon/NeonSpinner.d.ts.map +1 -0
  7. package/dist/components/neon/NeonText.d.ts +12 -0
  8. package/dist/components/neon/NeonText.d.ts.map +1 -0
  9. package/dist/components/neon/index.d.ts +4 -0
  10. package/dist/components/neon/index.d.ts.map +1 -0
  11. package/dist/components/particle/ParticleField.d.ts +3 -0
  12. package/dist/components/particle/ParticleField.d.ts.map +1 -0
  13. package/dist/components/particle/ParticleTrail.d.ts +12 -0
  14. package/dist/components/particle/ParticleTrail.d.ts.map +1 -0
  15. package/dist/components/particle/index.d.ts +2 -0
  16. package/dist/components/particle/index.d.ts.map +1 -1
  17. package/dist/components/status/InfoIndicator.d.ts +29 -0
  18. package/dist/components/status/InfoIndicator.d.ts.map +1 -0
  19. package/dist/components/status/WarningIndicator.d.ts +29 -0
  20. package/dist/components/status/WarningIndicator.d.ts.map +1 -0
  21. package/dist/components/status/index.d.ts +2 -0
  22. package/dist/components/status/index.d.ts.map +1 -1
  23. package/dist/index.cjs +41 -27
  24. package/dist/index.js +41 -27
  25. package/dist/index10.cjs +1 -1
  26. package/dist/index10.js +1 -1
  27. package/dist/index11.cjs +1 -1
  28. package/dist/index11.js +1 -1
  29. package/dist/index12.cjs +1 -1
  30. package/dist/index12.js +1 -1
  31. package/dist/index13.cjs +1 -1
  32. package/dist/index13.js +1 -1
  33. package/dist/index14.cjs +1 -1
  34. package/dist/index14.js +1 -1
  35. package/dist/index15.cjs +1 -1
  36. package/dist/index15.js +1 -1
  37. package/dist/index17.cjs +1 -1
  38. package/dist/index17.js +1 -1
  39. package/dist/index18.cjs +1 -1
  40. package/dist/index18.js +1 -1
  41. package/dist/index19.cjs +1 -1
  42. package/dist/index19.js +1 -1
  43. package/dist/index20.cjs +1 -1
  44. package/dist/index20.js +1 -1
  45. package/dist/index21.cjs +1 -1
  46. package/dist/index21.js +1 -1
  47. package/dist/index22.cjs +1 -1
  48. package/dist/index22.js +1 -1
  49. package/dist/index23.cjs +1 -1
  50. package/dist/index23.js +1 -1
  51. package/dist/index24.cjs +1 -1
  52. package/dist/index24.js +1 -1
  53. package/dist/index25.cjs +1 -1
  54. package/dist/index25.js +1 -1
  55. package/dist/index26.cjs +1 -1
  56. package/dist/index26.js +1 -1
  57. package/dist/index27.cjs +1 -1
  58. package/dist/index27.js +1 -1
  59. package/dist/index28.cjs +1 -1
  60. package/dist/index28.js +1 -1
  61. package/dist/index29.cjs +1 -1
  62. package/dist/index29.js +1 -1
  63. package/dist/index30.cjs +1 -1
  64. package/dist/index30.js +1 -1
  65. package/dist/index31.cjs +1 -1
  66. package/dist/index31.js +1 -1
  67. package/dist/index32.cjs +1 -1
  68. package/dist/index32.js +1 -1
  69. package/dist/index33.cjs +1 -1
  70. package/dist/index33.js +1 -1
  71. package/dist/index34.cjs +1 -1
  72. package/dist/index34.js +1 -1
  73. package/dist/index35.cjs +1 -1
  74. package/dist/index35.js +1 -1
  75. package/dist/index36.cjs +1 -1
  76. package/dist/index36.js +1 -1
  77. package/dist/index37.cjs +59 -145
  78. package/dist/index37.js +61 -147
  79. package/dist/index38.cjs +32 -53
  80. package/dist/index38.js +33 -54
  81. package/dist/index39.cjs +138 -84
  82. package/dist/index39.js +140 -86
  83. package/dist/index40.cjs +33 -106
  84. package/dist/index40.js +34 -107
  85. package/dist/index41.cjs +66 -50
  86. package/dist/index41.js +66 -50
  87. package/dist/index42.cjs +123 -44
  88. package/dist/index42.js +124 -45
  89. package/dist/index43.cjs +43 -85
  90. package/dist/index43.js +44 -86
  91. package/dist/index44.cjs +35 -27
  92. package/dist/index44.js +35 -27
  93. package/dist/index45.cjs +87 -58
  94. package/dist/index45.js +87 -58
  95. package/dist/index46.cjs +35 -88
  96. package/dist/index46.js +36 -89
  97. package/dist/index47.cjs +62 -58
  98. package/dist/index47.js +63 -59
  99. package/dist/index48.cjs +87 -110
  100. package/dist/index48.js +88 -111
  101. package/dist/index49.cjs +48 -109
  102. package/dist/index49.js +49 -110
  103. package/dist/index50.cjs +110 -62
  104. package/dist/index50.js +111 -63
  105. package/dist/index51.cjs +104 -49
  106. package/dist/index51.js +104 -49
  107. package/dist/index52.cjs +43 -77
  108. package/dist/index52.js +44 -78
  109. package/dist/index53.cjs +56 -56
  110. package/dist/index53.js +56 -56
  111. package/dist/index54.cjs +104 -149
  112. package/dist/index54.js +106 -151
  113. package/dist/index55.cjs +97 -38
  114. package/dist/index55.js +99 -40
  115. package/dist/index56.cjs +161 -27
  116. package/dist/index56.js +162 -28
  117. package/dist/index57.cjs +36 -102
  118. package/dist/index57.js +38 -104
  119. package/dist/index58.cjs +19 -34
  120. package/dist/index58.js +20 -35
  121. package/dist/index59.cjs +87 -34
  122. package/dist/index59.js +89 -36
  123. package/dist/index60.cjs +25 -23
  124. package/dist/index60.js +25 -23
  125. package/dist/index61.cjs +32 -65
  126. package/dist/index61.js +34 -67
  127. package/dist/index62.cjs +29 -36
  128. package/dist/index62.js +30 -37
  129. package/dist/index63.cjs +66 -59
  130. package/dist/index63.js +69 -62
  131. package/dist/index64.cjs +71 -121
  132. package/dist/index64.js +72 -122
  133. package/dist/index65.cjs +92 -0
  134. package/dist/index65.js +92 -0
  135. package/dist/index66.cjs +76 -0
  136. package/dist/index66.js +76 -0
  137. package/dist/index67.cjs +76 -0
  138. package/dist/index67.js +76 -0
  139. package/dist/index68.cjs +64 -0
  140. package/dist/index68.js +64 -0
  141. package/dist/index69.cjs +60 -0
  142. package/dist/index69.js +60 -0
  143. package/dist/index7.cjs +1 -1
  144. package/dist/index7.js +1 -1
  145. package/dist/index70.cjs +57 -0
  146. package/dist/index70.js +57 -0
  147. package/dist/index71.cjs +125 -0
  148. package/dist/index71.js +125 -0
  149. package/dist/index8.cjs +1 -1
  150. package/dist/index8.js +1 -1
  151. package/dist/index9.cjs +1 -1
  152. package/dist/index9.js +1 -1
  153. package/dist/premium-react-loaders.css +85 -0
  154. package/dist/types/index.d.ts +1 -0
  155. package/dist/types/index.d.ts.map +1 -1
  156. package/dist/types/neon.d.ts +26 -0
  157. package/dist/types/neon.d.ts.map +1 -0
  158. package/dist/types/particle.d.ts +18 -0
  159. package/dist/types/particle.d.ts.map +1 -1
  160. package/dist/types/status.d.ts +30 -0
  161. package/dist/types/status.d.ts.map +1 -1
  162. package/package.json +1 -1
package/dist/index57.js CHANGED
@@ -1,119 +1,53 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { forwardRef, useRef, useEffect } from "react";
3
- import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index64.js";
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { forwardRef, useState, useRef, useEffect } from "react";
4
3
  import { cn } from "./index3.js";
5
- const LiquidFill = forwardRef(
4
+ const LiveRegion = forwardRef(
6
5
  ({
7
- value,
8
- size = 80,
9
- color = "#3b82f6",
10
- waveAmplitude = 4,
11
- onComplete,
12
- speed = "normal",
13
- respectMotionPreference = true,
14
- delay = 0,
15
- minDuration = 0,
16
- transition,
17
- className,
18
- style,
19
- testId = "liquid-fill",
20
- visible = true,
21
- ariaLabel,
22
- ...rest
6
+ message,
7
+ politeness = "polite",
8
+ clearAfter,
9
+ atomic = true,
10
+ relevant = "additions",
11
+ className
23
12
  }, ref) => {
24
- const prefersReducedMotion = useReducedMotion();
25
- const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
26
- const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(visible, delay, minDuration, transition);
27
- const onCompleteRef = useRef(onComplete);
28
- onCompleteRef.current = onComplete;
29
- const isIndeterminate = value === void 0;
30
- const clampedValue = isIndeterminate ? 50 : Math.min(100, Math.max(0, value));
13
+ const [displayMessage, setDisplayMessage] = useState(message);
14
+ const clearTimerRef = useRef(null);
31
15
  useEffect(() => {
32
- if (!isIndeterminate && clampedValue === 100 && onCompleteRef.current) {
33
- onCompleteRef.current();
16
+ setDisplayMessage(message);
17
+ if (clearTimerRef.current) {
18
+ clearTimeout(clearTimerRef.current);
19
+ clearTimerRef.current = null;
34
20
  }
35
- }, [clampedValue, isIndeterminate]);
36
- if (!shouldRender) return null;
37
- const progressLabel = ariaLabel || (isIndeterminate ? "Loading..." : `Loading ${clampedValue}%`);
38
- const fillBottom = `${clampedValue}%`;
21
+ if (clearAfter && message) {
22
+ clearTimerRef.current = setTimeout(() => {
23
+ setDisplayMessage("");
24
+ }, clearAfter);
25
+ }
26
+ return () => {
27
+ if (clearTimerRef.current) {
28
+ clearTimeout(clearTimerRef.current);
29
+ }
30
+ };
31
+ }, [message, clearAfter]);
39
32
  return /* @__PURE__ */ jsx(
40
33
  "div",
41
34
  {
42
35
  ref,
43
- "data-testid": testId,
44
- className: cn("inline-flex items-center justify-center", className),
45
- style: { opacity, transition: transitionStyle, ...style },
46
- role: "status",
47
- "aria-label": progressLabel,
48
- "aria-busy": "true",
49
- ...rest,
50
- children: /* @__PURE__ */ jsxs(
51
- "div",
52
- {
53
- className: "relative overflow-hidden rounded-full",
54
- style: { width: size, height: size },
55
- children: [
56
- /* @__PURE__ */ jsx(
57
- "div",
58
- {
59
- className: "absolute inset-0 rounded-full",
60
- style: { backgroundColor: `${color}20` }
61
- }
62
- ),
63
- /* @__PURE__ */ jsxs(
64
- "div",
65
- {
66
- className: "absolute left-0 right-0 bottom-0",
67
- style: {
68
- height: fillBottom,
69
- transition: isIndeterminate ? void 0 : "height 0.4s ease-in-out",
70
- overflow: "hidden"
71
- },
72
- children: [
73
- /* @__PURE__ */ jsx(
74
- "div",
75
- {
76
- style: {
77
- position: "absolute",
78
- top: -waveAmplitude * 2,
79
- left: 0,
80
- width: "200%",
81
- height: waveAmplitude * 4,
82
- backgroundColor: color,
83
- borderRadius: "40%",
84
- animation: `liquid-wave ${effectiveDuration} linear infinite`
85
- }
86
- }
87
- ),
88
- /* @__PURE__ */ jsx(
89
- "div",
90
- {
91
- className: "absolute bottom-0 left-0 right-0",
92
- style: { backgroundColor: color, top: waveAmplitude * 2 }
93
- }
94
- )
95
- ]
96
- }
97
- ),
98
- !isIndeterminate && /* @__PURE__ */ jsxs(
99
- "span",
100
- {
101
- className: "absolute inset-0 flex items-center justify-center text-xs font-bold",
102
- style: { color: clampedValue > 50 ? "#fff" : color },
103
- children: [
104
- clampedValue,
105
- "%"
106
- ]
107
- }
108
- )
109
- ]
110
- }
111
- )
36
+ className: cn(
37
+ // Visually hidden but accessible to screen readers
38
+ "sr-only absolute w-px h-px p-0 -m-px overflow-hidden whitespace-nowrap border-0",
39
+ className
40
+ ),
41
+ role: politeness === "assertive" ? "alert" : "status",
42
+ "aria-live": politeness,
43
+ "aria-atomic": atomic,
44
+ "aria-relevant": relevant,
45
+ children: displayMessage
112
46
  }
113
47
  );
114
48
  }
115
49
  );
116
- LiquidFill.displayName = "LiquidFill";
50
+ LiveRegion.displayName = "LiveRegion";
117
51
  export {
118
- LiquidFill
52
+ LiveRegion
119
53
  };
package/dist/index58.cjs CHANGED
@@ -2,14 +2,12 @@
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 colors = require("./index4.cjs");
6
- const hooks = require("./index64.cjs");
5
+ const hooks = require("./index71.cjs");
7
6
  const classNames = require("./index3.cjs");
8
- const WaveCircle = react.forwardRef(
7
+ const MorphBlob = react.forwardRef(
9
8
  ({
10
9
  size = 80,
11
10
  color = "#3b82f6",
12
- ringCount = 3,
13
11
  speed = "normal",
14
12
  respectMotionPreference = true,
15
13
  delay = 0,
@@ -17,7 +15,7 @@ const WaveCircle = react.forwardRef(
17
15
  transition,
18
16
  className,
19
17
  style,
20
- testId = "wave-circle",
18
+ testId = "morph-blob",
21
19
  visible = true,
22
20
  ariaLabel = "Loading...",
23
21
  ...rest
@@ -26,45 +24,32 @@ const WaveCircle = react.forwardRef(
26
24
  const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
27
25
  const { shouldRender, opacity, transitionStyle } = hooks.useLoaderVisibility(visible, delay, minDuration, transition);
28
26
  if (!shouldRender) return null;
29
- const clampedCount = Math.min(5, Math.max(2, ringCount));
30
- const durationMs = colors.parseDurationMs(effectiveDuration);
31
- return /* @__PURE__ */ jsxRuntime.jsxs(
27
+ return /* @__PURE__ */ jsxRuntime.jsx(
32
28
  "div",
33
29
  {
34
30
  ref,
35
31
  "data-testid": testId,
36
- className: classNames.cn("relative inline-flex items-center justify-center", className),
37
- style: { width: size, height: size, opacity, transition: transitionStyle, ...style },
32
+ className: classNames.cn("inline-flex items-center justify-center", className),
33
+ style: { opacity, transition: transitionStyle, ...style },
38
34
  role: "status",
39
35
  "aria-label": ariaLabel,
40
36
  "aria-busy": "true",
41
37
  ...rest,
42
- children: [
43
- /* @__PURE__ */ jsxRuntime.jsx(
44
- "div",
45
- {
46
- className: "absolute rounded-full z-10",
47
- style: { width: size * 0.15, height: size * 0.15, backgroundColor: color }
38
+ children: /* @__PURE__ */ jsxRuntime.jsx(
39
+ "div",
40
+ {
41
+ style: {
42
+ width: size,
43
+ height: size,
44
+ backgroundColor: color,
45
+ borderRadius: "60% 40% 30% 70% / 60% 30% 70% 40%",
46
+ animation: `morph-blob ${effectiveDuration} ease-in-out infinite`
48
47
  }
49
- ),
50
- Array.from({ length: clampedCount }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx(
51
- "div",
52
- {
53
- className: "absolute rounded-full border-2",
54
- style: {
55
- width: size,
56
- height: size,
57
- borderColor: color,
58
- animation: `wave-circle-expand ${effectiveDuration} ease-out infinite`,
59
- animationDelay: `${i / clampedCount * durationMs}ms`
60
- }
61
- },
62
- i
63
- ))
64
- ]
48
+ }
49
+ )
65
50
  }
66
51
  );
67
52
  }
68
53
  );
69
- WaveCircle.displayName = "WaveCircle";
70
- exports.WaveCircle = WaveCircle;
54
+ MorphBlob.displayName = "MorphBlob";
55
+ exports.MorphBlob = MorphBlob;
package/dist/index58.js CHANGED
@@ -1,13 +1,11 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
1
+ import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
- import { parseDurationMs } from "./index4.js";
4
- import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index64.js";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index71.js";
5
4
  import { cn } from "./index3.js";
6
- const WaveCircle = forwardRef(
5
+ const MorphBlob = forwardRef(
7
6
  ({
8
7
  size = 80,
9
8
  color = "#3b82f6",
10
- ringCount = 3,
11
9
  speed = "normal",
12
10
  respectMotionPreference = true,
13
11
  delay = 0,
@@ -15,7 +13,7 @@ const WaveCircle = forwardRef(
15
13
  transition,
16
14
  className,
17
15
  style,
18
- testId = "wave-circle",
16
+ testId = "morph-blob",
19
17
  visible = true,
20
18
  ariaLabel = "Loading...",
21
19
  ...rest
@@ -24,47 +22,34 @@ const WaveCircle = forwardRef(
24
22
  const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
25
23
  const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(visible, delay, minDuration, transition);
26
24
  if (!shouldRender) return null;
27
- const clampedCount = Math.min(5, Math.max(2, ringCount));
28
- const durationMs = parseDurationMs(effectiveDuration);
29
- return /* @__PURE__ */ jsxs(
25
+ return /* @__PURE__ */ jsx(
30
26
  "div",
31
27
  {
32
28
  ref,
33
29
  "data-testid": testId,
34
- className: cn("relative inline-flex items-center justify-center", className),
35
- style: { width: size, height: size, opacity, transition: transitionStyle, ...style },
30
+ className: cn("inline-flex items-center justify-center", className),
31
+ style: { opacity, transition: transitionStyle, ...style },
36
32
  role: "status",
37
33
  "aria-label": ariaLabel,
38
34
  "aria-busy": "true",
39
35
  ...rest,
40
- children: [
41
- /* @__PURE__ */ jsx(
42
- "div",
43
- {
44
- className: "absolute rounded-full z-10",
45
- style: { width: size * 0.15, height: size * 0.15, backgroundColor: color }
36
+ children: /* @__PURE__ */ jsx(
37
+ "div",
38
+ {
39
+ style: {
40
+ width: size,
41
+ height: size,
42
+ backgroundColor: color,
43
+ borderRadius: "60% 40% 30% 70% / 60% 30% 70% 40%",
44
+ animation: `morph-blob ${effectiveDuration} ease-in-out infinite`
46
45
  }
47
- ),
48
- Array.from({ length: clampedCount }, (_, i) => /* @__PURE__ */ jsx(
49
- "div",
50
- {
51
- className: "absolute rounded-full border-2",
52
- style: {
53
- width: size,
54
- height: size,
55
- borderColor: color,
56
- animation: `wave-circle-expand ${effectiveDuration} ease-out infinite`,
57
- animationDelay: `${i / clampedCount * durationMs}ms`
58
- }
59
- },
60
- i
61
- ))
62
- ]
46
+ }
47
+ )
63
48
  }
64
49
  );
65
50
  }
66
51
  );
67
- WaveCircle.displayName = "WaveCircle";
52
+ MorphBlob.displayName = "MorphBlob";
68
53
  export {
69
- WaveCircle
54
+ MorphBlob
70
55
  };
package/dist/index59.cjs CHANGED
@@ -2,15 +2,15 @@
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 classNames = require("./index3.cjs");
7
- const GradientSpinner = react.forwardRef(
7
+ const LiquidFill = react.forwardRef(
8
8
  ({
9
- size = 48,
9
+ value,
10
+ size = 80,
10
11
  color = "#3b82f6",
11
- secondaryColor = "#8b5cf6",
12
- thickness = 4,
13
- backgroundColor = "white",
12
+ waveAmplitude = 4,
13
+ onComplete,
14
14
  speed = "normal",
15
15
  respectMotionPreference = true,
16
16
  delay = 0,
@@ -18,49 +18,102 @@ const GradientSpinner = react.forwardRef(
18
18
  transition,
19
19
  className,
20
20
  style,
21
- testId = "gradient-spinner",
21
+ testId = "liquid-fill",
22
22
  visible = true,
23
- ariaLabel = "Loading...",
23
+ ariaLabel,
24
24
  ...rest
25
25
  }, ref) => {
26
26
  const prefersReducedMotion = hooks.useReducedMotion();
27
27
  const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
28
28
  const { shouldRender, opacity, transitionStyle } = hooks.useLoaderVisibility(visible, delay, minDuration, transition);
29
+ const onCompleteRef = react.useRef(onComplete);
30
+ onCompleteRef.current = onComplete;
31
+ const isIndeterminate = value === void 0;
32
+ const clampedValue = isIndeterminate ? 50 : Math.min(100, Math.max(0, value));
33
+ react.useEffect(() => {
34
+ if (!isIndeterminate && clampedValue === 100 && onCompleteRef.current) {
35
+ onCompleteRef.current();
36
+ }
37
+ }, [clampedValue, isIndeterminate]);
29
38
  if (!shouldRender) return null;
30
- const inner = size - thickness * 2;
31
- return /* @__PURE__ */ jsxRuntime.jsxs(
39
+ const progressLabel = ariaLabel || (isIndeterminate ? "Loading..." : `Loading ${clampedValue}%`);
40
+ const fillBottom = `${clampedValue}%`;
41
+ return /* @__PURE__ */ jsxRuntime.jsx(
32
42
  "div",
33
43
  {
34
44
  ref,
35
45
  "data-testid": testId,
36
- className: classNames.cn("relative inline-flex items-center justify-center", className),
37
- style: { width: size, height: size, opacity, transition: transitionStyle, ...style },
46
+ className: classNames.cn("inline-flex items-center justify-center", className),
47
+ style: { opacity, transition: transitionStyle, ...style },
38
48
  role: "status",
39
- "aria-label": ariaLabel,
49
+ "aria-label": progressLabel,
40
50
  "aria-busy": "true",
41
51
  ...rest,
42
- children: [
43
- /* @__PURE__ */ jsxRuntime.jsx(
44
- "div",
45
- {
46
- className: "absolute inset-0 rounded-full",
47
- style: {
48
- background: `conic-gradient(from 0deg, ${color}, ${secondaryColor}, transparent)`,
49
- animation: `gradient-spin ${effectiveDuration} linear infinite`
50
- }
51
- }
52
- ),
53
- /* @__PURE__ */ jsxRuntime.jsx(
54
- "div",
55
- {
56
- className: "absolute rounded-full",
57
- style: { width: inner, height: inner, backgroundColor }
58
- }
59
- )
60
- ]
52
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
53
+ "div",
54
+ {
55
+ className: "relative overflow-hidden rounded-full",
56
+ style: { width: size, height: size },
57
+ children: [
58
+ /* @__PURE__ */ jsxRuntime.jsx(
59
+ "div",
60
+ {
61
+ className: "absolute inset-0 rounded-full",
62
+ style: { backgroundColor: `${color}20` }
63
+ }
64
+ ),
65
+ /* @__PURE__ */ jsxRuntime.jsxs(
66
+ "div",
67
+ {
68
+ className: "absolute left-0 right-0 bottom-0",
69
+ style: {
70
+ height: fillBottom,
71
+ transition: isIndeterminate ? void 0 : "height 0.4s ease-in-out",
72
+ overflow: "hidden"
73
+ },
74
+ children: [
75
+ /* @__PURE__ */ jsxRuntime.jsx(
76
+ "div",
77
+ {
78
+ style: {
79
+ position: "absolute",
80
+ top: -waveAmplitude * 2,
81
+ left: 0,
82
+ width: "200%",
83
+ height: waveAmplitude * 4,
84
+ backgroundColor: color,
85
+ borderRadius: "40%",
86
+ animation: `liquid-wave ${effectiveDuration} linear infinite`
87
+ }
88
+ }
89
+ ),
90
+ /* @__PURE__ */ jsxRuntime.jsx(
91
+ "div",
92
+ {
93
+ className: "absolute bottom-0 left-0 right-0",
94
+ style: { backgroundColor: color, top: waveAmplitude * 2 }
95
+ }
96
+ )
97
+ ]
98
+ }
99
+ ),
100
+ !isIndeterminate && /* @__PURE__ */ jsxRuntime.jsxs(
101
+ "span",
102
+ {
103
+ className: "absolute inset-0 flex items-center justify-center text-xs font-bold",
104
+ style: { color: clampedValue > 50 ? "#fff" : color },
105
+ children: [
106
+ clampedValue,
107
+ "%"
108
+ ]
109
+ }
110
+ )
111
+ ]
112
+ }
113
+ )
61
114
  }
62
115
  );
63
116
  }
64
117
  );
65
- GradientSpinner.displayName = "GradientSpinner";
66
- exports.GradientSpinner = GradientSpinner;
118
+ LiquidFill.displayName = "LiquidFill";
119
+ exports.LiquidFill = LiquidFill;
package/dist/index59.js CHANGED
@@ -1,14 +1,14 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { forwardRef } from "react";
3
- import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index64.js";
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, useRef, useEffect } from "react";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index71.js";
4
4
  import { cn } from "./index3.js";
5
- const GradientSpinner = forwardRef(
5
+ const LiquidFill = forwardRef(
6
6
  ({
7
- size = 48,
7
+ value,
8
+ size = 80,
8
9
  color = "#3b82f6",
9
- secondaryColor = "#8b5cf6",
10
- thickness = 4,
11
- backgroundColor = "white",
10
+ waveAmplitude = 4,
11
+ onComplete,
12
12
  speed = "normal",
13
13
  respectMotionPreference = true,
14
14
  delay = 0,
@@ -16,51 +16,104 @@ const GradientSpinner = forwardRef(
16
16
  transition,
17
17
  className,
18
18
  style,
19
- testId = "gradient-spinner",
19
+ testId = "liquid-fill",
20
20
  visible = true,
21
- ariaLabel = "Loading...",
21
+ ariaLabel,
22
22
  ...rest
23
23
  }, ref) => {
24
24
  const prefersReducedMotion = useReducedMotion();
25
25
  const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
26
26
  const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(visible, delay, minDuration, transition);
27
+ const onCompleteRef = useRef(onComplete);
28
+ onCompleteRef.current = onComplete;
29
+ const isIndeterminate = value === void 0;
30
+ const clampedValue = isIndeterminate ? 50 : Math.min(100, Math.max(0, value));
31
+ useEffect(() => {
32
+ if (!isIndeterminate && clampedValue === 100 && onCompleteRef.current) {
33
+ onCompleteRef.current();
34
+ }
35
+ }, [clampedValue, isIndeterminate]);
27
36
  if (!shouldRender) return null;
28
- const inner = size - thickness * 2;
29
- return /* @__PURE__ */ jsxs(
37
+ const progressLabel = ariaLabel || (isIndeterminate ? "Loading..." : `Loading ${clampedValue}%`);
38
+ const fillBottom = `${clampedValue}%`;
39
+ return /* @__PURE__ */ jsx(
30
40
  "div",
31
41
  {
32
42
  ref,
33
43
  "data-testid": testId,
34
- className: cn("relative inline-flex items-center justify-center", className),
35
- style: { width: size, height: size, opacity, transition: transitionStyle, ...style },
44
+ className: cn("inline-flex items-center justify-center", className),
45
+ style: { opacity, transition: transitionStyle, ...style },
36
46
  role: "status",
37
- "aria-label": ariaLabel,
47
+ "aria-label": progressLabel,
38
48
  "aria-busy": "true",
39
49
  ...rest,
40
- children: [
41
- /* @__PURE__ */ jsx(
42
- "div",
43
- {
44
- className: "absolute inset-0 rounded-full",
45
- style: {
46
- background: `conic-gradient(from 0deg, ${color}, ${secondaryColor}, transparent)`,
47
- animation: `gradient-spin ${effectiveDuration} linear infinite`
48
- }
49
- }
50
- ),
51
- /* @__PURE__ */ jsx(
52
- "div",
53
- {
54
- className: "absolute rounded-full",
55
- style: { width: inner, height: inner, backgroundColor }
56
- }
57
- )
58
- ]
50
+ children: /* @__PURE__ */ jsxs(
51
+ "div",
52
+ {
53
+ className: "relative overflow-hidden rounded-full",
54
+ style: { width: size, height: size },
55
+ children: [
56
+ /* @__PURE__ */ jsx(
57
+ "div",
58
+ {
59
+ className: "absolute inset-0 rounded-full",
60
+ style: { backgroundColor: `${color}20` }
61
+ }
62
+ ),
63
+ /* @__PURE__ */ jsxs(
64
+ "div",
65
+ {
66
+ className: "absolute left-0 right-0 bottom-0",
67
+ style: {
68
+ height: fillBottom,
69
+ transition: isIndeterminate ? void 0 : "height 0.4s ease-in-out",
70
+ overflow: "hidden"
71
+ },
72
+ children: [
73
+ /* @__PURE__ */ jsx(
74
+ "div",
75
+ {
76
+ style: {
77
+ position: "absolute",
78
+ top: -waveAmplitude * 2,
79
+ left: 0,
80
+ width: "200%",
81
+ height: waveAmplitude * 4,
82
+ backgroundColor: color,
83
+ borderRadius: "40%",
84
+ animation: `liquid-wave ${effectiveDuration} linear infinite`
85
+ }
86
+ }
87
+ ),
88
+ /* @__PURE__ */ jsx(
89
+ "div",
90
+ {
91
+ className: "absolute bottom-0 left-0 right-0",
92
+ style: { backgroundColor: color, top: waveAmplitude * 2 }
93
+ }
94
+ )
95
+ ]
96
+ }
97
+ ),
98
+ !isIndeterminate && /* @__PURE__ */ jsxs(
99
+ "span",
100
+ {
101
+ className: "absolute inset-0 flex items-center justify-center text-xs font-bold",
102
+ style: { color: clampedValue > 50 ? "#fff" : color },
103
+ children: [
104
+ clampedValue,
105
+ "%"
106
+ ]
107
+ }
108
+ )
109
+ ]
110
+ }
111
+ )
59
112
  }
60
113
  );
61
114
  }
62
115
  );
63
- GradientSpinner.displayName = "GradientSpinner";
116
+ LiquidFill.displayName = "LiquidFill";
64
117
  export {
65
- GradientSpinner
118
+ LiquidFill
66
119
  };