premium-react-loaders 2.1.0 → 2.2.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 (81) hide show
  1. package/README.md +59 -3
  2. package/dist/components/button/ButtonSpinner.d.ts +25 -0
  3. package/dist/components/button/ButtonSpinner.d.ts.map +1 -0
  4. package/dist/components/button/index.d.ts +2 -0
  5. package/dist/components/button/index.d.ts.map +1 -0
  6. package/dist/components/index.d.ts +2 -0
  7. package/dist/components/index.d.ts.map +1 -1
  8. package/dist/components/status/ErrorIndicator.d.ts +32 -0
  9. package/dist/components/status/ErrorIndicator.d.ts.map +1 -0
  10. package/dist/components/status/SuccessCheckmark.d.ts +31 -0
  11. package/dist/components/status/SuccessCheckmark.d.ts.map +1 -0
  12. package/dist/components/status/index.d.ts +3 -0
  13. package/dist/components/status/index.d.ts.map +1 -0
  14. package/dist/index.cjs +6 -0
  15. package/dist/index.js +6 -0
  16. package/dist/index10.cjs +1 -1
  17. package/dist/index10.js +1 -1
  18. package/dist/index11.cjs +1 -1
  19. package/dist/index11.js +1 -1
  20. package/dist/index12.cjs +1 -1
  21. package/dist/index12.js +1 -1
  22. package/dist/index13.cjs +1 -1
  23. package/dist/index13.js +1 -1
  24. package/dist/index14.cjs +1 -1
  25. package/dist/index14.js +1 -1
  26. package/dist/index15.cjs +1 -1
  27. package/dist/index15.js +1 -1
  28. package/dist/index16.cjs +1 -1
  29. package/dist/index16.js +1 -1
  30. package/dist/index17.cjs +1 -1
  31. package/dist/index17.js +1 -1
  32. package/dist/index18.cjs +1 -1
  33. package/dist/index18.js +1 -1
  34. package/dist/index19.cjs +1 -1
  35. package/dist/index19.js +1 -1
  36. package/dist/index20.cjs +1 -1
  37. package/dist/index20.js +1 -1
  38. package/dist/index21.cjs +1 -1
  39. package/dist/index21.js +1 -1
  40. package/dist/index22.cjs +1 -1
  41. package/dist/index22.js +1 -1
  42. package/dist/index23.cjs +1 -1
  43. package/dist/index23.js +1 -1
  44. package/dist/index24.cjs +1 -1
  45. package/dist/index24.js +1 -1
  46. package/dist/index25.cjs +1 -1
  47. package/dist/index25.js +1 -1
  48. package/dist/index26.cjs +1 -1
  49. package/dist/index26.js +1 -1
  50. package/dist/index27.cjs +1 -1
  51. package/dist/index27.js +1 -1
  52. package/dist/index28.cjs +1 -1
  53. package/dist/index28.js +1 -1
  54. package/dist/index29.cjs +1 -1
  55. package/dist/index29.js +1 -1
  56. package/dist/index30.cjs +1 -1
  57. package/dist/index30.js +1 -1
  58. package/dist/index31.cjs +1 -1
  59. package/dist/index31.js +1 -1
  60. package/dist/index32.cjs +143 -119
  61. package/dist/index32.js +144 -120
  62. package/dist/index33.cjs +100 -0
  63. package/dist/index33.js +100 -0
  64. package/dist/index34.cjs +117 -0
  65. package/dist/index34.js +117 -0
  66. package/dist/index35.cjs +125 -0
  67. package/dist/index35.js +125 -0
  68. package/dist/index7.cjs +1 -1
  69. package/dist/index7.js +1 -1
  70. package/dist/index8.cjs +1 -1
  71. package/dist/index8.js +1 -1
  72. package/dist/index9.cjs +1 -1
  73. package/dist/index9.js +1 -1
  74. package/dist/premium-react-loaders.css +140 -0
  75. package/dist/types/button.d.ts +31 -0
  76. package/dist/types/button.d.ts.map +1 -0
  77. package/dist/types/index.d.ts +2 -0
  78. package/dist/types/index.d.ts.map +1 -1
  79. package/dist/types/status.d.ts +34 -0
  80. package/dist/types/status.d.ts.map +1 -0
  81. package/package.json +1 -1
package/dist/index28.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
- import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index32.js";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index35.js";
4
4
  import { normalizeSize, parseSizeToNumber } from "./index4.js";
5
5
  import { cn } from "./index3.js";
6
6
  const PulseWave = forwardRef(
package/dist/index29.cjs CHANGED
@@ -2,7 +2,7 @@
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("./index32.cjs");
5
+ const hooks = require("./index35.cjs");
6
6
  const colors = require("./index4.cjs");
7
7
  const classNames = require("./index3.cjs");
8
8
  const PulseBars = react.forwardRef(
package/dist/index29.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
- import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index32.js";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index35.js";
4
4
  import { normalizeSize, parseSizeToNumber } from "./index4.js";
5
5
  import { cn } from "./index3.js";
6
6
  const PulseBars = forwardRef(
package/dist/index30.cjs CHANGED
@@ -2,7 +2,7 @@
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("./index32.cjs");
5
+ const hooks = require("./index35.cjs");
6
6
  const colors = require("./index4.cjs");
7
7
  const classNames = require("./index3.cjs");
8
8
  const TypingIndicator = react.forwardRef(
package/dist/index30.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
- import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index32.js";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index35.js";
4
4
  import { normalizeSize } from "./index4.js";
5
5
  import { cn } from "./index3.js";
6
6
  const TypingIndicator = forwardRef(
package/dist/index31.cjs CHANGED
@@ -2,7 +2,7 @@
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("./index32.cjs");
5
+ const hooks = require("./index35.cjs");
6
6
  const classNames = require("./index3.cjs");
7
7
  const LoaderOverlay = react.forwardRef(
8
8
  ({
package/dist/index31.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
- import { useLoaderVisibility } from "./index32.js";
3
+ import { useLoaderVisibility } from "./index35.js";
4
4
  import { cn } from "./index3.js";
5
5
  const LoaderOverlay = forwardRef(
6
6
  ({
package/dist/index32.cjs CHANGED
@@ -1,125 +1,149 @@
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;
5
+ const hooks = require("./index35.cjs");
6
+ const classNames = require("./index3.cjs");
7
+ const colors = require("./index4.cjs");
8
+ const ButtonSpinner = react.forwardRef(
9
+ ({
10
+ size = 16,
11
+ color = "currentColor",
12
+ variant = "circle",
13
+ position = "left",
14
+ thickness = 2,
15
+ dotCount = 3,
16
+ barCount = 3,
17
+ speed = "normal",
18
+ gap = 8,
19
+ showContent = true,
20
+ children,
21
+ delay = 0,
22
+ minDuration = 0,
23
+ transition,
24
+ respectMotionPreference = true,
25
+ className,
26
+ style,
27
+ testId = "button-spinner",
28
+ visible = true,
29
+ ariaLabel = "Loading...",
30
+ ...rest
31
+ }, ref) => {
32
+ const prefersReducedMotion = hooks.useReducedMotion();
33
+ const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
34
+ const { shouldRender, opacity, transitionStyle } = hooks.useLoaderVisibility(
35
+ visible,
36
+ delay,
37
+ minDuration,
38
+ transition
39
+ );
40
+ if (!shouldRender) {
41
+ return children ? /* @__PURE__ */ jsxRuntime.jsx("div", { className, style, children }) : null;
9
42
  }
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);
106
- }
107
- if (minDurationTimerRef.current) {
108
- clearTimeout(minDurationTimerRef.current);
109
- }
110
- if (transitionTimerRef.current) {
111
- clearTimeout(transitionTimerRef.current);
43
+ const spinnerSize = colors.normalizeSize(size);
44
+ const gapSize = typeof gap === "number" ? `${gap}px` : gap;
45
+ const renderSpinner = () => {
46
+ switch (variant) {
47
+ case "dots":
48
+ return /* @__PURE__ */ jsxRuntime.jsx(
49
+ "div",
50
+ {
51
+ className: "inline-flex items-center justify-center",
52
+ style: { gap: `${parseInt(spinnerSize) / 8}px` },
53
+ children: Array.from({ length: dotCount }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
54
+ "div",
55
+ {
56
+ className: "animate-button-dot-pulse",
57
+ style: {
58
+ width: `${parseInt(spinnerSize) / 3}px`,
59
+ height: `${parseInt(spinnerSize) / 3}px`,
60
+ backgroundColor: color,
61
+ borderRadius: "50%",
62
+ animationDuration: effectiveDuration,
63
+ animationDelay: `${i * parseInt(effectiveDuration) / (dotCount * 3)}ms`
64
+ }
65
+ },
66
+ i
67
+ ))
68
+ }
69
+ );
70
+ case "bars":
71
+ return /* @__PURE__ */ jsxRuntime.jsx(
72
+ "div",
73
+ {
74
+ className: "inline-flex items-center justify-center",
75
+ style: { gap: `${parseInt(spinnerSize) / 8}px`, height: spinnerSize },
76
+ children: Array.from({ length: barCount }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
77
+ "div",
78
+ {
79
+ className: "animate-button-bar-pulse",
80
+ style: {
81
+ width: `${parseInt(spinnerSize) / 6}px`,
82
+ height: "100%",
83
+ backgroundColor: color,
84
+ borderRadius: "2px",
85
+ animationDuration: effectiveDuration,
86
+ animationDelay: `${i * parseInt(effectiveDuration) / (barCount * 3)}ms`
87
+ }
88
+ },
89
+ i
90
+ ))
91
+ }
92
+ );
93
+ case "circle":
94
+ default:
95
+ return /* @__PURE__ */ jsxRuntime.jsx(
96
+ "svg",
97
+ {
98
+ className: "animate-spinner-rotate",
99
+ style: {
100
+ width: spinnerSize,
101
+ height: spinnerSize,
102
+ animationDuration: effectiveDuration
103
+ },
104
+ viewBox: "0 0 50 50",
105
+ children: /* @__PURE__ */ jsxRuntime.jsx(
106
+ "circle",
107
+ {
108
+ cx: "25",
109
+ cy: "25",
110
+ r: 25 - thickness * 4,
111
+ fill: "none",
112
+ stroke: color,
113
+ strokeWidth: thickness * 2,
114
+ strokeDasharray: "80, 200",
115
+ strokeLinecap: "round"
116
+ }
117
+ )
118
+ }
119
+ );
112
120
  }
113
121
  };
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;
122
+ const flexDirection = position === "right" ? "row-reverse" : "row";
123
+ return /* @__PURE__ */ jsxRuntime.jsxs(
124
+ "div",
125
+ {
126
+ ref,
127
+ "data-testid": testId,
128
+ className: classNames.cn("inline-flex items-center justify-center", className),
129
+ style: {
130
+ ...style,
131
+ flexDirection: position === "center" ? "column" : flexDirection,
132
+ gap: showContent && children ? gapSize : 0,
133
+ opacity,
134
+ transition: transitionStyle
135
+ },
136
+ role: "status",
137
+ "aria-label": ariaLabel,
138
+ "aria-busy": "true",
139
+ ...rest,
140
+ children: [
141
+ renderSpinner(),
142
+ showContent && children && /* @__PURE__ */ jsxRuntime.jsx("span", { children })
143
+ ]
144
+ }
145
+ );
146
+ }
147
+ );
148
+ ButtonSpinner.displayName = "ButtonSpinner";
149
+ exports.ButtonSpinner = ButtonSpinner;
package/dist/index32.js CHANGED
@@ -1,125 +1,149 @@
1
- import { useState, useRef, useEffect } from "react";
2
- function useReducedMotion() {
3
- const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);
4
- useEffect(() => {
5
- if (typeof window === "undefined" || !window.matchMedia) {
6
- return;
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index35.js";
4
+ import { cn } from "./index3.js";
5
+ import { normalizeSize } from "./index4.js";
6
+ const ButtonSpinner = forwardRef(
7
+ ({
8
+ size = 16,
9
+ color = "currentColor",
10
+ variant = "circle",
11
+ position = "left",
12
+ thickness = 2,
13
+ dotCount = 3,
14
+ barCount = 3,
15
+ speed = "normal",
16
+ gap = 8,
17
+ showContent = true,
18
+ children,
19
+ delay = 0,
20
+ minDuration = 0,
21
+ transition,
22
+ respectMotionPreference = true,
23
+ className,
24
+ style,
25
+ testId = "button-spinner",
26
+ visible = true,
27
+ ariaLabel = "Loading...",
28
+ ...rest
29
+ }, ref) => {
30
+ const prefersReducedMotion = useReducedMotion();
31
+ const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
32
+ const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(
33
+ visible,
34
+ delay,
35
+ minDuration,
36
+ transition
37
+ );
38
+ if (!shouldRender) {
39
+ return children ? /* @__PURE__ */ jsx("div", { className, style, children }) : null;
7
40
  }
8
- const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
9
- setPrefersReducedMotion(mediaQuery.matches);
10
- const handleChange = (event) => {
11
- setPrefersReducedMotion(event.matches);
12
- };
13
- if (mediaQuery.addEventListener) {
14
- mediaQuery.addEventListener("change", handleChange);
15
- return () => mediaQuery.removeEventListener("change", handleChange);
16
- } else {
17
- mediaQuery.addListener(handleChange);
18
- return () => mediaQuery.removeListener(handleChange);
19
- }
20
- }, []);
21
- return prefersReducedMotion;
22
- }
23
- function getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion) {
24
- if (respectMotionPreference && prefersReducedMotion) {
25
- return "0.01ms";
26
- }
27
- if (typeof speed === "number") {
28
- const validSpeed = !isNaN(speed) && speed > 0 ? Math.max(50, Math.min(1e4, speed)) : 1e3;
29
- return `${validSpeed}ms`;
30
- }
31
- const speedMap = {
32
- slow: "2s",
33
- normal: "1s",
34
- fast: "0.5s"
35
- };
36
- return speedMap[speed] || speedMap.normal;
37
- }
38
- function useLoaderVisibility(visible = true, delay = 0, minDuration = 0, transition) {
39
- const transitionDuration = transition === true ? 150 : typeof transition === "number" ? transition : 0;
40
- const hasTransition = transitionDuration > 0;
41
- const [shouldRender, setShouldRender] = useState(visible && delay === 0);
42
- const [isTransitioning, setIsTransitioning] = useState(visible && delay === 0 && hasTransition);
43
- const showTimeRef = useRef(visible && delay === 0 ? Date.now() : null);
44
- const delayTimerRef = useRef(null);
45
- const minDurationTimerRef = useRef(null);
46
- const transitionTimerRef = useRef(null);
47
- useEffect(() => {
48
- if (delayTimerRef.current) {
49
- clearTimeout(delayTimerRef.current);
50
- delayTimerRef.current = null;
51
- }
52
- if (minDurationTimerRef.current) {
53
- clearTimeout(minDurationTimerRef.current);
54
- minDurationTimerRef.current = null;
55
- }
56
- if (transitionTimerRef.current) {
57
- clearTimeout(transitionTimerRef.current);
58
- transitionTimerRef.current = null;
59
- }
60
- if (visible) {
61
- if (delay > 0) {
62
- delayTimerRef.current = setTimeout(() => {
63
- setShouldRender(true);
64
- showTimeRef.current = Date.now();
65
- if (hasTransition) {
66
- setIsTransitioning(true);
67
- }
68
- }, delay);
69
- } else {
70
- setShouldRender(true);
71
- showTimeRef.current = Date.now();
72
- if (hasTransition) {
73
- setIsTransitioning(true);
74
- }
75
- }
76
- } else {
77
- const hideLoader = () => {
78
- if (hasTransition) {
79
- setIsTransitioning(false);
80
- transitionTimerRef.current = setTimeout(() => {
81
- setShouldRender(false);
82
- showTimeRef.current = null;
83
- }, transitionDuration);
84
- } else {
85
- setShouldRender(false);
86
- showTimeRef.current = null;
87
- }
88
- };
89
- if (showTimeRef.current !== null && minDuration > 0) {
90
- const elapsedTime = Date.now() - showTimeRef.current;
91
- const remainingTime = minDuration - elapsedTime;
92
- if (remainingTime > 0) {
93
- minDurationTimerRef.current = setTimeout(hideLoader, remainingTime);
94
- } else {
95
- hideLoader();
96
- }
97
- } else {
98
- hideLoader();
99
- }
100
- }
101
- return () => {
102
- if (delayTimerRef.current) {
103
- clearTimeout(delayTimerRef.current);
104
- }
105
- if (minDurationTimerRef.current) {
106
- clearTimeout(minDurationTimerRef.current);
107
- }
108
- if (transitionTimerRef.current) {
109
- clearTimeout(transitionTimerRef.current);
41
+ const spinnerSize = normalizeSize(size);
42
+ const gapSize = typeof gap === "number" ? `${gap}px` : gap;
43
+ const renderSpinner = () => {
44
+ switch (variant) {
45
+ case "dots":
46
+ return /* @__PURE__ */ jsx(
47
+ "div",
48
+ {
49
+ className: "inline-flex items-center justify-center",
50
+ style: { gap: `${parseInt(spinnerSize) / 8}px` },
51
+ children: Array.from({ length: dotCount }).map((_, i) => /* @__PURE__ */ jsx(
52
+ "div",
53
+ {
54
+ className: "animate-button-dot-pulse",
55
+ style: {
56
+ width: `${parseInt(spinnerSize) / 3}px`,
57
+ height: `${parseInt(spinnerSize) / 3}px`,
58
+ backgroundColor: color,
59
+ borderRadius: "50%",
60
+ animationDuration: effectiveDuration,
61
+ animationDelay: `${i * parseInt(effectiveDuration) / (dotCount * 3)}ms`
62
+ }
63
+ },
64
+ i
65
+ ))
66
+ }
67
+ );
68
+ case "bars":
69
+ return /* @__PURE__ */ jsx(
70
+ "div",
71
+ {
72
+ className: "inline-flex items-center justify-center",
73
+ style: { gap: `${parseInt(spinnerSize) / 8}px`, height: spinnerSize },
74
+ children: Array.from({ length: barCount }).map((_, i) => /* @__PURE__ */ jsx(
75
+ "div",
76
+ {
77
+ className: "animate-button-bar-pulse",
78
+ style: {
79
+ width: `${parseInt(spinnerSize) / 6}px`,
80
+ height: "100%",
81
+ backgroundColor: color,
82
+ borderRadius: "2px",
83
+ animationDuration: effectiveDuration,
84
+ animationDelay: `${i * parseInt(effectiveDuration) / (barCount * 3)}ms`
85
+ }
86
+ },
87
+ i
88
+ ))
89
+ }
90
+ );
91
+ case "circle":
92
+ default:
93
+ return /* @__PURE__ */ jsx(
94
+ "svg",
95
+ {
96
+ className: "animate-spinner-rotate",
97
+ style: {
98
+ width: spinnerSize,
99
+ height: spinnerSize,
100
+ animationDuration: effectiveDuration
101
+ },
102
+ viewBox: "0 0 50 50",
103
+ children: /* @__PURE__ */ jsx(
104
+ "circle",
105
+ {
106
+ cx: "25",
107
+ cy: "25",
108
+ r: 25 - thickness * 4,
109
+ fill: "none",
110
+ stroke: color,
111
+ strokeWidth: thickness * 2,
112
+ strokeDasharray: "80, 200",
113
+ strokeLinecap: "round"
114
+ }
115
+ )
116
+ }
117
+ );
110
118
  }
111
119
  };
112
- }, [visible, delay, minDuration, hasTransition, transitionDuration]);
113
- const opacity = hasTransition ? isTransitioning ? 1 : 0 : 1;
114
- const transitionStyle = hasTransition ? `opacity ${transitionDuration}ms ease-in-out` : "none";
115
- return {
116
- shouldRender,
117
- opacity,
118
- transitionStyle
119
- };
120
- }
120
+ const flexDirection = position === "right" ? "row-reverse" : "row";
121
+ return /* @__PURE__ */ jsxs(
122
+ "div",
123
+ {
124
+ ref,
125
+ "data-testid": testId,
126
+ className: cn("inline-flex items-center justify-center", className),
127
+ style: {
128
+ ...style,
129
+ flexDirection: position === "center" ? "column" : flexDirection,
130
+ gap: showContent && children ? gapSize : 0,
131
+ opacity,
132
+ transition: transitionStyle
133
+ },
134
+ role: "status",
135
+ "aria-label": ariaLabel,
136
+ "aria-busy": "true",
137
+ ...rest,
138
+ children: [
139
+ renderSpinner(),
140
+ showContent && children && /* @__PURE__ */ jsx("span", { children })
141
+ ]
142
+ }
143
+ );
144
+ }
145
+ );
146
+ ButtonSpinner.displayName = "ButtonSpinner";
121
147
  export {
122
- getEffectiveDuration,
123
- useLoaderVisibility,
124
- useReducedMotion
148
+ ButtonSpinner
125
149
  };