premium-react-loaders 1.0.2 → 1.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 (107) hide show
  1. package/dist/components/progress/ProgressSteps.d.ts +16 -0
  2. package/dist/components/progress/ProgressSteps.d.ts.map +1 -0
  3. package/dist/components/progress/index.d.ts +1 -0
  4. package/dist/components/progress/index.d.ts.map +1 -1
  5. package/dist/components/pulse/TypingIndicator.d.ts +16 -0
  6. package/dist/components/pulse/TypingIndicator.d.ts.map +1 -0
  7. package/dist/components/pulse/index.d.ts +1 -0
  8. package/dist/components/pulse/index.d.ts.map +1 -1
  9. package/dist/components/skeleton/SkeletonForm.d.ts +16 -0
  10. package/dist/components/skeleton/SkeletonForm.d.ts.map +1 -0
  11. package/dist/components/skeleton/index.d.ts +1 -0
  12. package/dist/components/skeleton/index.d.ts.map +1 -1
  13. package/dist/components/spinner/SpinnerPulse.d.ts +15 -0
  14. package/dist/components/spinner/SpinnerPulse.d.ts.map +1 -0
  15. package/dist/components/spinner/SpinnerWave.d.ts +15 -0
  16. package/dist/components/spinner/SpinnerWave.d.ts.map +1 -0
  17. package/dist/components/spinner/index.d.ts +2 -0
  18. package/dist/components/spinner/index.d.ts.map +1 -1
  19. package/dist/index.cjs +23 -13
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +23 -13
  23. package/dist/index.js.map +1 -1
  24. package/dist/index13.cjs +54 -35
  25. package/dist/index13.cjs.map +1 -1
  26. package/dist/index13.js +56 -37
  27. package/dist/index13.js.map +1 -1
  28. package/dist/index14.cjs +23 -12
  29. package/dist/index14.cjs.map +1 -1
  30. package/dist/index14.js +23 -12
  31. package/dist/index14.js.map +1 -1
  32. package/dist/index15.cjs +11 -34
  33. package/dist/index15.cjs.map +1 -1
  34. package/dist/index15.js +11 -34
  35. package/dist/index15.js.map +1 -1
  36. package/dist/index16.cjs +40 -23
  37. package/dist/index16.cjs.map +1 -1
  38. package/dist/index16.js +41 -24
  39. package/dist/index16.js.map +1 -1
  40. package/dist/index17.cjs +23 -36
  41. package/dist/index17.cjs.map +1 -1
  42. package/dist/index17.js +23 -36
  43. package/dist/index17.js.map +1 -1
  44. package/dist/index18.cjs +46 -78
  45. package/dist/index18.cjs.map +1 -1
  46. package/dist/index18.js +48 -80
  47. package/dist/index18.js.map +1 -1
  48. package/dist/index19.cjs +39 -103
  49. package/dist/index19.cjs.map +1 -1
  50. package/dist/index19.js +40 -104
  51. package/dist/index19.js.map +1 -1
  52. package/dist/index20.cjs +52 -107
  53. package/dist/index20.cjs.map +1 -1
  54. package/dist/index20.js +54 -109
  55. package/dist/index20.js.map +1 -1
  56. package/dist/index21.cjs +73 -27
  57. package/dist/index21.cjs.map +1 -1
  58. package/dist/index21.js +76 -30
  59. package/dist/index21.js.map +1 -1
  60. package/dist/index22.cjs +98 -31
  61. package/dist/index22.cjs.map +1 -1
  62. package/dist/index22.js +99 -32
  63. package/dist/index22.js.map +1 -1
  64. package/dist/index23.cjs +104 -33
  65. package/dist/index23.cjs.map +1 -1
  66. package/dist/index23.js +106 -35
  67. package/dist/index23.js.map +1 -1
  68. package/dist/index24.cjs +108 -48
  69. package/dist/index24.cjs.map +1 -1
  70. package/dist/index24.js +110 -50
  71. package/dist/index24.js.map +1 -1
  72. package/dist/index25.cjs +55 -16
  73. package/dist/index25.cjs.map +1 -1
  74. package/dist/index25.js +54 -15
  75. package/dist/index25.js.map +1 -1
  76. package/dist/index26.cjs +62 -0
  77. package/dist/index26.cjs.map +1 -0
  78. package/dist/index26.js +62 -0
  79. package/dist/index26.js.map +1 -0
  80. package/dist/index27.cjs +64 -0
  81. package/dist/index27.cjs.map +1 -0
  82. package/dist/index27.js +64 -0
  83. package/dist/index27.js.map +1 -0
  84. package/dist/index28.cjs +61 -0
  85. package/dist/index28.cjs.map +1 -0
  86. package/dist/index28.js +61 -0
  87. package/dist/index28.js.map +1 -0
  88. package/dist/index29.cjs +71 -0
  89. package/dist/index29.cjs.map +1 -0
  90. package/dist/index29.js +71 -0
  91. package/dist/index29.js.map +1 -0
  92. package/dist/index3.cjs +1 -1
  93. package/dist/index3.js +1 -1
  94. package/dist/index30.cjs +18 -0
  95. package/dist/index30.cjs.map +1 -0
  96. package/dist/index30.js +18 -0
  97. package/dist/index30.js.map +1 -0
  98. package/dist/premium-react-loaders.css +29 -0
  99. package/dist/types/progress.d.ts +24 -1
  100. package/dist/types/progress.d.ts.map +1 -1
  101. package/dist/types/pulse.d.ts +13 -0
  102. package/dist/types/pulse.d.ts.map +1 -1
  103. package/dist/types/skeleton.d.ts +17 -0
  104. package/dist/types/skeleton.d.ts.map +1 -1
  105. package/dist/types/spinner.d.ts +18 -0
  106. package/dist/types/spinner.d.ts.map +1 -1
  107. package/package.json +1 -1
package/dist/index20.js CHANGED
@@ -1,135 +1,80 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { forwardRef, useMemo } from "react";
3
- import { normalizeSize, getAnimationDuration, parseSizeToNumber } from "./index4.js";
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
4
3
  import { cn } from "./index3.js";
5
- const ProgressRing = forwardRef(
4
+ import { normalizeSize, getAnimationDuration } from "./index4.js";
5
+ const SpinnerPulse = forwardRef(
6
6
  ({
7
- value = 0,
8
- indeterminate = false,
9
- showValue = false,
10
- size = 60,
11
- thickness = 4,
7
+ size = 40,
12
8
  color = "#3b82f6",
13
- secondaryColor = "#e0e0e0",
14
- gradient = false,
15
- buffer,
9
+ pulses = 2,
10
+ maxScale = 1.8,
16
11
  speed = "normal",
17
12
  className,
18
13
  style,
19
- testId = "progress-ring",
14
+ testId = "spinner-pulse",
20
15
  visible = true,
21
- ariaLabel,
16
+ ariaLabel = "Loading...",
22
17
  ...rest
23
18
  }, ref) => {
24
19
  if (!visible) return null;
25
- const clampedValue = Math.min(100, Math.max(0, value));
26
- const clampedBuffer = buffer !== void 0 ? Math.min(100, Math.max(0, buffer)) : void 0;
27
- const sizeValue = parseSizeToNumber(size, 60);
28
- const thicknessValue = parseSizeToNumber(thickness, 4);
29
- const radius = (sizeValue - thicknessValue * 2) / 2;
30
- const circumference = 2 * Math.PI * radius;
31
- const strokeDashoffset = circumference - clampedValue / 100 * circumference;
32
- const bufferDashoffset = clampedBuffer !== void 0 ? circumference - clampedBuffer / 100 * circumference : void 0;
33
- const progressLabel = ariaLabel || `Loading ${clampedValue}%`;
34
20
  const animationDuration = getAnimationDuration(speed);
35
- const gradientId = useMemo(() => `progress-gradient-${Math.random().toString(36).substr(2, 9)}`, []);
36
- return /* @__PURE__ */ jsxs(
21
+ const sizeValue = normalizeSize(size);
22
+ return /* @__PURE__ */ jsx(
37
23
  "div",
38
24
  {
39
25
  ref,
40
26
  "data-testid": testId,
41
- className: cn("inline-flex items-center justify-center relative", className),
42
- style: {
43
- width: normalizeSize(size),
44
- height: normalizeSize(size),
45
- ...style
46
- },
47
- role: "progressbar",
48
- "aria-label": progressLabel,
49
- "aria-valuenow": indeterminate ? void 0 : clampedValue,
50
- "aria-valuemin": 0,
51
- "aria-valuemax": 100,
27
+ className: cn("inline-flex items-center justify-center", className),
28
+ style,
29
+ role: "status",
30
+ "aria-label": ariaLabel,
31
+ "aria-busy": "true",
52
32
  ...rest,
53
- children: [
54
- /* @__PURE__ */ jsxs(
55
- "svg",
56
- {
57
- className: cn(indeterminate && "animate-spinner-rotate"),
33
+ children: /* @__PURE__ */ jsxs(
34
+ "div",
35
+ {
36
+ className: "relative",
37
+ style: {
58
38
  width: sizeValue,
59
- height: sizeValue,
60
- viewBox: `0 0 ${sizeValue} ${sizeValue}`,
61
- style: indeterminate ? { animation: `spinner-rotate ${animationDuration} linear infinite` } : void 0,
62
- children: [
63
- gradient && /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [
64
- /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: color }),
65
- /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: secondaryColor === "#e0e0e0" ? "#8b5cf6" : secondaryColor })
66
- ] }) }),
67
- /* @__PURE__ */ jsx(
68
- "circle",
69
- {
70
- cx: sizeValue / 2,
71
- cy: sizeValue / 2,
72
- r: radius,
73
- fill: "none",
74
- stroke: gradient ? "#e0e0e0" : secondaryColor,
75
- strokeWidth: thicknessValue
39
+ height: sizeValue
40
+ },
41
+ children: [
42
+ Array.from({ length: pulses }).map((_, index) => /* @__PURE__ */ jsx(
43
+ "div",
44
+ {
45
+ className: "absolute inset-0 rounded-full",
46
+ style: {
47
+ backgroundColor: color,
48
+ animation: `heartbeat-pulse ${animationDuration} ease-out infinite`,
49
+ animationDelay: `${index * 0.3}s`,
50
+ // @ts-ignore - CSS variable for animation
51
+ "--max-scale": maxScale
76
52
  }
77
- ),
78
- bufferDashoffset !== void 0 && !indeterminate && /* @__PURE__ */ jsx(
79
- "circle",
80
- {
81
- cx: sizeValue / 2,
82
- cy: sizeValue / 2,
83
- r: radius,
84
- fill: "none",
85
- stroke: gradient ? `url(#${gradientId})` : color,
86
- strokeWidth: thicknessValue,
87
- strokeLinecap: "round",
88
- strokeDasharray: circumference,
89
- strokeDashoffset: bufferDashoffset,
90
- transform: `rotate(-90 ${sizeValue / 2} ${sizeValue / 2})`,
91
- opacity: 0.3
53
+ },
54
+ index
55
+ )),
56
+ /* @__PURE__ */ jsx(
57
+ "div",
58
+ {
59
+ className: "absolute rounded-full",
60
+ style: {
61
+ backgroundColor: color,
62
+ width: "50%",
63
+ height: "50%",
64
+ top: "25%",
65
+ left: "25%"
92
66
  }
93
- ),
94
- /* @__PURE__ */ jsx(
95
- "circle",
96
- {
97
- cx: sizeValue / 2,
98
- cy: sizeValue / 2,
99
- r: radius,
100
- fill: "none",
101
- stroke: gradient ? `url(#${gradientId})` : color,
102
- strokeWidth: thicknessValue,
103
- strokeLinecap: "round",
104
- strokeDasharray: circumference,
105
- strokeDashoffset: indeterminate ? circumference * 0.75 : strokeDashoffset,
106
- transform: `rotate(-90 ${sizeValue / 2} ${sizeValue / 2})`,
107
- style: {
108
- transition: indeterminate ? "none" : "stroke-dashoffset 0.3s ease-in-out"
109
- }
110
- }
111
- )
112
- ]
113
- }
114
- ),
115
- showValue && !indeterminate && /* @__PURE__ */ jsxs(
116
- "span",
117
- {
118
- className: "absolute text-sm font-semibold",
119
- style: { color },
120
- children: [
121
- clampedValue,
122
- "%"
123
- ]
124
- }
125
- )
126
- ]
67
+ }
68
+ )
69
+ ]
70
+ }
71
+ )
127
72
  }
128
73
  );
129
74
  }
130
75
  );
131
- ProgressRing.displayName = "ProgressRing";
76
+ SpinnerPulse.displayName = "SpinnerPulse";
132
77
  export {
133
- ProgressRing
78
+ SpinnerPulse
134
79
  };
135
80
  //# sourceMappingURL=index20.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index20.js","sources":["../src/components/progress/ProgressRing.tsx"],"sourcesContent":["import { forwardRef, useMemo } from 'react';\nimport { ProgressRingProps } from '../../types';\nimport { cn, normalizeSize, parseSizeToNumber, getAnimationDuration } from '../../utils';\n\n/**\n * ProgressRing - Ring-style progress with gradient option\n *\n * A circular progress ring with optional gradient colors.\n *\n * @example\n * ```tsx\n * <ProgressRing value={75} showValue />\n * <ProgressRing value={60} gradient secondaryColor=\"#8b5cf6\" />\n * <ProgressRing indeterminate speed=\"fast\" />\n * <ProgressRing value={50} buffer={75} />\n * ```\n */\nexport const ProgressRing = forwardRef<HTMLDivElement, ProgressRingProps>(\n (\n {\n value = 0,\n indeterminate = false,\n showValue = false,\n size = 60,\n thickness = 4,\n color = '#3b82f6',\n secondaryColor = '#e0e0e0',\n gradient = false,\n buffer,\n speed = 'normal',\n className,\n style,\n testId = 'progress-ring',\n visible = true,\n ariaLabel,\n ...rest\n },\n ref\n ) => {\n if (!visible) return null;\n\n const clampedValue = Math.min(100, Math.max(0, value));\n const clampedBuffer = buffer !== undefined ? Math.min(100, Math.max(0, buffer)) : undefined;\n const sizeValue = parseSizeToNumber(size, 60);\n const thicknessValue = parseSizeToNumber(thickness, 4);\n const radius = (sizeValue - thicknessValue * 2) / 2;\n const circumference = 2 * Math.PI * radius;\n const strokeDashoffset = circumference - (clampedValue / 100) * circumference;\n const bufferDashoffset = clampedBuffer !== undefined ? circumference - (clampedBuffer / 100) * circumference : undefined;\n const progressLabel = ariaLabel || `Loading ${clampedValue}%`;\n const animationDuration = getAnimationDuration(speed);\n const gradientId = useMemo(() => `progress-gradient-${Math.random().toString(36).substr(2, 9)}`, []);\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('inline-flex items-center justify-center relative', className)}\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n ...style,\n }}\n role=\"progressbar\"\n aria-label={progressLabel}\n aria-valuenow={indeterminate ? undefined : clampedValue}\n aria-valuemin={0}\n aria-valuemax={100}\n {...rest}\n >\n <svg\n className={cn(indeterminate && 'animate-spinner-rotate')}\n width={sizeValue}\n height={sizeValue}\n viewBox={`0 0 ${sizeValue} ${sizeValue}`}\n style={indeterminate ? { animation: `spinner-rotate ${animationDuration} linear infinite` } : undefined}\n >\n {gradient && (\n <defs>\n <linearGradient id={gradientId} x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor={color} />\n <stop offset=\"100%\" stopColor={secondaryColor === '#e0e0e0' ? '#8b5cf6' : secondaryColor} />\n </linearGradient>\n </defs>\n )}\n {/* Background circle */}\n <circle\n cx={sizeValue / 2}\n cy={sizeValue / 2}\n r={radius}\n fill=\"none\"\n stroke={gradient ? '#e0e0e0' : secondaryColor}\n strokeWidth={thicknessValue}\n />\n {/* Buffer circle (behind progress) */}\n {bufferDashoffset !== undefined && !indeterminate && (\n <circle\n cx={sizeValue / 2}\n cy={sizeValue / 2}\n r={radius}\n fill=\"none\"\n stroke={gradient ? `url(#${gradientId})` : color}\n strokeWidth={thicknessValue}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={bufferDashoffset}\n transform={`rotate(-90 ${sizeValue / 2} ${sizeValue / 2})`}\n opacity={0.3}\n />\n )}\n {/* Progress circle */}\n <circle\n cx={sizeValue / 2}\n cy={sizeValue / 2}\n r={radius}\n fill=\"none\"\n stroke={gradient ? `url(#${gradientId})` : color}\n strokeWidth={thicknessValue}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={indeterminate ? circumference * 0.75 : strokeDashoffset}\n transform={`rotate(-90 ${sizeValue / 2} ${sizeValue / 2})`}\n style={{\n transition: indeterminate ? 'none' : 'stroke-dashoffset 0.3s ease-in-out',\n }}\n />\n </svg>\n {showValue && !indeterminate && (\n <span\n className=\"absolute text-sm font-semibold\"\n style={{ color }}\n >\n {clampedValue}%\n </span>\n )}\n </div>\n );\n }\n);\n\nProgressRing.displayName = 'ProgressRing';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index20.js","sources":["../src/components/spinner/SpinnerPulse.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerPulseProps } from '../../types';\nimport { cn, normalizeSize, getAnimationDuration } from '../../utils';\n\n/**\n * SpinnerPulse - Heartbeat pulse spinner\n *\n * A spinner with pulsing circles that scale and fade, creating a heartbeat effect.\n *\n * @example\n * ```tsx\n * <SpinnerPulse size={60} color=\"#3b82f6\" />\n * <SpinnerPulse size={80} pulses={3} />\n * <SpinnerPulse size={50} maxScale={2.5} speed=\"slow\" />\n * ```\n */\nexport const SpinnerPulse = forwardRef<HTMLDivElement, SpinnerPulseProps>(\n (\n {\n size = 40,\n color = '#3b82f6',\n pulses = 2,\n maxScale = 1.8,\n speed = 'normal',\n className,\n style,\n testId = 'spinner-pulse',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n if (!visible) return null;\n\n const animationDuration = getAnimationDuration(speed);\n const sizeValue = normalizeSize(size);\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('inline-flex items-center justify-center', className)}\n style={style}\n role=\"status\"\n aria-label={ariaLabel}\n aria-busy=\"true\"\n {...rest}\n >\n <div\n className=\"relative\"\n style={{\n width: sizeValue,\n height: sizeValue,\n }}\n >\n {/* Pulsing circles */}\n {Array.from({ length: pulses }).map((_, index) => (\n <div\n key={index}\n className=\"absolute inset-0 rounded-full\"\n style={{\n backgroundColor: color,\n animation: `heartbeat-pulse ${animationDuration} ease-out infinite`,\n animationDelay: `${index * 0.3}s`,\n // @ts-ignore - CSS variable for animation\n '--max-scale': maxScale,\n }}\n />\n ))}\n\n {/* Static center circle */}\n <div\n className=\"absolute rounded-full\"\n style={{\n backgroundColor: color,\n width: '50%',\n height: '50%',\n top: '25%',\n left: '25%',\n }}\n />\n </div>\n </div>\n );\n }\n);\n\nSpinnerPulse.displayName = 'SpinnerPulse';\n"],"names":[],"mappings":";;;;AAgBO,MAAM,eAAe;AAAA,EAC1B,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,IACX,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG;AAAA,EAAA,GAEL,QACG;AACH,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,oBAAoB,qBAAqB,KAAK;AACpD,UAAM,YAAY,cAAc,IAAI;AAEpC,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAW,GAAG,2CAA2C,SAAS;AAAA,QAClE;AAAA,QACA,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,aAAU;AAAA,QACT,GAAG;AAAA,QAEJ,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,OAAO;AAAA,cACP,QAAQ;AAAA,YAAA;AAAA,YAIT,UAAA;AAAA,cAAA,MAAM,KAAK,EAAE,QAAQ,OAAA,CAAQ,EAAE,IAAI,CAAC,GAAG,UACtC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,iBAAiB;AAAA,oBACjB,WAAW,mBAAmB,iBAAiB;AAAA,oBAC/C,gBAAgB,GAAG,QAAQ,GAAG;AAAA;AAAA,oBAE9B,eAAe;AAAA,kBAAA;AAAA,gBACjB;AAAA,gBARK;AAAA,cAAA,CAUR;AAAA,cAGD;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,iBAAiB;AAAA,oBACjB,OAAO;AAAA,oBACP,QAAQ;AAAA,oBACR,KAAK;AAAA,oBACL,MAAM;AAAA,kBAAA;AAAA,gBACR;AAAA,cAAA;AAAA,YACF;AAAA,UAAA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,aAAa,cAAc;"}
package/dist/index21.cjs CHANGED
@@ -4,54 +4,100 @@ const jsxRuntime = require("react/jsx-runtime");
4
4
  const react = require("react");
5
5
  const colors = require("./index4.cjs");
6
6
  const classNames = require("./index3.cjs");
7
- const PulseDots = react.forwardRef(
7
+ const ProgressBar = react.forwardRef(
8
8
  ({
9
- size = 40,
9
+ value = 0,
10
+ indeterminate = false,
11
+ showValue = false,
12
+ height = "0.5rem",
10
13
  color = "#3b82f6",
11
- dotCount = 3,
12
- dotSize = 10,
14
+ secondaryColor = "#e0e0e0",
15
+ gradient = false,
16
+ buffer,
13
17
  speed = "normal",
14
18
  className,
15
19
  style,
16
- testId = "pulse-dots",
20
+ testId = "progress-bar",
17
21
  visible = true,
18
- ariaLabel = "Loading...",
22
+ ariaLabel,
19
23
  ...rest
20
24
  }, ref) => {
21
25
  if (!visible) return null;
26
+ const clampedValue = Math.min(100, Math.max(0, value));
27
+ const clampedBuffer = buffer !== void 0 ? Math.min(100, Math.max(0, buffer)) : void 0;
28
+ const progressLabel = ariaLabel || `Loading ${clampedValue}%`;
22
29
  const animationDuration = colors.getAnimationDuration(speed);
23
- return /* @__PURE__ */ jsxRuntime.jsx(
30
+ const gradientId = react.useMemo(() => `progress-bar-gradient-${Math.random().toString(36).substr(2, 9)}`, []);
31
+ return /* @__PURE__ */ jsxRuntime.jsxs(
24
32
  "div",
25
33
  {
26
34
  ref,
27
35
  "data-testid": testId,
28
- className: classNames.cn("inline-flex items-center justify-center gap-2", className),
36
+ className: classNames.cn("relative w-full overflow-hidden rounded-full", className),
29
37
  style: {
30
- height: colors.normalizeSize(size),
38
+ height: colors.normalizeSize(height),
39
+ backgroundColor: secondaryColor,
31
40
  ...style
32
41
  },
33
- role: "status",
34
- "aria-label": ariaLabel,
35
- "aria-busy": "true",
42
+ role: "progressbar",
43
+ "aria-label": progressLabel,
44
+ "aria-valuenow": indeterminate ? void 0 : clampedValue,
45
+ "aria-valuemin": 0,
46
+ "aria-valuemax": 100,
36
47
  ...rest,
37
- children: Array.from({ length: dotCount }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
38
- "div",
39
- {
40
- className: "rounded-full",
41
- style: {
42
- width: colors.normalizeSize(dotSize),
43
- height: colors.normalizeSize(dotSize),
44
- backgroundColor: color,
45
- animation: `pulse-bounce ${animationDuration} ease-in-out infinite`,
46
- animationDelay: `${index * 0.15}s`
48
+ children: [
49
+ gradient && !indeterminate && /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "0", height: "0", style: { position: "absolute" }, children: /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [
50
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color }),
51
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: secondaryColor || "#8b5cf6" })
52
+ ] }) }) }),
53
+ clampedBuffer !== void 0 && !indeterminate && /* @__PURE__ */ jsxRuntime.jsx(
54
+ "div",
55
+ {
56
+ className: "absolute h-full rounded-full opacity-30",
57
+ style: {
58
+ width: `${clampedBuffer}%`,
59
+ backgroundColor: color
60
+ }
47
61
  }
48
- },
49
- index
50
- ))
62
+ ),
63
+ indeterminate ? /* @__PURE__ */ jsxRuntime.jsx(
64
+ "div",
65
+ {
66
+ className: "absolute h-full rounded-full",
67
+ style: {
68
+ backgroundColor: gradient ? `url(#${gradientId})` : color,
69
+ animation: `progress-indeterminate ${animationDuration} ease-in-out infinite`,
70
+ width: "40%"
71
+ }
72
+ }
73
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
74
+ "div",
75
+ {
76
+ className: "h-full rounded-full transition-all duration-300 ease-in-out",
77
+ style: {
78
+ width: `${clampedValue}%`,
79
+ background: gradient ? `url(#${gradientId})` : color
80
+ }
81
+ }
82
+ ),
83
+ showValue && !indeterminate && /* @__PURE__ */ jsxRuntime.jsxs(
84
+ "span",
85
+ {
86
+ className: "absolute inset-0 flex items-center justify-center text-xs font-medium",
87
+ style: {
88
+ color: clampedValue > 50 ? colors.getContrastColor(color) : secondaryColor === "#e0e0e0" ? "#000000" : colors.getContrastColor(secondaryColor)
89
+ },
90
+ children: [
91
+ clampedValue,
92
+ "%"
93
+ ]
94
+ }
95
+ )
96
+ ]
51
97
  }
52
98
  );
53
99
  }
54
100
  );
55
- PulseDots.displayName = "PulseDots";
56
- exports.PulseDots = PulseDots;
101
+ ProgressBar.displayName = "ProgressBar";
102
+ exports.ProgressBar = ProgressBar;
57
103
  //# sourceMappingURL=index21.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index21.cjs","sources":["../src/components/pulse/PulseDots.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { PulseDotsProps } from '../../types';\nimport { cn, normalizeSize, getAnimationDuration } from '../../utils';\n\n/**\n * PulseDots - Bouncing dots loader\n *\n * A loader with bouncing dots that scale and fade in a sequence.\n *\n * @example\n * ```tsx\n * <PulseDots size={40} color=\"#3b82f6\" />\n * <PulseDots size={32} dotCount={5} speed=\"fast\" />\n * ```\n */\nexport const PulseDots = forwardRef<HTMLDivElement, PulseDotsProps>(\n (\n {\n size = 40,\n color = '#3b82f6',\n dotCount = 3,\n dotSize = 10,\n speed = 'normal',\n className,\n style,\n testId = 'pulse-dots',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n if (!visible) return null;\n\n const animationDuration = getAnimationDuration(speed);\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('inline-flex items-center justify-center gap-2', className)}\n style={{\n height: normalizeSize(size),\n ...style,\n }}\n role=\"status\"\n aria-label={ariaLabel}\n aria-busy=\"true\"\n {...rest}\n >\n {Array.from({ length: dotCount }).map((_, index) => (\n <div\n key={index}\n className=\"rounded-full\"\n style={{\n width: normalizeSize(dotSize),\n height: normalizeSize(dotSize),\n backgroundColor: color,\n animation: `pulse-bounce ${animationDuration} ease-in-out infinite`,\n animationDelay: `${index * 0.15}s`,\n }}\n />\n ))}\n </div>\n );\n }\n);\n\nPulseDots.displayName = 'PulseDots';\n"],"names":["forwardRef","getAnimationDuration","jsx","cn","normalizeSize"],"mappings":";;;;;;AAeO,MAAM,YAAYA,MAAAA;AAAAA,EACvB,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,UAAU;AAAA,IACV,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG;AAAA,EAAA,GAEL,QACG;AACH,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,oBAAoBC,OAAAA,qBAAqB,KAAK;AAEpD,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAWC,WAAAA,GAAG,iDAAiD,SAAS;AAAA,QACxE,OAAO;AAAA,UACL,QAAQC,OAAAA,cAAc,IAAI;AAAA,UAC1B,GAAG;AAAA,QAAA;AAAA,QAEL,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,aAAU;AAAA,QACT,GAAG;AAAA,QAEH,UAAA,MAAM,KAAK,EAAE,QAAQ,UAAU,EAAE,IAAI,CAAC,GAAG,UACxCF,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,OAAOE,OAAAA,cAAc,OAAO;AAAA,cAC5B,QAAQA,OAAAA,cAAc,OAAO;AAAA,cAC7B,iBAAiB;AAAA,cACjB,WAAW,gBAAgB,iBAAiB;AAAA,cAC5C,gBAAgB,GAAG,QAAQ,IAAI;AAAA,YAAA;AAAA,UACjC;AAAA,UARK;AAAA,QAAA,CAUR;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEA,UAAU,cAAc;;"}
1
+ {"version":3,"file":"index21.cjs","sources":["../src/components/progress/ProgressBar.tsx"],"sourcesContent":["import { forwardRef, useMemo } from 'react';\nimport { ProgressBarProps } from '../../types';\nimport { cn, normalizeSize, getContrastColor, getAnimationDuration } from '../../utils';\n\n/**\n * ProgressBar - Linear progress bar\n *\n * A horizontal progress bar that can be determinate (showing specific progress) or indeterminate (loading animation).\n *\n * @example\n * ```tsx\n * <ProgressBar value={75} showValue />\n * <ProgressBar indeterminate />\n * <ProgressBar value={50} height={8} color=\"#8b5cf6\" />\n * <ProgressBar value={50} buffer={75} /> // YouTube-style buffering\n * <ProgressBar value={60} gradient /> // Gradient progress\n * ```\n */\nexport const ProgressBar = forwardRef<HTMLDivElement, ProgressBarProps>(\n (\n {\n value = 0,\n indeterminate = false,\n showValue = false,\n height = '0.5rem',\n color = '#3b82f6',\n secondaryColor = '#e0e0e0',\n gradient = false,\n buffer,\n speed = 'normal',\n className,\n style,\n testId = 'progress-bar',\n visible = true,\n ariaLabel,\n ...rest\n },\n ref\n ) => {\n if (!visible) return null;\n\n const clampedValue = Math.min(100, Math.max(0, value));\n const clampedBuffer = buffer !== undefined ? Math.min(100, Math.max(0, buffer)) : undefined;\n const progressLabel = ariaLabel || `Loading ${clampedValue}%`;\n const animationDuration = getAnimationDuration(speed);\n\n // Generate gradient ID for SVG-based gradient\n const gradientId = useMemo(() => `progress-bar-gradient-${Math.random().toString(36).substr(2, 9)}`, []);\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('relative w-full overflow-hidden rounded-full', className)}\n style={{\n height: normalizeSize(height),\n backgroundColor: secondaryColor,\n ...style,\n }}\n role=\"progressbar\"\n aria-label={progressLabel}\n aria-valuenow={indeterminate ? undefined : clampedValue}\n aria-valuemin={0}\n aria-valuemax={100}\n {...rest}\n >\n {/* Gradient SVG definition */}\n {gradient && !indeterminate && (\n <svg width=\"0\" height=\"0\" style={{ position: 'absolute' }}>\n <defs>\n <linearGradient id={gradientId} x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stopColor={color} />\n <stop offset=\"100%\" stopColor={secondaryColor || '#8b5cf6'} />\n </linearGradient>\n </defs>\n </svg>\n )}\n\n {/* Buffer indicator (shows behind main progress) */}\n {clampedBuffer !== undefined && !indeterminate && (\n <div\n className=\"absolute h-full rounded-full opacity-30\"\n style={{\n width: `${clampedBuffer}%`,\n backgroundColor: color,\n }}\n />\n )}\n\n {indeterminate ? (\n <div\n className=\"absolute h-full rounded-full\"\n style={{\n backgroundColor: gradient ? `url(#${gradientId})` : color,\n animation: `progress-indeterminate ${animationDuration} ease-in-out infinite`,\n width: '40%',\n }}\n />\n ) : (\n <div\n className=\"h-full rounded-full transition-all duration-300 ease-in-out\"\n style={{\n width: `${clampedValue}%`,\n background: gradient ? `url(#${gradientId})` : color,\n }}\n />\n )}\n\n {showValue && !indeterminate && (\n <span\n className=\"absolute inset-0 flex items-center justify-center text-xs font-medium\"\n style={{\n color: clampedValue > 50 ? getContrastColor(color) : secondaryColor === '#e0e0e0' ? '#000000' : getContrastColor(secondaryColor)\n }}\n >\n {clampedValue}%\n </span>\n )}\n </div>\n );\n }\n);\n\nProgressBar.displayName = 'ProgressBar';\n"],"names":["forwardRef","getAnimationDuration","useMemo","jsxs","cn","normalizeSize","jsx","getContrastColor"],"mappings":"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"}
package/dist/index21.js CHANGED
@@ -1,57 +1,103 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import { forwardRef } from "react";
3
- import { normalizeSize, getAnimationDuration } from "./index4.js";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { forwardRef, useMemo } from "react";
3
+ import { normalizeSize, getAnimationDuration, getContrastColor } from "./index4.js";
4
4
  import { cn } from "./index3.js";
5
- const PulseDots = forwardRef(
5
+ const ProgressBar = forwardRef(
6
6
  ({
7
- size = 40,
7
+ value = 0,
8
+ indeterminate = false,
9
+ showValue = false,
10
+ height = "0.5rem",
8
11
  color = "#3b82f6",
9
- dotCount = 3,
10
- dotSize = 10,
12
+ secondaryColor = "#e0e0e0",
13
+ gradient = false,
14
+ buffer,
11
15
  speed = "normal",
12
16
  className,
13
17
  style,
14
- testId = "pulse-dots",
18
+ testId = "progress-bar",
15
19
  visible = true,
16
- ariaLabel = "Loading...",
20
+ ariaLabel,
17
21
  ...rest
18
22
  }, ref) => {
19
23
  if (!visible) return null;
24
+ const clampedValue = Math.min(100, Math.max(0, value));
25
+ const clampedBuffer = buffer !== void 0 ? Math.min(100, Math.max(0, buffer)) : void 0;
26
+ const progressLabel = ariaLabel || `Loading ${clampedValue}%`;
20
27
  const animationDuration = getAnimationDuration(speed);
21
- return /* @__PURE__ */ jsx(
28
+ const gradientId = useMemo(() => `progress-bar-gradient-${Math.random().toString(36).substr(2, 9)}`, []);
29
+ return /* @__PURE__ */ jsxs(
22
30
  "div",
23
31
  {
24
32
  ref,
25
33
  "data-testid": testId,
26
- className: cn("inline-flex items-center justify-center gap-2", className),
34
+ className: cn("relative w-full overflow-hidden rounded-full", className),
27
35
  style: {
28
- height: normalizeSize(size),
36
+ height: normalizeSize(height),
37
+ backgroundColor: secondaryColor,
29
38
  ...style
30
39
  },
31
- role: "status",
32
- "aria-label": ariaLabel,
33
- "aria-busy": "true",
40
+ role: "progressbar",
41
+ "aria-label": progressLabel,
42
+ "aria-valuenow": indeterminate ? void 0 : clampedValue,
43
+ "aria-valuemin": 0,
44
+ "aria-valuemax": 100,
34
45
  ...rest,
35
- children: Array.from({ length: dotCount }).map((_, index) => /* @__PURE__ */ jsx(
36
- "div",
37
- {
38
- className: "rounded-full",
39
- style: {
40
- width: normalizeSize(dotSize),
41
- height: normalizeSize(dotSize),
42
- backgroundColor: color,
43
- animation: `pulse-bounce ${animationDuration} ease-in-out infinite`,
44
- animationDelay: `${index * 0.15}s`
46
+ children: [
47
+ gradient && !indeterminate && /* @__PURE__ */ jsx("svg", { width: "0", height: "0", style: { position: "absolute" }, children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [
48
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: color }),
49
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: secondaryColor || "#8b5cf6" })
50
+ ] }) }) }),
51
+ clampedBuffer !== void 0 && !indeterminate && /* @__PURE__ */ jsx(
52
+ "div",
53
+ {
54
+ className: "absolute h-full rounded-full opacity-30",
55
+ style: {
56
+ width: `${clampedBuffer}%`,
57
+ backgroundColor: color
58
+ }
45
59
  }
46
- },
47
- index
48
- ))
60
+ ),
61
+ indeterminate ? /* @__PURE__ */ jsx(
62
+ "div",
63
+ {
64
+ className: "absolute h-full rounded-full",
65
+ style: {
66
+ backgroundColor: gradient ? `url(#${gradientId})` : color,
67
+ animation: `progress-indeterminate ${animationDuration} ease-in-out infinite`,
68
+ width: "40%"
69
+ }
70
+ }
71
+ ) : /* @__PURE__ */ jsx(
72
+ "div",
73
+ {
74
+ className: "h-full rounded-full transition-all duration-300 ease-in-out",
75
+ style: {
76
+ width: `${clampedValue}%`,
77
+ background: gradient ? `url(#${gradientId})` : color
78
+ }
79
+ }
80
+ ),
81
+ showValue && !indeterminate && /* @__PURE__ */ jsxs(
82
+ "span",
83
+ {
84
+ className: "absolute inset-0 flex items-center justify-center text-xs font-medium",
85
+ style: {
86
+ color: clampedValue > 50 ? getContrastColor(color) : secondaryColor === "#e0e0e0" ? "#000000" : getContrastColor(secondaryColor)
87
+ },
88
+ children: [
89
+ clampedValue,
90
+ "%"
91
+ ]
92
+ }
93
+ )
94
+ ]
49
95
  }
50
96
  );
51
97
  }
52
98
  );
53
- PulseDots.displayName = "PulseDots";
99
+ ProgressBar.displayName = "ProgressBar";
54
100
  export {
55
- PulseDots
101
+ ProgressBar
56
102
  };
57
103
  //# sourceMappingURL=index21.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index21.js","sources":["../src/components/pulse/PulseDots.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { PulseDotsProps } from '../../types';\nimport { cn, normalizeSize, getAnimationDuration } from '../../utils';\n\n/**\n * PulseDots - Bouncing dots loader\n *\n * A loader with bouncing dots that scale and fade in a sequence.\n *\n * @example\n * ```tsx\n * <PulseDots size={40} color=\"#3b82f6\" />\n * <PulseDots size={32} dotCount={5} speed=\"fast\" />\n * ```\n */\nexport const PulseDots = forwardRef<HTMLDivElement, PulseDotsProps>(\n (\n {\n size = 40,\n color = '#3b82f6',\n dotCount = 3,\n dotSize = 10,\n speed = 'normal',\n className,\n style,\n testId = 'pulse-dots',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n if (!visible) return null;\n\n const animationDuration = getAnimationDuration(speed);\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('inline-flex items-center justify-center gap-2', className)}\n style={{\n height: normalizeSize(size),\n ...style,\n }}\n role=\"status\"\n aria-label={ariaLabel}\n aria-busy=\"true\"\n {...rest}\n >\n {Array.from({ length: dotCount }).map((_, index) => (\n <div\n key={index}\n className=\"rounded-full\"\n style={{\n width: normalizeSize(dotSize),\n height: normalizeSize(dotSize),\n backgroundColor: color,\n animation: `pulse-bounce ${animationDuration} ease-in-out infinite`,\n animationDelay: `${index * 0.15}s`,\n }}\n />\n ))}\n </div>\n );\n }\n);\n\nPulseDots.displayName = 'PulseDots';\n"],"names":[],"mappings":";;;;AAeO,MAAM,YAAY;AAAA,EACvB,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,UAAU;AAAA,IACV,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG;AAAA,EAAA,GAEL,QACG;AACH,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,oBAAoB,qBAAqB,KAAK;AAEpD,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAW,GAAG,iDAAiD,SAAS;AAAA,QACxE,OAAO;AAAA,UACL,QAAQ,cAAc,IAAI;AAAA,UAC1B,GAAG;AAAA,QAAA;AAAA,QAEL,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,aAAU;AAAA,QACT,GAAG;AAAA,QAEH,UAAA,MAAM,KAAK,EAAE,QAAQ,UAAU,EAAE,IAAI,CAAC,GAAG,UACxC;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,OAAO,cAAc,OAAO;AAAA,cAC5B,QAAQ,cAAc,OAAO;AAAA,cAC7B,iBAAiB;AAAA,cACjB,WAAW,gBAAgB,iBAAiB;AAAA,cAC5C,gBAAgB,GAAG,QAAQ,IAAI;AAAA,YAAA;AAAA,UACjC;AAAA,UARK;AAAA,QAAA,CAUR;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEA,UAAU,cAAc;"}
1
+ {"version":3,"file":"index21.js","sources":["../src/components/progress/ProgressBar.tsx"],"sourcesContent":["import { forwardRef, useMemo } from 'react';\nimport { ProgressBarProps } from '../../types';\nimport { cn, normalizeSize, getContrastColor, getAnimationDuration } from '../../utils';\n\n/**\n * ProgressBar - Linear progress bar\n *\n * A horizontal progress bar that can be determinate (showing specific progress) or indeterminate (loading animation).\n *\n * @example\n * ```tsx\n * <ProgressBar value={75} showValue />\n * <ProgressBar indeterminate />\n * <ProgressBar value={50} height={8} color=\"#8b5cf6\" />\n * <ProgressBar value={50} buffer={75} /> // YouTube-style buffering\n * <ProgressBar value={60} gradient /> // Gradient progress\n * ```\n */\nexport const ProgressBar = forwardRef<HTMLDivElement, ProgressBarProps>(\n (\n {\n value = 0,\n indeterminate = false,\n showValue = false,\n height = '0.5rem',\n color = '#3b82f6',\n secondaryColor = '#e0e0e0',\n gradient = false,\n buffer,\n speed = 'normal',\n className,\n style,\n testId = 'progress-bar',\n visible = true,\n ariaLabel,\n ...rest\n },\n ref\n ) => {\n if (!visible) return null;\n\n const clampedValue = Math.min(100, Math.max(0, value));\n const clampedBuffer = buffer !== undefined ? Math.min(100, Math.max(0, buffer)) : undefined;\n const progressLabel = ariaLabel || `Loading ${clampedValue}%`;\n const animationDuration = getAnimationDuration(speed);\n\n // Generate gradient ID for SVG-based gradient\n const gradientId = useMemo(() => `progress-bar-gradient-${Math.random().toString(36).substr(2, 9)}`, []);\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('relative w-full overflow-hidden rounded-full', className)}\n style={{\n height: normalizeSize(height),\n backgroundColor: secondaryColor,\n ...style,\n }}\n role=\"progressbar\"\n aria-label={progressLabel}\n aria-valuenow={indeterminate ? undefined : clampedValue}\n aria-valuemin={0}\n aria-valuemax={100}\n {...rest}\n >\n {/* Gradient SVG definition */}\n {gradient && !indeterminate && (\n <svg width=\"0\" height=\"0\" style={{ position: 'absolute' }}>\n <defs>\n <linearGradient id={gradientId} x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stopColor={color} />\n <stop offset=\"100%\" stopColor={secondaryColor || '#8b5cf6'} />\n </linearGradient>\n </defs>\n </svg>\n )}\n\n {/* Buffer indicator (shows behind main progress) */}\n {clampedBuffer !== undefined && !indeterminate && (\n <div\n className=\"absolute h-full rounded-full opacity-30\"\n style={{\n width: `${clampedBuffer}%`,\n backgroundColor: color,\n }}\n />\n )}\n\n {indeterminate ? (\n <div\n className=\"absolute h-full rounded-full\"\n style={{\n backgroundColor: gradient ? `url(#${gradientId})` : color,\n animation: `progress-indeterminate ${animationDuration} ease-in-out infinite`,\n width: '40%',\n }}\n />\n ) : (\n <div\n className=\"h-full rounded-full transition-all duration-300 ease-in-out\"\n style={{\n width: `${clampedValue}%`,\n background: gradient ? `url(#${gradientId})` : color,\n }}\n />\n )}\n\n {showValue && !indeterminate && (\n <span\n className=\"absolute inset-0 flex items-center justify-center text-xs font-medium\"\n style={{\n color: clampedValue > 50 ? getContrastColor(color) : secondaryColor === '#e0e0e0' ? '#000000' : getContrastColor(secondaryColor)\n }}\n >\n {clampedValue}%\n </span>\n )}\n </div>\n );\n }\n);\n\nProgressBar.displayName = 'ProgressBar';\n"],"names":[],"mappings":";;;;AAkBO,MAAM,cAAc;AAAA,EACzB,CACE;AAAA,IACE,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,eAAe,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,CAAC;AACrD,UAAM,gBAAgB,WAAW,SAAY,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI;AAClF,UAAM,gBAAgB,aAAa,WAAW,YAAY;AAC1D,UAAM,oBAAoB,qBAAqB,KAAK;AAGpD,UAAM,aAAa,QAAQ,MAAM,yBAAyB,KAAK,SAAS,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC,CAAC,IAAI,EAAE;AAEvG,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAW,GAAG,gDAAgD,SAAS;AAAA,QACvE,OAAO;AAAA,UACL,QAAQ,cAAc,MAAM;AAAA,UAC5B,iBAAiB;AAAA,UACjB,GAAG;AAAA,QAAA;AAAA,QAEL,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,iBAAe,gBAAgB,SAAY;AAAA,QAC3C,iBAAe;AAAA,QACf,iBAAe;AAAA,QACd,GAAG;AAAA,QAGH,UAAA;AAAA,UAAA,YAAY,CAAC,iBACZ,oBAAC,OAAA,EAAI,OAAM,KAAI,QAAO,KAAI,OAAO,EAAE,UAAU,WAAA,GAC3C,8BAAC,QAAA,EACC,UAAA,qBAAC,kBAAA,EAAe,IAAI,YAAY,IAAG,MAAK,IAAG,MAAK,IAAG,QAAO,IAAG,MAC3D,UAAA;AAAA,YAAA,oBAAC,QAAA,EAAK,QAAO,MAAK,WAAW,OAAO;AAAA,gCACnC,QAAA,EAAK,QAAO,QAAO,WAAW,kBAAkB,UAAA,CAAW;AAAA,UAAA,EAAA,CAC9D,GACF,GACF;AAAA,UAID,kBAAkB,UAAa,CAAC,iBAC/B;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,OAAO,GAAG,aAAa;AAAA,gBACvB,iBAAiB;AAAA,cAAA;AAAA,YACnB;AAAA,UAAA;AAAA,UAIH,gBACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,iBAAiB,WAAW,QAAQ,UAAU,MAAM;AAAA,gBACpD,WAAW,0BAA0B,iBAAiB;AAAA,gBACtD,OAAO;AAAA,cAAA;AAAA,YACT;AAAA,UAAA,IAGF;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,OAAO,GAAG,YAAY;AAAA,gBACtB,YAAY,WAAW,QAAQ,UAAU,MAAM;AAAA,cAAA;AAAA,YACjD;AAAA,UAAA;AAAA,UAIH,aAAa,CAAC,iBACb;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,OAAO,eAAe,KAAK,iBAAiB,KAAK,IAAI,mBAAmB,YAAY,YAAY,iBAAiB,cAAc;AAAA,cAAA;AAAA,cAGhI,UAAA;AAAA,gBAAA;AAAA,gBAAa;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAChB;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,YAAY,cAAc;"}