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
@@ -1 +1 @@
1
- {"version":3,"file":"index12.js","sources":["../src/components/skeleton/SkeletonPage.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SkeletonPageProps } from '../../types';\nimport { cn } from '../../utils';\nimport { Skeleton } from './Skeleton';\nimport { SkeletonText } from './SkeletonText';\nimport { SkeletonAvatar } from './SkeletonAvatar';\n\n/**\n * SkeletonPage - Pre-built page loading skeleton\n *\n * A ready-to-use skeleton layout for full page loading states.\n * Displays a common page structure with header, navigation, and content sections.\n *\n * @example\n * ```tsx\n * <SkeletonPage />\n * <SkeletonPage variant=\"dashboard\" />\n * <SkeletonPage variant=\"article\" animate={false} />\n * ```\n */\nexport const SkeletonPage = forwardRef<HTMLDivElement, SkeletonPageProps>(\n (\n {\n variant = 'default',\n animate = true,\n baseColor = '#e0e0e0',\n highlightColor = '#f5f5f5',\n className,\n style,\n testId = 'skeleton-page',\n visible = true,\n ...rest\n },\n ref\n ) => {\n if (!visible) return null;\n\n const commonProps = {\n animate,\n baseColor,\n highlightColor,\n };\n\n const renderDefault = () => (\n <div className=\"space-y-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b pb-4\">\n <Skeleton width={200} height={32} {...commonProps} />\n <div className=\"flex items-center gap-4\">\n <Skeleton width={100} height={36} borderRadius={6} {...commonProps} />\n <SkeletonAvatar size={40} {...commonProps} />\n </div>\n </div>\n\n {/* Content */}\n <div className=\"space-y-4\">\n <SkeletonText lines={3} {...commonProps} />\n <div className=\"grid grid-cols-3 gap-4\">\n <Skeleton height={120} borderRadius={8} {...commonProps} />\n <Skeleton height={120} borderRadius={8} {...commonProps} />\n <Skeleton height={120} borderRadius={8} {...commonProps} />\n </div>\n <SkeletonText lines={5} {...commonProps} />\n </div>\n </div>\n );\n\n const renderDashboard = () => (\n <div className=\"space-y-6\">\n {/* Header with stats */}\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <Skeleton width={180} height={28} {...commonProps} />\n <Skeleton width={120} height={36} borderRadius={6} {...commonProps} />\n </div>\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(4)].map((_, i) => (\n <div key={i} className=\"p-4 border rounded-lg space-y-2\">\n <Skeleton width={100} height={16} {...commonProps} />\n <Skeleton width={80} height={32} {...commonProps} />\n <Skeleton width={60} height={12} {...commonProps} />\n </div>\n ))}\n </div>\n </div>\n\n {/* Chart area */}\n <Skeleton height={300} borderRadius={8} {...commonProps} />\n\n {/* Table */}\n <div className=\"space-y-3\">\n <div className=\"flex gap-4\">\n <Skeleton width={150} height={20} {...commonProps} />\n <Skeleton width={150} height={20} {...commonProps} />\n <Skeleton width={150} height={20} {...commonProps} />\n </div>\n {[...Array(5)].map((_, i) => (\n <div key={i} className=\"flex gap-4\">\n <Skeleton width={150} height={16} {...commonProps} />\n <Skeleton width={150} height={16} {...commonProps} />\n <Skeleton width={150} height={16} {...commonProps} />\n </div>\n ))}\n </div>\n </div>\n );\n\n const renderArticle = () => (\n <div className=\"max-w-3xl mx-auto space-y-6\">\n {/* Article header */}\n <div className=\"space-y-4\">\n <Skeleton width=\"80%\" height={40} {...commonProps} />\n <div className=\"flex items-center gap-3\">\n <SkeletonAvatar size={48} {...commonProps} />\n <div className=\"space-y-2 flex-1\">\n <Skeleton width={120} height={16} {...commonProps} />\n <Skeleton width={180} height={14} {...commonProps} />\n </div>\n </div>\n </div>\n\n {/* Featured image */}\n <Skeleton height={400} borderRadius={8} {...commonProps} />\n\n {/* Article content */}\n <div className=\"space-y-4\">\n <SkeletonText lines={4} {...commonProps} />\n <Skeleton height={200} borderRadius={8} {...commonProps} />\n <SkeletonText lines={6} {...commonProps} />\n <Skeleton height={250} borderRadius={8} {...commonProps} />\n <SkeletonText lines={4} {...commonProps} />\n </div>\n </div>\n );\n\n const renderProfile = () => (\n <div className=\"space-y-6\">\n {/* Profile header */}\n <div className=\"flex items-start gap-6 border-b pb-6\">\n <SkeletonAvatar size={120} {...commonProps} />\n <div className=\"flex-1 space-y-3\">\n <Skeleton width={200} height={32} {...commonProps} />\n <Skeleton width={150} height={20} {...commonProps} />\n <SkeletonText lines={2} {...commonProps} />\n <div className=\"flex gap-3\">\n <Skeleton width={100} height={36} borderRadius={6} {...commonProps} />\n <Skeleton width={100} height={36} borderRadius={6} {...commonProps} />\n </div>\n </div>\n </div>\n\n {/* Profile content grid */}\n <div className=\"grid grid-cols-3 gap-6\">\n {/* Left sidebar */}\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Skeleton width={100} height={20} {...commonProps} />\n {[...Array(4)].map((_, i) => (\n <Skeleton key={i} height={16} {...commonProps} />\n ))}\n </div>\n </div>\n\n {/* Main content */}\n <div className=\"col-span-2 space-y-4\">\n {[...Array(3)].map((_, i) => (\n <div key={i} className=\"p-4 border rounded-lg space-y-3\">\n <div className=\"flex items-center gap-3\">\n <SkeletonAvatar size={40} {...commonProps} />\n <div className=\"flex-1 space-y-2\">\n <Skeleton width={150} height={16} {...commonProps} />\n <Skeleton width={100} height={12} {...commonProps} />\n </div>\n </div>\n <SkeletonText lines={2} {...commonProps} />\n <Skeleton height={200} borderRadius={6} {...commonProps} />\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n\n const renderContent = () => {\n switch (variant) {\n case 'dashboard':\n return renderDashboard();\n case 'article':\n return renderArticle();\n case 'profile':\n return renderProfile();\n default:\n return renderDefault();\n }\n };\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('w-full p-6', className)}\n style={style}\n role=\"status\"\n aria-label=\"Loading page...\"\n aria-busy=\"true\"\n {...rest}\n >\n {renderContent()}\n </div>\n );\n }\n);\n\nSkeletonPage.displayName = 'SkeletonPage';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index12.js","sources":["../src/components/skeleton/SkeletonPage.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SkeletonPageProps } from '../../types';\nimport { cn, useLoaderVisibility } from '../../utils';\nimport { Skeleton } from './Skeleton';\nimport { SkeletonText } from './SkeletonText';\nimport { SkeletonAvatar } from './SkeletonAvatar';\n\n/**\n * SkeletonPage - Pre-built page loading skeleton\n *\n * A ready-to-use skeleton layout for full page loading states.\n * Displays a common page structure with header, navigation, and content sections.\n *\n * @example\n * ```tsx\n * <SkeletonPage />\n * <SkeletonPage variant=\"dashboard\" />\n * <SkeletonPage variant=\"article\" animate={false} />\n * ```\n */\nexport const SkeletonPage = forwardRef<HTMLDivElement, SkeletonPageProps>(\n (\n {\n variant = 'default',\n animate = true,\n baseColor = '#e0e0e0',\n highlightColor = '#f5f5f5',\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'skeleton-page',\n visible = true,\n ...rest\n },\n ref\n ) => {\n const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(\n visible,\n delay,\n minDuration,\n transition\n );\n\n if (!shouldRender) return null;\n\n const commonProps = {\n animate,\n baseColor,\n highlightColor,\n };\n\n const renderDefault = () => (\n <div className=\"space-y-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b pb-4\">\n <Skeleton width={200} height={32} {...commonProps} />\n <div className=\"flex items-center gap-4\">\n <Skeleton width={100} height={36} borderRadius={6} {...commonProps} />\n <SkeletonAvatar size={40} {...commonProps} />\n </div>\n </div>\n\n {/* Content */}\n <div className=\"space-y-4\">\n <SkeletonText lines={3} {...commonProps} />\n <div className=\"grid grid-cols-3 gap-4\">\n <Skeleton height={120} borderRadius={8} {...commonProps} />\n <Skeleton height={120} borderRadius={8} {...commonProps} />\n <Skeleton height={120} borderRadius={8} {...commonProps} />\n </div>\n <SkeletonText lines={5} {...commonProps} />\n </div>\n </div>\n );\n\n const renderDashboard = () => (\n <div className=\"space-y-6\">\n {/* Header with stats */}\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <Skeleton width={180} height={28} {...commonProps} />\n <Skeleton width={120} height={36} borderRadius={6} {...commonProps} />\n </div>\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(4)].map((_, i) => (\n <div key={i} className=\"p-4 border rounded-lg space-y-2\">\n <Skeleton width={100} height={16} {...commonProps} />\n <Skeleton width={80} height={32} {...commonProps} />\n <Skeleton width={60} height={12} {...commonProps} />\n </div>\n ))}\n </div>\n </div>\n\n {/* Chart area */}\n <Skeleton height={300} borderRadius={8} {...commonProps} />\n\n {/* Table */}\n <div className=\"space-y-3\">\n <div className=\"flex gap-4\">\n <Skeleton width={150} height={20} {...commonProps} />\n <Skeleton width={150} height={20} {...commonProps} />\n <Skeleton width={150} height={20} {...commonProps} />\n </div>\n {[...Array(5)].map((_, i) => (\n <div key={i} className=\"flex gap-4\">\n <Skeleton width={150} height={16} {...commonProps} />\n <Skeleton width={150} height={16} {...commonProps} />\n <Skeleton width={150} height={16} {...commonProps} />\n </div>\n ))}\n </div>\n </div>\n );\n\n const renderArticle = () => (\n <div className=\"max-w-3xl mx-auto space-y-6\">\n {/* Article header */}\n <div className=\"space-y-4\">\n <Skeleton width=\"80%\" height={40} {...commonProps} />\n <div className=\"flex items-center gap-3\">\n <SkeletonAvatar size={48} {...commonProps} />\n <div className=\"space-y-2 flex-1\">\n <Skeleton width={120} height={16} {...commonProps} />\n <Skeleton width={180} height={14} {...commonProps} />\n </div>\n </div>\n </div>\n\n {/* Featured image */}\n <Skeleton height={400} borderRadius={8} {...commonProps} />\n\n {/* Article content */}\n <div className=\"space-y-4\">\n <SkeletonText lines={4} {...commonProps} />\n <Skeleton height={200} borderRadius={8} {...commonProps} />\n <SkeletonText lines={6} {...commonProps} />\n <Skeleton height={250} borderRadius={8} {...commonProps} />\n <SkeletonText lines={4} {...commonProps} />\n </div>\n </div>\n );\n\n const renderProfile = () => (\n <div className=\"space-y-6\">\n {/* Profile header */}\n <div className=\"flex items-start gap-6 border-b pb-6\">\n <SkeletonAvatar size={120} {...commonProps} />\n <div className=\"flex-1 space-y-3\">\n <Skeleton width={200} height={32} {...commonProps} />\n <Skeleton width={150} height={20} {...commonProps} />\n <SkeletonText lines={2} {...commonProps} />\n <div className=\"flex gap-3\">\n <Skeleton width={100} height={36} borderRadius={6} {...commonProps} />\n <Skeleton width={100} height={36} borderRadius={6} {...commonProps} />\n </div>\n </div>\n </div>\n\n {/* Profile content grid */}\n <div className=\"grid grid-cols-3 gap-6\">\n {/* Left sidebar */}\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Skeleton width={100} height={20} {...commonProps} />\n {[...Array(4)].map((_, i) => (\n <Skeleton key={i} height={16} {...commonProps} />\n ))}\n </div>\n </div>\n\n {/* Main content */}\n <div className=\"col-span-2 space-y-4\">\n {[...Array(3)].map((_, i) => (\n <div key={i} className=\"p-4 border rounded-lg space-y-3\">\n <div className=\"flex items-center gap-3\">\n <SkeletonAvatar size={40} {...commonProps} />\n <div className=\"flex-1 space-y-2\">\n <Skeleton width={150} height={16} {...commonProps} />\n <Skeleton width={100} height={12} {...commonProps} />\n </div>\n </div>\n <SkeletonText lines={2} {...commonProps} />\n <Skeleton height={200} borderRadius={6} {...commonProps} />\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n\n const renderContent = () => {\n switch (variant) {\n case 'dashboard':\n return renderDashboard();\n case 'article':\n return renderArticle();\n case 'profile':\n return renderProfile();\n default:\n return renderDefault();\n }\n };\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('w-full p-6', className)}\n style={{\n ...style,\n opacity,\n transition: transitionStyle,\n }}\n role=\"status\"\n aria-label=\"Loading page...\"\n aria-busy=\"true\"\n {...rest}\n >\n {renderContent()}\n </div>\n );\n }\n);\n\nSkeletonPage.displayName = 'SkeletonPage';\n"],"names":[],"mappings":"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"}
package/dist/index13.cjs CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const react = require("react");
5
5
  const Skeleton = require("./index5.cjs");
6
+ const hooks = require("./index31.cjs");
6
7
  const colors = require("./index4.cjs");
7
8
  const classNames = require("./index3.cjs");
8
9
  const SkeletonForm = react.forwardRef(
@@ -16,13 +17,22 @@ const SkeletonForm = react.forwardRef(
16
17
  animate = true,
17
18
  baseColor,
18
19
  highlightColor,
20
+ delay = 0,
21
+ minDuration = 0,
22
+ transition,
19
23
  className,
20
24
  style,
21
25
  testId = "skeleton-form",
22
26
  visible = true,
23
27
  ...rest
24
28
  }, ref) => {
25
- if (!visible) return null;
29
+ const { shouldRender, opacity, transitionStyle } = hooks.useLoaderVisibility(
30
+ visible,
31
+ delay,
32
+ minDuration,
33
+ transition
34
+ );
35
+ if (!shouldRender) return null;
26
36
  const gapValue = colors.normalizeSize(gap);
27
37
  const buttonAlign = buttonPosition === "left" ? "justify-start" : buttonPosition === "right" ? "justify-end" : "justify-center";
28
38
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -31,7 +41,7 @@ const SkeletonForm = react.forwardRef(
31
41
  ref,
32
42
  "data-testid": testId,
33
43
  className: classNames.cn("w-full", className),
34
- style: { ...style, display: "flex", flexDirection: "column", gap: gapValue },
44
+ style: { ...style, display: "flex", flexDirection: "column", gap: gapValue, opacity, transition: transitionStyle },
35
45
  role: "status",
36
46
  "aria-label": "Loading form...",
37
47
  "aria-busy": "true",
@@ -1 +1 @@
1
- {"version":3,"file":"index13.cjs","sources":["../src/components/skeleton/SkeletonForm.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SkeletonFormProps } from '../../types';\nimport { cn, normalizeSize } from '../../utils';\nimport { Skeleton } from './Skeleton';\n\n/**\n * SkeletonForm - Form loading skeleton\n *\n * A skeleton loader for form layouts with configurable fields, labels, and submit button.\n *\n * @example\n * ```tsx\n * <SkeletonForm />\n * <SkeletonForm fields={5} showLabels={true} />\n * <SkeletonForm fields={3} showButton={false} />\n * <SkeletonForm fields={4} buttonPosition=\"right\" />\n * ```\n */\nexport const SkeletonForm = forwardRef<HTMLDivElement, SkeletonFormProps>(\n (\n {\n fields = 3,\n showLabels = true,\n showButton = true,\n gap = 16,\n buttonWidth = '120px',\n buttonPosition = 'left',\n animate = true,\n baseColor,\n highlightColor,\n className,\n style,\n testId = 'skeleton-form',\n visible = true,\n ...rest\n },\n ref\n ) => {\n if (!visible) return null;\n\n const gapValue = normalizeSize(gap);\n const buttonAlign =\n buttonPosition === 'left'\n ? 'justify-start'\n : buttonPosition === 'right'\n ? 'justify-end'\n : 'justify-center';\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('w-full', className)}\n style={{ ...style, display: 'flex', flexDirection: 'column', gap: gapValue }}\n role=\"status\"\n aria-label=\"Loading form...\"\n aria-busy=\"true\"\n {...rest}\n >\n {/* Form Fields */}\n {Array.from({ length: fields }).map((_, index) => (\n <div key={index} className=\"w-full\" style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n {/* Field Label */}\n {showLabels && (\n <Skeleton\n width=\"30%\"\n height=\"0.875rem\"\n variant=\"text\"\n animate={animate}\n baseColor={baseColor}\n highlightColor={highlightColor}\n />\n )}\n {/* Field Input */}\n <Skeleton\n width=\"100%\"\n height=\"2.5rem\"\n variant=\"rectangular\"\n animate={animate}\n baseColor={baseColor}\n highlightColor={highlightColor}\n />\n </div>\n ))}\n\n {/* Submit Button */}\n {showButton && (\n <div className={cn('flex', buttonAlign)} style={{ marginTop: '8px' }}>\n <Skeleton\n width={buttonWidth}\n height=\"2.5rem\"\n variant=\"rounded\"\n animate={animate}\n baseColor={baseColor}\n highlightColor={highlightColor}\n />\n </div>\n )}\n </div>\n );\n }\n);\n\nSkeletonForm.displayName = 'SkeletonForm';\n"],"names":["forwardRef","normalizeSize","jsxs","cn","jsx","Skeleton"],"mappings":";;;;;;;AAkBO,MAAM,eAAeA,MAAAA;AAAAA,EAC1B,CACE;AAAA,IACE,SAAS;AAAA,IACT,aAAa;AAAA,IACb,aAAa;AAAA,IACb,MAAM;AAAA,IACN,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,GAAG;AAAA,EAAA,GAEL,QACG;AACH,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,WAAWC,OAAAA,cAAc,GAAG;AAClC,UAAM,cACJ,mBAAmB,SACf,kBACA,mBAAmB,UACnB,gBACA;AAEN,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAWC,WAAAA,GAAG,UAAU,SAAS;AAAA,QACjC,OAAO,EAAE,GAAG,OAAO,SAAS,QAAQ,eAAe,UAAU,KAAK,SAAA;AAAA,QAClE,MAAK;AAAA,QACL,cAAW;AAAA,QACX,aAAU;AAAA,QACT,GAAG;AAAA,QAGH,UAAA;AAAA,UAAA,MAAM,KAAK,EAAE,QAAQ,OAAA,CAAQ,EAAE,IAAI,CAAC,GAAG,UACtCD,2BAAAA,KAAC,SAAgB,WAAU,UAAS,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,MAAA,GAEzF,UAAA;AAAA,YAAA,cACCE,2BAAAA;AAAAA,cAACC,SAAAA;AAAAA,cAAA;AAAA,gBACC,OAAM;AAAA,gBACN,QAAO;AAAA,gBACP,SAAQ;AAAA,gBACR;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAAA;AAAA,YAIJD,2BAAAA;AAAAA,cAACC,SAAAA;AAAAA,cAAA;AAAA,gBACC,OAAM;AAAA,gBACN,QAAO;AAAA,gBACP,SAAQ;AAAA,gBACR;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAAA;AAAA,UACF,EAAA,GApBQ,KAqBV,CACD;AAAA,UAGA,cACCD,2BAAAA,IAAC,OAAA,EAAI,WAAWD,WAAAA,GAAG,QAAQ,WAAW,GAAG,OAAO,EAAE,WAAW,MAAA,GAC3D,UAAAC,2BAAAA;AAAAA,YAACC,SAAAA;AAAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP,QAAO;AAAA,cACP,SAAQ;AAAA,cACR;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,UAAA,EACF,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,aAAa,cAAc;;"}
1
+ {"version":3,"file":"index13.cjs","sources":["../src/components/skeleton/SkeletonForm.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SkeletonFormProps } from '../../types';\nimport { cn, normalizeSize, useLoaderVisibility } from '../../utils';\nimport { Skeleton } from './Skeleton';\n\n/**\n * SkeletonForm - Form loading skeleton\n *\n * A skeleton loader for form layouts with configurable fields, labels, and submit button.\n *\n * @example\n * ```tsx\n * <SkeletonForm />\n * <SkeletonForm fields={5} showLabels={true} />\n * <SkeletonForm fields={3} showButton={false} />\n * <SkeletonForm fields={4} buttonPosition=\"right\" />\n * ```\n */\nexport const SkeletonForm = forwardRef<HTMLDivElement, SkeletonFormProps>(\n (\n {\n fields = 3,\n showLabels = true,\n showButton = true,\n gap = 16,\n buttonWidth = '120px',\n buttonPosition = 'left',\n animate = true,\n baseColor,\n highlightColor,\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'skeleton-form',\n visible = true,\n ...rest\n },\n ref\n ) => {\n const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(\n visible,\n delay,\n minDuration,\n transition\n );\n\n if (!shouldRender) return null;\n\n const gapValue = normalizeSize(gap);\n const buttonAlign =\n buttonPosition === 'left'\n ? 'justify-start'\n : buttonPosition === 'right'\n ? 'justify-end'\n : 'justify-center';\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('w-full', className)}\n style={{ ...style, display: 'flex', flexDirection: 'column', gap: gapValue, opacity, transition: transitionStyle }}\n role=\"status\"\n aria-label=\"Loading form...\"\n aria-busy=\"true\"\n {...rest}\n >\n {/* Form Fields */}\n {Array.from({ length: fields }).map((_, index) => (\n <div key={index} className=\"w-full\" style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n {/* Field Label */}\n {showLabels && (\n <Skeleton\n width=\"30%\"\n height=\"0.875rem\"\n variant=\"text\"\n animate={animate}\n baseColor={baseColor}\n highlightColor={highlightColor}\n />\n )}\n {/* Field Input */}\n <Skeleton\n width=\"100%\"\n height=\"2.5rem\"\n variant=\"rectangular\"\n animate={animate}\n baseColor={baseColor}\n highlightColor={highlightColor}\n />\n </div>\n ))}\n\n {/* Submit Button */}\n {showButton && (\n <div className={cn('flex', buttonAlign)} style={{ marginTop: '8px' }}>\n <Skeleton\n width={buttonWidth}\n height=\"2.5rem\"\n variant=\"rounded\"\n animate={animate}\n baseColor={baseColor}\n highlightColor={highlightColor}\n />\n </div>\n )}\n </div>\n );\n }\n);\n\nSkeletonForm.displayName = 'SkeletonForm';\n"],"names":["forwardRef","useLoaderVisibility","normalizeSize","jsxs","cn","jsx","Skeleton"],"mappings":";;;;;;;;AAkBO,MAAM,eAAeA,MAAAA;AAAAA,EAC1B,CACE;AAAA,IACE,SAAS;AAAA,IACT,aAAa;AAAA,IACb,aAAa;AAAA,IACb,MAAM;AAAA,IACN,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,EAAE,cAAc,SAAS,gBAAA,IAAoBC,MAAAA;AAAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,CAAC,aAAc,QAAO;AAE1B,UAAM,WAAWC,OAAAA,cAAc,GAAG;AAClC,UAAM,cACJ,mBAAmB,SACf,kBACA,mBAAmB,UACnB,gBACA;AAEN,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAWC,WAAAA,GAAG,UAAU,SAAS;AAAA,QACjC,OAAO,EAAE,GAAG,OAAO,SAAS,QAAQ,eAAe,UAAU,KAAK,UAAU,SAAS,YAAY,gBAAA;AAAA,QACjG,MAAK;AAAA,QACL,cAAW;AAAA,QACX,aAAU;AAAA,QACT,GAAG;AAAA,QAGH,UAAA;AAAA,UAAA,MAAM,KAAK,EAAE,QAAQ,OAAA,CAAQ,EAAE,IAAI,CAAC,GAAG,UACtCD,2BAAAA,KAAC,SAAgB,WAAU,UAAS,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,MAAA,GAEzF,UAAA;AAAA,YAAA,cACCE,2BAAAA;AAAAA,cAACC,SAAAA;AAAAA,cAAA;AAAA,gBACC,OAAM;AAAA,gBACN,QAAO;AAAA,gBACP,SAAQ;AAAA,gBACR;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAAA;AAAA,YAIJD,2BAAAA;AAAAA,cAACC,SAAAA;AAAAA,cAAA;AAAA,gBACC,OAAM;AAAA,gBACN,QAAO;AAAA,gBACP,SAAQ;AAAA,gBACR;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAAA;AAAA,UACF,EAAA,GApBQ,KAqBV,CACD;AAAA,UAGA,cACCD,2BAAAA,IAAC,OAAA,EAAI,WAAWD,WAAAA,GAAG,QAAQ,WAAW,GAAG,OAAO,EAAE,WAAW,MAAA,GAC3D,UAAAC,2BAAAA;AAAAA,YAACC,SAAAA;AAAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP,QAAO;AAAA,cACP,SAAQ;AAAA,cACR;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,UAAA,EACF,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,aAAa,cAAc;;"}
package/dist/index13.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  import { Skeleton } from "./index5.js";
4
+ import { useLoaderVisibility } from "./index31.js";
4
5
  import { normalizeSize } from "./index4.js";
5
6
  import { cn } from "./index3.js";
6
7
  const SkeletonForm = forwardRef(
@@ -14,13 +15,22 @@ const SkeletonForm = forwardRef(
14
15
  animate = true,
15
16
  baseColor,
16
17
  highlightColor,
18
+ delay = 0,
19
+ minDuration = 0,
20
+ transition,
17
21
  className,
18
22
  style,
19
23
  testId = "skeleton-form",
20
24
  visible = true,
21
25
  ...rest
22
26
  }, ref) => {
23
- if (!visible) return null;
27
+ const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(
28
+ visible,
29
+ delay,
30
+ minDuration,
31
+ transition
32
+ );
33
+ if (!shouldRender) return null;
24
34
  const gapValue = normalizeSize(gap);
25
35
  const buttonAlign = buttonPosition === "left" ? "justify-start" : buttonPosition === "right" ? "justify-end" : "justify-center";
26
36
  return /* @__PURE__ */ jsxs(
@@ -29,7 +39,7 @@ const SkeletonForm = forwardRef(
29
39
  ref,
30
40
  "data-testid": testId,
31
41
  className: cn("w-full", className),
32
- style: { ...style, display: "flex", flexDirection: "column", gap: gapValue },
42
+ style: { ...style, display: "flex", flexDirection: "column", gap: gapValue, opacity, transition: transitionStyle },
33
43
  role: "status",
34
44
  "aria-label": "Loading form...",
35
45
  "aria-busy": "true",
@@ -1 +1 @@
1
- {"version":3,"file":"index13.js","sources":["../src/components/skeleton/SkeletonForm.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SkeletonFormProps } from '../../types';\nimport { cn, normalizeSize } from '../../utils';\nimport { Skeleton } from './Skeleton';\n\n/**\n * SkeletonForm - Form loading skeleton\n *\n * A skeleton loader for form layouts with configurable fields, labels, and submit button.\n *\n * @example\n * ```tsx\n * <SkeletonForm />\n * <SkeletonForm fields={5} showLabels={true} />\n * <SkeletonForm fields={3} showButton={false} />\n * <SkeletonForm fields={4} buttonPosition=\"right\" />\n * ```\n */\nexport const SkeletonForm = forwardRef<HTMLDivElement, SkeletonFormProps>(\n (\n {\n fields = 3,\n showLabels = true,\n showButton = true,\n gap = 16,\n buttonWidth = '120px',\n buttonPosition = 'left',\n animate = true,\n baseColor,\n highlightColor,\n className,\n style,\n testId = 'skeleton-form',\n visible = true,\n ...rest\n },\n ref\n ) => {\n if (!visible) return null;\n\n const gapValue = normalizeSize(gap);\n const buttonAlign =\n buttonPosition === 'left'\n ? 'justify-start'\n : buttonPosition === 'right'\n ? 'justify-end'\n : 'justify-center';\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('w-full', className)}\n style={{ ...style, display: 'flex', flexDirection: 'column', gap: gapValue }}\n role=\"status\"\n aria-label=\"Loading form...\"\n aria-busy=\"true\"\n {...rest}\n >\n {/* Form Fields */}\n {Array.from({ length: fields }).map((_, index) => (\n <div key={index} className=\"w-full\" style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n {/* Field Label */}\n {showLabels && (\n <Skeleton\n width=\"30%\"\n height=\"0.875rem\"\n variant=\"text\"\n animate={animate}\n baseColor={baseColor}\n highlightColor={highlightColor}\n />\n )}\n {/* Field Input */}\n <Skeleton\n width=\"100%\"\n height=\"2.5rem\"\n variant=\"rectangular\"\n animate={animate}\n baseColor={baseColor}\n highlightColor={highlightColor}\n />\n </div>\n ))}\n\n {/* Submit Button */}\n {showButton && (\n <div className={cn('flex', buttonAlign)} style={{ marginTop: '8px' }}>\n <Skeleton\n width={buttonWidth}\n height=\"2.5rem\"\n variant=\"rounded\"\n animate={animate}\n baseColor={baseColor}\n highlightColor={highlightColor}\n />\n </div>\n )}\n </div>\n );\n }\n);\n\nSkeletonForm.displayName = 'SkeletonForm';\n"],"names":[],"mappings":";;;;;AAkBO,MAAM,eAAe;AAAA,EAC1B,CACE;AAAA,IACE,SAAS;AAAA,IACT,aAAa;AAAA,IACb,aAAa;AAAA,IACb,MAAM;AAAA,IACN,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,GAAG;AAAA,EAAA,GAEL,QACG;AACH,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,WAAW,cAAc,GAAG;AAClC,UAAM,cACJ,mBAAmB,SACf,kBACA,mBAAmB,UACnB,gBACA;AAEN,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAW,GAAG,UAAU,SAAS;AAAA,QACjC,OAAO,EAAE,GAAG,OAAO,SAAS,QAAQ,eAAe,UAAU,KAAK,SAAA;AAAA,QAClE,MAAK;AAAA,QACL,cAAW;AAAA,QACX,aAAU;AAAA,QACT,GAAG;AAAA,QAGH,UAAA;AAAA,UAAA,MAAM,KAAK,EAAE,QAAQ,OAAA,CAAQ,EAAE,IAAI,CAAC,GAAG,UACtC,qBAAC,SAAgB,WAAU,UAAS,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,MAAA,GAEzF,UAAA;AAAA,YAAA,cACC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAM;AAAA,gBACN,QAAO;AAAA,gBACP,SAAQ;AAAA,gBACR;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAAA;AAAA,YAIJ;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAM;AAAA,gBACN,QAAO;AAAA,gBACP,SAAQ;AAAA,gBACR;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAAA;AAAA,UACF,EAAA,GApBQ,KAqBV,CACD;AAAA,UAGA,cACC,oBAAC,OAAA,EAAI,WAAW,GAAG,QAAQ,WAAW,GAAG,OAAO,EAAE,WAAW,MAAA,GAC3D,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP,QAAO;AAAA,cACP,SAAQ;AAAA,cACR;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,UAAA,EACF,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,aAAa,cAAc;"}
1
+ {"version":3,"file":"index13.js","sources":["../src/components/skeleton/SkeletonForm.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SkeletonFormProps } from '../../types';\nimport { cn, normalizeSize, useLoaderVisibility } from '../../utils';\nimport { Skeleton } from './Skeleton';\n\n/**\n * SkeletonForm - Form loading skeleton\n *\n * A skeleton loader for form layouts with configurable fields, labels, and submit button.\n *\n * @example\n * ```tsx\n * <SkeletonForm />\n * <SkeletonForm fields={5} showLabels={true} />\n * <SkeletonForm fields={3} showButton={false} />\n * <SkeletonForm fields={4} buttonPosition=\"right\" />\n * ```\n */\nexport const SkeletonForm = forwardRef<HTMLDivElement, SkeletonFormProps>(\n (\n {\n fields = 3,\n showLabels = true,\n showButton = true,\n gap = 16,\n buttonWidth = '120px',\n buttonPosition = 'left',\n animate = true,\n baseColor,\n highlightColor,\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'skeleton-form',\n visible = true,\n ...rest\n },\n ref\n ) => {\n const { shouldRender, opacity, transitionStyle } = useLoaderVisibility(\n visible,\n delay,\n minDuration,\n transition\n );\n\n if (!shouldRender) return null;\n\n const gapValue = normalizeSize(gap);\n const buttonAlign =\n buttonPosition === 'left'\n ? 'justify-start'\n : buttonPosition === 'right'\n ? 'justify-end'\n : 'justify-center';\n\n return (\n <div\n ref={ref}\n data-testid={testId}\n className={cn('w-full', className)}\n style={{ ...style, display: 'flex', flexDirection: 'column', gap: gapValue, opacity, transition: transitionStyle }}\n role=\"status\"\n aria-label=\"Loading form...\"\n aria-busy=\"true\"\n {...rest}\n >\n {/* Form Fields */}\n {Array.from({ length: fields }).map((_, index) => (\n <div key={index} className=\"w-full\" style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n {/* Field Label */}\n {showLabels && (\n <Skeleton\n width=\"30%\"\n height=\"0.875rem\"\n variant=\"text\"\n animate={animate}\n baseColor={baseColor}\n highlightColor={highlightColor}\n />\n )}\n {/* Field Input */}\n <Skeleton\n width=\"100%\"\n height=\"2.5rem\"\n variant=\"rectangular\"\n animate={animate}\n baseColor={baseColor}\n highlightColor={highlightColor}\n />\n </div>\n ))}\n\n {/* Submit Button */}\n {showButton && (\n <div className={cn('flex', buttonAlign)} style={{ marginTop: '8px' }}>\n <Skeleton\n width={buttonWidth}\n height=\"2.5rem\"\n variant=\"rounded\"\n animate={animate}\n baseColor={baseColor}\n highlightColor={highlightColor}\n />\n </div>\n )}\n </div>\n );\n }\n);\n\nSkeletonForm.displayName = 'SkeletonForm';\n"],"names":[],"mappings":";;;;;;AAkBO,MAAM,eAAe;AAAA,EAC1B,CACE;AAAA,IACE,SAAS;AAAA,IACT,aAAa;AAAA,IACb,aAAa;AAAA,IACb,MAAM;AAAA,IACN,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,EAAE,cAAc,SAAS,gBAAA,IAAoB;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,CAAC,aAAc,QAAO;AAE1B,UAAM,WAAW,cAAc,GAAG;AAClC,UAAM,cACJ,mBAAmB,SACf,kBACA,mBAAmB,UACnB,gBACA;AAEN,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAa;AAAA,QACb,WAAW,GAAG,UAAU,SAAS;AAAA,QACjC,OAAO,EAAE,GAAG,OAAO,SAAS,QAAQ,eAAe,UAAU,KAAK,UAAU,SAAS,YAAY,gBAAA;AAAA,QACjG,MAAK;AAAA,QACL,cAAW;AAAA,QACX,aAAU;AAAA,QACT,GAAG;AAAA,QAGH,UAAA;AAAA,UAAA,MAAM,KAAK,EAAE,QAAQ,OAAA,CAAQ,EAAE,IAAI,CAAC,GAAG,UACtC,qBAAC,SAAgB,WAAU,UAAS,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,MAAA,GAEzF,UAAA;AAAA,YAAA,cACC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAM;AAAA,gBACN,QAAO;AAAA,gBACP,SAAQ;AAAA,gBACR;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAAA;AAAA,YAIJ;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,OAAM;AAAA,gBACN,QAAO;AAAA,gBACP,SAAQ;AAAA,gBACR;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAAA;AAAA,UACF,EAAA,GApBQ,KAqBV,CACD;AAAA,UAGA,cACC,oBAAC,OAAA,EAAI,WAAW,GAAG,QAAQ,WAAW,GAAG,OAAO,EAAE,WAAW,MAAA,GAC3D,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP,QAAO;AAAA,cACP,SAAQ;AAAA,cACR;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,UAAA,EACF,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,aAAa,cAAc;"}
package/dist/index14.cjs CHANGED
@@ -13,6 +13,9 @@ const SpinnerCircle = 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-circle",
@@ -20,16 +23,26 @@ const SpinnerCircle = 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
  return /* @__PURE__ */ jsxRuntime.jsx(
27
36
  "div",
28
37
  {
29
38
  ref,
30
39
  "data-testid": testId,
31
40
  className: classNames.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":"index14.cjs","sources":["../src/components/spinner/SpinnerCircle.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerCircleProps } from '../../types';\nimport { cn, normalizeSize, useReducedMotion, getEffectiveDuration } from '../../utils';\n\n/**\n * SpinnerCircle - Basic rotating circle spinner\n *\n * A simple, elegant circular spinner with a partial arc that rotates continuously.\n *\n * @example\n * ```tsx\n * <SpinnerCircle size={40} color=\"#3b82f6\" />\n * <SpinnerCircle size=\"lg\" thickness={3} speed=\"fast\" />\n * <SpinnerCircle size=\"md\" reverse />\n * ```\n */\nexport const SpinnerCircle = forwardRef<HTMLDivElement, SpinnerCircleProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n thickness = 4,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n className,\n style,\n testId = 'spinner-circle',\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 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 <svg\n className=\"animate-spinner-rotate\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n animationDuration: effectiveDuration,\n animationDirection: reverse ? 'reverse' : 'normal',\n }}\n viewBox=\"0 0 50 50\"\n >\n <circle\n cx=\"25\"\n cy=\"25\"\n r={25 - thickness * 2}\n fill=\"none\"\n stroke={color}\n strokeWidth={thickness}\n strokeDasharray=\"80, 200\"\n strokeLinecap=\"round\"\n />\n </svg>\n </div>\n );\n }\n);\n\nSpinnerCircle.displayName = 'SpinnerCircle';\n"],"names":["forwardRef","useReducedMotion","getEffectiveDuration","jsx","cn","normalizeSize"],"mappings":";;;;;;;AAgBO,MAAM,gBAAgBA,MAAAA;AAAAA,EAC3B,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,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,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,mBAAmB;AAAA,cACnB,oBAAoB,UAAU,YAAY;AAAA,YAAA;AAAA,YAE5C,SAAQ;AAAA,YAER,UAAAF,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,GAAG,KAAK,YAAY;AAAA,gBACpB,MAAK;AAAA,gBACL,QAAQ;AAAA,gBACR,aAAa;AAAA,gBACb,iBAAgB;AAAA,gBAChB,eAAc;AAAA,cAAA;AAAA,YAAA;AAAA,UAChB;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,cAAc,cAAc;;"}
1
+ {"version":3,"file":"index14.cjs","sources":["../src/components/spinner/SpinnerCircle.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerCircleProps } from '../../types';\nimport {\n cn,\n normalizeSize,\n useReducedMotion,\n getEffectiveDuration,\n useLoaderVisibility,\n} from '../../utils';\n\n/**\n * SpinnerCircle - Basic rotating circle spinner\n *\n * A simple, elegant circular spinner with a partial arc that rotates continuously.\n *\n * @example\n * ```tsx\n * <SpinnerCircle size={40} color=\"#3b82f6\" />\n * <SpinnerCircle size=\"lg\" thickness={3} speed=\"fast\" />\n * <SpinnerCircle size=\"md\" reverse />\n * ```\n */\nexport const SpinnerCircle = forwardRef<HTMLDivElement, SpinnerCircleProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n thickness = 4,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-circle',\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 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 <svg\n className=\"animate-spinner-rotate\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n animationDuration: effectiveDuration,\n animationDirection: reverse ? 'reverse' : 'normal',\n }}\n viewBox=\"0 0 50 50\"\n >\n <circle\n cx=\"25\"\n cy=\"25\"\n r={25 - thickness * 2}\n fill=\"none\"\n stroke={color}\n strokeWidth={thickness}\n strokeDasharray=\"80, 200\"\n strokeLinecap=\"round\"\n />\n </svg>\n </div>\n );\n }\n);\n\nSpinnerCircle.displayName = 'SpinnerCircle';\n"],"names":["forwardRef","useReducedMotion","getEffectiveDuration","useLoaderVisibility","jsx","cn","normalizeSize"],"mappings":";;;;;;;AAsBO,MAAM,gBAAgBA,MAAAA;AAAAA,EAC3B,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,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,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,mBAAmB;AAAA,cACnB,oBAAoB,UAAU,YAAY;AAAA,YAAA;AAAA,YAE5C,SAAQ;AAAA,YAER,UAAAF,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,GAAG,KAAK,YAAY;AAAA,gBACpB,MAAK;AAAA,gBACL,QAAQ;AAAA,gBACR,aAAa;AAAA,gBACb,iBAAgB;AAAA,gBAChB,eAAc;AAAA,cAAA;AAAA,YAAA;AAAA,UAChB;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,cAAc,cAAc;;"}
package/dist/index14.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 SpinnerCircle = forwardRef(
@@ -11,6 +11,9 @@ const SpinnerCircle = 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-circle",
@@ -18,16 +21,26 @@ const SpinnerCircle = 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
  return /* @__PURE__ */ jsx(
25
34
  "div",
26
35
  {
27
36
  ref,
28
37
  "data-testid": testId,
29
38
  className: cn("inline-flex items-center justify-center", className),
30
- style,
39
+ style: {
40
+ ...style,
41
+ opacity,
42
+ transition: transitionStyle
43
+ },
31
44
  role: "status",
32
45
  "aria-label": ariaLabel,
33
46
  "aria-busy": "true",
@@ -1 +1 @@
1
- {"version":3,"file":"index14.js","sources":["../src/components/spinner/SpinnerCircle.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerCircleProps } from '../../types';\nimport { cn, normalizeSize, useReducedMotion, getEffectiveDuration } from '../../utils';\n\n/**\n * SpinnerCircle - Basic rotating circle spinner\n *\n * A simple, elegant circular spinner with a partial arc that rotates continuously.\n *\n * @example\n * ```tsx\n * <SpinnerCircle size={40} color=\"#3b82f6\" />\n * <SpinnerCircle size=\"lg\" thickness={3} speed=\"fast\" />\n * <SpinnerCircle size=\"md\" reverse />\n * ```\n */\nexport const SpinnerCircle = forwardRef<HTMLDivElement, SpinnerCircleProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n thickness = 4,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n className,\n style,\n testId = 'spinner-circle',\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 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 <svg\n className=\"animate-spinner-rotate\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n animationDuration: effectiveDuration,\n animationDirection: reverse ? 'reverse' : 'normal',\n }}\n viewBox=\"0 0 50 50\"\n >\n <circle\n cx=\"25\"\n cy=\"25\"\n r={25 - thickness * 2}\n fill=\"none\"\n stroke={color}\n strokeWidth={thickness}\n strokeDasharray=\"80, 200\"\n strokeLinecap=\"round\"\n />\n </svg>\n </div>\n );\n }\n);\n\nSpinnerCircle.displayName = 'SpinnerCircle';\n"],"names":[],"mappings":";;;;;AAgBO,MAAM,gBAAgB;AAAA,EAC3B,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,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,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,mBAAmB;AAAA,cACnB,oBAAoB,UAAU,YAAY;AAAA,YAAA;AAAA,YAE5C,SAAQ;AAAA,YAER,UAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,GAAG,KAAK,YAAY;AAAA,gBACpB,MAAK;AAAA,gBACL,QAAQ;AAAA,gBACR,aAAa;AAAA,gBACb,iBAAgB;AAAA,gBAChB,eAAc;AAAA,cAAA;AAAA,YAAA;AAAA,UAChB;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,cAAc,cAAc;"}
1
+ {"version":3,"file":"index14.js","sources":["../src/components/spinner/SpinnerCircle.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerCircleProps } from '../../types';\nimport {\n cn,\n normalizeSize,\n useReducedMotion,\n getEffectiveDuration,\n useLoaderVisibility,\n} from '../../utils';\n\n/**\n * SpinnerCircle - Basic rotating circle spinner\n *\n * A simple, elegant circular spinner with a partial arc that rotates continuously.\n *\n * @example\n * ```tsx\n * <SpinnerCircle size={40} color=\"#3b82f6\" />\n * <SpinnerCircle size=\"lg\" thickness={3} speed=\"fast\" />\n * <SpinnerCircle size=\"md\" reverse />\n * ```\n */\nexport const SpinnerCircle = forwardRef<HTMLDivElement, SpinnerCircleProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n thickness = 4,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-circle',\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 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 <svg\n className=\"animate-spinner-rotate\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n animationDuration: effectiveDuration,\n animationDirection: reverse ? 'reverse' : 'normal',\n }}\n viewBox=\"0 0 50 50\"\n >\n <circle\n cx=\"25\"\n cy=\"25\"\n r={25 - thickness * 2}\n fill=\"none\"\n stroke={color}\n strokeWidth={thickness}\n strokeDasharray=\"80, 200\"\n strokeLinecap=\"round\"\n />\n </svg>\n </div>\n );\n }\n);\n\nSpinnerCircle.displayName = 'SpinnerCircle';\n"],"names":[],"mappings":";;;;;AAsBO,MAAM,gBAAgB;AAAA,EAC3B,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,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,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,mBAAmB;AAAA,cACnB,oBAAoB,UAAU,YAAY;AAAA,YAAA;AAAA,YAE5C,SAAQ;AAAA,YAER,UAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,GAAG,KAAK,YAAY;AAAA,gBACpB,MAAK;AAAA,gBACL,QAAQ;AAAA,gBACR,aAAa;AAAA,gBACb,iBAAgB;AAAA,gBAChB,eAAc;AAAA,cAAA;AAAA,YAAA;AAAA,UAChB;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,cAAc,cAAc;"}
package/dist/index15.cjs CHANGED
@@ -14,6 +14,9 @@ const SpinnerRing = 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-ring",
@@ -21,16 +24,26 @@ const SpinnerRing = 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
  return /* @__PURE__ */ jsxRuntime.jsx(
28
37
  "div",
29
38
  {
30
39
  ref,
31
40
  "data-testid": testId,
32
41
  className: classNames.cn("inline-flex items-center justify-center", className),
33
- style,
42
+ style: {
43
+ ...style,
44
+ opacity,
45
+ transition: transitionStyle
46
+ },
34
47
  role: "status",
35
48
  "aria-label": ariaLabel,
36
49
  "aria-busy": "true",
@@ -1 +1 @@
1
- {"version":3,"file":"index15.cjs","sources":["../src/components/spinner/SpinnerRing.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerRingProps } from '../../types';\nimport { cn, normalizeSize, useReducedMotion, getEffectiveDuration } from '../../utils';\n\n/**\n * SpinnerRing - Border-only rotating spinner\n *\n * A ring-style spinner with a transparent center and colored border.\n *\n * @example\n * ```tsx\n * <SpinnerRing size=\"lg\" color=\"#8b5cf6\" />\n * <SpinnerRing size=\"sm\" thickness={3} speed=\"slow\" />\n * <SpinnerRing size=\"md\" color=\"#3b82f6\" secondaryColor=\"#e0e0e0\" reverse />\n * ```\n */\nexport const SpinnerRing = forwardRef<HTMLDivElement, SpinnerRingProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n secondaryColor = 'rgba(0, 0, 0, 0.1)',\n thickness = 4,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n className,\n style,\n testId = 'spinner-ring',\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 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=\"rounded-full\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n border: `${thickness}px solid ${secondaryColor}`,\n borderTopColor: color,\n animation: `spinner-rotate ${effectiveDuration} linear infinite`,\n animationDirection: reverse ? 'reverse' : 'normal',\n }}\n />\n </div>\n );\n }\n);\n\nSpinnerRing.displayName = 'SpinnerRing';\n"],"names":["forwardRef","useReducedMotion","getEffectiveDuration","jsx","cn","normalizeSize"],"mappings":";;;;;;;AAgBO,MAAM,cAAcA,MAAAA;AAAAA,EACzB,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,YAAY;AAAA,IACZ,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,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,QAAQ,GAAG,SAAS,YAAY,cAAc;AAAA,cAC9C,gBAAgB;AAAA,cAChB,WAAW,kBAAkB,iBAAiB;AAAA,cAC9C,oBAAoB,UAAU,YAAY;AAAA,YAAA;AAAA,UAC5C;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,YAAY,cAAc;;"}
1
+ {"version":3,"file":"index15.cjs","sources":["../src/components/spinner/SpinnerRing.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerRingProps } from '../../types';\nimport {\n cn,\n normalizeSize,\n useReducedMotion,\n getEffectiveDuration,\n useLoaderVisibility,\n} from '../../utils';\n\n/**\n * SpinnerRing - Border-only rotating spinner\n *\n * A ring-style spinner with a transparent center and colored border.\n *\n * @example\n * ```tsx\n * <SpinnerRing size=\"lg\" color=\"#8b5cf6\" />\n * <SpinnerRing size=\"sm\" thickness={3} speed=\"slow\" />\n * <SpinnerRing size=\"md\" color=\"#3b82f6\" secondaryColor=\"#e0e0e0\" reverse />\n * ```\n */\nexport const SpinnerRing = forwardRef<HTMLDivElement, SpinnerRingProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n secondaryColor = 'rgba(0, 0, 0, 0.1)',\n thickness = 4,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-ring',\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 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=\"rounded-full\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n border: `${thickness}px solid ${secondaryColor}`,\n borderTopColor: color,\n animation: `spinner-rotate ${effectiveDuration} linear infinite`,\n animationDirection: reverse ? 'reverse' : 'normal',\n }}\n />\n </div>\n );\n }\n);\n\nSpinnerRing.displayName = 'SpinnerRing';\n"],"names":["forwardRef","useReducedMotion","getEffectiveDuration","useLoaderVisibility","jsx","cn","normalizeSize"],"mappings":";;;;;;;AAsBO,MAAM,cAAcA,MAAAA;AAAAA,EACzB,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,YAAY;AAAA,IACZ,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,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,QAAQ,GAAG,SAAS,YAAY,cAAc;AAAA,cAC9C,gBAAgB;AAAA,cAChB,WAAW,kBAAkB,iBAAiB;AAAA,cAC9C,oBAAoB,UAAU,YAAY;AAAA,YAAA;AAAA,UAC5C;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,YAAY,cAAc;;"}
package/dist/index15.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 SpinnerRing = forwardRef(
@@ -12,6 +12,9 @@ const SpinnerRing = 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-ring",
@@ -19,16 +22,26 @@ const SpinnerRing = 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
  return /* @__PURE__ */ jsx(
26
35
  "div",
27
36
  {
28
37
  ref,
29
38
  "data-testid": testId,
30
39
  className: cn("inline-flex items-center justify-center", className),
31
- style,
40
+ style: {
41
+ ...style,
42
+ opacity,
43
+ transition: transitionStyle
44
+ },
32
45
  role: "status",
33
46
  "aria-label": ariaLabel,
34
47
  "aria-busy": "true",
@@ -1 +1 @@
1
- {"version":3,"file":"index15.js","sources":["../src/components/spinner/SpinnerRing.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerRingProps } from '../../types';\nimport { cn, normalizeSize, useReducedMotion, getEffectiveDuration } from '../../utils';\n\n/**\n * SpinnerRing - Border-only rotating spinner\n *\n * A ring-style spinner with a transparent center and colored border.\n *\n * @example\n * ```tsx\n * <SpinnerRing size=\"lg\" color=\"#8b5cf6\" />\n * <SpinnerRing size=\"sm\" thickness={3} speed=\"slow\" />\n * <SpinnerRing size=\"md\" color=\"#3b82f6\" secondaryColor=\"#e0e0e0\" reverse />\n * ```\n */\nexport const SpinnerRing = forwardRef<HTMLDivElement, SpinnerRingProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n secondaryColor = 'rgba(0, 0, 0, 0.1)',\n thickness = 4,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n className,\n style,\n testId = 'spinner-ring',\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 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=\"rounded-full\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n border: `${thickness}px solid ${secondaryColor}`,\n borderTopColor: color,\n animation: `spinner-rotate ${effectiveDuration} linear infinite`,\n animationDirection: reverse ? 'reverse' : 'normal',\n }}\n />\n </div>\n );\n }\n);\n\nSpinnerRing.displayName = 'SpinnerRing';\n"],"names":[],"mappings":";;;;;AAgBO,MAAM,cAAc;AAAA,EACzB,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,YAAY;AAAA,IACZ,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,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,QAAQ,GAAG,SAAS,YAAY,cAAc;AAAA,cAC9C,gBAAgB;AAAA,cAChB,WAAW,kBAAkB,iBAAiB;AAAA,cAC9C,oBAAoB,UAAU,YAAY;AAAA,YAAA;AAAA,UAC5C;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,YAAY,cAAc;"}
1
+ {"version":3,"file":"index15.js","sources":["../src/components/spinner/SpinnerRing.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerRingProps } from '../../types';\nimport {\n cn,\n normalizeSize,\n useReducedMotion,\n getEffectiveDuration,\n useLoaderVisibility,\n} from '../../utils';\n\n/**\n * SpinnerRing - Border-only rotating spinner\n *\n * A ring-style spinner with a transparent center and colored border.\n *\n * @example\n * ```tsx\n * <SpinnerRing size=\"lg\" color=\"#8b5cf6\" />\n * <SpinnerRing size=\"sm\" thickness={3} speed=\"slow\" />\n * <SpinnerRing size=\"md\" color=\"#3b82f6\" secondaryColor=\"#e0e0e0\" reverse />\n * ```\n */\nexport const SpinnerRing = forwardRef<HTMLDivElement, SpinnerRingProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n secondaryColor = 'rgba(0, 0, 0, 0.1)',\n thickness = 4,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-ring',\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 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=\"rounded-full\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n border: `${thickness}px solid ${secondaryColor}`,\n borderTopColor: color,\n animation: `spinner-rotate ${effectiveDuration} linear infinite`,\n animationDirection: reverse ? 'reverse' : 'normal',\n }}\n />\n </div>\n );\n }\n);\n\nSpinnerRing.displayName = 'SpinnerRing';\n"],"names":[],"mappings":";;;;;AAsBO,MAAM,cAAc;AAAA,EACzB,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,YAAY;AAAA,IACZ,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,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,QAAQ,GAAG,SAAS,YAAY,cAAc;AAAA,cAC9C,gBAAgB;AAAA,cAChB,WAAW,kBAAkB,iBAAiB;AAAA,cAC9C,oBAAoB,UAAU,YAAY;AAAA,YAAA;AAAA,UAC5C;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,YAAY,cAAc;"}
package/dist/index16.cjs CHANGED
@@ -14,6 +14,9 @@ const SpinnerDots = 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-dots",
@@ -21,9 +24,15 @@ const SpinnerDots = 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.parseSizeToNumber(size, 40);
28
37
  const dotSizeValue = colors.parseSizeToNumber(dotSize, 4);
29
38
  const radius = (sizeValue - dotSizeValue) / 2;
@@ -33,7 +42,11 @@ const SpinnerDots = react.forwardRef(
33
42
  ref,
34
43
  "data-testid": testId,
35
44
  className: classNames.cn("inline-flex items-center justify-center", className),
36
- style,
45
+ style: {
46
+ ...style,
47
+ opacity,
48
+ transition: transitionStyle
49
+ },
37
50
  role: "status",
38
51
  "aria-label": ariaLabel,
39
52
  "aria-busy": "true",
@@ -1 +1 @@
1
- {"version":3,"file":"index16.cjs","sources":["../src/components/spinner/SpinnerDots.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerDotsProps } from '../../types';\nimport { cn, normalizeSize, parseSizeToNumber, useReducedMotion, getEffectiveDuration } from '../../utils';\n\n/**\n * SpinnerDots - Multiple dots rotating around center\n *\n * A spinner with multiple dots arranged in a circle that rotates continuously.\n *\n * @example\n * ```tsx\n * <SpinnerDots size=\"lg\" color=\"#3b82f6\" />\n * <SpinnerDots size=\"md\" dotCount={8} dotSize={6} reverse />\n * ```\n */\nexport const SpinnerDots = forwardRef<HTMLDivElement, SpinnerDotsProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n dotCount = 8,\n dotSize = 4,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n className,\n style,\n testId = 'spinner-dots',\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 dotSizeValue = parseSizeToNumber(dotSize, 4);\n const radius = (sizeValue - dotSizeValue) / 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=\"relative\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n animation: `spinner-rotate ${effectiveDuration} linear infinite`,\n animationDirection: reverse ? 'reverse' : 'normal',\n }}\n >\n {Array.from({ length: dotCount }).map((_, index) => {\n const angle = (360 / dotCount) * index;\n const radian = (angle * Math.PI) / 180;\n const x = radius * Math.cos(radian) + radius;\n const y = radius * Math.sin(radian) + radius;\n\n return (\n <div\n key={index}\n className=\"absolute rounded-full\"\n style={{\n width: normalizeSize(dotSize),\n height: normalizeSize(dotSize),\n backgroundColor: color,\n left: `${x}px`,\n top: `${y}px`,\n opacity: 1 - (index / dotCount) * 0.7, // Fade effect\n }}\n />\n );\n })}\n </div>\n </div>\n );\n }\n);\n\nSpinnerDots.displayName = 'SpinnerDots';\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,UAAU;AAAA,IACV,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,eAAeA,OAAAA,kBAAkB,SAAS,CAAC;AACjD,UAAM,UAAU,YAAY,gBAAgB;AAE5C,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,WAAW,kBAAkB,iBAAiB;AAAA,cAC9C,oBAAoB,UAAU,YAAY;AAAA,YAAA;AAAA,YAG3C,UAAA,MAAM,KAAK,EAAE,QAAQ,SAAA,CAAU,EAAE,IAAI,CAAC,GAAG,UAAU;AAClD,oBAAM,QAAS,MAAM,WAAY;AACjC,oBAAM,SAAU,QAAQ,KAAK,KAAM;AACnC,oBAAM,IAAI,SAAS,KAAK,IAAI,MAAM,IAAI;AACtC,oBAAM,IAAI,SAAS,KAAK,IAAI,MAAM,IAAI;AAEtC,qBACEF,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,OAAOE,OAAAA,cAAc,OAAO;AAAA,oBAC5B,QAAQA,OAAAA,cAAc,OAAO;AAAA,oBAC7B,iBAAiB;AAAA,oBACjB,MAAM,GAAG,CAAC;AAAA,oBACV,KAAK,GAAG,CAAC;AAAA,oBACT,SAAS,IAAK,QAAQ,WAAY;AAAA;AAAA,kBAAA;AAAA,gBACpC;AAAA,gBATK;AAAA,cAAA;AAAA,YAYX,CAAC;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,YAAY,cAAc;;"}
1
+ {"version":3,"file":"index16.cjs","sources":["../src/components/spinner/SpinnerDots.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerDotsProps } from '../../types';\nimport {\n cn,\n normalizeSize,\n parseSizeToNumber,\n useReducedMotion,\n getEffectiveDuration,\n useLoaderVisibility,\n} from '../../utils';\n\n/**\n * SpinnerDots - Multiple dots rotating around center\n *\n * A spinner with multiple dots arranged in a circle that rotates continuously.\n *\n * @example\n * ```tsx\n * <SpinnerDots size=\"lg\" color=\"#3b82f6\" />\n * <SpinnerDots size=\"md\" dotCount={8} dotSize={6} reverse />\n * ```\n */\nexport const SpinnerDots = forwardRef<HTMLDivElement, SpinnerDotsProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n dotCount = 8,\n dotSize = 4,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-dots',\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 dotSizeValue = parseSizeToNumber(dotSize, 4);\n const radius = (sizeValue - dotSizeValue) / 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=\"relative\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n animation: `spinner-rotate ${effectiveDuration} linear infinite`,\n animationDirection: reverse ? 'reverse' : 'normal',\n }}\n >\n {Array.from({ length: dotCount }).map((_, index) => {\n const angle = (360 / dotCount) * index;\n const radian = (angle * Math.PI) / 180;\n const x = radius * Math.cos(radian) + radius;\n const y = radius * Math.sin(radian) + radius;\n\n return (\n <div\n key={index}\n className=\"absolute rounded-full\"\n style={{\n width: normalizeSize(dotSize),\n height: normalizeSize(dotSize),\n backgroundColor: color,\n left: `${x}px`,\n top: `${y}px`,\n opacity: 1 - (index / dotCount) * 0.7, // Fade effect\n }}\n />\n );\n })}\n </div>\n </div>\n );\n }\n);\n\nSpinnerDots.displayName = 'SpinnerDots';\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,UAAU;AAAA,IACV,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,eAAeA,OAAAA,kBAAkB,SAAS,CAAC;AACjD,UAAM,UAAU,YAAY,gBAAgB;AAE5C,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,WAAW,kBAAkB,iBAAiB;AAAA,cAC9C,oBAAoB,UAAU,YAAY;AAAA,YAAA;AAAA,YAG3C,UAAA,MAAM,KAAK,EAAE,QAAQ,SAAA,CAAU,EAAE,IAAI,CAAC,GAAG,UAAU;AAClD,oBAAM,QAAS,MAAM,WAAY;AACjC,oBAAM,SAAU,QAAQ,KAAK,KAAM;AACnC,oBAAM,IAAI,SAAS,KAAK,IAAI,MAAM,IAAI;AACtC,oBAAM,IAAI,SAAS,KAAK,IAAI,MAAM,IAAI;AAEtC,qBACEF,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,OAAOE,OAAAA,cAAc,OAAO;AAAA,oBAC5B,QAAQA,OAAAA,cAAc,OAAO;AAAA,oBAC7B,iBAAiB;AAAA,oBACjB,MAAM,GAAG,CAAC;AAAA,oBACV,KAAK,GAAG,CAAC;AAAA,oBACT,SAAS,IAAK,QAAQ,WAAY;AAAA;AAAA,kBAAA;AAAA,gBACpC;AAAA,gBATK;AAAA,cAAA;AAAA,YAYX,CAAC;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,YAAY,cAAc;;"}
package/dist/index16.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  import { normalizeSize, parseSizeToNumber } from "./index4.js";
4
- import { useReducedMotion, getEffectiveDuration } from "./index31.js";
4
+ import { useReducedMotion, useLoaderVisibility, getEffectiveDuration } from "./index31.js";
5
5
  import { cn } from "./index3.js";
6
6
  const SpinnerDots = forwardRef(
7
7
  ({
@@ -12,6 +12,9 @@ const SpinnerDots = 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-dots",
@@ -19,9 +22,15 @@ const SpinnerDots = 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 = parseSizeToNumber(size, 40);
26
35
  const dotSizeValue = parseSizeToNumber(dotSize, 4);
27
36
  const radius = (sizeValue - dotSizeValue) / 2;
@@ -31,7 +40,11 @@ const SpinnerDots = forwardRef(
31
40
  ref,
32
41
  "data-testid": testId,
33
42
  className: 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":"index16.js","sources":["../src/components/spinner/SpinnerDots.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerDotsProps } from '../../types';\nimport { cn, normalizeSize, parseSizeToNumber, useReducedMotion, getEffectiveDuration } from '../../utils';\n\n/**\n * SpinnerDots - Multiple dots rotating around center\n *\n * A spinner with multiple dots arranged in a circle that rotates continuously.\n *\n * @example\n * ```tsx\n * <SpinnerDots size=\"lg\" color=\"#3b82f6\" />\n * <SpinnerDots size=\"md\" dotCount={8} dotSize={6} reverse />\n * ```\n */\nexport const SpinnerDots = forwardRef<HTMLDivElement, SpinnerDotsProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n dotCount = 8,\n dotSize = 4,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n className,\n style,\n testId = 'spinner-dots',\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 dotSizeValue = parseSizeToNumber(dotSize, 4);\n const radius = (sizeValue - dotSizeValue) / 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=\"relative\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n animation: `spinner-rotate ${effectiveDuration} linear infinite`,\n animationDirection: reverse ? 'reverse' : 'normal',\n }}\n >\n {Array.from({ length: dotCount }).map((_, index) => {\n const angle = (360 / dotCount) * index;\n const radian = (angle * Math.PI) / 180;\n const x = radius * Math.cos(radian) + radius;\n const y = radius * Math.sin(radian) + radius;\n\n return (\n <div\n key={index}\n className=\"absolute rounded-full\"\n style={{\n width: normalizeSize(dotSize),\n height: normalizeSize(dotSize),\n backgroundColor: color,\n left: `${x}px`,\n top: `${y}px`,\n opacity: 1 - (index / dotCount) * 0.7, // Fade effect\n }}\n />\n );\n })}\n </div>\n </div>\n );\n }\n);\n\nSpinnerDots.displayName = 'SpinnerDots';\n"],"names":[],"mappings":";;;;;AAeO,MAAM,cAAc;AAAA,EACzB,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,UAAU;AAAA,IACV,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,eAAe,kBAAkB,SAAS,CAAC;AACjD,UAAM,UAAU,YAAY,gBAAgB;AAE5C,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,WAAW,kBAAkB,iBAAiB;AAAA,cAC9C,oBAAoB,UAAU,YAAY;AAAA,YAAA;AAAA,YAG3C,UAAA,MAAM,KAAK,EAAE,QAAQ,SAAA,CAAU,EAAE,IAAI,CAAC,GAAG,UAAU;AAClD,oBAAM,QAAS,MAAM,WAAY;AACjC,oBAAM,SAAU,QAAQ,KAAK,KAAM;AACnC,oBAAM,IAAI,SAAS,KAAK,IAAI,MAAM,IAAI;AACtC,oBAAM,IAAI,SAAS,KAAK,IAAI,MAAM,IAAI;AAEtC,qBACE;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,OAAO,cAAc,OAAO;AAAA,oBAC5B,QAAQ,cAAc,OAAO;AAAA,oBAC7B,iBAAiB;AAAA,oBACjB,MAAM,GAAG,CAAC;AAAA,oBACV,KAAK,GAAG,CAAC;AAAA,oBACT,SAAS,IAAK,QAAQ,WAAY;AAAA;AAAA,kBAAA;AAAA,gBACpC;AAAA,gBATK;AAAA,cAAA;AAAA,YAYX,CAAC;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,YAAY,cAAc;"}
1
+ {"version":3,"file":"index16.js","sources":["../src/components/spinner/SpinnerDots.tsx"],"sourcesContent":["import { forwardRef } from 'react';\nimport { SpinnerDotsProps } from '../../types';\nimport {\n cn,\n normalizeSize,\n parseSizeToNumber,\n useReducedMotion,\n getEffectiveDuration,\n useLoaderVisibility,\n} from '../../utils';\n\n/**\n * SpinnerDots - Multiple dots rotating around center\n *\n * A spinner with multiple dots arranged in a circle that rotates continuously.\n *\n * @example\n * ```tsx\n * <SpinnerDots size=\"lg\" color=\"#3b82f6\" />\n * <SpinnerDots size=\"md\" dotCount={8} dotSize={6} reverse />\n * ```\n */\nexport const SpinnerDots = forwardRef<HTMLDivElement, SpinnerDotsProps>(\n (\n {\n size = 'md',\n color = '#3b82f6',\n dotCount = 8,\n dotSize = 4,\n speed = 'normal',\n reverse = false,\n respectMotionPreference = true,\n delay = 0,\n minDuration = 0,\n transition,\n className,\n style,\n testId = 'spinner-dots',\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 dotSizeValue = parseSizeToNumber(dotSize, 4);\n const radius = (sizeValue - dotSizeValue) / 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=\"relative\"\n style={{\n width: normalizeSize(size),\n height: normalizeSize(size),\n animation: `spinner-rotate ${effectiveDuration} linear infinite`,\n animationDirection: reverse ? 'reverse' : 'normal',\n }}\n >\n {Array.from({ length: dotCount }).map((_, index) => {\n const angle = (360 / dotCount) * index;\n const radian = (angle * Math.PI) / 180;\n const x = radius * Math.cos(radian) + radius;\n const y = radius * Math.sin(radian) + radius;\n\n return (\n <div\n key={index}\n className=\"absolute rounded-full\"\n style={{\n width: normalizeSize(dotSize),\n height: normalizeSize(dotSize),\n backgroundColor: color,\n left: `${x}px`,\n top: `${y}px`,\n opacity: 1 - (index / dotCount) * 0.7, // Fade effect\n }}\n />\n );\n })}\n </div>\n </div>\n );\n }\n);\n\nSpinnerDots.displayName = 'SpinnerDots';\n"],"names":[],"mappings":";;;;;AAsBO,MAAM,cAAc;AAAA,EACzB,CACE;AAAA,IACE,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,UAAU;AAAA,IACV,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,eAAe,kBAAkB,SAAS,CAAC;AACjD,UAAM,UAAU,YAAY,gBAAgB;AAE5C,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,WAAW,kBAAkB,iBAAiB;AAAA,cAC9C,oBAAoB,UAAU,YAAY;AAAA,YAAA;AAAA,YAG3C,UAAA,MAAM,KAAK,EAAE,QAAQ,SAAA,CAAU,EAAE,IAAI,CAAC,GAAG,UAAU;AAClD,oBAAM,QAAS,MAAM,WAAY;AACjC,oBAAM,SAAU,QAAQ,KAAK,KAAM;AACnC,oBAAM,IAAI,SAAS,KAAK,IAAI,MAAM,IAAI;AACtC,oBAAM,IAAI,SAAS,KAAK,IAAI,MAAM,IAAI;AAEtC,qBACE;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,OAAO,cAAc,OAAO;AAAA,oBAC5B,QAAQ,cAAc,OAAO;AAAA,oBAC7B,iBAAiB;AAAA,oBACjB,MAAM,GAAG,CAAC;AAAA,oBACV,KAAK,GAAG,CAAC;AAAA,oBACT,SAAS,IAAK,QAAQ,WAAY;AAAA;AAAA,kBAAA;AAAA,gBACpC;AAAA,gBATK;AAAA,cAAA;AAAA,YAYX,CAAC;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,YAAY,cAAc;"}