premium-react-loaders 1.0.2 → 1.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 (143) hide show
  1. package/README.md +55 -6
  2. package/dist/components/progress/ProgressBar.d.ts.map +1 -1
  3. package/dist/components/progress/ProgressCircle.d.ts.map +1 -1
  4. package/dist/components/progress/ProgressRing.d.ts.map +1 -1
  5. package/dist/components/progress/ProgressSteps.d.ts +16 -0
  6. package/dist/components/progress/ProgressSteps.d.ts.map +1 -0
  7. package/dist/components/progress/index.d.ts +1 -0
  8. package/dist/components/progress/index.d.ts.map +1 -1
  9. package/dist/components/pulse/PulseBars.d.ts +2 -2
  10. package/dist/components/pulse/PulseBars.d.ts.map +1 -1
  11. package/dist/components/pulse/PulseDots.d.ts +2 -2
  12. package/dist/components/pulse/PulseDots.d.ts.map +1 -1
  13. package/dist/components/pulse/PulseWave.d.ts +2 -2
  14. package/dist/components/pulse/PulseWave.d.ts.map +1 -1
  15. package/dist/components/pulse/TypingIndicator.d.ts +16 -0
  16. package/dist/components/pulse/TypingIndicator.d.ts.map +1 -0
  17. package/dist/components/pulse/index.d.ts +1 -0
  18. package/dist/components/pulse/index.d.ts.map +1 -1
  19. package/dist/components/skeleton/SkeletonForm.d.ts +16 -0
  20. package/dist/components/skeleton/SkeletonForm.d.ts.map +1 -0
  21. package/dist/components/skeleton/index.d.ts +1 -0
  22. package/dist/components/skeleton/index.d.ts.map +1 -1
  23. package/dist/components/spinner/SpinnerBars.d.ts +2 -2
  24. package/dist/components/spinner/SpinnerBars.d.ts.map +1 -1
  25. package/dist/components/spinner/SpinnerCircle.d.ts +2 -1
  26. package/dist/components/spinner/SpinnerCircle.d.ts.map +1 -1
  27. package/dist/components/spinner/SpinnerDots.d.ts +2 -2
  28. package/dist/components/spinner/SpinnerDots.d.ts.map +1 -1
  29. package/dist/components/spinner/SpinnerGrid.d.ts +2 -2
  30. package/dist/components/spinner/SpinnerGrid.d.ts.map +1 -1
  31. package/dist/components/spinner/SpinnerPulse.d.ts +15 -0
  32. package/dist/components/spinner/SpinnerPulse.d.ts.map +1 -0
  33. package/dist/components/spinner/SpinnerRing.d.ts +3 -3
  34. package/dist/components/spinner/SpinnerRing.d.ts.map +1 -1
  35. package/dist/components/spinner/SpinnerWave.d.ts +15 -0
  36. package/dist/components/spinner/SpinnerWave.d.ts.map +1 -0
  37. package/dist/components/spinner/index.d.ts +2 -0
  38. package/dist/components/spinner/index.d.ts.map +1 -1
  39. package/dist/index.cjs +23 -13
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.ts +1 -1
  42. package/dist/index.js +23 -13
  43. package/dist/index.js.map +1 -1
  44. package/dist/index13.cjs +54 -35
  45. package/dist/index13.cjs.map +1 -1
  46. package/dist/index13.js +56 -37
  47. package/dist/index13.js.map +1 -1
  48. package/dist/index14.cjs +29 -12
  49. package/dist/index14.cjs.map +1 -1
  50. package/dist/index14.js +30 -13
  51. package/dist/index14.js.map +1 -1
  52. package/dist/index15.cjs +19 -36
  53. package/dist/index15.cjs.map +1 -1
  54. package/dist/index15.js +19 -36
  55. package/dist/index15.js.map +1 -1
  56. package/dist/index16.cjs +47 -24
  57. package/dist/index16.cjs.map +1 -1
  58. package/dist/index16.js +48 -25
  59. package/dist/index16.js.map +1 -1
  60. package/dist/index17.cjs +29 -38
  61. package/dist/index17.cjs.map +1 -1
  62. package/dist/index17.js +29 -38
  63. package/dist/index17.js.map +1 -1
  64. package/dist/index18.cjs +52 -79
  65. package/dist/index18.cjs.map +1 -1
  66. package/dist/index18.js +54 -81
  67. package/dist/index18.js.map +1 -1
  68. package/dist/index19.cjs +45 -104
  69. package/dist/index19.cjs.map +1 -1
  70. package/dist/index19.js +46 -105
  71. package/dist/index19.js.map +1 -1
  72. package/dist/index20.cjs +58 -108
  73. package/dist/index20.cjs.map +1 -1
  74. package/dist/index20.js +60 -110
  75. package/dist/index20.js.map +1 -1
  76. package/dist/index21.cjs +79 -28
  77. package/dist/index21.cjs.map +1 -1
  78. package/dist/index21.js +82 -31
  79. package/dist/index21.js.map +1 -1
  80. package/dist/index22.cjs +106 -32
  81. package/dist/index22.cjs.map +1 -1
  82. package/dist/index22.js +108 -34
  83. package/dist/index22.js.map +1 -1
  84. package/dist/index23.cjs +112 -34
  85. package/dist/index23.cjs.map +1 -1
  86. package/dist/index23.js +115 -37
  87. package/dist/index23.js.map +1 -1
  88. package/dist/index24.cjs +108 -48
  89. package/dist/index24.cjs.map +1 -1
  90. package/dist/index24.js +110 -50
  91. package/dist/index24.js.map +1 -1
  92. package/dist/index25.cjs +59 -16
  93. package/dist/index25.cjs.map +1 -1
  94. package/dist/index25.js +58 -15
  95. package/dist/index25.js.map +1 -1
  96. package/dist/index26.cjs +66 -0
  97. package/dist/index26.cjs.map +1 -0
  98. package/dist/index26.js +66 -0
  99. package/dist/index26.js.map +1 -0
  100. package/dist/index27.cjs +69 -0
  101. package/dist/index27.cjs.map +1 -0
  102. package/dist/index27.js +69 -0
  103. package/dist/index27.js.map +1 -0
  104. package/dist/index28.cjs +65 -0
  105. package/dist/index28.cjs.map +1 -0
  106. package/dist/index28.js +65 -0
  107. package/dist/index28.js.map +1 -0
  108. package/dist/index29.cjs +71 -0
  109. package/dist/index29.cjs.map +1 -0
  110. package/dist/index29.js +71 -0
  111. package/dist/index29.js.map +1 -0
  112. package/dist/index3.cjs +1 -1
  113. package/dist/index3.js +1 -1
  114. package/dist/index30.cjs +18 -0
  115. package/dist/index30.cjs.map +1 -0
  116. package/dist/index30.js +18 -0
  117. package/dist/index30.js.map +1 -0
  118. package/dist/index31.cjs +42 -0
  119. package/dist/index31.cjs.map +1 -0
  120. package/dist/index31.js +42 -0
  121. package/dist/index31.js.map +1 -0
  122. package/dist/index4.cjs +10 -0
  123. package/dist/index4.cjs.map +1 -1
  124. package/dist/index4.js +10 -0
  125. package/dist/index4.js.map +1 -1
  126. package/dist/premium-react-loaders.css +299 -3
  127. package/dist/types/common.d.ts +14 -2
  128. package/dist/types/common.d.ts.map +1 -1
  129. package/dist/types/progress.d.ts +24 -1
  130. package/dist/types/progress.d.ts.map +1 -1
  131. package/dist/types/pulse.d.ts +13 -0
  132. package/dist/types/pulse.d.ts.map +1 -1
  133. package/dist/types/skeleton.d.ts +17 -0
  134. package/dist/types/skeleton.d.ts.map +1 -1
  135. package/dist/types/spinner.d.ts +18 -0
  136. package/dist/types/spinner.d.ts.map +1 -1
  137. package/dist/utils/colors.d.ts +2 -1
  138. package/dist/utils/colors.d.ts.map +1 -1
  139. package/dist/utils/hooks.d.ts +10 -0
  140. package/dist/utils/hooks.d.ts.map +1 -0
  141. package/dist/utils/index.d.ts +1 -0
  142. package/dist/utils/index.d.ts.map +1 -1
  143. package/package.json +1 -1
package/dist/index18.cjs CHANGED
@@ -2,102 +2,75 @@
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");
5
+ const hooks = require("./index31.cjs");
6
6
  const classNames = require("./index3.cjs");
7
- const ProgressBar = react.forwardRef(
7
+ const colors = require("./index4.cjs");
8
+ const SpinnerGrid = react.forwardRef(
8
9
  ({
9
- value = 0,
10
- indeterminate = false,
11
- showValue = false,
12
- height = "0.5rem",
10
+ size = "md",
13
11
  color = "#3b82f6",
14
- secondaryColor = "#e0e0e0",
15
- gradient = false,
16
- buffer,
12
+ gridSize = 3,
17
13
  speed = "normal",
14
+ reverse = false,
15
+ respectMotionPreference = true,
18
16
  className,
19
17
  style,
20
- testId = "progress-bar",
18
+ testId = "spinner-grid",
21
19
  visible = true,
22
- ariaLabel,
20
+ ariaLabel = "Loading...",
23
21
  ...rest
24
22
  }, ref) => {
25
23
  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}%`;
29
- const animationDuration = colors.getAnimationDuration(speed);
30
- const gradientId = react.useMemo(() => `progress-bar-gradient-${Math.random().toString(36).substr(2, 9)}`, []);
31
- return /* @__PURE__ */ jsxRuntime.jsxs(
24
+ const prefersReducedMotion = hooks.useReducedMotion();
25
+ const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
26
+ const sizeValue = colors.parseSizeToNumber(size, 40);
27
+ const cellSize = Math.floor(sizeValue / gridSize) - 2;
28
+ return /* @__PURE__ */ jsxRuntime.jsx(
32
29
  "div",
33
30
  {
34
31
  ref,
35
32
  "data-testid": testId,
36
- className: classNames.cn("relative w-full overflow-hidden rounded-full", className),
37
- style: {
38
- height: colors.normalizeSize(height),
39
- backgroundColor: secondaryColor,
40
- ...style
41
- },
42
- role: "progressbar",
43
- "aria-label": progressLabel,
44
- "aria-valuenow": indeterminate ? void 0 : clampedValue,
45
- "aria-valuemin": 0,
46
- "aria-valuemax": 100,
33
+ className: classNames.cn("inline-flex items-center justify-center", className),
34
+ style,
35
+ role: "status",
36
+ "aria-label": ariaLabel,
37
+ "aria-busy": "true",
47
38
  ...rest,
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
- }
61
- }
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
- ]
39
+ children: /* @__PURE__ */ jsxRuntime.jsx(
40
+ "div",
41
+ {
42
+ className: "grid gap-0.5",
43
+ style: {
44
+ width: colors.normalizeSize(size),
45
+ height: colors.normalizeSize(size),
46
+ gridTemplateColumns: `repeat(${gridSize}, 1fr)`
47
+ },
48
+ children: Array.from({ length: gridSize * gridSize }).map((_, index) => {
49
+ const row = Math.floor(index / gridSize);
50
+ const col = index % gridSize;
51
+ const maxDelay = (gridSize - 1) * 2;
52
+ const delay = reverse ? (maxDelay - (row + col)) * 0.1 : (row + col) * 0.1;
53
+ return /* @__PURE__ */ jsxRuntime.jsx(
54
+ "div",
55
+ {
56
+ className: "rounded-sm",
57
+ style: {
58
+ width: `${cellSize}px`,
59
+ height: `${cellSize}px`,
60
+ backgroundColor: color,
61
+ animation: `fade-pulse ${effectiveDuration} ease-in-out infinite`,
62
+ animationDelay: `${delay}s`
63
+ }
64
+ },
65
+ index
66
+ );
67
+ })
68
+ }
69
+ )
97
70
  }
98
71
  );
99
72
  }
100
73
  );
101
- ProgressBar.displayName = "ProgressBar";
102
- exports.ProgressBar = ProgressBar;
74
+ SpinnerGrid.displayName = "SpinnerGrid";
75
+ exports.SpinnerGrid = SpinnerGrid;
103
76
  //# sourceMappingURL=index18.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index18.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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"}
1
+ {"version":3,"file":"index18.cjs","sources":["../src/components/spinner/SpinnerGrid.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerGridProps } from '../../types';\nimport { cn, normalizeSize, parseSizeToNumber, useReducedMotion, getEffectiveDuration } from '../../utils';\n\n/**\n * SpinnerGrid - Grid of fading squares\n *\n * A spinner with a grid of squares that fade in and out in a pattern.\n *\n * @example\n * ```tsx\n * <SpinnerGrid size=\"lg\" color=\"#3b82f6\" />\n * <SpinnerGrid size=\"md\" gridSize={4} reverse />\n * ```\n */\nexport const SpinnerGrid = forwardRef<HTMLDivElement, SpinnerGridProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n gridSize = 3,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n className,\n style,\n testId = 'spinner-grid',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n if (!visible) return null;\n\n const prefersReducedMotion = useReducedMotion();\n const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);\n\n const sizeValue = parseSizeToNumber(size, 40);\n const cellSize = Math.floor(sizeValue / gridSize) - 2;\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=\"grid gap-0.5\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n gridTemplateColumns: `repeat(${gridSize}, 1fr)`,\n }}\n >\n {Array.from({ length: gridSize * gridSize }).map((_, index) => {\n const row = Math.floor(index / gridSize);\n const col = index % gridSize;\n const maxDelay = (gridSize - 1) * 2;\n const delay = reverse ? (maxDelay - (row + col)) * 0.1 : (row + col) * 0.1;\n\n return (\n <div\n key={index}\n className=\"rounded-sm\"\n style={{\n width: `${cellSize}px`,\n height: `${cellSize}px`,\n backgroundColor: color,\n animation: `fade-pulse ${effectiveDuration} ease-in-out infinite`,\n animationDelay: `${delay}s`,\n }}\n />\n );\n })}\n </div>\n </div>\n );\n }\n);\n\nSpinnerGrid.displayName = 'SpinnerGrid';\n"],"names":["forwardRef","useReducedMotion","getEffectiveDuration","parseSizeToNumber","jsx","cn","normalizeSize"],"mappings":";;;;;;;AAeO,MAAM,cAAcA,MAAAA;AAAAA,EACzB,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,0BAA0B;AAAA,IAC1B;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,uBAAuBC,MAAAA,iBAAA;AAC7B,UAAM,oBAAoBC,MAAAA,qBAAqB,OAAO,yBAAyB,oBAAoB;AAEnG,UAAM,YAAYC,OAAAA,kBAAkB,MAAM,EAAE;AAC5C,UAAM,WAAW,KAAK,MAAM,YAAY,QAAQ,IAAI;AAEpD,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAWC,WAAAA,GAAG,2CAA2C,SAAS;AAAA,QAClE;AAAA,QACA,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,aAAU;AAAA,QACT,GAAG;AAAA,QAEJ,UAAAD,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,OAAOE,OAAAA,cAAc,IAAI;AAAA,cACzB,QAAQA,OAAAA,cAAc,IAAI;AAAA,cAC1B,qBAAqB,UAAU,QAAQ;AAAA,YAAA;AAAA,YAGxC,UAAA,MAAM,KAAK,EAAE,QAAQ,WAAW,SAAA,CAAU,EAAE,IAAI,CAAC,GAAG,UAAU;AAC7D,oBAAM,MAAM,KAAK,MAAM,QAAQ,QAAQ;AACvC,oBAAM,MAAM,QAAQ;AACpB,oBAAM,YAAY,WAAW,KAAK;AAClC,oBAAM,QAAQ,WAAW,YAAY,MAAM,QAAQ,OAAO,MAAM,OAAO;AAEvE,qBACEF,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,OAAO,GAAG,QAAQ;AAAA,oBAClB,QAAQ,GAAG,QAAQ;AAAA,oBACnB,iBAAiB;AAAA,oBACjB,WAAW,cAAc,iBAAiB;AAAA,oBAC1C,gBAAgB,GAAG,KAAK;AAAA,kBAAA;AAAA,gBAC1B;AAAA,gBARK;AAAA,cAAA;AAAA,YAWX,CAAC;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,YAAY,cAAc;;"}
package/dist/index18.js CHANGED
@@ -1,103 +1,76 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { forwardRef, useMemo } from "react";
3
- import { normalizeSize, getAnimationDuration, getContrastColor } from "./index4.js";
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { useReducedMotion, getEffectiveDuration } from "./index31.js";
4
4
  import { cn } from "./index3.js";
5
- const ProgressBar = forwardRef(
5
+ import { normalizeSize, parseSizeToNumber } from "./index4.js";
6
+ const SpinnerGrid = forwardRef(
6
7
  ({
7
- value = 0,
8
- indeterminate = false,
9
- showValue = false,
10
- height = "0.5rem",
8
+ size = "md",
11
9
  color = "#3b82f6",
12
- secondaryColor = "#e0e0e0",
13
- gradient = false,
14
- buffer,
10
+ gridSize = 3,
15
11
  speed = "normal",
12
+ reverse = false,
13
+ respectMotionPreference = true,
16
14
  className,
17
15
  style,
18
- testId = "progress-bar",
16
+ testId = "spinner-grid",
19
17
  visible = true,
20
- ariaLabel,
18
+ ariaLabel = "Loading...",
21
19
  ...rest
22
20
  }, ref) => {
23
21
  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}%`;
27
- const animationDuration = getAnimationDuration(speed);
28
- const gradientId = useMemo(() => `progress-bar-gradient-${Math.random().toString(36).substr(2, 9)}`, []);
29
- return /* @__PURE__ */ jsxs(
22
+ const prefersReducedMotion = useReducedMotion();
23
+ const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
24
+ const sizeValue = parseSizeToNumber(size, 40);
25
+ const cellSize = Math.floor(sizeValue / gridSize) - 2;
26
+ return /* @__PURE__ */ jsx(
30
27
  "div",
31
28
  {
32
29
  ref,
33
30
  "data-testid": testId,
34
- className: cn("relative w-full overflow-hidden rounded-full", className),
35
- style: {
36
- height: normalizeSize(height),
37
- backgroundColor: secondaryColor,
38
- ...style
39
- },
40
- role: "progressbar",
41
- "aria-label": progressLabel,
42
- "aria-valuenow": indeterminate ? void 0 : clampedValue,
43
- "aria-valuemin": 0,
44
- "aria-valuemax": 100,
31
+ className: cn("inline-flex items-center justify-center", className),
32
+ style,
33
+ role: "status",
34
+ "aria-label": ariaLabel,
35
+ "aria-busy": "true",
45
36
  ...rest,
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
- }
59
- }
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
- ]
37
+ children: /* @__PURE__ */ jsx(
38
+ "div",
39
+ {
40
+ className: "grid gap-0.5",
41
+ style: {
42
+ width: normalizeSize(size),
43
+ height: normalizeSize(size),
44
+ gridTemplateColumns: `repeat(${gridSize}, 1fr)`
45
+ },
46
+ children: Array.from({ length: gridSize * gridSize }).map((_, index) => {
47
+ const row = Math.floor(index / gridSize);
48
+ const col = index % gridSize;
49
+ const maxDelay = (gridSize - 1) * 2;
50
+ const delay = reverse ? (maxDelay - (row + col)) * 0.1 : (row + col) * 0.1;
51
+ return /* @__PURE__ */ jsx(
52
+ "div",
53
+ {
54
+ className: "rounded-sm",
55
+ style: {
56
+ width: `${cellSize}px`,
57
+ height: `${cellSize}px`,
58
+ backgroundColor: color,
59
+ animation: `fade-pulse ${effectiveDuration} ease-in-out infinite`,
60
+ animationDelay: `${delay}s`
61
+ }
62
+ },
63
+ index
64
+ );
65
+ })
66
+ }
67
+ )
95
68
  }
96
69
  );
97
70
  }
98
71
  );
99
- ProgressBar.displayName = "ProgressBar";
72
+ SpinnerGrid.displayName = "SpinnerGrid";
100
73
  export {
101
- ProgressBar
74
+ SpinnerGrid
102
75
  };
103
76
  //# sourceMappingURL=index18.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index18.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;"}
1
+ {"version":3,"file":"index18.js","sources":["../src/components/spinner/SpinnerGrid.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerGridProps } from '../../types';\nimport { cn, normalizeSize, parseSizeToNumber, useReducedMotion, getEffectiveDuration } from '../../utils';\n\n/**\n * SpinnerGrid - Grid of fading squares\n *\n * A spinner with a grid of squares that fade in and out in a pattern.\n *\n * @example\n * ```tsx\n * <SpinnerGrid size=\"lg\" color=\"#3b82f6\" />\n * <SpinnerGrid size=\"md\" gridSize={4} reverse />\n * ```\n */\nexport const SpinnerGrid = forwardRef<HTMLDivElement, SpinnerGridProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n gridSize = 3,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n className,\n style,\n testId = 'spinner-grid',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n if (!visible) return null;\n\n const prefersReducedMotion = useReducedMotion();\n const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);\n\n const sizeValue = parseSizeToNumber(size, 40);\n const cellSize = Math.floor(sizeValue / gridSize) - 2;\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=\"grid gap-0.5\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n gridTemplateColumns: `repeat(${gridSize}, 1fr)`,\n }}\n >\n {Array.from({ length: gridSize * gridSize }).map((_, index) => {\n const row = Math.floor(index / gridSize);\n const col = index % gridSize;\n const maxDelay = (gridSize - 1) * 2;\n const delay = reverse ? (maxDelay - (row + col)) * 0.1 : (row + col) * 0.1;\n\n return (\n <div\n key={index}\n className=\"rounded-sm\"\n style={{\n width: `${cellSize}px`,\n height: `${cellSize}px`,\n backgroundColor: color,\n animation: `fade-pulse ${effectiveDuration} ease-in-out infinite`,\n animationDelay: `${delay}s`,\n }}\n />\n );\n })}\n </div>\n </div>\n );\n }\n);\n\nSpinnerGrid.displayName = 'SpinnerGrid';\n"],"names":[],"mappings":";;;;;AAeO,MAAM,cAAc;AAAA,EACzB,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,0BAA0B;AAAA,IAC1B;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,uBAAuB,iBAAA;AAC7B,UAAM,oBAAoB,qBAAqB,OAAO,yBAAyB,oBAAoB;AAEnG,UAAM,YAAY,kBAAkB,MAAM,EAAE;AAC5C,UAAM,WAAW,KAAK,MAAM,YAAY,QAAQ,IAAI;AAEpD,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,cAAc,IAAI;AAAA,cACzB,QAAQ,cAAc,IAAI;AAAA,cAC1B,qBAAqB,UAAU,QAAQ;AAAA,YAAA;AAAA,YAGxC,UAAA,MAAM,KAAK,EAAE,QAAQ,WAAW,SAAA,CAAU,EAAE,IAAI,CAAC,GAAG,UAAU;AAC7D,oBAAM,MAAM,KAAK,MAAM,QAAQ,QAAQ;AACvC,oBAAM,MAAM,QAAQ;AACpB,oBAAM,YAAY,WAAW,KAAK;AAClC,oBAAM,QAAQ,WAAW,YAAY,MAAM,QAAQ,OAAO,MAAM,OAAO;AAEvE,qBACE;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,OAAO,GAAG,QAAQ;AAAA,oBAClB,QAAQ,GAAG,QAAQ;AAAA,oBACnB,iBAAiB;AAAA,oBACjB,WAAW,cAAc,iBAAiB;AAAA,oBAC1C,gBAAgB,GAAG,KAAK;AAAA,kBAAA;AAAA,gBAC1B;AAAA,gBARK;AAAA,cAAA;AAAA,YAWX,CAAC;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,YAAY,cAAc;"}
package/dist/index19.cjs CHANGED
@@ -2,128 +2,69 @@
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");
5
+ const hooks = require("./index31.cjs");
6
6
  const classNames = require("./index3.cjs");
7
- const ProgressCircle = react.forwardRef(
7
+ const colors = require("./index4.cjs");
8
+ const SpinnerWave = react.forwardRef(
8
9
  ({
9
- value = 0,
10
- indeterminate = false,
11
- showValue = false,
12
- size = 60,
13
- thickness = 4,
10
+ size = "md",
14
11
  color = "#3b82f6",
15
- secondaryColor = "#e0e0e0",
16
- buffer,
12
+ ripples = 3,
13
+ maxScale = 2,
17
14
  speed = "normal",
15
+ reverse = false,
16
+ respectMotionPreference = true,
18
17
  className,
19
18
  style,
20
- testId = "progress-circle",
19
+ testId = "spinner-wave",
21
20
  visible = true,
22
- ariaLabel,
21
+ ariaLabel = "Loading...",
23
22
  ...rest
24
23
  }, ref) => {
25
24
  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 sizeValue = colors.parseSizeToNumber(size, 60);
29
- const thicknessValue = colors.parseSizeToNumber(thickness, 4);
30
- const radius = (sizeValue - thicknessValue * 2) / 2;
31
- const circumference = 2 * Math.PI * radius;
32
- const strokeDashoffset = circumference - clampedValue / 100 * circumference;
33
- const bufferDashoffset = clampedBuffer !== void 0 ? circumference - clampedBuffer / 100 * circumference : void 0;
34
- const progressLabel = ariaLabel || `Loading ${clampedValue}%`;
35
- const animationDuration = colors.getAnimationDuration(speed);
36
- return /* @__PURE__ */ jsxRuntime.jsxs(
25
+ const prefersReducedMotion = hooks.useReducedMotion();
26
+ const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
27
+ const sizeValue = colors.normalizeSize(size);
28
+ return /* @__PURE__ */ jsxRuntime.jsx(
37
29
  "div",
38
30
  {
39
31
  ref,
40
32
  "data-testid": testId,
41
- className: classNames.cn("inline-flex items-center justify-center relative", className),
42
- style: {
43
- width: colors.normalizeSize(size),
44
- height: colors.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,
33
+ className: classNames.cn("inline-flex items-center justify-center", className),
34
+ style,
35
+ role: "status",
36
+ "aria-label": ariaLabel,
37
+ "aria-busy": "true",
52
38
  ...rest,
53
- children: [
54
- /* @__PURE__ */ jsxRuntime.jsxs(
55
- "svg",
56
- {
57
- className: classNames.cn(indeterminate && "animate-spinner-rotate"),
39
+ children: /* @__PURE__ */ jsxRuntime.jsx(
40
+ "div",
41
+ {
42
+ className: "relative",
43
+ style: {
58
44
  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
- /* @__PURE__ */ jsxRuntime.jsx(
64
- "circle",
65
- {
66
- cx: sizeValue / 2,
67
- cy: sizeValue / 2,
68
- r: radius,
69
- fill: "none",
70
- stroke: secondaryColor,
71
- strokeWidth: thicknessValue
72
- }
73
- ),
74
- bufferDashoffset !== void 0 && !indeterminate && /* @__PURE__ */ jsxRuntime.jsx(
75
- "circle",
76
- {
77
- cx: sizeValue / 2,
78
- cy: sizeValue / 2,
79
- r: radius,
80
- fill: "none",
81
- stroke: color,
82
- strokeWidth: thicknessValue,
83
- strokeLinecap: "round",
84
- strokeDasharray: circumference,
85
- strokeDashoffset: bufferDashoffset,
86
- transform: `rotate(-90 ${sizeValue / 2} ${sizeValue / 2})`,
87
- opacity: 0.3
88
- }
89
- ),
90
- /* @__PURE__ */ jsxRuntime.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: indeterminate ? circumference * 0.75 : strokeDashoffset,
102
- transform: `rotate(-90 ${sizeValue / 2} ${sizeValue / 2})`,
103
- style: {
104
- transition: indeterminate ? "none" : "stroke-dashoffset 0.3s ease-in-out"
105
- }
106
- }
107
- )
108
- ]
109
- }
110
- ),
111
- showValue && !indeterminate && /* @__PURE__ */ jsxRuntime.jsxs(
112
- "span",
113
- {
114
- className: "absolute text-sm font-medium",
115
- style: { color },
116
- children: [
117
- clampedValue,
118
- "%"
119
- ]
120
- }
121
- )
122
- ]
45
+ height: sizeValue
46
+ },
47
+ children: Array.from({ length: ripples }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
48
+ "div",
49
+ {
50
+ className: "absolute inset-0 rounded-full border-2",
51
+ style: {
52
+ borderColor: color,
53
+ animation: `ripple-expand ${effectiveDuration} ease-out infinite`,
54
+ animationDelay: reverse ? `${(ripples - index - 1) * 0.4}s` : `${index * 0.4}s`,
55
+ animationDirection: reverse ? "reverse" : "normal",
56
+ // @ts-ignore - CSS variable for animation
57
+ "--max-scale": maxScale
58
+ }
59
+ },
60
+ index
61
+ ))
62
+ }
63
+ )
123
64
  }
124
65
  );
125
66
  }
126
67
  );
127
- ProgressCircle.displayName = "ProgressCircle";
128
- exports.ProgressCircle = ProgressCircle;
68
+ SpinnerWave.displayName = "SpinnerWave";
69
+ exports.SpinnerWave = SpinnerWave;
129
70
  //# sourceMappingURL=index19.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index19.cjs","sources":["../src/components/progress/ProgressCircle.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { ProgressCircleProps } from '../../types';\nimport { cn, normalizeSize, parseSizeToNumber, getAnimationDuration } from '../../utils';\n\n/**\n * ProgressCircle - SVG-based circular progress indicator\n *\n * A circular progress indicator that shows progress as a partial circle.\n *\n * @example\n * ```tsx\n * <ProgressCircle value={75} showValue />\n * <ProgressCircle value={50} size={80} thickness={6} />\n * <ProgressCircle indeterminate speed=\"fast\" />\n * <ProgressCircle value={50} buffer={75} />\n * ```\n */\nexport const ProgressCircle = forwardRef<HTMLDivElement, ProgressCircleProps>(\n (\n {\n value = 0,\n indeterminate = false,\n showValue = false,\n size = 60,\n thickness = 4,\n color = '#3b82f6',\n secondaryColor = '#e0e0e0',\n buffer,\n speed = 'normal',\n className,\n style,\n testId = 'progress-circle',\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\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 {/* Background circle */}\n <circle\n cx={sizeValue / 2}\n cy={sizeValue / 2}\n r={radius}\n fill=\"none\"\n stroke={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={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={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-medium\"\n style={{ color }}\n >\n {clampedValue}%\n </span>\n )}\n </div>\n );\n }\n);\n\nProgressCircle.displayName = 'ProgressCircle';\n"],"names":["forwardRef","parseSizeToNumber","getAnimationDuration","jsxs","cn","normalizeSize","jsx"],"mappings":";;;;;;AAiBO,MAAM,iBAAiBA,MAAAA;AAAAA,EAC5B,CACE;AAAA,IACE,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB;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,YAAYC,OAAAA,kBAAkB,MAAM,EAAE;AAC5C,UAAM,iBAAiBA,OAAAA,kBAAkB,WAAW,CAAC;AACrD,UAAM,UAAU,YAAY,iBAAiB,KAAK;AAClD,UAAM,gBAAgB,IAAI,KAAK,KAAK;AACpC,UAAM,mBAAmB,gBAAiB,eAAe,MAAO;AAChE,UAAM,mBAAmB,kBAAkB,SAAY,gBAAiB,gBAAgB,MAAO,gBAAgB;AAC/G,UAAM,gBAAgB,aAAa,WAAW,YAAY;AAC1D,UAAM,oBAAoBC,OAAAA,qBAAqB,KAAK;AAEpD,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAWC,WAAAA,GAAG,oDAAoD,SAAS;AAAA,QAC3E,OAAO;AAAA,UACL,OAAOC,OAAAA,cAAc,IAAI;AAAA,UACzB,QAAQA,OAAAA,cAAc,IAAI;AAAA,UAC1B,GAAG;AAAA,QAAA;AAAA,QAEL,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,iBAAe,gBAAgB,SAAY;AAAA,QAC3C,iBAAe;AAAA,QACf,iBAAe;AAAA,QACd,GAAG;AAAA,QAEJ,UAAA;AAAA,UAAAF,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWC,WAAAA,GAAG,iBAAiB,wBAAwB;AAAA,cACvD,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,SAAS,OAAO,SAAS,IAAI,SAAS;AAAA,cACtC,OAAO,gBAAgB,EAAE,WAAW,kBAAkB,iBAAiB,uBAAuB;AAAA,cAG9F,UAAA;AAAA,gBAAAE,2BAAAA;AAAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,IAAI,YAAY;AAAA,oBAChB,IAAI,YAAY;AAAA,oBAChB,GAAG;AAAA,oBACH,MAAK;AAAA,oBACL,QAAQ;AAAA,oBACR,aAAa;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAGd,qBAAqB,UAAa,CAAC,iBAClCA,2BAAAA;AAAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,IAAI,YAAY;AAAA,oBAChB,IAAI,YAAY;AAAA,oBAChB,GAAG;AAAA,oBACH,MAAK;AAAA,oBACL,QAAQ;AAAA,oBACR,aAAa;AAAA,oBACb,eAAc;AAAA,oBACd,iBAAiB;AAAA,oBACjB,kBAAkB;AAAA,oBAClB,WAAW,cAAc,YAAY,CAAC,IAAI,YAAY,CAAC;AAAA,oBACvD,SAAS;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAIbA,2BAAAA;AAAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,IAAI,YAAY;AAAA,oBAChB,IAAI,YAAY;AAAA,oBAChB,GAAG;AAAA,oBACH,MAAK;AAAA,oBACL,QAAQ;AAAA,oBACR,aAAa;AAAA,oBACb,eAAc;AAAA,oBACd,iBAAiB;AAAA,oBACjB,kBAAkB,gBAAgB,gBAAgB,OAAO;AAAA,oBACzD,WAAW,cAAc,YAAY,CAAC,IAAI,YAAY,CAAC;AAAA,oBACvD,OAAO;AAAA,sBACL,YAAY,gBAAgB,SAAS;AAAA,oBAAA;AAAA,kBACvC;AAAA,gBAAA;AAAA,cACF;AAAA,YAAA;AAAA,UAAA;AAAA,UAED,aAAa,CAAC,iBACbH,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,MAAA;AAAA,cAER,UAAA;AAAA,gBAAA;AAAA,gBAAa;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAChB;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,eAAe,cAAc;;"}
1
+ {"version":3,"file":"index19.cjs","sources":["../src/components/spinner/SpinnerWave.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerWaveProps } from '../../types';\nimport { cn, normalizeSize, useReducedMotion, getEffectiveDuration } from '../../utils';\n\n/**\n * SpinnerWave - Ripple wave spinner\n *\n * A spinner with expanding ripple circles creating a wave effect.\n *\n * @example\n * ```tsx\n * <SpinnerWave size=\"lg\" color=\"#3b82f6\" />\n * <SpinnerWave size=\"xl\" ripples={5} reverse />\n * <SpinnerWave size=\"md\" maxScale={2.5} speed=\"fast\" />\n * ```\n */\nexport const SpinnerWave = forwardRef<HTMLDivElement, SpinnerWaveProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n ripples = 3,\n maxScale = 2,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n className,\n style,\n testId = 'spinner-wave',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n if (!visible) return null;\n\n const prefersReducedMotion = useReducedMotion();\n const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);\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 {/* Expanding ripples */}\n {Array.from({ length: ripples }).map((_, index) => (\n <div\n key={index}\n className=\"absolute inset-0 rounded-full border-2\"\n style={{\n borderColor: color,\n animation: `ripple-expand ${effectiveDuration} ease-out infinite`,\n animationDelay: reverse ? `${(ripples - index - 1) * 0.4}s` : `${index * 0.4}s`,\n animationDirection: reverse ? 'reverse' : 'normal',\n // @ts-ignore - CSS variable for animation\n '--max-scale': maxScale,\n }}\n />\n ))}\n </div>\n </div>\n );\n }\n);\n\nSpinnerWave.displayName = 'SpinnerWave';\n"],"names":["forwardRef","useReducedMotion","getEffectiveDuration","normalizeSize","jsx","cn"],"mappings":";;;;;;;AAgBO,MAAM,cAAcA,MAAAA;AAAAA,EACzB,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,0BAA0B;AAAA,IAC1B;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,uBAAuBC,MAAAA,iBAAA;AAC7B,UAAM,oBAAoBC,MAAAA,qBAAqB,OAAO,yBAAyB,oBAAoB;AACnG,UAAM,YAAYC,OAAAA,cAAc,IAAI;AAEpC,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAWC,WAAAA,GAAG,2CAA2C,SAAS;AAAA,QAClE;AAAA,QACA,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,aAAU;AAAA,QACT,GAAG;AAAA,QAEJ,UAAAD,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,OAAO;AAAA,cACP,QAAQ;AAAA,YAAA;AAAA,YAIT,UAAA,MAAM,KAAK,EAAE,QAAQ,SAAS,EAAE,IAAI,CAAC,GAAG,UACvCA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,aAAa;AAAA,kBACb,WAAW,iBAAiB,iBAAiB;AAAA,kBAC7C,gBAAgB,UAAU,IAAI,UAAU,QAAQ,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG;AAAA,kBAC5E,oBAAoB,UAAU,YAAY;AAAA;AAAA,kBAE1C,eAAe;AAAA,gBAAA;AAAA,cACjB;AAAA,cATK;AAAA,YAAA,CAWR;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,YAAY,cAAc;;"}