premium-react-loaders 1.3.0 → 2.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 (138) hide show
  1. package/README.md +264 -30
  2. package/dist/components/pulse/TypingIndicator.d.ts.map +1 -1
  3. package/dist/context/ThemeContext.d.ts +84 -0
  4. package/dist/context/ThemeContext.d.ts.map +1 -0
  5. package/dist/context/index.d.ts +3 -0
  6. package/dist/context/index.d.ts.map +1 -0
  7. package/dist/hooks/index.d.ts +3 -0
  8. package/dist/hooks/index.d.ts.map +1 -0
  9. package/dist/hooks/useLoader.d.ts +56 -0
  10. package/dist/hooks/useLoader.d.ts.map +1 -0
  11. package/dist/index.cjs +31 -27
  12. package/dist/index.d.ts +5 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +31 -27
  15. package/dist/index10.cjs +20 -32
  16. package/dist/index10.js +20 -32
  17. package/dist/index11.cjs +47 -26
  18. package/dist/index11.js +47 -26
  19. package/dist/index12.cjs +30 -127
  20. package/dist/index12.js +31 -128
  21. package/dist/index13.cjs +30 -54
  22. package/dist/index13.js +30 -54
  23. package/dist/index14.cjs +127 -44
  24. package/dist/index14.js +128 -45
  25. package/dist/index15.cjs +58 -38
  26. package/dist/index15.js +59 -39
  27. package/dist/index16.cjs +24 -37
  28. package/dist/index16.js +24 -37
  29. package/dist/index17.cjs +19 -22
  30. package/dist/index17.js +19 -22
  31. package/dist/index18.cjs +25 -21
  32. package/dist/index18.js +25 -21
  33. package/dist/index19.cjs +22 -33
  34. package/dist/index19.js +22 -33
  35. package/dist/index20.cjs +26 -36
  36. package/dist/index20.js +28 -38
  37. package/dist/index21.cjs +40 -77
  38. package/dist/index21.js +42 -79
  39. package/dist/index22.cjs +53 -103
  40. package/dist/index22.js +54 -104
  41. package/dist/index23.cjs +46 -81
  42. package/dist/index23.js +47 -82
  43. package/dist/index24.cjs +105 -104
  44. package/dist/index24.js +107 -106
  45. package/dist/index25.cjs +108 -28
  46. package/dist/index25.js +111 -31
  47. package/dist/index26.cjs +104 -37
  48. package/dist/index26.js +106 -39
  49. package/dist/index27.cjs +22 -31
  50. package/dist/index27.js +23 -32
  51. package/dist/index28.cjs +30 -30
  52. package/dist/index28.js +31 -31
  53. package/dist/index29.cjs +49 -53
  54. package/dist/index29.js +50 -54
  55. package/dist/index3.cjs +11 -3
  56. package/dist/index3.js +11 -3
  57. package/dist/index30.cjs +77 -17
  58. package/dist/index30.js +76 -16
  59. package/dist/index31.cjs +77 -121
  60. package/dist/index31.js +78 -122
  61. package/dist/index32.cjs +125 -0
  62. package/dist/index32.js +125 -0
  63. package/dist/index4.cjs +0 -1
  64. package/dist/index4.js +0 -1
  65. package/dist/index5.cjs +11 -73
  66. package/dist/index5.js +12 -74
  67. package/dist/index6.cjs +86 -66
  68. package/dist/index6.js +87 -67
  69. package/dist/index7.cjs +40 -21
  70. package/dist/index7.js +40 -21
  71. package/dist/index8.cjs +34 -22
  72. package/dist/index8.js +34 -22
  73. package/dist/index9.cjs +21 -56
  74. package/dist/index9.js +22 -57
  75. package/dist/premium-react-loaders.css +250 -1073
  76. package/dist/utils/classNames.d.ts +3 -2
  77. package/dist/utils/classNames.d.ts.map +1 -1
  78. package/package.json +5 -8
  79. package/dist/index.cjs.map +0 -1
  80. package/dist/index.js.map +0 -1
  81. package/dist/index10.cjs.map +0 -1
  82. package/dist/index10.js.map +0 -1
  83. package/dist/index11.cjs.map +0 -1
  84. package/dist/index11.js.map +0 -1
  85. package/dist/index12.cjs.map +0 -1
  86. package/dist/index12.js.map +0 -1
  87. package/dist/index13.cjs.map +0 -1
  88. package/dist/index13.js.map +0 -1
  89. package/dist/index14.cjs.map +0 -1
  90. package/dist/index14.js.map +0 -1
  91. package/dist/index15.cjs.map +0 -1
  92. package/dist/index15.js.map +0 -1
  93. package/dist/index16.cjs.map +0 -1
  94. package/dist/index16.js.map +0 -1
  95. package/dist/index17.cjs.map +0 -1
  96. package/dist/index17.js.map +0 -1
  97. package/dist/index18.cjs.map +0 -1
  98. package/dist/index18.js.map +0 -1
  99. package/dist/index19.cjs.map +0 -1
  100. package/dist/index19.js.map +0 -1
  101. package/dist/index20.cjs.map +0 -1
  102. package/dist/index20.js.map +0 -1
  103. package/dist/index21.cjs.map +0 -1
  104. package/dist/index21.js.map +0 -1
  105. package/dist/index22.cjs.map +0 -1
  106. package/dist/index22.js.map +0 -1
  107. package/dist/index23.cjs.map +0 -1
  108. package/dist/index23.js.map +0 -1
  109. package/dist/index24.cjs.map +0 -1
  110. package/dist/index24.js.map +0 -1
  111. package/dist/index25.cjs.map +0 -1
  112. package/dist/index25.js.map +0 -1
  113. package/dist/index26.cjs.map +0 -1
  114. package/dist/index26.js.map +0 -1
  115. package/dist/index27.cjs.map +0 -1
  116. package/dist/index27.js.map +0 -1
  117. package/dist/index28.cjs.map +0 -1
  118. package/dist/index28.js.map +0 -1
  119. package/dist/index29.cjs.map +0 -1
  120. package/dist/index29.js.map +0 -1
  121. package/dist/index3.cjs.map +0 -1
  122. package/dist/index3.js.map +0 -1
  123. package/dist/index30.cjs.map +0 -1
  124. package/dist/index30.js.map +0 -1
  125. package/dist/index31.cjs.map +0 -1
  126. package/dist/index31.js.map +0 -1
  127. package/dist/index4.cjs.map +0 -1
  128. package/dist/index4.js.map +0 -1
  129. package/dist/index5.cjs.map +0 -1
  130. package/dist/index5.js.map +0 -1
  131. package/dist/index6.cjs.map +0 -1
  132. package/dist/index6.js.map +0 -1
  133. package/dist/index7.cjs.map +0 -1
  134. package/dist/index7.js.map +0 -1
  135. package/dist/index8.cjs.map +0 -1
  136. package/dist/index8.js.map +0 -1
  137. package/dist/index9.cjs.map +0 -1
  138. package/dist/index9.js.map +0 -1
package/dist/index24.js CHANGED
@@ -1,29 +1,33 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { forwardRef, Fragment } from "react";
3
- import { useLoaderVisibility } from "./index31.js";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index32.js";
4
+ import { normalizeSize, parseSizeToNumber } from "./index4.js";
4
5
  import { cn } from "./index3.js";
5
- const ProgressSteps = forwardRef(
6
+ const ProgressCircle = forwardRef(
6
7
  ({
7
- steps,
8
- currentStep,
9
- labels,
10
- showNumbers = true,
11
- orientation = "horizontal",
12
- connector = "line",
8
+ value = 0,
9
+ indeterminate = false,
10
+ showValue = false,
11
+ size = "lg",
12
+ thickness = 4,
13
13
  color = "#3b82f6",
14
- completedColor,
15
- activeColor,
16
- inactiveColor = "#e0e0e0",
14
+ secondaryColor = "#e0e0e0",
15
+ buffer,
16
+ speed = "normal",
17
+ reverse = false,
18
+ respectMotionPreference = true,
17
19
  delay = 0,
18
20
  minDuration = 0,
19
21
  transition,
20
22
  className,
21
23
  style,
22
- testId = "progress-steps",
24
+ testId = "progress-circle",
23
25
  visible = true,
24
- ariaLabel = "Progress steps",
26
+ ariaLabel,
25
27
  ...rest
26
28
  }, ref) => {
29
+ const prefersReducedMotion = useReducedMotion();
30
+ const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
27
31
  const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(
28
32
  visible,
29
33
  delay,
@@ -31,115 +35,112 @@ const ProgressSteps = forwardRef(
31
35
  transition
32
36
  );
33
37
  if (!shouldRender) return null;
34
- const completed = completedColor || color;
35
- const active = activeColor || color;
36
- const getStepStatus = (index) => {
37
- if (index < currentStep) return "completed";
38
- if (index === currentStep) return "active";
39
- return "inactive";
40
- };
41
- const getStepColor = (status) => {
42
- if (status === "completed") return completed;
43
- if (status === "active") return active;
44
- return inactiveColor;
45
- };
46
- const getConnectorColor = (index) => {
47
- return index < currentStep ? completed : inactiveColor;
48
- };
49
- const isHorizontal = orientation === "horizontal";
50
- return /* @__PURE__ */ jsx(
38
+ const clampedValue = Math.min(100, Math.max(0, value));
39
+ const clampedBuffer = buffer !== void 0 ? Math.min(100, Math.max(0, buffer)) : void 0;
40
+ const sizeValue = parseSizeToNumber(size, 56);
41
+ const thicknessValue = parseSizeToNumber(thickness, 4);
42
+ const radius = (sizeValue - thicknessValue * 2) / 2;
43
+ const circumference = 2 * Math.PI * radius;
44
+ const strokeDashoffset = circumference - clampedValue / 100 * circumference;
45
+ const bufferDashoffset = clampedBuffer !== void 0 ? circumference - clampedBuffer / 100 * circumference : void 0;
46
+ const progressLabel = ariaLabel || `Loading ${clampedValue}%`;
47
+ return /* @__PURE__ */ jsxs(
51
48
  "div",
52
49
  {
53
50
  ref,
54
51
  "data-testid": testId,
55
- className: cn(
56
- "flex",
57
- isHorizontal ? "flex-row items-center w-full" : "flex-col items-start",
58
- className
59
- ),
52
+ className: cn("inline-flex items-center justify-center relative", className),
60
53
  style: {
54
+ width: normalizeSize(size),
55
+ height: normalizeSize(size),
61
56
  ...style,
62
57
  opacity,
63
58
  transition: transitionStyle
64
59
  },
65
60
  role: "progressbar",
66
- "aria-label": ariaLabel,
67
- "aria-valuenow": currentStep,
61
+ "aria-label": progressLabel,
62
+ "aria-valuenow": indeterminate ? void 0 : clampedValue,
68
63
  "aria-valuemin": 0,
69
- "aria-valuemax": steps - 1,
64
+ "aria-valuemax": 100,
70
65
  ...rest,
71
- children: Array.from({ length: steps }).map((_, index) => {
72
- const status = getStepStatus(index);
73
- const stepColor = getStepColor(status);
74
- const showConnector = index < steps - 1 && connector === "line";
75
- return /* @__PURE__ */ jsxs(Fragment, { children: [
76
- /* @__PURE__ */ jsxs(
77
- "div",
78
- {
79
- className: cn(
80
- "flex items-center",
81
- isHorizontal ? "flex-col" : "flex-row gap-3"
66
+ children: [
67
+ /* @__PURE__ */ jsxs(
68
+ "svg",
69
+ {
70
+ className: cn(indeterminate && "animate-spinner-rotate"),
71
+ width: sizeValue,
72
+ height: sizeValue,
73
+ viewBox: `0 0 ${sizeValue} ${sizeValue}`,
74
+ style: indeterminate ? {
75
+ animation: `spinner-rotate ${effectiveDuration} linear infinite`,
76
+ animationDirection: reverse ? "reverse" : "normal"
77
+ } : void 0,
78
+ children: [
79
+ /* @__PURE__ */ jsx(
80
+ "circle",
81
+ {
82
+ cx: sizeValue / 2,
83
+ cy: sizeValue / 2,
84
+ r: radius,
85
+ fill: "none",
86
+ stroke: secondaryColor,
87
+ strokeWidth: thicknessValue
88
+ }
82
89
  ),
83
- children: [
84
- /* @__PURE__ */ jsx(
85
- "div",
86
- {
87
- className: "rounded-full flex items-center justify-center font-medium text-sm transition-colors",
88
- style: {
89
- width: "2rem",
90
- height: "2rem",
91
- backgroundColor: stepColor,
92
- color: "#ffffff"
93
- },
94
- children: showNumbers && /* @__PURE__ */ jsx("span", { children: index + 1 })
95
- }
96
- ),
97
- (labels == null ? void 0 : labels[index]) && /* @__PURE__ */ jsx(
98
- "span",
99
- {
100
- className: cn(
101
- "text-xs mt-1 transition-colors",
102
- isHorizontal ? "text-center" : "text-left"
103
- ),
104
- style: {
105
- color: status === "inactive" ? "#9ca3af" : "#374151",
106
- maxWidth: isHorizontal ? "80px" : "none"
107
- },
108
- children: labels[index]
90
+ bufferDashoffset !== void 0 && !indeterminate && /* @__PURE__ */ jsx(
91
+ "circle",
92
+ {
93
+ cx: sizeValue / 2,
94
+ cy: sizeValue / 2,
95
+ r: radius,
96
+ fill: "none",
97
+ stroke: color,
98
+ strokeWidth: thicknessValue,
99
+ strokeLinecap: "round",
100
+ strokeDasharray: circumference,
101
+ strokeDashoffset: bufferDashoffset,
102
+ transform: `rotate(-90 ${sizeValue / 2} ${sizeValue / 2})`,
103
+ opacity: 0.3
104
+ }
105
+ ),
106
+ /* @__PURE__ */ jsx(
107
+ "circle",
108
+ {
109
+ cx: sizeValue / 2,
110
+ cy: sizeValue / 2,
111
+ r: radius,
112
+ fill: "none",
113
+ stroke: color,
114
+ strokeWidth: thicknessValue,
115
+ strokeLinecap: "round",
116
+ strokeDasharray: circumference,
117
+ strokeDashoffset: indeterminate ? circumference * 0.75 : strokeDashoffset,
118
+ transform: `rotate(-90 ${sizeValue / 2} ${sizeValue / 2})`,
119
+ style: {
120
+ transition: indeterminate ? "none" : "stroke-dashoffset 0.3s ease-in-out"
109
121
  }
110
- )
111
- ]
112
- }
113
- ),
114
- showConnector && /* @__PURE__ */ jsx(
115
- "div",
116
- {
117
- className: "transition-colors",
118
- style: {
119
- backgroundColor: getConnectorColor(index),
120
- ...isHorizontal ? {
121
- height: "2px",
122
- flex: 1,
123
- marginLeft: "4px",
124
- marginRight: "4px"
125
- } : {
126
- width: "2px",
127
- height: "32px",
128
- marginLeft: "15px",
129
- marginTop: (labels == null ? void 0 : labels[index]) ? "4px" : "0",
130
- marginBottom: "4px"
131
122
  }
132
- }
133
- }
134
- )
135
- ] }, index);
136
- })
123
+ )
124
+ ]
125
+ }
126
+ ),
127
+ showValue && !indeterminate && /* @__PURE__ */ jsxs(
128
+ "span",
129
+ {
130
+ className: "absolute text-sm font-medium",
131
+ style: { color },
132
+ children: [
133
+ clampedValue,
134
+ "%"
135
+ ]
136
+ }
137
+ )
138
+ ]
137
139
  }
138
140
  );
139
141
  }
140
142
  );
141
- ProgressSteps.displayName = "ProgressSteps";
143
+ ProgressCircle.displayName = "ProgressCircle";
142
144
  export {
143
- ProgressSteps
145
+ ProgressCircle
144
146
  };
145
- //# sourceMappingURL=index24.js.map
package/dist/index25.cjs CHANGED
@@ -2,15 +2,20 @@
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("./index31.cjs");
5
+ const hooks = require("./index32.cjs");
6
6
  const colors = require("./index4.cjs");
7
7
  const classNames = require("./index3.cjs");
8
- const PulseDots = react.forwardRef(
8
+ const ProgressRing = react.forwardRef(
9
9
  ({
10
- size = "md",
10
+ value = 0,
11
+ indeterminate = false,
12
+ showValue = false,
13
+ size = "lg",
14
+ thickness = 4,
11
15
  color = "#3b82f6",
12
- dotCount = 3,
13
- dotSize = 10,
16
+ secondaryColor = "#e0e0e0",
17
+ gradient = false,
18
+ buffer,
14
19
  speed = "normal",
15
20
  reverse = false,
16
21
  respectMotionPreference = true,
@@ -19,13 +24,14 @@ const PulseDots = react.forwardRef(
19
24
  transition,
20
25
  className,
21
26
  style,
22
- testId = "pulse-dots",
27
+ testId = "progress-ring",
23
28
  visible = true,
24
- ariaLabel = "Loading...",
29
+ ariaLabel,
25
30
  ...rest
26
31
  }, ref) => {
27
32
  const prefersReducedMotion = hooks.useReducedMotion();
28
33
  const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
34
+ const gradientId = react.useMemo(() => `progress-gradient-${Math.random().toString(36).substr(2, 9)}`, []);
29
35
  const { shouldRender, opacity, transitionStyle } = hooks.useLoaderVisibility(
30
36
  visible,
31
37
  delay,
@@ -33,40 +39,114 @@ const PulseDots = react.forwardRef(
33
39
  transition
34
40
  );
35
41
  if (!shouldRender) return null;
36
- return /* @__PURE__ */ jsxRuntime.jsx(
42
+ const clampedValue = Math.min(100, Math.max(0, value));
43
+ const clampedBuffer = buffer !== void 0 ? Math.min(100, Math.max(0, buffer)) : void 0;
44
+ const sizeValue = colors.parseSizeToNumber(size, 56);
45
+ const thicknessValue = colors.parseSizeToNumber(thickness, 4);
46
+ const radius = (sizeValue - thicknessValue * 2) / 2;
47
+ const circumference = 2 * Math.PI * radius;
48
+ const strokeDashoffset = circumference - clampedValue / 100 * circumference;
49
+ const bufferDashoffset = clampedBuffer !== void 0 ? circumference - clampedBuffer / 100 * circumference : void 0;
50
+ const progressLabel = ariaLabel || `Loading ${clampedValue}%`;
51
+ return /* @__PURE__ */ jsxRuntime.jsxs(
37
52
  "div",
38
53
  {
39
54
  ref,
40
55
  "data-testid": testId,
41
- className: classNames.cn("inline-flex items-center justify-center gap-2", className),
56
+ className: classNames.cn("inline-flex items-center justify-center relative", className),
42
57
  style: {
58
+ width: colors.normalizeSize(size),
43
59
  height: colors.normalizeSize(size),
44
60
  ...style,
45
61
  opacity,
46
62
  transition: transitionStyle
47
63
  },
48
- role: "status",
49
- "aria-label": ariaLabel,
50
- "aria-busy": "true",
64
+ role: "progressbar",
65
+ "aria-label": progressLabel,
66
+ "aria-valuenow": indeterminate ? void 0 : clampedValue,
67
+ "aria-valuemin": 0,
68
+ "aria-valuemax": 100,
51
69
  ...rest,
52
- children: Array.from({ length: dotCount }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
53
- "div",
54
- {
55
- className: "rounded-full",
56
- style: {
57
- width: colors.normalizeSize(dotSize),
58
- height: colors.normalizeSize(dotSize),
59
- backgroundColor: color,
60
- animation: `pulse-bounce ${effectiveDuration} ease-in-out infinite`,
61
- animationDelay: reverse ? `${(dotCount - index - 1) * 0.15}s` : `${index * 0.15}s`
70
+ children: [
71
+ /* @__PURE__ */ jsxRuntime.jsxs(
72
+ "svg",
73
+ {
74
+ className: classNames.cn(indeterminate && "animate-spinner-rotate"),
75
+ width: sizeValue,
76
+ height: sizeValue,
77
+ viewBox: `0 0 ${sizeValue} ${sizeValue}`,
78
+ style: indeterminate ? {
79
+ animation: `spinner-rotate ${effectiveDuration} linear infinite`,
80
+ animationDirection: reverse ? "reverse" : "normal"
81
+ } : void 0,
82
+ children: [
83
+ gradient && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [
84
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color }),
85
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: secondaryColor === "#e0e0e0" ? "#8b5cf6" : secondaryColor })
86
+ ] }) }),
87
+ /* @__PURE__ */ jsxRuntime.jsx(
88
+ "circle",
89
+ {
90
+ cx: sizeValue / 2,
91
+ cy: sizeValue / 2,
92
+ r: radius,
93
+ fill: "none",
94
+ stroke: gradient ? "#e0e0e0" : secondaryColor,
95
+ strokeWidth: thicknessValue
96
+ }
97
+ ),
98
+ bufferDashoffset !== void 0 && !indeterminate && /* @__PURE__ */ jsxRuntime.jsx(
99
+ "circle",
100
+ {
101
+ cx: sizeValue / 2,
102
+ cy: sizeValue / 2,
103
+ r: radius,
104
+ fill: "none",
105
+ stroke: gradient ? `url(#${gradientId})` : color,
106
+ strokeWidth: thicknessValue,
107
+ strokeLinecap: "round",
108
+ strokeDasharray: circumference,
109
+ strokeDashoffset: bufferDashoffset,
110
+ transform: `rotate(-90 ${sizeValue / 2} ${sizeValue / 2})`,
111
+ opacity: 0.3
112
+ }
113
+ ),
114
+ /* @__PURE__ */ jsxRuntime.jsx(
115
+ "circle",
116
+ {
117
+ cx: sizeValue / 2,
118
+ cy: sizeValue / 2,
119
+ r: radius,
120
+ fill: "none",
121
+ stroke: gradient ? `url(#${gradientId})` : color,
122
+ strokeWidth: thicknessValue,
123
+ strokeLinecap: "round",
124
+ strokeDasharray: circumference,
125
+ strokeDashoffset: indeterminate ? circumference * 0.75 : strokeDashoffset,
126
+ transform: `rotate(-90 ${sizeValue / 2} ${sizeValue / 2})`,
127
+ style: {
128
+ transition: indeterminate ? "none" : "stroke-dashoffset 0.3s ease-in-out"
129
+ }
130
+ }
131
+ )
132
+ ]
62
133
  }
63
- },
64
- index
65
- ))
134
+ ),
135
+ showValue && !indeterminate && /* @__PURE__ */ jsxRuntime.jsxs(
136
+ "span",
137
+ {
138
+ className: "absolute text-sm font-semibold",
139
+ style: { color },
140
+ children: [
141
+ clampedValue,
142
+ "%"
143
+ ]
144
+ }
145
+ )
146
+ ]
66
147
  }
67
148
  );
68
149
  }
69
150
  );
70
- PulseDots.displayName = "PulseDots";
71
- exports.PulseDots = PulseDots;
72
- //# sourceMappingURL=index25.cjs.map
151
+ ProgressRing.displayName = "ProgressRing";
152
+ exports.ProgressRing = ProgressRing;
package/dist/index25.js CHANGED
@@ -1,14 +1,19 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import { forwardRef } from "react";
3
- import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index31.js";
4
- import { normalizeSize } from "./index4.js";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { forwardRef, useMemo } from "react";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index32.js";
4
+ import { normalizeSize, parseSizeToNumber } from "./index4.js";
5
5
  import { cn } from "./index3.js";
6
- const PulseDots = forwardRef(
6
+ const ProgressRing = forwardRef(
7
7
  ({
8
- size = "md",
8
+ value = 0,
9
+ indeterminate = false,
10
+ showValue = false,
11
+ size = "lg",
12
+ thickness = 4,
9
13
  color = "#3b82f6",
10
- dotCount = 3,
11
- dotSize = 10,
14
+ secondaryColor = "#e0e0e0",
15
+ gradient = false,
16
+ buffer,
12
17
  speed = "normal",
13
18
  reverse = false,
14
19
  respectMotionPreference = true,
@@ -17,13 +22,14 @@ const PulseDots = forwardRef(
17
22
  transition,
18
23
  className,
19
24
  style,
20
- testId = "pulse-dots",
25
+ testId = "progress-ring",
21
26
  visible = true,
22
- ariaLabel = "Loading...",
27
+ ariaLabel,
23
28
  ...rest
24
29
  }, ref) => {
25
30
  const prefersReducedMotion = useReducedMotion();
26
31
  const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
32
+ const gradientId = useMemo(() => `progress-gradient-${Math.random().toString(36).substr(2, 9)}`, []);
27
33
  const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(
28
34
  visible,
29
35
  delay,
@@ -31,42 +37,116 @@ const PulseDots = forwardRef(
31
37
  transition
32
38
  );
33
39
  if (!shouldRender) return null;
34
- return /* @__PURE__ */ jsx(
40
+ const clampedValue = Math.min(100, Math.max(0, value));
41
+ const clampedBuffer = buffer !== void 0 ? Math.min(100, Math.max(0, buffer)) : void 0;
42
+ const sizeValue = parseSizeToNumber(size, 56);
43
+ const thicknessValue = parseSizeToNumber(thickness, 4);
44
+ const radius = (sizeValue - thicknessValue * 2) / 2;
45
+ const circumference = 2 * Math.PI * radius;
46
+ const strokeDashoffset = circumference - clampedValue / 100 * circumference;
47
+ const bufferDashoffset = clampedBuffer !== void 0 ? circumference - clampedBuffer / 100 * circumference : void 0;
48
+ const progressLabel = ariaLabel || `Loading ${clampedValue}%`;
49
+ return /* @__PURE__ */ jsxs(
35
50
  "div",
36
51
  {
37
52
  ref,
38
53
  "data-testid": testId,
39
- className: cn("inline-flex items-center justify-center gap-2", className),
54
+ className: cn("inline-flex items-center justify-center relative", className),
40
55
  style: {
56
+ width: normalizeSize(size),
41
57
  height: normalizeSize(size),
42
58
  ...style,
43
59
  opacity,
44
60
  transition: transitionStyle
45
61
  },
46
- role: "status",
47
- "aria-label": ariaLabel,
48
- "aria-busy": "true",
62
+ role: "progressbar",
63
+ "aria-label": progressLabel,
64
+ "aria-valuenow": indeterminate ? void 0 : clampedValue,
65
+ "aria-valuemin": 0,
66
+ "aria-valuemax": 100,
49
67
  ...rest,
50
- children: Array.from({ length: dotCount }).map((_, index) => /* @__PURE__ */ jsx(
51
- "div",
52
- {
53
- className: "rounded-full",
54
- style: {
55
- width: normalizeSize(dotSize),
56
- height: normalizeSize(dotSize),
57
- backgroundColor: color,
58
- animation: `pulse-bounce ${effectiveDuration} ease-in-out infinite`,
59
- animationDelay: reverse ? `${(dotCount - index - 1) * 0.15}s` : `${index * 0.15}s`
68
+ children: [
69
+ /* @__PURE__ */ jsxs(
70
+ "svg",
71
+ {
72
+ className: cn(indeterminate && "animate-spinner-rotate"),
73
+ width: sizeValue,
74
+ height: sizeValue,
75
+ viewBox: `0 0 ${sizeValue} ${sizeValue}`,
76
+ style: indeterminate ? {
77
+ animation: `spinner-rotate ${effectiveDuration} linear infinite`,
78
+ animationDirection: reverse ? "reverse" : "normal"
79
+ } : void 0,
80
+ children: [
81
+ gradient && /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [
82
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: color }),
83
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: secondaryColor === "#e0e0e0" ? "#8b5cf6" : secondaryColor })
84
+ ] }) }),
85
+ /* @__PURE__ */ jsx(
86
+ "circle",
87
+ {
88
+ cx: sizeValue / 2,
89
+ cy: sizeValue / 2,
90
+ r: radius,
91
+ fill: "none",
92
+ stroke: gradient ? "#e0e0e0" : secondaryColor,
93
+ strokeWidth: thicknessValue
94
+ }
95
+ ),
96
+ bufferDashoffset !== void 0 && !indeterminate && /* @__PURE__ */ jsx(
97
+ "circle",
98
+ {
99
+ cx: sizeValue / 2,
100
+ cy: sizeValue / 2,
101
+ r: radius,
102
+ fill: "none",
103
+ stroke: gradient ? `url(#${gradientId})` : color,
104
+ strokeWidth: thicknessValue,
105
+ strokeLinecap: "round",
106
+ strokeDasharray: circumference,
107
+ strokeDashoffset: bufferDashoffset,
108
+ transform: `rotate(-90 ${sizeValue / 2} ${sizeValue / 2})`,
109
+ opacity: 0.3
110
+ }
111
+ ),
112
+ /* @__PURE__ */ jsx(
113
+ "circle",
114
+ {
115
+ cx: sizeValue / 2,
116
+ cy: sizeValue / 2,
117
+ r: radius,
118
+ fill: "none",
119
+ stroke: gradient ? `url(#${gradientId})` : color,
120
+ strokeWidth: thicknessValue,
121
+ strokeLinecap: "round",
122
+ strokeDasharray: circumference,
123
+ strokeDashoffset: indeterminate ? circumference * 0.75 : strokeDashoffset,
124
+ transform: `rotate(-90 ${sizeValue / 2} ${sizeValue / 2})`,
125
+ style: {
126
+ transition: indeterminate ? "none" : "stroke-dashoffset 0.3s ease-in-out"
127
+ }
128
+ }
129
+ )
130
+ ]
60
131
  }
61
- },
62
- index
63
- ))
132
+ ),
133
+ showValue && !indeterminate && /* @__PURE__ */ jsxs(
134
+ "span",
135
+ {
136
+ className: "absolute text-sm font-semibold",
137
+ style: { color },
138
+ children: [
139
+ clampedValue,
140
+ "%"
141
+ ]
142
+ }
143
+ )
144
+ ]
64
145
  }
65
146
  );
66
147
  }
67
148
  );
68
- PulseDots.displayName = "PulseDots";
149
+ ProgressRing.displayName = "ProgressRing";
69
150
  export {
70
- PulseDots
151
+ ProgressRing
71
152
  };
72
- //# sourceMappingURL=index25.js.map