premium-react-loaders 1.2.0 → 1.3.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 (135) hide show
  1. package/dist/components/overlay/LoaderOverlay.d.ts.map +1 -1
  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.map +1 -1
  6. package/dist/components/pulse/PulseBars.d.ts.map +1 -1
  7. package/dist/components/pulse/PulseDots.d.ts.map +1 -1
  8. package/dist/components/pulse/PulseWave.d.ts.map +1 -1
  9. package/dist/components/pulse/TypingIndicator.d.ts.map +1 -1
  10. package/dist/components/skeleton/Skeleton.d.ts.map +1 -1
  11. package/dist/components/skeleton/SkeletonAvatar.d.ts.map +1 -1
  12. package/dist/components/skeleton/SkeletonCard.d.ts.map +1 -1
  13. package/dist/components/skeleton/SkeletonForm.d.ts.map +1 -1
  14. package/dist/components/skeleton/SkeletonImage.d.ts.map +1 -1
  15. package/dist/components/skeleton/SkeletonList.d.ts.map +1 -1
  16. package/dist/components/skeleton/SkeletonPage.d.ts.map +1 -1
  17. package/dist/components/skeleton/SkeletonTable.d.ts.map +1 -1
  18. package/dist/components/skeleton/SkeletonText.d.ts.map +1 -1
  19. package/dist/components/spinner/SpinnerBars.d.ts.map +1 -1
  20. package/dist/components/spinner/SpinnerCircle.d.ts.map +1 -1
  21. package/dist/components/spinner/SpinnerDots.d.ts.map +1 -1
  22. package/dist/components/spinner/SpinnerGrid.d.ts.map +1 -1
  23. package/dist/components/spinner/SpinnerPulse.d.ts.map +1 -1
  24. package/dist/components/spinner/SpinnerRing.d.ts.map +1 -1
  25. package/dist/components/spinner/SpinnerWave.d.ts.map +1 -1
  26. package/dist/index10.cjs +14 -2
  27. package/dist/index10.cjs.map +1 -1
  28. package/dist/index10.js +14 -2
  29. package/dist/index10.js.map +1 -1
  30. package/dist/index11.cjs +16 -2
  31. package/dist/index11.cjs.map +1 -1
  32. package/dist/index11.js +16 -2
  33. package/dist/index11.js.map +1 -1
  34. package/dist/index12.cjs +16 -2
  35. package/dist/index12.cjs.map +1 -1
  36. package/dist/index12.js +16 -2
  37. package/dist/index12.js.map +1 -1
  38. package/dist/index13.cjs +12 -2
  39. package/dist/index13.cjs.map +1 -1
  40. package/dist/index13.js +12 -2
  41. package/dist/index13.js.map +1 -1
  42. package/dist/index14.cjs +15 -2
  43. package/dist/index14.cjs.map +1 -1
  44. package/dist/index14.js +16 -3
  45. package/dist/index14.js.map +1 -1
  46. package/dist/index15.cjs +15 -2
  47. package/dist/index15.cjs.map +1 -1
  48. package/dist/index15.js +16 -3
  49. package/dist/index15.js.map +1 -1
  50. package/dist/index16.cjs +15 -2
  51. package/dist/index16.cjs.map +1 -1
  52. package/dist/index16.js +16 -3
  53. package/dist/index16.js.map +1 -1
  54. package/dist/index17.cjs +13 -2
  55. package/dist/index17.cjs.map +1 -1
  56. package/dist/index17.js +14 -3
  57. package/dist/index17.js.map +1 -1
  58. package/dist/index18.cjs +17 -4
  59. package/dist/index18.cjs.map +1 -1
  60. package/dist/index18.js +18 -5
  61. package/dist/index18.js.map +1 -1
  62. package/dist/index19.cjs +15 -2
  63. package/dist/index19.cjs.map +1 -1
  64. package/dist/index19.js +16 -3
  65. package/dist/index19.js.map +1 -1
  66. package/dist/index20.cjs +15 -2
  67. package/dist/index20.cjs.map +1 -1
  68. package/dist/index20.js +16 -3
  69. package/dist/index20.js.map +1 -1
  70. package/dist/index21.cjs +14 -3
  71. package/dist/index21.cjs.map +1 -1
  72. package/dist/index21.js +15 -4
  73. package/dist/index21.js.map +1 -1
  74. package/dist/index22.cjs +13 -2
  75. package/dist/index22.cjs.map +1 -1
  76. package/dist/index22.js +14 -3
  77. package/dist/index22.js.map +1 -1
  78. package/dist/index23.cjs +14 -3
  79. package/dist/index23.cjs.map +1 -1
  80. package/dist/index23.js +15 -4
  81. package/dist/index23.js.map +1 -1
  82. package/dist/index24.cjs +16 -2
  83. package/dist/index24.cjs.map +1 -1
  84. package/dist/index24.js +16 -2
  85. package/dist/index24.js.map +1 -1
  86. package/dist/index25.cjs +13 -2
  87. package/dist/index25.cjs.map +1 -1
  88. package/dist/index25.js +14 -3
  89. package/dist/index25.js.map +1 -1
  90. package/dist/index26.cjs +15 -4
  91. package/dist/index26.cjs.map +1 -1
  92. package/dist/index26.js +16 -5
  93. package/dist/index26.js.map +1 -1
  94. package/dist/index27.cjs +15 -4
  95. package/dist/index27.cjs.map +1 -1
  96. package/dist/index27.js +16 -5
  97. package/dist/index27.js.map +1 -1
  98. package/dist/index28.cjs +13 -2
  99. package/dist/index28.cjs.map +1 -1
  100. package/dist/index28.js +14 -3
  101. package/dist/index28.js.map +1 -1
  102. package/dist/index29.cjs +14 -2
  103. package/dist/index29.cjs.map +1 -1
  104. package/dist/index29.js +14 -2
  105. package/dist/index29.js.map +1 -1
  106. package/dist/index31.cjs +84 -0
  107. package/dist/index31.cjs.map +1 -1
  108. package/dist/index31.js +85 -1
  109. package/dist/index31.js.map +1 -1
  110. package/dist/index5.cjs +14 -2
  111. package/dist/index5.cjs.map +1 -1
  112. package/dist/index5.js +14 -2
  113. package/dist/index5.js.map +1 -1
  114. package/dist/index6.cjs +14 -2
  115. package/dist/index6.cjs.map +1 -1
  116. package/dist/index6.js +14 -2
  117. package/dist/index6.js.map +1 -1
  118. package/dist/index7.cjs +16 -2
  119. package/dist/index7.cjs.map +1 -1
  120. package/dist/index7.js +16 -2
  121. package/dist/index7.js.map +1 -1
  122. package/dist/index8.cjs +14 -2
  123. package/dist/index8.cjs.map +1 -1
  124. package/dist/index8.js +14 -2
  125. package/dist/index8.js.map +1 -1
  126. package/dist/index9.cjs +16 -2
  127. package/dist/index9.cjs.map +1 -1
  128. package/dist/index9.js +16 -2
  129. package/dist/index9.js.map +1 -1
  130. package/dist/premium-react-loaders.css +136 -4
  131. package/dist/types/common.d.ts +6 -0
  132. package/dist/types/common.d.ts.map +1 -1
  133. package/dist/utils/hooks.d.ts +9 -0
  134. package/dist/utils/hooks.d.ts.map +1 -1
  135. package/package.json +1 -1
package/dist/index17.cjs CHANGED
@@ -13,6 +13,9 @@ const SpinnerBars = react.forwardRef(
13
13
  speed = "normal",
14
14
  reverse = false,
15
15
  respectMotionPreference = true,
16
+ delay = 0,
17
+ minDuration = 0,
18
+ transition,
16
19
  className,
17
20
  style,
18
21
  testId = "spinner-bars",
@@ -20,9 +23,15 @@ const SpinnerBars = react.forwardRef(
20
23
  ariaLabel = "Loading...",
21
24
  ...rest
22
25
  }, ref) => {
23
- if (!visible) return null;
24
26
  const prefersReducedMotion = hooks.useReducedMotion();
25
27
  const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
28
+ const { shouldRender, opacity, transitionStyle } = hooks.useLoaderVisibility(
29
+ visible,
30
+ delay,
31
+ minDuration,
32
+ transition
33
+ );
34
+ if (!shouldRender) return null;
26
35
  const sizeValue = colors.parseSizeToNumber(size, 40);
27
36
  const barWidth = Math.floor(sizeValue / (barCount * 2));
28
37
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -33,7 +42,9 @@ const SpinnerBars = react.forwardRef(
33
42
  className: classNames.cn("inline-flex items-center justify-center gap-1", className),
34
43
  style: {
35
44
  height: colors.normalizeSize(size),
36
- ...style
45
+ ...style,
46
+ opacity,
47
+ transition: transitionStyle
37
48
  },
38
49
  role: "status",
39
50
  "aria-label": ariaLabel,
@@ -1 +1 @@
1
- {"version":3,"file":"index17.cjs","sources":["../src/components/spinner/SpinnerBars.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerBarsProps } from '../../types';\nimport { cn, normalizeSize, parseSizeToNumber, useReducedMotion, getEffectiveDuration } from '../../utils';\n\n/**\n * SpinnerBars - Vertical bars with wave animation\n *\n * A spinner with vertical bars that animate in a wave pattern.\n *\n * @example\n * ```tsx\n * <SpinnerBars size=\"lg\" color=\"#3b82f6\" />\n * <SpinnerBars size=\"sm\" barCount={5} speed=\"fast\" reverse />\n * ```\n */\nexport const SpinnerBars = forwardRef<HTMLDivElement, SpinnerBarsProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n barCount = 5,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n className,\n style,\n testId = 'spinner-bars',\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 barWidth = Math.floor(sizeValue / (barCount * 2));\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('inline-flex items-center justify-center gap-1', 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: barCount }).map((_, index) => (\n <div\n key={index}\n className=\"rounded-sm\"\n style={{\n width: `${barWidth}px`,\n height: '100%',\n backgroundColor: color,\n animation: `pulse-wave ${effectiveDuration} ease-in-out infinite`,\n animationDelay: reverse ? `${(barCount - index - 1) * 0.1}s` : `${index * 0.1}s`,\n }}\n />\n ))}\n </div>\n );\n }\n);\n\nSpinnerBars.displayName = 'SpinnerBars';\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,aAAa,WAAW,EAAE;AAEtD,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,OAAO,GAAG,QAAQ;AAAA,cAClB,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,WAAW,cAAc,iBAAiB;AAAA,cAC1C,gBAAgB,UAAU,IAAI,WAAW,QAAQ,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG;AAAA,YAAA;AAAA,UAC/E;AAAA,UARK;AAAA,QAAA,CAUR;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEA,YAAY,cAAc;;"}
1
+ {"version":3,"file":"index17.cjs","sources":["../src/components/spinner/SpinnerBars.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerBarsProps } from '../../types';\nimport {\n cn,\n normalizeSize,\n parseSizeToNumber,\n useReducedMotion,\n getEffectiveDuration,\n useLoaderVisibility,\n} from '../../utils';\n\n/**\n * SpinnerBars - Vertical bars with wave animation\n *\n * A spinner with vertical bars that animate in a wave pattern.\n *\n * @example\n * ```tsx\n * <SpinnerBars size=\"lg\" color=\"#3b82f6\" />\n * <SpinnerBars size=\"sm\" barCount={5} speed=\"fast\" reverse />\n * ```\n */\nexport const SpinnerBars = forwardRef<HTMLDivElement, SpinnerBarsProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n barCount = 5,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-bars',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n const prefersReducedMotion = useReducedMotion();\n const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);\n const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(\n visible,\n delay,\n minDuration,\n transition\n );\n\n if (!shouldRender) return null;\n\n const sizeValue = parseSizeToNumber(size, 40);\n const barWidth = Math.floor(sizeValue / (barCount * 2));\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('inline-flex items-center justify-center gap-1', className)}\n style={{\n height: normalizeSize(size),\n ...style,\n opacity,\n transition: transitionStyle,\n }}\n role=\"status\"\n aria-label={ariaLabel}\n aria-busy=\"true\"\n {...rest}\n >\n {Array.from({ length: barCount }).map((_, index) => (\n <div\n key={index}\n className=\"rounded-sm\"\n style={{\n width: `${barWidth}px`,\n height: '100%',\n backgroundColor: color,\n animation: `pulse-wave ${effectiveDuration} ease-in-out infinite`,\n animationDelay: reverse ? `${(barCount - index - 1) * 0.1}s` : `${index * 0.1}s`,\n }}\n />\n ))}\n </div>\n );\n }\n);\n\nSpinnerBars.displayName = 'SpinnerBars';\n"],"names":["forwardRef","useReducedMotion","getEffectiveDuration","useLoaderVisibility","parseSizeToNumber","jsx","cn","normalizeSize"],"mappings":";;;;;;;AAsBO,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,QAAQ;AAAA,IACR,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,uBAAuBC,MAAAA,iBAAA;AAC7B,UAAM,oBAAoBC,MAAAA,qBAAqB,OAAO,yBAAyB,oBAAoB;AACnG,UAAM,EAAE,cAAc,SAAS,gBAAA,IAAoBC,MAAAA;AAAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,CAAC,aAAc,QAAO;AAE1B,UAAM,YAAYC,OAAAA,kBAAkB,MAAM,EAAE;AAC5C,UAAM,WAAW,KAAK,MAAM,aAAa,WAAW,EAAE;AAEtD,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,UACH;AAAA,UACA,YAAY;AAAA,QAAA;AAAA,QAEd,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,OAAO,GAAG,QAAQ;AAAA,cAClB,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,WAAW,cAAc,iBAAiB;AAAA,cAC1C,gBAAgB,UAAU,IAAI,WAAW,QAAQ,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG;AAAA,YAAA;AAAA,UAC/E;AAAA,UARK;AAAA,QAAA,CAUR;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEA,YAAY,cAAc;;"}
package/dist/index17.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
- import { useReducedMotion, getEffectiveDuration } from "./index31.js";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index31.js";
4
4
  import { normalizeSize, parseSizeToNumber } from "./index4.js";
5
5
  import { cn } from "./index3.js";
6
6
  const SpinnerBars = forwardRef(
@@ -11,6 +11,9 @@ const SpinnerBars = forwardRef(
11
11
  speed = "normal",
12
12
  reverse = false,
13
13
  respectMotionPreference = true,
14
+ delay = 0,
15
+ minDuration = 0,
16
+ transition,
14
17
  className,
15
18
  style,
16
19
  testId = "spinner-bars",
@@ -18,9 +21,15 @@ const SpinnerBars = forwardRef(
18
21
  ariaLabel = "Loading...",
19
22
  ...rest
20
23
  }, ref) => {
21
- if (!visible) return null;
22
24
  const prefersReducedMotion = useReducedMotion();
23
25
  const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
26
+ const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(
27
+ visible,
28
+ delay,
29
+ minDuration,
30
+ transition
31
+ );
32
+ if (!shouldRender) return null;
24
33
  const sizeValue = parseSizeToNumber(size, 40);
25
34
  const barWidth = Math.floor(sizeValue / (barCount * 2));
26
35
  return /* @__PURE__ */ jsx(
@@ -31,7 +40,9 @@ const SpinnerBars = forwardRef(
31
40
  className: cn("inline-flex items-center justify-center gap-1", className),
32
41
  style: {
33
42
  height: normalizeSize(size),
34
- ...style
43
+ ...style,
44
+ opacity,
45
+ transition: transitionStyle
35
46
  },
36
47
  role: "status",
37
48
  "aria-label": ariaLabel,
@@ -1 +1 @@
1
- {"version":3,"file":"index17.js","sources":["../src/components/spinner/SpinnerBars.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerBarsProps } from '../../types';\nimport { cn, normalizeSize, parseSizeToNumber, useReducedMotion, getEffectiveDuration } from '../../utils';\n\n/**\n * SpinnerBars - Vertical bars with wave animation\n *\n * A spinner with vertical bars that animate in a wave pattern.\n *\n * @example\n * ```tsx\n * <SpinnerBars size=\"lg\" color=\"#3b82f6\" />\n * <SpinnerBars size=\"sm\" barCount={5} speed=\"fast\" reverse />\n * ```\n */\nexport const SpinnerBars = forwardRef<HTMLDivElement, SpinnerBarsProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n barCount = 5,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n className,\n style,\n testId = 'spinner-bars',\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 barWidth = Math.floor(sizeValue / (barCount * 2));\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('inline-flex items-center justify-center gap-1', 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: barCount }).map((_, index) => (\n <div\n key={index}\n className=\"rounded-sm\"\n style={{\n width: `${barWidth}px`,\n height: '100%',\n backgroundColor: color,\n animation: `pulse-wave ${effectiveDuration} ease-in-out infinite`,\n animationDelay: reverse ? `${(barCount - index - 1) * 0.1}s` : `${index * 0.1}s`,\n }}\n />\n ))}\n </div>\n );\n }\n);\n\nSpinnerBars.displayName = 'SpinnerBars';\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,aAAa,WAAW,EAAE;AAEtD,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,GAAG,QAAQ;AAAA,cAClB,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,WAAW,cAAc,iBAAiB;AAAA,cAC1C,gBAAgB,UAAU,IAAI,WAAW,QAAQ,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG;AAAA,YAAA;AAAA,UAC/E;AAAA,UARK;AAAA,QAAA,CAUR;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEA,YAAY,cAAc;"}
1
+ {"version":3,"file":"index17.js","sources":["../src/components/spinner/SpinnerBars.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerBarsProps } from '../../types';\nimport {\n cn,\n normalizeSize,\n parseSizeToNumber,\n useReducedMotion,\n getEffectiveDuration,\n useLoaderVisibility,\n} from '../../utils';\n\n/**\n * SpinnerBars - Vertical bars with wave animation\n *\n * A spinner with vertical bars that animate in a wave pattern.\n *\n * @example\n * ```tsx\n * <SpinnerBars size=\"lg\" color=\"#3b82f6\" />\n * <SpinnerBars size=\"sm\" barCount={5} speed=\"fast\" reverse />\n * ```\n */\nexport const SpinnerBars = forwardRef<HTMLDivElement, SpinnerBarsProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n barCount = 5,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-bars',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n const prefersReducedMotion = useReducedMotion();\n const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);\n const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(\n visible,\n delay,\n minDuration,\n transition\n );\n\n if (!shouldRender) return null;\n\n const sizeValue = parseSizeToNumber(size, 40);\n const barWidth = Math.floor(sizeValue / (barCount * 2));\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('inline-flex items-center justify-center gap-1', className)}\n style={{\n height: normalizeSize(size),\n ...style,\n opacity,\n transition: transitionStyle,\n }}\n role=\"status\"\n aria-label={ariaLabel}\n aria-busy=\"true\"\n {...rest}\n >\n {Array.from({ length: barCount }).map((_, index) => (\n <div\n key={index}\n className=\"rounded-sm\"\n style={{\n width: `${barWidth}px`,\n height: '100%',\n backgroundColor: color,\n animation: `pulse-wave ${effectiveDuration} ease-in-out infinite`,\n animationDelay: reverse ? `${(barCount - index - 1) * 0.1}s` : `${index * 0.1}s`,\n }}\n />\n ))}\n </div>\n );\n }\n);\n\nSpinnerBars.displayName = 'SpinnerBars';\n"],"names":[],"mappings":";;;;;AAsBO,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,QAAQ;AAAA,IACR,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,uBAAuB,iBAAA;AAC7B,UAAM,oBAAoB,qBAAqB,OAAO,yBAAyB,oBAAoB;AACnG,UAAM,EAAE,cAAc,SAAS,gBAAA,IAAoB;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,CAAC,aAAc,QAAO;AAE1B,UAAM,YAAY,kBAAkB,MAAM,EAAE;AAC5C,UAAM,WAAW,KAAK,MAAM,aAAa,WAAW,EAAE;AAEtD,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,UACH;AAAA,UACA,YAAY;AAAA,QAAA;AAAA,QAEd,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,GAAG,QAAQ;AAAA,cAClB,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,WAAW,cAAc,iBAAiB;AAAA,cAC1C,gBAAgB,UAAU,IAAI,WAAW,QAAQ,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG;AAAA,YAAA;AAAA,UAC/E;AAAA,UARK;AAAA,QAAA,CAUR;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEA,YAAY,cAAc;"}
package/dist/index18.cjs CHANGED
@@ -13,6 +13,9 @@ const SpinnerGrid = react.forwardRef(
13
13
  speed = "normal",
14
14
  reverse = false,
15
15
  respectMotionPreference = true,
16
+ delay = 0,
17
+ minDuration = 0,
18
+ transition,
16
19
  className,
17
20
  style,
18
21
  testId = "spinner-grid",
@@ -20,9 +23,15 @@ const SpinnerGrid = react.forwardRef(
20
23
  ariaLabel = "Loading...",
21
24
  ...rest
22
25
  }, ref) => {
23
- if (!visible) return null;
24
26
  const prefersReducedMotion = hooks.useReducedMotion();
25
27
  const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
28
+ const { shouldRender, opacity, transitionStyle } = hooks.useLoaderVisibility(
29
+ visible,
30
+ delay,
31
+ minDuration,
32
+ transition
33
+ );
34
+ if (!shouldRender) return null;
26
35
  const sizeValue = colors.parseSizeToNumber(size, 40);
27
36
  const cellSize = Math.floor(sizeValue / gridSize) - 2;
28
37
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -31,7 +40,11 @@ const SpinnerGrid = react.forwardRef(
31
40
  ref,
32
41
  "data-testid": testId,
33
42
  className: classNames.cn("inline-flex items-center justify-center", className),
34
- style,
43
+ style: {
44
+ ...style,
45
+ opacity,
46
+ transition: transitionStyle
47
+ },
35
48
  role: "status",
36
49
  "aria-label": ariaLabel,
37
50
  "aria-busy": "true",
@@ -49,7 +62,7 @@ const SpinnerGrid = react.forwardRef(
49
62
  const row = Math.floor(index / gridSize);
50
63
  const col = index % gridSize;
51
64
  const maxDelay = (gridSize - 1) * 2;
52
- const delay = reverse ? (maxDelay - (row + col)) * 0.1 : (row + col) * 0.1;
65
+ const delay2 = reverse ? (maxDelay - (row + col)) * 0.1 : (row + col) * 0.1;
53
66
  return /* @__PURE__ */ jsxRuntime.jsx(
54
67
  "div",
55
68
  {
@@ -59,7 +72,7 @@ const SpinnerGrid = react.forwardRef(
59
72
  height: `${cellSize}px`,
60
73
  backgroundColor: color,
61
74
  animation: `fade-pulse ${effectiveDuration} ease-in-out infinite`,
62
- animationDelay: `${delay}s`
75
+ animationDelay: `${delay2}s`
63
76
  }
64
77
  },
65
78
  index
@@ -1 +1 @@
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;;"}
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, useLoaderVisibility } 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 delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-grid',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n const prefersReducedMotion = useReducedMotion();\n const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);\n const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(\n visible,\n delay,\n minDuration,\n transition\n );\n\n if (!shouldRender) return null;\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={{\n ...style,\n opacity,\n transition: transitionStyle,\n }}\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","useLoaderVisibility","parseSizeToNumber","jsx","cn","normalizeSize","delay"],"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,QAAQ;AAAA,IACR,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,uBAAuBC,MAAAA,iBAAA;AAC7B,UAAM,oBAAoBC,MAAAA,qBAAqB,OAAO,yBAAyB,oBAAoB;AACnG,UAAM,EAAE,cAAc,SAAS,gBAAA,IAAoBC,MAAAA;AAAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,CAAC,aAAc,QAAO;AAE1B,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,OAAO;AAAA,UACL,GAAG;AAAA,UACH;AAAA,UACA,YAAY;AAAA,QAAA;AAAA,QAEd,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,oBAAMC,SAAQ,WAAW,YAAY,MAAM,QAAQ,OAAO,MAAM,OAAO;AAEvE,qBACEH,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,GAAGG,MAAK;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,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
- import { useReducedMotion, getEffectiveDuration } from "./index31.js";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index31.js";
4
4
  import { cn } from "./index3.js";
5
5
  import { normalizeSize, parseSizeToNumber } from "./index4.js";
6
6
  const SpinnerGrid = forwardRef(
@@ -11,6 +11,9 @@ const SpinnerGrid = forwardRef(
11
11
  speed = "normal",
12
12
  reverse = false,
13
13
  respectMotionPreference = true,
14
+ delay = 0,
15
+ minDuration = 0,
16
+ transition,
14
17
  className,
15
18
  style,
16
19
  testId = "spinner-grid",
@@ -18,9 +21,15 @@ const SpinnerGrid = forwardRef(
18
21
  ariaLabel = "Loading...",
19
22
  ...rest
20
23
  }, ref) => {
21
- if (!visible) return null;
22
24
  const prefersReducedMotion = useReducedMotion();
23
25
  const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
26
+ const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(
27
+ visible,
28
+ delay,
29
+ minDuration,
30
+ transition
31
+ );
32
+ if (!shouldRender) return null;
24
33
  const sizeValue = parseSizeToNumber(size, 40);
25
34
  const cellSize = Math.floor(sizeValue / gridSize) - 2;
26
35
  return /* @__PURE__ */ jsx(
@@ -29,7 +38,11 @@ const SpinnerGrid = forwardRef(
29
38
  ref,
30
39
  "data-testid": testId,
31
40
  className: cn("inline-flex items-center justify-center", className),
32
- style,
41
+ style: {
42
+ ...style,
43
+ opacity,
44
+ transition: transitionStyle
45
+ },
33
46
  role: "status",
34
47
  "aria-label": ariaLabel,
35
48
  "aria-busy": "true",
@@ -47,7 +60,7 @@ const SpinnerGrid = forwardRef(
47
60
  const row = Math.floor(index / gridSize);
48
61
  const col = index % gridSize;
49
62
  const maxDelay = (gridSize - 1) * 2;
50
- const delay = reverse ? (maxDelay - (row + col)) * 0.1 : (row + col) * 0.1;
63
+ const delay2 = reverse ? (maxDelay - (row + col)) * 0.1 : (row + col) * 0.1;
51
64
  return /* @__PURE__ */ jsx(
52
65
  "div",
53
66
  {
@@ -57,7 +70,7 @@ const SpinnerGrid = forwardRef(
57
70
  height: `${cellSize}px`,
58
71
  backgroundColor: color,
59
72
  animation: `fade-pulse ${effectiveDuration} ease-in-out infinite`,
60
- animationDelay: `${delay}s`
73
+ animationDelay: `${delay2}s`
61
74
  }
62
75
  },
63
76
  index
@@ -1 +1 @@
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;"}
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, useLoaderVisibility } 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 delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-grid',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n const prefersReducedMotion = useReducedMotion();\n const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);\n const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(\n visible,\n delay,\n minDuration,\n transition\n );\n\n if (!shouldRender) return null;\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={{\n ...style,\n opacity,\n transition: transitionStyle,\n }}\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":["delay"],"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,QAAQ;AAAA,IACR,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,uBAAuB,iBAAA;AAC7B,UAAM,oBAAoB,qBAAqB,OAAO,yBAAyB,oBAAoB;AACnG,UAAM,EAAE,cAAc,SAAS,gBAAA,IAAoB;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,CAAC,aAAc,QAAO;AAE1B,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,OAAO;AAAA,UACL,GAAG;AAAA,UACH;AAAA,UACA,YAAY;AAAA,QAAA;AAAA,QAEd,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,oBAAMA,SAAQ,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,GAAGA,MAAK;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
@@ -14,6 +14,9 @@ const SpinnerWave = react.forwardRef(
14
14
  speed = "normal",
15
15
  reverse = false,
16
16
  respectMotionPreference = true,
17
+ delay = 0,
18
+ minDuration = 0,
19
+ transition,
17
20
  className,
18
21
  style,
19
22
  testId = "spinner-wave",
@@ -21,9 +24,15 @@ const SpinnerWave = react.forwardRef(
21
24
  ariaLabel = "Loading...",
22
25
  ...rest
23
26
  }, ref) => {
24
- if (!visible) return null;
25
27
  const prefersReducedMotion = hooks.useReducedMotion();
26
28
  const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
29
+ const { shouldRender, opacity, transitionStyle } = hooks.useLoaderVisibility(
30
+ visible,
31
+ delay,
32
+ minDuration,
33
+ transition
34
+ );
35
+ if (!shouldRender) return null;
27
36
  const sizeValue = colors.normalizeSize(size);
28
37
  return /* @__PURE__ */ jsxRuntime.jsx(
29
38
  "div",
@@ -31,7 +40,11 @@ const SpinnerWave = react.forwardRef(
31
40
  ref,
32
41
  "data-testid": testId,
33
42
  className: classNames.cn("inline-flex items-center justify-center", className),
34
- style,
43
+ style: {
44
+ ...style,
45
+ opacity,
46
+ transition: transitionStyle
47
+ },
35
48
  role: "status",
36
49
  "aria-label": ariaLabel,
37
50
  "aria-busy": "true",
@@ -1 +1 @@
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;;"}
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, useLoaderVisibility } 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 delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-wave',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n const prefersReducedMotion = useReducedMotion();\n const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);\n const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(\n visible,\n delay,\n minDuration,\n transition\n );\n\n if (!shouldRender) return null;\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={{\n ...style,\n opacity,\n transition: transitionStyle,\n }}\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","useLoaderVisibility","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,QAAQ;AAAA,IACR,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,uBAAuBC,MAAAA,iBAAA;AAC7B,UAAM,oBAAoBC,MAAAA,qBAAqB,OAAO,yBAAyB,oBAAoB;AACnG,UAAM,EAAE,cAAc,SAAS,gBAAA,IAAoBC,MAAAA;AAAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,CAAC,aAAc,QAAO;AAC1B,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,OAAO;AAAA,UACL,GAAG;AAAA,UACH;AAAA,UACA,YAAY;AAAA,QAAA;AAAA,QAEd,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;;"}
package/dist/index19.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
- import { useReducedMotion, getEffectiveDuration } from "./index31.js";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index31.js";
4
4
  import { cn } from "./index3.js";
5
5
  import { normalizeSize } from "./index4.js";
6
6
  const SpinnerWave = forwardRef(
@@ -12,6 +12,9 @@ const SpinnerWave = forwardRef(
12
12
  speed = "normal",
13
13
  reverse = false,
14
14
  respectMotionPreference = true,
15
+ delay = 0,
16
+ minDuration = 0,
17
+ transition,
15
18
  className,
16
19
  style,
17
20
  testId = "spinner-wave",
@@ -19,9 +22,15 @@ const SpinnerWave = forwardRef(
19
22
  ariaLabel = "Loading...",
20
23
  ...rest
21
24
  }, ref) => {
22
- if (!visible) return null;
23
25
  const prefersReducedMotion = useReducedMotion();
24
26
  const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
27
+ const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(
28
+ visible,
29
+ delay,
30
+ minDuration,
31
+ transition
32
+ );
33
+ if (!shouldRender) return null;
25
34
  const sizeValue = normalizeSize(size);
26
35
  return /* @__PURE__ */ jsx(
27
36
  "div",
@@ -29,7 +38,11 @@ const SpinnerWave = forwardRef(
29
38
  ref,
30
39
  "data-testid": testId,
31
40
  className: cn("inline-flex items-center justify-center", className),
32
- style,
41
+ style: {
42
+ ...style,
43
+ opacity,
44
+ transition: transitionStyle
45
+ },
33
46
  role: "status",
34
47
  "aria-label": ariaLabel,
35
48
  "aria-busy": "true",
@@ -1 +1 @@
1
- {"version":3,"file":"index19.js","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":[],"mappings":";;;;;AAgBO,MAAM,cAAc;AAAA,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,uBAAuB,iBAAA;AAC7B,UAAM,oBAAoB,qBAAqB,OAAO,yBAAyB,oBAAoB;AACnG,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,MAAM,KAAK,EAAE,QAAQ,SAAS,EAAE,IAAI,CAAC,GAAG,UACvC;AAAA,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;"}
1
+ {"version":3,"file":"index19.js","sources":["../src/components/spinner/SpinnerWave.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerWaveProps } from '../../types';\nimport { cn, normalizeSize, useReducedMotion, getEffectiveDuration, useLoaderVisibility } 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 delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-wave',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n const prefersReducedMotion = useReducedMotion();\n const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);\n const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(\n visible,\n delay,\n minDuration,\n transition\n );\n\n if (!shouldRender) return null;\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={{\n ...style,\n opacity,\n transition: transitionStyle,\n }}\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":[],"mappings":";;;;;AAgBO,MAAM,cAAc;AAAA,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,QAAQ;AAAA,IACR,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,uBAAuB,iBAAA;AAC7B,UAAM,oBAAoB,qBAAqB,OAAO,yBAAyB,oBAAoB;AACnG,UAAM,EAAE,cAAc,SAAS,gBAAA,IAAoB;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,CAAC,aAAc,QAAO;AAC1B,UAAM,YAAY,cAAc,IAAI;AAEpC,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAW,GAAG,2CAA2C,SAAS;AAAA,QAClE,OAAO;AAAA,UACL,GAAG;AAAA,UACH;AAAA,UACA,YAAY;AAAA,QAAA;AAAA,QAEd,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,MAAM,KAAK,EAAE,QAAQ,SAAS,EAAE,IAAI,CAAC,GAAG,UACvC;AAAA,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;"}
package/dist/index20.cjs CHANGED
@@ -14,6 +14,9 @@ const SpinnerPulse = react.forwardRef(
14
14
  speed = "normal",
15
15
  reverse = false,
16
16
  respectMotionPreference = true,
17
+ delay = 0,
18
+ minDuration = 0,
19
+ transition,
17
20
  className,
18
21
  style,
19
22
  testId = "spinner-pulse",
@@ -21,9 +24,15 @@ const SpinnerPulse = react.forwardRef(
21
24
  ariaLabel = "Loading...",
22
25
  ...rest
23
26
  }, ref) => {
24
- if (!visible) return null;
25
27
  const prefersReducedMotion = hooks.useReducedMotion();
26
28
  const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
29
+ const { shouldRender, opacity, transitionStyle } = hooks.useLoaderVisibility(
30
+ visible,
31
+ delay,
32
+ minDuration,
33
+ transition
34
+ );
35
+ if (!shouldRender) return null;
27
36
  const sizeValue = colors.normalizeSize(size);
28
37
  return /* @__PURE__ */ jsxRuntime.jsx(
29
38
  "div",
@@ -31,7 +40,11 @@ const SpinnerPulse = react.forwardRef(
31
40
  ref,
32
41
  "data-testid": testId,
33
42
  className: classNames.cn("inline-flex items-center justify-center", className),
34
- style,
43
+ style: {
44
+ ...style,
45
+ opacity,
46
+ transition: transitionStyle
47
+ },
35
48
  role: "status",
36
49
  "aria-label": ariaLabel,
37
50
  "aria-busy": "true",
@@ -1 +1 @@
1
- {"version":3,"file":"index20.cjs","sources":["../src/components/spinner/SpinnerPulse.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerPulseProps } from '../../types';\nimport { cn, normalizeSize, useReducedMotion, getEffectiveDuration } 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=\"lg\" color=\"#3b82f6\" />\n * <SpinnerPulse size=\"xl\" pulses={3} reverse />\n * <SpinnerPulse size=\"md\" maxScale={2.5} speed=\"slow\" />\n * ```\n */\nexport const SpinnerPulse = forwardRef<HTMLDivElement, SpinnerPulseProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n pulses = 2,\n maxScale = 1.8,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\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 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 {/* 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 ${effectiveDuration} ease-out infinite`,\n animationDelay: reverse ? `${(pulses - index - 1) * 0.3}s` : `${index * 0.3}s`,\n animationDirection: reverse ? 'reverse' : 'normal',\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":["forwardRef","useReducedMotion","getEffectiveDuration","normalizeSize","jsx","cn","jsxs"],"mappings":";;;;;;;AAgBO,MAAM,eAAeA,MAAAA;AAAAA,EAC1B,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,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,UAAAC,2BAAAA;AAAAA,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,UACtCF,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,iBAAiB;AAAA,oBACjB,WAAW,mBAAmB,iBAAiB;AAAA,oBAC/C,gBAAgB,UAAU,IAAI,SAAS,QAAQ,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG;AAAA,oBAC3E,oBAAoB,UAAU,YAAY;AAAA;AAAA,oBAE1C,eAAe;AAAA,kBAAA;AAAA,gBACjB;AAAA,gBATK;AAAA,cAAA,CAWR;AAAA,cAGDA,2BAAAA;AAAAA,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;;"}
1
+ {"version":3,"file":"index20.cjs","sources":["../src/components/spinner/SpinnerPulse.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerPulseProps } from '../../types';\nimport { cn, normalizeSize, useReducedMotion, getEffectiveDuration, useLoaderVisibility } 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=\"lg\" color=\"#3b82f6\" />\n * <SpinnerPulse size=\"xl\" pulses={3} reverse />\n * <SpinnerPulse size=\"md\" maxScale={2.5} speed=\"slow\" />\n * ```\n */\nexport const SpinnerPulse = forwardRef<HTMLDivElement, SpinnerPulseProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n pulses = 2,\n maxScale = 1.8,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-pulse',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n const prefersReducedMotion = useReducedMotion();\n const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);\n const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(\n visible,\n delay,\n minDuration,\n transition\n );\n\n if (!shouldRender) return null;\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={{\n ...style,\n opacity,\n transition: transitionStyle,\n }}\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 ${effectiveDuration} ease-out infinite`,\n animationDelay: reverse ? `${(pulses - index - 1) * 0.3}s` : `${index * 0.3}s`,\n animationDirection: reverse ? 'reverse' : 'normal',\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":["forwardRef","useReducedMotion","getEffectiveDuration","useLoaderVisibility","normalizeSize","jsx","cn","jsxs"],"mappings":";;;;;;;AAgBO,MAAM,eAAeA,MAAAA;AAAAA,EAC1B,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,0BAA0B;AAAA,IAC1B,QAAQ;AAAA,IACR,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,uBAAuBC,MAAAA,iBAAA;AAC7B,UAAM,oBAAoBC,MAAAA,qBAAqB,OAAO,yBAAyB,oBAAoB;AACnG,UAAM,EAAE,cAAc,SAAS,gBAAA,IAAoBC,MAAAA;AAAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,CAAC,aAAc,QAAO;AAC1B,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,OAAO;AAAA,UACL,GAAG;AAAA,UACH;AAAA,UACA,YAAY;AAAA,QAAA;AAAA,QAEd,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,aAAU;AAAA,QACT,GAAG;AAAA,QAEJ,UAAAC,2BAAAA;AAAAA,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,UACtCF,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,iBAAiB;AAAA,oBACjB,WAAW,mBAAmB,iBAAiB;AAAA,oBAC/C,gBAAgB,UAAU,IAAI,SAAS,QAAQ,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG;AAAA,oBAC3E,oBAAoB,UAAU,YAAY;AAAA;AAAA,oBAE1C,eAAe;AAAA,kBAAA;AAAA,gBACjB;AAAA,gBATK;AAAA,cAAA,CAWR;AAAA,cAGDA,2BAAAA;AAAAA,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/index20.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
- import { useReducedMotion, getEffectiveDuration } from "./index31.js";
3
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index31.js";
4
4
  import { cn } from "./index3.js";
5
5
  import { normalizeSize } from "./index4.js";
6
6
  const SpinnerPulse = forwardRef(
@@ -12,6 +12,9 @@ const SpinnerPulse = forwardRef(
12
12
  speed = "normal",
13
13
  reverse = false,
14
14
  respectMotionPreference = true,
15
+ delay = 0,
16
+ minDuration = 0,
17
+ transition,
15
18
  className,
16
19
  style,
17
20
  testId = "spinner-pulse",
@@ -19,9 +22,15 @@ const SpinnerPulse = forwardRef(
19
22
  ariaLabel = "Loading...",
20
23
  ...rest
21
24
  }, ref) => {
22
- if (!visible) return null;
23
25
  const prefersReducedMotion = useReducedMotion();
24
26
  const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
27
+ const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(
28
+ visible,
29
+ delay,
30
+ minDuration,
31
+ transition
32
+ );
33
+ if (!shouldRender) return null;
25
34
  const sizeValue = normalizeSize(size);
26
35
  return /* @__PURE__ */ jsx(
27
36
  "div",
@@ -29,7 +38,11 @@ const SpinnerPulse = forwardRef(
29
38
  ref,
30
39
  "data-testid": testId,
31
40
  className: cn("inline-flex items-center justify-center", className),
32
- style,
41
+ style: {
42
+ ...style,
43
+ opacity,
44
+ transition: transitionStyle
45
+ },
33
46
  role: "status",
34
47
  "aria-label": ariaLabel,
35
48
  "aria-busy": "true",
@@ -1 +1 @@
1
- {"version":3,"file":"index20.js","sources":["../src/components/spinner/SpinnerPulse.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerPulseProps } from '../../types';\nimport { cn, normalizeSize, useReducedMotion, getEffectiveDuration } 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=\"lg\" color=\"#3b82f6\" />\n * <SpinnerPulse size=\"xl\" pulses={3} reverse />\n * <SpinnerPulse size=\"md\" maxScale={2.5} speed=\"slow\" />\n * ```\n */\nexport const SpinnerPulse = forwardRef<HTMLDivElement, SpinnerPulseProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n pulses = 2,\n maxScale = 1.8,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\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 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 {/* 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 ${effectiveDuration} ease-out infinite`,\n animationDelay: reverse ? `${(pulses - index - 1) * 0.3}s` : `${index * 0.3}s`,\n animationDirection: reverse ? 'reverse' : 'normal',\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,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;AACnG,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,UAAU,IAAI,SAAS,QAAQ,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG;AAAA,oBAC3E,oBAAoB,UAAU,YAAY;AAAA;AAAA,oBAE1C,eAAe;AAAA,kBAAA;AAAA,gBACjB;AAAA,gBATK;AAAA,cAAA,CAWR;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;"}
1
+ {"version":3,"file":"index20.js","sources":["../src/components/spinner/SpinnerPulse.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerPulseProps } from '../../types';\nimport { cn, normalizeSize, useReducedMotion, getEffectiveDuration, useLoaderVisibility } 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=\"lg\" color=\"#3b82f6\" />\n * <SpinnerPulse size=\"xl\" pulses={3} reverse />\n * <SpinnerPulse size=\"md\" maxScale={2.5} speed=\"slow\" />\n * ```\n */\nexport const SpinnerPulse = forwardRef<HTMLDivElement, SpinnerPulseProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n pulses = 2,\n maxScale = 1.8,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-pulse',\n visible = true,\n ariaLabel = 'Loading...',\n ...rest\n },\n ref\n ) => {\n const prefersReducedMotion = useReducedMotion();\n const effectiveDuration = getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);\n const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(\n visible,\n delay,\n minDuration,\n transition\n );\n\n if (!shouldRender) return null;\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={{\n ...style,\n opacity,\n transition: transitionStyle,\n }}\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 ${effectiveDuration} ease-out infinite`,\n animationDelay: reverse ? `${(pulses - index - 1) * 0.3}s` : `${index * 0.3}s`,\n animationDirection: reverse ? 'reverse' : 'normal',\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,UAAU;AAAA,IACV,0BAA0B;AAAA,IAC1B,QAAQ;AAAA,IACR,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,uBAAuB,iBAAA;AAC7B,UAAM,oBAAoB,qBAAqB,OAAO,yBAAyB,oBAAoB;AACnG,UAAM,EAAE,cAAc,SAAS,gBAAA,IAAoB;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,CAAC,aAAc,QAAO;AAC1B,UAAM,YAAY,cAAc,IAAI;AAEpC,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAW,GAAG,2CAA2C,SAAS;AAAA,QAClE,OAAO;AAAA,UACL,GAAG;AAAA,UACH;AAAA,UACA,YAAY;AAAA,QAAA;AAAA,QAEd,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,UAAU,IAAI,SAAS,QAAQ,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG;AAAA,oBAC3E,oBAAoB,UAAU,YAAY;AAAA;AAAA,oBAE1C,eAAe;AAAA,kBAAA;AAAA,gBACjB;AAAA,gBATK;AAAA,cAAA,CAWR;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
@@ -18,6 +18,9 @@ const ProgressBar = react.forwardRef(
18
18
  speed = "normal",
19
19
  reverse = false,
20
20
  respectMotionPreference = true,
21
+ delay = 0,
22
+ minDuration = 0,
23
+ transition,
21
24
  className,
22
25
  style,
23
26
  testId = "progress-bar",
@@ -25,13 +28,19 @@ const ProgressBar = react.forwardRef(
25
28
  ariaLabel,
26
29
  ...rest
27
30
  }, ref) => {
28
- if (!visible) return null;
29
31
  const prefersReducedMotion = hooks.useReducedMotion();
30
32
  const effectiveDuration = hooks.getEffectiveDuration(speed, respectMotionPreference, prefersReducedMotion);
33
+ const gradientId = react.useMemo(() => `progress-bar-gradient-${Math.random().toString(36).substr(2, 9)}`, []);
34
+ const { shouldRender, opacity, transitionStyle } = hooks.useLoaderVisibility(
35
+ visible,
36
+ delay,
37
+ minDuration,
38
+ transition
39
+ );
40
+ if (!shouldRender) return null;
31
41
  const clampedValue = Math.min(100, Math.max(0, value));
32
42
  const clampedBuffer = buffer !== void 0 ? Math.min(100, Math.max(0, buffer)) : void 0;
33
43
  const progressLabel = ariaLabel || `Loading ${clampedValue}%`;
34
- const gradientId = react.useMemo(() => `progress-bar-gradient-${Math.random().toString(36).substr(2, 9)}`, []);
35
44
  return /* @__PURE__ */ jsxRuntime.jsxs(
36
45
  "div",
37
46
  {
@@ -41,7 +50,9 @@ const ProgressBar = react.forwardRef(
41
50
  style: {
42
51
  height: colors.normalizeSize(height),
43
52
  backgroundColor: secondaryColor,
44
- ...style
53
+ ...style,
54
+ opacity,
55
+ transition: transitionStyle
45
56
  },
46
57
  role: "progressbar",
47
58
  "aria-label": progressLabel,