@shohojdhara/atomix 0.5.1 → 0.5.2

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 (123) hide show
  1. package/atomix.config.ts +12 -0
  2. package/build-tools/webpack-loader.js +5 -4
  3. package/dist/atomix.css +138 -17
  4. package/dist/atomix.css.map +1 -1
  5. package/dist/atomix.min.css +1 -1
  6. package/dist/atomix.min.css.map +1 -1
  7. package/dist/build-tools/webpack-loader.js +5 -4
  8. package/dist/charts.d.ts +23 -23
  9. package/dist/charts.js +40 -37
  10. package/dist/charts.js.map +1 -1
  11. package/dist/config.d.ts +624 -0
  12. package/dist/config.js +59 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/core.d.ts +2 -2
  15. package/dist/core.js +111 -50
  16. package/dist/core.js.map +1 -1
  17. package/dist/forms.d.ts +3 -6
  18. package/dist/forms.js +2 -2
  19. package/dist/forms.js.map +1 -1
  20. package/dist/heavy.d.ts +1 -1
  21. package/dist/heavy.js +173 -111
  22. package/dist/heavy.js.map +1 -1
  23. package/dist/index.d.ts +98 -65
  24. package/dist/index.esm.js +427 -422
  25. package/dist/index.esm.js.map +1 -1
  26. package/dist/index.js +394 -391
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.min.js +1 -1
  29. package/dist/index.min.js.map +1 -1
  30. package/dist/layout.js +59 -60
  31. package/dist/layout.js.map +1 -1
  32. package/dist/theme.js +4 -4
  33. package/dist/theme.js.map +1 -1
  34. package/package.json +14 -9
  35. package/scripts/atomix-cli.js +15 -1
  36. package/scripts/cli/__tests__/complexity-utils.test.js +24 -0
  37. package/scripts/cli/__tests__/detector.test.js +50 -0
  38. package/scripts/cli/__tests__/template-engine.test.js +23 -0
  39. package/scripts/cli/__tests__/test-setup.js +3 -0
  40. package/scripts/cli/commands/doctor.js +15 -3
  41. package/scripts/cli/commands/generate.js +113 -51
  42. package/scripts/cli/internal/ai-engine.js +30 -10
  43. package/scripts/cli/internal/complexity-utils.js +60 -0
  44. package/scripts/cli/internal/component-validator.js +49 -16
  45. package/scripts/cli/internal/generator.js +89 -36
  46. package/scripts/cli/internal/hook-generator.js +5 -2
  47. package/scripts/cli/internal/itcss-generator.js +16 -12
  48. package/scripts/cli/templates/next-templates.js +81 -30
  49. package/scripts/cli/templates/storybook-templates.js +12 -2
  50. package/scripts/cli/utils/detector.js +45 -7
  51. package/scripts/cli/utils/diagnostics.js +78 -0
  52. package/scripts/cli/utils/telemetry.js +13 -0
  53. package/src/components/Accordion/Accordion.stories.tsx +4 -0
  54. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +1 -1
  55. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +219 -0
  56. package/src/components/AtomixGlass/glass-utils.ts +1 -1
  57. package/src/components/Button/Button.tsx +114 -57
  58. package/src/components/Callout/Callout.tsx +4 -4
  59. package/src/components/Chart/ChartRenderer.tsx +1 -1
  60. package/src/components/Chart/DonutChart.tsx +11 -8
  61. package/src/components/EdgePanel/EdgePanel.tsx +119 -115
  62. package/src/components/Form/Select.tsx +4 -4
  63. package/src/components/List/List.tsx +4 -4
  64. package/src/components/Navigation/SideMenu/SideMenu.tsx +6 -6
  65. package/src/components/PhotoViewer/PhotoViewerImage.tsx +1 -1
  66. package/src/components/ProductReview/ProductReview.tsx +4 -2
  67. package/src/components/Rating/Rating.tsx +4 -2
  68. package/src/components/SectionIntro/SectionIntro.tsx +4 -2
  69. package/src/components/Steps/Steps.tsx +1 -1
  70. package/src/components/Tabs/Tabs.tsx +5 -5
  71. package/src/components/Testimonial/Testimonial.tsx +4 -2
  72. package/src/components/VideoPlayer/VideoPlayer.tsx +4 -2
  73. package/src/layouts/CssGrid/CssGrid.stories.tsx +464 -0
  74. package/src/layouts/CssGrid/CssGrid.tsx +215 -0
  75. package/src/layouts/CssGrid/index.ts +8 -0
  76. package/src/layouts/CssGrid/scripts/CssGrid.js +284 -0
  77. package/src/layouts/CssGrid/scripts/index.js +43 -0
  78. package/src/layouts/Grid/scripts/Container.js +139 -0
  79. package/src/layouts/Grid/scripts/Grid.js +184 -0
  80. package/src/layouts/Grid/scripts/GridCol.js +273 -0
  81. package/src/layouts/Grid/scripts/Row.js +154 -0
  82. package/src/layouts/Grid/scripts/index.js +48 -0
  83. package/src/layouts/MasonryGrid/MasonryGrid.tsx +71 -59
  84. package/src/lib/composables/atomix-glass/useGlassSize.ts +1 -1
  85. package/src/lib/composables/useAccordion.ts +5 -5
  86. package/src/lib/composables/useAtomixGlass.ts +3 -3
  87. package/src/lib/composables/useBarChart.ts +2 -2
  88. package/src/lib/composables/useChart.ts +3 -2
  89. package/src/lib/composables/useChartToolbar.ts +48 -66
  90. package/src/lib/composables/useDataTable.ts +1 -1
  91. package/src/lib/composables/useDatePicker.ts +2 -2
  92. package/src/lib/composables/useEdgePanel.ts +45 -54
  93. package/src/lib/composables/useHeroBackgroundSlider.ts +5 -5
  94. package/src/lib/composables/usePhotoViewer.ts +2 -3
  95. package/src/lib/composables/usePieChart.ts +1 -1
  96. package/src/lib/composables/usePopover.ts +151 -139
  97. package/src/lib/composables/useSideMenu.ts +28 -41
  98. package/src/lib/composables/useSlider.ts +2 -6
  99. package/src/lib/composables/useTooltip.ts +2 -2
  100. package/src/lib/config/index.ts +39 -0
  101. package/src/lib/theme/devtools/Comparator.tsx +1 -1
  102. package/src/lib/theme/devtools/Inspector.tsx +1 -1
  103. package/src/lib/theme/devtools/LiveEditor.tsx +1 -1
  104. package/src/lib/theme/runtime/ThemeProvider.tsx +1 -1
  105. package/src/styles/01-settings/_index.scss +1 -0
  106. package/src/styles/01-settings/_settings.atomix-glass.scss +174 -0
  107. package/src/styles/01-settings/_settings.masonry-grid.scss +42 -6
  108. package/src/styles/02-tools/_tools.glass.scss +6 -0
  109. package/src/styles/05-objects/_objects.masonry-grid.scss +162 -24
  110. package/src/styles/06-components/_components.atomix-glass.scss +4 -4
  111. package/src/lib/composables/useBreadcrumb.ts +0 -81
  112. package/src/lib/composables/useChartInteractions.ts +0 -123
  113. package/src/lib/composables/useChartPerformance.ts +0 -347
  114. package/src/lib/composables/useDropdown.ts +0 -338
  115. package/src/lib/composables/useModal.ts +0 -110
  116. package/src/lib/hooks/usePerformanceMonitor.ts +0 -148
  117. package/src/lib/utils/displacement-generator.ts +0 -92
  118. package/src/lib/utils/memoryMonitor.ts +0 -191
  119. package/src/styles/01-settings/_settings.testtypecheck.scss +0 -53
  120. package/src/styles/01-settings/_settings.typedbutton.scss +0 -53
  121. package/src/styles/06-components/_components.testbutton.scss +0 -212
  122. package/src/styles/06-components/_components.testtypecheck.scss +0 -212
  123. package/src/styles/06-components/_components.typedbutton.scss +0 -212
package/dist/index.js CHANGED
@@ -1988,19 +1988,19 @@ function useAccordion(initialProps) {
1988
1988
  disabled: !1,
1989
1989
  iconPosition: "right",
1990
1990
  ...initialProps
1991
- }, isControlled = "boolean" == typeof defaultProps.isOpen, [internalOpen, setInternalOpen] = React.useState(defaultProps.defaultOpen || !1), isOpen = isControlled ? defaultProps.isOpen : internalOpen, [panelHeight, setPanelHeight] = React.useState(isOpen ? "auto" : "0px"), panelRef = React.useRef(null), contentRef = React.useRef(null), updatePanelHeight = () => {
1991
+ }, isControlled = "boolean" == typeof defaultProps.isOpen, [internalOpen, setInternalOpen] = React.useState(defaultProps.defaultOpen || !1), isOpen = isControlled ? defaultProps.isOpen : internalOpen, [panelHeight, setPanelHeight] = React.useState(isOpen ? "auto" : "0px"), panelRef = React.useRef(null), contentRef = React.useRef(null), updatePanelHeight = React.useCallback((() => {
1992
1992
  if (contentRef.current && panelRef.current) {
1993
1993
  const height = isOpen ? `${contentRef.current.clientHeight}px` : "0px";
1994
1994
  panelRef.current.style.setProperty(ACCORDION.CSS_VARS.PANEL_HEIGHT, height), setPanelHeight(height);
1995
1995
  }
1996
- };
1996
+ }), [ isOpen ]);
1997
1997
  // Controlled/uncontrolled open state
1998
1998
  /**
1999
1999
  * Effect to update panel height when open state changes
2000
2000
  */
2001
2001
  return React.useEffect((() => {
2002
2002
  updatePanelHeight();
2003
- }), [ isOpen ]),
2003
+ }), [ isOpen, updatePanelHeight ]),
2004
2004
  /**
2005
2005
  * Effect to handle window resize and update panel height
2006
2006
  */
@@ -2009,7 +2009,7 @@ function useAccordion(initialProps) {
2009
2009
  isOpen && updatePanelHeight();
2010
2010
  };
2011
2011
  return window.addEventListener("resize", handleResize), () => window.removeEventListener("resize", handleResize);
2012
- }), [ isOpen ]), {
2012
+ }), [ isOpen, updatePanelHeight ]), {
2013
2013
  state: {
2014
2014
  isOpen: isOpen,
2015
2015
  panelHeight: panelHeight
@@ -5344,7 +5344,100 @@ class ThemeNaming {
5344
5344
 
5345
5345
  ThemeNaming.prefix = "atomix";
5346
5346
 
5347
- const Button = React__default.default.memo( React.forwardRef((({label: label, children: children, onClick: onClick, variant: variant = "primary", size: size = "md", disabled: disabled = !1, loading: loading = !1, loadingText: loadingText, icon: icon, iconName: iconName, iconSize: iconSize = "sm", iconPosition: iconPosition = "start", iconOnly: iconOnly = !1, rounded: rounded = !1, fullWidth: fullWidth = !1, block: block = !1, active: active = !1, selected: selected = !1, type: type = "button", className: className = "", as: Component = "button", href: href, target: target, glass: glass, onHover: onHover, onFocus: onFocus, onBlur: onBlur, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, tabIndex: tabIndex, style: style, linkComponent: linkComponent, ...props}, ref) => {
5347
+ var aCallable = aCallable$3, toObject = toObject$2, IndexedObject = indexedObject, lengthOfArrayLike = lengthOfArrayLike$2, $TypeError = TypeError, REDUCE_EMPTY = "Reduce of empty array with no initial value", createMethod = function(IS_RIGHT) {
5348
+ return function(that, callbackfn, argumentsLength, memo) {
5349
+ var O = toObject(that), self = IndexedObject(O), length = lengthOfArrayLike(O);
5350
+ if (aCallable(callbackfn), 0 === length && argumentsLength < 2) throw new $TypeError(REDUCE_EMPTY);
5351
+ var index = IS_RIGHT ? length - 1 : 0, i = IS_RIGHT ? -1 : 1;
5352
+ if (argumentsLength < 2) for (;;) {
5353
+ if (index in self) {
5354
+ memo = self[index], index += i;
5355
+ break;
5356
+ }
5357
+ if (index += i, IS_RIGHT ? index < 0 : length <= index) throw new $TypeError(REDUCE_EMPTY);
5358
+ }
5359
+ for (;IS_RIGHT ? index >= 0 : length > index; index += i) index in self && (memo = callbackfn(memo, self[index], index, O));
5360
+ return memo;
5361
+ };
5362
+ }, arrayReduce = {
5363
+ // `Array.prototype.reduce` method
5364
+ // https://tc39.es/ecma262/#sec-array.prototype.reduce
5365
+ left: createMethod(!1),
5366
+ // `Array.prototype.reduceRight` method
5367
+ // https://tc39.es/ecma262/#sec-array.prototype.reduceright
5368
+ right: createMethod(!0)
5369
+ }, fails = fails$9, globalThis$1 = globalThis_1, userAgent = environmentUserAgent, classof = classofRaw$2, userAgentStartsWith = function(string) {
5370
+ return userAgent.slice(0, string.length) === string;
5371
+ }, environment = userAgentStartsWith("Bun/") ? "BUN" : userAgentStartsWith("Cloudflare-Workers") ? "CLOUDFLARE" : userAgentStartsWith("Deno/") ? "DENO" : userAgentStartsWith("Node.js/") ? "NODE" : globalThis$1.Bun && "string" == typeof Bun.version ? "BUN" : globalThis$1.Deno && "object" == typeof Deno.version ? "DENO" : "process" === classof(globalThis$1.process) ? "NODE" : globalThis$1.window && globalThis$1.document ? "BROWSER" : "REST", $reduce = arrayReduce.left;
5372
+
5373
+ // `Array.prototype.reduce` method
5374
+ // https://tc39.es/ecma262/#sec-array.prototype.reduce
5375
+ _export({
5376
+ target: "Array",
5377
+ proto: !0,
5378
+ forced: !("NODE" === environment) && environmentV8Version > 79 && environmentV8Version < 83 || !function(METHOD_NAME, argument) {
5379
+ var method = [][METHOD_NAME];
5380
+ return !!method && fails((function() {
5381
+ // eslint-disable-next-line no-useless-call -- required for testing
5382
+ method.call(null, argument || function() {
5383
+ return 1;
5384
+ }, 1);
5385
+ }));
5386
+ }("reduce")
5387
+ }, {
5388
+ reduce: function(callbackfn /* , initialValue */) {
5389
+ var length = arguments.length;
5390
+ return $reduce(this, callbackfn, length, length > 1 ? arguments[1] : void 0);
5391
+ }
5392
+ });
5393
+
5394
+ var reduce$3 = getBuiltInPrototypeMethod$3("Array", "reduce"), isPrototypeOf = objectIsPrototypeOf, method = reduce$3, ArrayPrototype = Array.prototype, _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
5395
+ var own = it.reduce;
5396
+ return it === ArrayPrototype || isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.reduce ? method : own;
5397
+ }));
5398
+
5399
+ /**
5400
+ * Render a slot with the given props
5401
+ *
5402
+ * Priority order:
5403
+ * 1. render function
5404
+ * 2. component
5405
+ * 3. children
5406
+ * 4. fallback
5407
+ *
5408
+ * @example
5409
+ * renderSlot(
5410
+ * { render: (props) => <CustomButton {...props} /> },
5411
+ * { onClick: handleClick, children: 'Click me' }
5412
+ * )
5413
+ */
5414
+ function renderSlot(slot, props, fallback) {
5415
+ // No slot provided, use fallback
5416
+ if (!slot) return fallback;
5417
+ // Slot is a plain React node
5418
+ if ( React__default.default.isValidElement(slot) || "string" == typeof slot || "number" == typeof slot) return slot;
5419
+ // Slot is an object with rendering options
5420
+ if ("object" == typeof slot && null !== slot) {
5421
+ const slotObj = slot;
5422
+ // Priority 1: render function
5423
+ if (slotObj.render && "function" == typeof slotObj.render) return slotObj.render(props);
5424
+ // Priority 2: component
5425
+ if (slotObj.component) {
5426
+ const Component = slotObj.component;
5427
+ return jsxRuntime.jsx(Component, {
5428
+ ...props
5429
+ });
5430
+ }
5431
+ // Priority 3: children
5432
+ if (void 0 !== slotObj.children) return slotObj.children;
5433
+ }
5434
+ // Fallback
5435
+ return fallback;
5436
+ }
5437
+
5438
+ /**
5439
+ * Check if a value is a slot configuration
5440
+ */ const Button = React__default.default.memo( React.forwardRef((({label: label, children: children, onClick: onClick, variant: variant = "primary", size: size = "md", disabled: disabled = !1, loading: loading = !1, loadingText: loadingText, icon: icon, iconName: iconName, iconSize: iconSize = "sm", iconPosition: iconPosition = "start", iconOnly: iconOnly = !1, rounded: rounded = !1, fullWidth: fullWidth = !1, block: block = !1, active: active = !1, selected: selected = !1, type: type = "button", className: className = "", as: Component = "button", href: href, target: target, glass: glass, onHover: onHover, onFocus: onFocus, onBlur: onBlur, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, tabIndex: tabIndex, style: style, linkComponent: linkComponent, slots: slots, ...props}, ref) => {
5348
5441
  const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href), iconElement = iconName ? jsxRuntime.jsx(Icon, {
5349
5442
  name: iconName,
5350
5443
  size: iconSize
@@ -5360,17 +5453,28 @@ const Button = React__default.default.memo( React.forwardRef((({label: label, c
5360
5453
  children: [ loading && jsxRuntime.jsx("span", {
5361
5454
  className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.SPINNER_ELEMENT),
5362
5455
  "aria-hidden": "true",
5363
- children: jsxRuntime.jsx(Spinner, {
5456
+ children: renderSlot(slots?.spinner, {
5457
+ className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.SPINNER_ELEMENT),
5364
5458
  size: spinnerSize,
5365
5459
  variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
5366
- })
5460
+ }, jsxRuntime.jsx(Spinner, {
5461
+ size: spinnerSize,
5462
+ variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
5463
+ }))
5367
5464
  }), iconElement && !loading && jsxRuntime.jsx("span", {
5368
5465
  className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.ICON_ELEMENT),
5369
5466
  "aria-hidden": "true",
5370
- children: iconElement
5467
+ children: renderSlot(slots?.icon, {
5468
+ className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.ICON_ELEMENT),
5469
+ children: iconElement,
5470
+ size: iconSize
5471
+ }, iconElement)
5371
5472
  }), !iconOnly && buttonText && jsxRuntime.jsx("span", {
5372
5473
  className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.LABEL_ELEMENT),
5373
- children: buttonText
5474
+ children: renderSlot(slots?.label, {
5475
+ className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.LABEL_ELEMENT),
5476
+ children: buttonText
5477
+ }, buttonText)
5374
5478
  }) ]
5375
5479
  }), buttonProps = {
5376
5480
  className: buttonClass,
@@ -5387,48 +5491,59 @@ const Button = React__default.default.memo( React.forwardRef((({label: label, c
5387
5491
  tabIndex: void 0 !== tabIndex ? tabIndex : isDisabled ? -1 : 0,
5388
5492
  style: style,
5389
5493
  ...props
5390
- };
5391
- // Determine if we should render as a link
5392
- // If disabled, we still check href, but we might want to render as button or anchor with aria-disabled
5393
- // The previous logic was Boolean(href && !isDisabled). This meant if disabled, it renders as <button>.
5394
- // This is a safe fallback for disabled links.
5395
- let content;
5396
- // Render as anchor if href is provided
5397
- if (shouldRenderAsLink)
5398
- // Use custom linkComponent if provided (e.g., Next.js Link)
5399
- if (linkComponent) {
5400
- const LinkComp = linkComponent, linkProps = {
5494
+ }, buttonChildren = renderSlot(slots?.root, {
5495
+ className: buttonClass,
5496
+ children: buttonContent,
5497
+ disabled: isDisabled,
5498
+ loading: loading,
5499
+ onClick: handleClickEvent,
5500
+ type: type,
5501
+ "aria-label": safeAriaLabel,
5502
+ "aria-disabled": isDisabled,
5503
+ "aria-busy": loading
5504
+ }, (() => {
5505
+ // Render as anchor if href is provided
5506
+ if (shouldRenderAsLink) {
5507
+ // Use custom linkComponent if provided (e.g., Next.js Link)
5508
+ if (linkComponent) {
5509
+ const LinkComp = linkComponent, linkProps = {
5510
+ ...buttonProps,
5511
+ ref: ref,
5512
+ // linkComponent usually forwards ref to anchor
5513
+ href: isDisabled ? void 0 : href,
5514
+ to: isDisabled ? void 0 : href,
5515
+ target: target,
5516
+ rel: "_blank" === target ? "noopener noreferrer" : void 0
5517
+ };
5518
+ return jsxRuntime.jsx(LinkComp, {
5519
+ ...linkProps,
5520
+ children: buttonContent
5521
+ });
5522
+ }
5523
+ // Fallback to regular anchor tag
5524
+ return jsxRuntime.jsx("a", {
5525
+ ...buttonProps,
5526
+ ref: ref,
5527
+ href: isDisabled ? void 0 : href,
5528
+ target: target,
5529
+ rel: "_blank" === target ? "noopener noreferrer" : void 0,
5530
+ children: buttonContent
5531
+ });
5532
+ }
5533
+ // Default button rendering
5534
+ return jsxRuntime.jsx(Component, {
5401
5535
  ...buttonProps,
5402
5536
  ref: ref,
5403
- // linkComponent usually forwards ref to anchor
5404
- href: isDisabled ? void 0 : href,
5405
- to: isDisabled ? void 0 : href,
5406
- target: target,
5407
- rel: "_blank" === target ? "noopener noreferrer" : void 0
5408
- };
5409
- content = jsxRuntime.jsx(LinkComp, {
5410
- ...linkProps,
5537
+ type: "button" === Component ? type : void 0,
5538
+ disabled: isDisabled,
5411
5539
  children: buttonContent
5412
5540
  });
5413
- } else
5414
- // Fallback to regular anchor tag
5415
- content = jsxRuntime.jsx("a", {
5416
- ...buttonProps,
5417
- ref: ref,
5418
- href: isDisabled ? void 0 : href,
5419
- target: target,
5420
- rel: "_blank" === target ? "noopener noreferrer" : void 0,
5421
- children: buttonContent
5422
- }); else
5423
- // Default button rendering
5424
- content = jsxRuntime.jsx(Component, {
5425
- ...buttonProps,
5426
- ref: ref,
5427
- type: "button" === Component ? type : void 0,
5428
- disabled: isDisabled,
5429
- children: buttonContent
5430
- });
5431
- if (glass) {
5541
+ })());
5542
+ // Determine if we should render as a link
5543
+ // If disabled, we still check href, but we might want to render as button or anchor with aria-disabled
5544
+ // The previous logic was Boolean(href && !isDisabled). This meant if disabled, it renders as <button>.
5545
+ // This is a safe fallback for disabled links.
5546
+ if (glass) {
5432
5547
  // Default glass props
5433
5548
  const defaultGlassProps = {
5434
5549
  displacementScale: 20,
@@ -5441,10 +5556,10 @@ const Button = React__default.default.memo( React.forwardRef((({label: label, c
5441
5556
  };
5442
5557
  return jsxRuntime.jsx(AtomixGlass, {
5443
5558
  ...glassProps,
5444
- children: content
5559
+ children: buttonChildren
5445
5560
  });
5446
5561
  }
5447
- return content;
5562
+ return buttonChildren;
5448
5563
  })));
5449
5564
 
5450
5565
  Button.displayName = "Button";
@@ -5552,7 +5667,7 @@ const CalloutContent = React.forwardRef((({children: children, className: class
5552
5667
 
5553
5668
  CalloutContent.displayName = "CalloutContent";
5554
5669
 
5555
- const Callout = React.memo((({title: title, children: children, icon: icon, variant: variant = "primary", onClose: onClose, actions: actions, compact: compact = !1, isToast: isToast = !1, glass: glass, className: className, style: style, ...props}) => {
5670
+ const CalloutComponentBase = ({title: title, children: children, icon: icon, variant: variant = "primary", onClose: onClose, actions: actions, compact: compact = !1, isToast: isToast = !1, glass: glass, className: className, style: style, ...props}) => {
5556
5671
  const {generateCalloutClass: generateCalloutClass, handleClose: handleClose} =
5557
5672
  /**
5558
5673
  * Callout state and functionality
@@ -5678,7 +5793,7 @@ const Callout = React.memo((({title: title, children: children, icon: icon, var
5678
5793
  style: style,
5679
5794
  children: calloutContent
5680
5795
  });
5681
- }));
5796
+ }, Callout = React.memo(CalloutComponentBase);
5682
5797
 
5683
5798
  Callout.displayName = "Callout",
5684
5799
  // Attach subcomponents
@@ -5968,60 +6083,6 @@ const ElevationCard = ({elevationClass: elevationClass = "is-elevated", classNam
5968
6083
  });
5969
6084
  };
5970
6085
 
5971
- ElevationCard.displayName = "ElevationCard";
5972
-
5973
- var aCallable = aCallable$3, toObject = toObject$2, IndexedObject = indexedObject, lengthOfArrayLike = lengthOfArrayLike$2, $TypeError = TypeError, REDUCE_EMPTY = "Reduce of empty array with no initial value", createMethod = function(IS_RIGHT) {
5974
- return function(that, callbackfn, argumentsLength, memo) {
5975
- var O = toObject(that), self = IndexedObject(O), length = lengthOfArrayLike(O);
5976
- if (aCallable(callbackfn), 0 === length && argumentsLength < 2) throw new $TypeError(REDUCE_EMPTY);
5977
- var index = IS_RIGHT ? length - 1 : 0, i = IS_RIGHT ? -1 : 1;
5978
- if (argumentsLength < 2) for (;;) {
5979
- if (index in self) {
5980
- memo = self[index], index += i;
5981
- break;
5982
- }
5983
- if (index += i, IS_RIGHT ? index < 0 : length <= index) throw new $TypeError(REDUCE_EMPTY);
5984
- }
5985
- for (;IS_RIGHT ? index >= 0 : length > index; index += i) index in self && (memo = callbackfn(memo, self[index], index, O));
5986
- return memo;
5987
- };
5988
- }, arrayReduce = {
5989
- // `Array.prototype.reduce` method
5990
- // https://tc39.es/ecma262/#sec-array.prototype.reduce
5991
- left: createMethod(!1),
5992
- // `Array.prototype.reduceRight` method
5993
- // https://tc39.es/ecma262/#sec-array.prototype.reduceright
5994
- right: createMethod(!0)
5995
- }, fails = fails$9, globalThis$1 = globalThis_1, userAgent = environmentUserAgent, classof = classofRaw$2, userAgentStartsWith = function(string) {
5996
- return userAgent.slice(0, string.length) === string;
5997
- }, environment = userAgentStartsWith("Bun/") ? "BUN" : userAgentStartsWith("Cloudflare-Workers") ? "CLOUDFLARE" : userAgentStartsWith("Deno/") ? "DENO" : userAgentStartsWith("Node.js/") ? "NODE" : globalThis$1.Bun && "string" == typeof Bun.version ? "BUN" : globalThis$1.Deno && "object" == typeof Deno.version ? "DENO" : "process" === classof(globalThis$1.process) ? "NODE" : globalThis$1.window && globalThis$1.document ? "BROWSER" : "REST", $reduce = arrayReduce.left;
5998
-
5999
- // `Array.prototype.reduce` method
6000
- // https://tc39.es/ecma262/#sec-array.prototype.reduce
6001
- _export({
6002
- target: "Array",
6003
- proto: !0,
6004
- forced: !("NODE" === environment) && environmentV8Version > 79 && environmentV8Version < 83 || !function(METHOD_NAME, argument) {
6005
- var method = [][METHOD_NAME];
6006
- return !!method && fails((function() {
6007
- // eslint-disable-next-line no-useless-call -- required for testing
6008
- method.call(null, argument || function() {
6009
- return 1;
6010
- }, 1);
6011
- }));
6012
- }("reduce")
6013
- }, {
6014
- reduce: function(callbackfn /* , initialValue */) {
6015
- var length = arguments.length;
6016
- return $reduce(this, callbackfn, length, length > 1 ? arguments[1] : void 0);
6017
- }
6018
- });
6019
-
6020
- var reduce$3 = getBuiltInPrototypeMethod$3("Array", "reduce"), isPrototypeOf = objectIsPrototypeOf, method = reduce$3, ArrayPrototype = Array.prototype, _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
6021
- var own = it.reduce;
6022
- return it === ArrayPrototype || isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.reduce ? method : own;
6023
- }));
6024
-
6025
6086
  /**
6026
6087
  * Comprehensive chart hook with shared functionality
6027
6088
  * @param initialProps - Initial chart properties
@@ -6059,8 +6120,11 @@ function useChart(initialProps) {
6059
6120
  }), animationFrameRef = React.useRef(null);
6060
6121
  // Default chart properties
6061
6122
  // Cleanup animation frame on unmount
6062
- React.useEffect((() => () => {
6063
- animationFrameRef.current && cancelAnimationFrame(animationFrameRef.current);
6123
+ React.useEffect((() => {
6124
+ const currentRef = animationFrameRef.current;
6125
+ return () => {
6126
+ currentRef && cancelAnimationFrame(currentRef);
6127
+ };
6064
6128
  }), []);
6065
6129
  /**
6066
6130
  * Point interaction handlers
@@ -6451,7 +6515,9 @@ function getDatasetBounds(data) {
6451
6515
 
6452
6516
  /**
6453
6517
  * Hook for managing chart toolbar state and generating chart-specific configurations
6454
- */ const ChartToolbar = React.memo( React.forwardRef((({chartType: chartType = "line", groups: groups = [], enableDefaults: enableDefaults = !0, defaults: defaults = {
6518
+ */ ElevationCard.displayName = "ElevationCard";
6519
+
6520
+ const ChartToolbar = React.memo( React.forwardRef((({chartType: chartType = "line", groups: groups = [], enableDefaults: enableDefaults = !0, defaults: defaults = {
6455
6521
  refresh: !0,
6456
6522
  export: !0,
6457
6523
  fullscreen: !0,
@@ -6941,8 +7007,8 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
6941
7007
  }), [ chartType ]), finalDefaults = React.useMemo((() => ({
6942
7008
  ...getChartDefaults(),
6943
7009
  ...defaults
6944
- })), [ getChartDefaults, defaults ]), enhancedHandlers = {
6945
- onRefresh: React.useCallback((() => {
7010
+ })), [ getChartDefaults, defaults ]), enhancedHandlers = React.useMemo((() => ({
7011
+ onRefresh: () => {
6946
7012
  setState((prev => ({
6947
7013
  ...prev,
6948
7014
  isRefreshing: !0
@@ -6952,8 +7018,8 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
6952
7018
  isRefreshing: !1
6953
7019
  })));
6954
7020
  }), 1e3);
6955
- }), [ handlers.onRefresh ]),
6956
- onExport: React.useCallback((async format => {
7021
+ },
7022
+ onExport: async format => {
6957
7023
  setState((prev => ({
6958
7024
  ...prev,
6959
7025
  isExporting: !0
@@ -6966,70 +7032,70 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
6966
7032
  isExporting: !1
6967
7033
  })));
6968
7034
  }
6969
- }), [ handlers.onExport ]),
6970
- onFullscreen: React.useCallback((isFullscreen => {
7035
+ },
7036
+ onFullscreen: isFullscreen => {
6971
7037
  setState((prev => ({
6972
7038
  ...prev,
6973
7039
  isFullscreen: isFullscreen
6974
7040
  }))), handlers.onFullscreen?.(isFullscreen);
6975
- }), [ handlers.onFullscreen ]),
6976
- onZoomIn: React.useCallback((() => {
7041
+ },
7042
+ onZoomIn: () => {
6977
7043
  setState((prev => ({
6978
7044
  ...prev,
6979
7045
  zoomLevel: Math.min(1.2 * prev.zoomLevel, 5)
6980
7046
  }))), handlers.onZoomIn?.();
6981
- }), [ handlers.onZoomIn ]),
6982
- onZoomOut: React.useCallback((() => {
7047
+ },
7048
+ onZoomOut: () => {
6983
7049
  setState((prev => ({
6984
7050
  ...prev,
6985
7051
  zoomLevel: Math.max(prev.zoomLevel / 1.2, .2)
6986
7052
  }))), handlers.onZoomOut?.();
6987
- }), [ handlers.onZoomOut ]),
6988
- onZoomReset: React.useCallback((() => {
7053
+ },
7054
+ onZoomReset: () => {
6989
7055
  setState((prev => ({
6990
7056
  ...prev,
6991
7057
  zoomLevel: 1
6992
7058
  }))), handlers.onZoomReset?.();
6993
- }), [ handlers.onZoomReset ]),
6994
- onPanToggle: React.useCallback((enabled => {
7059
+ },
7060
+ onPanToggle: enabled => {
6995
7061
  setState((prev => ({
6996
7062
  ...prev,
6997
7063
  panEnabled: enabled
6998
7064
  }))), handlers.onPanToggle?.(enabled);
6999
- }), [ handlers.onPanToggle ]),
7000
- onReset: React.useCallback((() => {
7065
+ },
7066
+ onReset: () => {
7001
7067
  setState((prev => ({
7002
7068
  ...prev,
7003
7069
  zoomLevel: 1,
7004
7070
  panEnabled: !1
7005
7071
  }))), handlers.onReset?.();
7006
- }), [ handlers.onReset ]),
7007
- onGridToggle: React.useCallback((show => {
7072
+ },
7073
+ onGridToggle: show => {
7008
7074
  setState((prev => ({
7009
7075
  ...prev,
7010
7076
  showGrid: show
7011
7077
  }))), handlers.onGridToggle?.(show);
7012
- }), [ handlers.onGridToggle ]),
7013
- onLegendToggle: React.useCallback((show => {
7078
+ },
7079
+ onLegendToggle: show => {
7014
7080
  setState((prev => ({
7015
7081
  ...prev,
7016
7082
  showLegend: show
7017
7083
  }))), handlers.onLegendToggle?.(show);
7018
- }), [ handlers.onLegendToggle ]),
7019
- onTooltipsToggle: React.useCallback((show => {
7084
+ },
7085
+ onTooltipsToggle: show => {
7020
7086
  setState((prev => ({
7021
7087
  ...prev,
7022
7088
  showTooltips: show
7023
7089
  }))), handlers.onTooltipsToggle?.(show);
7024
- }), [ handlers.onTooltipsToggle ]),
7025
- onAnimationsToggle: React.useCallback((enabled => {
7090
+ },
7091
+ onAnimationsToggle: enabled => {
7026
7092
  setState((prev => ({
7027
7093
  ...prev,
7028
7094
  animationsEnabled: enabled
7029
7095
  }))), handlers.onAnimationsToggle?.(enabled);
7030
- }), [ handlers.onAnimationsToggle ]),
7031
- onSettings: React.useCallback((() => {}), [])
7032
- }, generateToolbarGroups = React.useCallback((() => {
7096
+ },
7097
+ onSettings: () => {}
7098
+ })), [ handlers ]), generateToolbarGroups = React.useCallback((() => {
7033
7099
  const groups = [], dataActions = [];
7034
7100
  // Data actions group
7035
7101
  finalDefaults.refresh && dataActions.push({
@@ -7154,7 +7220,7 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
7154
7220
  actions: customActions
7155
7221
  });
7156
7222
  return groups;
7157
- }), [ chartType, finalDefaults, state, enhancedHandlers, customActions, customGroups ]);
7223
+ }), [ finalDefaults, state, enhancedHandlers, customActions, customGroups ]);
7158
7224
  // Keyboard shortcuts
7159
7225
  return React.useEffect((() => {
7160
7226
  const handleKeyDown = event => {
@@ -7746,7 +7812,7 @@ const ChartRenderer = React.memo( React.forwardRef((({datasets: datasets = [],
7746
7812
  announcement: announcement,
7747
7813
  focusedPoint: focusedPoint,
7748
7814
  getAccessibleDescription: () => "Chart description"
7749
- })), [ announcement, focusedPoint ]), transform = React.useMemo((() => chartContext ? `translate(${chartContext.panOffset.x}px, ${chartContext.panOffset.y}px) scale(${chartContext.zoomLevel})` : ""), [ chartContext?.panOffset.x, chartContext?.panOffset.y, chartContext?.zoomLevel ]), chartData = React.useMemo((() => {
7815
+ })), [ announcement, focusedPoint ]), transform = React.useMemo((() => chartContext ? `translate(${chartContext.panOffset.x}px, ${chartContext.panOffset.y}px) scale(${chartContext.zoomLevel})` : ""), [ chartContext ]), chartData = React.useMemo((() => {
7750
7816
  // Return null if dimensions not ready to prevent calculation with invalid dimensions
7751
7817
  if (!isInitialized || 0 === dimensions.width || 0 === dimensions.height) return null;
7752
7818
  const scales = calculateScales(processedData, dimensions.width, dimensions.height, void 0, config);
@@ -8159,7 +8225,7 @@ function useBarChart(datasets, options = {}) {
8159
8225
  opacity: .4
8160
8226
  } ]
8161
8227
  };
8162
- })) : []), [ options.useGradients ]), formatValue = React.useCallback((value => options.valueFormatter ? options.valueFormatter(value) : value.toString()), [ options.valueFormatter ]);
8228
+ })) : []), [ options.useGradients ]), formatValue = React.useCallback((value => options.valueFormatter ? options.valueFormatter(value) : value.toString()), [ options ]);
8163
8229
  return {
8164
8230
  // State
8165
8231
  hoveredBar: hoveredBar,
@@ -8185,7 +8251,7 @@ function useBarChart(datasets, options = {}) {
8185
8251
  y: horizontal ? y + height / 2 : y - 5
8186
8252
  };
8187
8253
  }
8188
- }), [ options.dataLabelPosition ]),
8254
+ }), [ options ]),
8189
8255
  // Handlers
8190
8256
  handleBarHover: handleBarHover,
8191
8257
  handleBarLeave: handleBarLeave,
@@ -8495,13 +8561,13 @@ const DonutChart = React.memo( React.forwardRef((({datasets: datasets = [], con
8495
8561
  roundedCorners: !0
8496
8562
  }, onDataPointClick: onDataPointClick, ...props}, ref) => {
8497
8563
  // Use the first dataset for donut chart
8498
- const dataset = datasets.length > 0 ? datasets[0] : {
8564
+ const dataset = React.useMemo((() => datasets.length > 0 ? datasets[0] : {
8499
8565
  label: "",
8500
8566
  data: []
8501
- }, chartData = React.useMemo((() => {
8567
+ }), [ datasets ]), chartData = React.useMemo((() => {
8502
8568
  if (!dataset?.data?.length) return null;
8503
8569
  // Filter out invalid data points
8504
- const validDataPoints = dataset?.data?.filter((point => "number" == typeof point.value && !isNaN(point.value) && isFinite(point.value) && point.value > 0));
8570
+ const validDataPoints = (dataset?.data || []).filter((point => "number" == typeof point.value && !isNaN(point.value) && isFinite(point.value) && point.value > 0));
8505
8571
  return validDataPoints.length ? {
8506
8572
  validDataPoints: validDataPoints
8507
8573
  } : null;
@@ -9460,7 +9526,7 @@ function usePieChart(data, options = {}) {
9460
9526
  const parts = [];
9461
9527
  return !1 !== options.showLabels && parts.push(slice.label), options.showPercentages && parts.push(`${Math.round(slice.percentage)}%`),
9462
9528
  options.showValues && parts.push(slice.value.toString()), parts.join(" - ");
9463
- }), [ options.labelFormatter, options.showLabels, options.showPercentages, options.showValues ]), getSliceTransform = React.useCallback(((slice, isHovered) => isHovered && options.enableHoverEffects && options.hoverOffset ? `translate(${Math.cos(slice.midAngle) * options.hoverOffset}, ${Math.sin(slice.midAngle) * options.hoverOffset})` : ""), [ options.enableHoverEffects, options.hoverOffset ]), isSliceSelected = React.useCallback((index => selectedSlices.has(index)), [ selectedSlices ]);
9529
+ }), [ options ]), getSliceTransform = React.useCallback(((slice, isHovered) => isHovered && options.enableHoverEffects && options.hoverOffset ? `translate(${Math.cos(slice.midAngle) * options.hoverOffset}, ${Math.sin(slice.midAngle) * options.hoverOffset})` : ""), [ options.enableHoverEffects, options.hoverOffset ]), isSliceSelected = React.useCallback((index => selectedSlices.has(index)), [ selectedSlices ]);
9464
9530
  return {
9465
9531
  // Data
9466
9532
  processedData: processedData,
@@ -10896,7 +10962,7 @@ const DataTable = React.memo((({data: data, columns: columns, className: classN
10896
10962
  const newOrder = columns.map((col => col.key)), currentOrderSet = new Set(columnOrder), newOrderSet = new Set(newOrder);
10897
10963
  // Only update if there are actual differences
10898
10964
  newOrder.length === columnOrder.length && newOrder.every((key => currentOrderSet.has(key))) && columnOrder.every((key => newOrderSet.has(key))) || setColumnOrder(newOrder);
10899
- }), [ columns ]),
10965
+ }), [ columns, columnOrder ]),
10900
10966
  // Update column visibility when columns prop changes
10901
10967
  React.useEffect((() => {
10902
10968
  setColumnVisibility((prev => {
@@ -11441,7 +11507,7 @@ function formatDate(date, format) {
11441
11507
  /**
11442
11508
  * Check if a date is within a min and max range
11443
11509
  */ function useDatePicker({value: value, onChange: onChange, selectionMode: selectionMode = "single", startDate: startDate, endDate: endDate, onRangeChange: onRangeChange, format: format = "MM/dd/yyyy", minDate: minDate, maxDate: maxDate, inline: inline = !1} = {}) {
11444
- const [isOpen, setIsOpen] = React.useState(inline), [inputValue, setInputValue] = React.useState(value ? formatDate(value, format) : ""), [rangeInputValue, setRangeInputValue] = React.useState(startDate && endDate ? `${formatDate(startDate, format)} - ${formatDate(endDate, format)}` : startDate ? `${formatDate(startDate, format)} - Select end date` : ""), [viewDate, setViewDate] = React.useState(value || startDate || new Date), [viewMode, setViewMode] = React.useState("days"), [rangeSelectionState, setRangeSelectionState] = React.useState(!startDate || startDate && endDate ? "start" : "end"), datePickerRef = React.useRef(null), inputRef = React.useRef(null), today = new Date, currentMonth = viewDate.getMonth(), currentYear = viewDate.getFullYear(), daysInMonth = getDaysInMonth(currentYear, currentMonth), firstDayOfMonth = new Date(currentYear, currentMonth, 1).getDay();
11510
+ const [isOpen, setIsOpen] = React.useState(inline), [inputValue, setInputValue] = React.useState(value ? formatDate(value, format) : ""), [rangeInputValue, setRangeInputValue] = React.useState(startDate && endDate ? `${formatDate(startDate, format)} - ${formatDate(endDate, format)}` : startDate ? `${formatDate(startDate, format)} - Select end date` : ""), [viewDate, setViewDate] = React.useState(value || startDate || new Date), [viewMode, setViewMode] = React.useState("days"), [rangeSelectionState, setRangeSelectionState] = React.useState(!startDate || startDate && endDate ? "start" : "end"), datePickerRef = React.useRef(null), inputRef = React.useRef(null), today = React.useMemo((() => new Date), []), currentMonth = viewDate.getMonth(), currentYear = viewDate.getFullYear(), daysInMonth = getDaysInMonth(currentYear, currentMonth), firstDayOfMonth = new Date(currentYear, currentMonth, 1).getDay();
11445
11511
  // Update input value when value or range dates change externally
11446
11512
  React.useEffect((() => {
11447
11513
  "single" === selectionMode ? setInputValue(value ? formatDate(value, format) : "") : (setRangeInputValue(startDate && endDate ? `${formatDate(startDate, format)} - ${formatDate(endDate, format)}` : startDate ? `${formatDate(startDate, format)} - Select end date` : ""),
@@ -11964,21 +12030,11 @@ const DatePicker = React.forwardRef((({value: value, onChange: onChange, select
11964
12030
  * @returns EdgePanel state and methods
11965
12031
  */
11966
12032
  function useEdgePanel(initialProps) {
11967
- // Default EdgePanel properties
11968
- const defaultProps = {
11969
- position: "start",
11970
- mode: "slide",
11971
- isOpen: !1,
11972
- backdrop: !0,
11973
- closeOnBackdropClick: !0,
11974
- closeOnEscape: !0,
11975
- glass: void 0,
11976
- ...initialProps
11977
- }, [isOpen, setIsOpen] = React.useState(defaultProps.isOpen || !1), containerRef = React.useRef(null), backdropRef = React.useRef(null), adjustBodyPadding = React.useCallback((() => {
11978
- if (!containerRef.current || "push" !== defaultProps.mode) return;
11979
- const {position: position} = defaultProps, size = "top" === position || "bottom" === position ? containerRef.current.clientHeight : containerRef.current.clientWidth;
12033
+ const {position: position = "start", mode: mode = "slide", isOpen: propIsOpen = !1, backdrop: backdrop = !0, closeOnBackdropClick: closeOnBackdropClick = !0, closeOnEscape: closeOnEscape = !0, glass: glass, onOpenChange: onOpenChange, className: className = ""} = initialProps || {}, [isOpen, setIsOpen] = React.useState(propIsOpen || !1), containerRef = React.useRef(null), backdropRef = React.useRef(null), adjustBodyPadding = React.useCallback((() => {
12034
+ if (!containerRef.current || "push" !== mode) return;
12035
+ const size = "top" === position || "bottom" === position ? containerRef.current.clientHeight : containerRef.current.clientWidth;
11980
12036
  // Map position to CSS padding property
11981
- let paddingProperty;
12037
+ let paddingProperty;
11982
12038
  switch (position) {
11983
12039
  case "start":
11984
12040
  paddingProperty = "paddingLeft";
@@ -11993,9 +12049,8 @@ function useEdgePanel(initialProps) {
11993
12049
  paddingProperty = `padding${position.charAt(0).toUpperCase() + position.slice(1)}`;
11994
12050
  }
11995
12051
  document.body.style[paddingProperty] = `${size}px`, document.body.classList.add("is-pushed");
11996
- }), [ defaultProps.mode, defaultProps.position ]), resetBodyPadding = React.useCallback((() => {
11997
- if ("push" !== defaultProps.mode) return;
11998
- const {position: position} = defaultProps;
12052
+ }), [ mode, position ]), resetBodyPadding = React.useCallback((() => {
12053
+ if ("push" !== mode) return;
11999
12054
  // Map position to CSS padding property
12000
12055
  let paddingProperty;
12001
12056
  switch (position) {
@@ -12012,11 +12067,10 @@ function useEdgePanel(initialProps) {
12012
12067
  paddingProperty = `padding${position.charAt(0).toUpperCase() + position.slice(1)}`;
12013
12068
  }
12014
12069
  document.body.style[paddingProperty] = "", document.body.classList.remove("is-pushed");
12015
- }), [ defaultProps.mode, defaultProps.position ]), openPanel = React.useCallback(((useFadeAnimation = !1) => {
12070
+ }), [ mode, position ]), openPanel = React.useCallback(((useFadeAnimation = !1) => {
12016
12071
  if (setIsOpen(!0), document.body.classList.add("is-edgepanel-open"), containerRef.current) {
12017
- const {mode: mode} = defaultProps;
12018
12072
  // Only add animation if not in 'none' mode
12019
- if ("none" !== mode) if (useFadeAnimation) {
12073
+ if ("none" !== mode) if (useFadeAnimation) {
12020
12074
  // Add fade animation class
12021
12075
  containerRef.current.classList.add("is-fade-animating"), containerRef.current.offsetHeight;
12022
12076
  // Remove animation class after animation completes
@@ -12036,14 +12090,13 @@ function useEdgePanel(initialProps) {
12036
12090
  // Set transform or opacity based on animation type
12037
12091
  useFadeAnimation ? (containerRef.current.style.opacity = "1", containerRef.current.style.transform = "") : containerRef.current.style.transform = "translate(0)",
12038
12092
  // If push mode, adjust body padding
12039
- "push" === defaultProps.mode && adjustBodyPadding();
12093
+ "push" === mode && adjustBodyPadding();
12040
12094
  }
12041
- defaultProps.onOpenChange && defaultProps.onOpenChange(!0);
12042
- }), [ defaultProps, adjustBodyPadding ]), closePanel = React.useCallback(((useFadeAnimation = !1) => {
12095
+ onOpenChange && onOpenChange(!0);
12096
+ }), [ mode, adjustBodyPadding, onOpenChange ]), closePanel = React.useCallback(((useFadeAnimation = !1) => {
12043
12097
  if (containerRef.current) {
12044
- const {position: position, mode: mode} = defaultProps;
12045
12098
  // Only add animation if not in 'none' mode
12046
- if ("none" !== mode) if (useFadeAnimation) {
12099
+ if ("none" !== mode) if (useFadeAnimation) {
12047
12100
  // Add fade out animation class
12048
12101
  containerRef.current.classList.add("is-fade-animating-out");
12049
12102
  // Capture container for setTimeout
@@ -12065,46 +12118,42 @@ function useEdgePanel(initialProps) {
12065
12118
  // Then set transform
12066
12119
  containerRef.current.style.transform = position ? EDGE_PANEL.TRANSFORM_VALUES[position] : "",
12067
12120
  // Reset body padding if push mode
12068
- "push" === defaultProps.mode && resetBodyPadding(), setTimeout((() => {
12069
- setIsOpen(!1), document.body.classList.remove("is-edgepanel-open"), defaultProps.onOpenChange && defaultProps.onOpenChange(!1);
12121
+ "push" === mode && resetBodyPadding(), setTimeout((() => {
12122
+ setIsOpen(!1), document.body.classList.remove("is-edgepanel-open"), onOpenChange && onOpenChange(!1);
12070
12123
  }), "none" === mode ? 0 : EDGE_PANEL.ANIMATION_DURATION);
12071
- } else setIsOpen(!1), document.body.classList.remove("is-edgepanel-open"), defaultProps.onOpenChange && defaultProps.onOpenChange(!1);
12072
- }), [ defaultProps, resetBodyPadding ]), handleEscapeKey = React.useCallback((event => {
12073
- defaultProps.closeOnEscape && "Escape" === event.key && isOpen && closePanel();
12074
- }), [ closePanel, defaultProps.closeOnEscape, isOpen ]), handleBackdropClick = React.useCallback((event => {
12075
- defaultProps.closeOnBackdropClick && event.target === event.currentTarget && closePanel();
12076
- }), [ closePanel, defaultProps.closeOnBackdropClick ]);
12124
+ } else setIsOpen(!1), document.body.classList.remove("is-edgepanel-open"), onOpenChange && onOpenChange(!1);
12125
+ }), [ mode, position, onOpenChange, resetBodyPadding ]), handleEscapeKey = React.useCallback((event => {
12126
+ closeOnEscape && "Escape" === event.key && isOpen && closePanel();
12127
+ }), [ closePanel, closeOnEscape, isOpen ]), handleBackdropClick = React.useCallback((event => {
12128
+ closeOnBackdropClick && event.target === event.currentTarget && closePanel();
12129
+ }), [ closePanel, closeOnBackdropClick ]);
12077
12130
  /**
12078
12131
  * Set up event listeners for keyboard events
12079
12132
  */
12080
- return React.useEffect((() => (isOpen && defaultProps.closeOnEscape && document.addEventListener("keydown", handleEscapeKey),
12133
+ return React.useEffect((() => (isOpen && closeOnEscape && document.addEventListener("keydown", handleEscapeKey),
12081
12134
  () => {
12082
12135
  document.removeEventListener("keydown", handleEscapeKey);
12083
- })), [ isOpen, handleEscapeKey, defaultProps.closeOnEscape ]),
12136
+ })), [ isOpen, handleEscapeKey, closeOnEscape ]),
12084
12137
  /**
12085
12138
  * Set initial transform values
12086
12139
  */
12087
12140
  React.useEffect((() => {
12088
- if (containerRef.current) {
12089
- const {position: position, mode: mode} = defaultProps;
12090
- isOpen || "slide" !== mode && "push" !== mode || !position || (containerRef.current.style.transform = EDGE_PANEL.TRANSFORM_VALUES[position],
12091
- // Set initial opacity for fade animations
12092
- defaultProps.glass && (containerRef.current.style.opacity = "0"));
12093
- }
12094
- }), [ defaultProps.mode, defaultProps.position, defaultProps.glass, isOpen ]),
12141
+ containerRef.current && (isOpen || "slide" !== mode && "push" !== mode || !position || (containerRef.current.style.transform = EDGE_PANEL.TRANSFORM_VALUES[position],
12142
+ // Set initial opacity for fade animations
12143
+ glass && (containerRef.current.style.opacity = "0")));
12144
+ }), [ mode, position, glass, isOpen ]),
12095
12145
  /**
12096
12146
  * Sync with prop changes
12097
12147
  */
12098
12148
  React.useEffect((() => {
12099
- void 0 !== defaultProps.isOpen && defaultProps.isOpen !== isOpen && (defaultProps.isOpen ? openPanel(!!defaultProps.glass) : closePanel(!!defaultProps.glass));
12100
- }), [ defaultProps.isOpen, closePanel, isOpen, openPanel, defaultProps.glass ]),
12101
- {
12149
+ void 0 !== propIsOpen && propIsOpen !== isOpen && (propIsOpen ? openPanel(!!glass) : closePanel(!!glass));
12150
+ }), [ propIsOpen, closePanel, isOpen, openPanel, glass ]), {
12102
12151
  isOpen: isOpen,
12103
12152
  containerRef: containerRef,
12104
12153
  backdropRef: backdropRef,
12105
12154
  generateEdgePanelClass: props => {
12106
- const {position: position = defaultProps.position, className: className = "", isOpen: propIsOpen} = props, baseClass = EDGE_PANEL.CLASSES.BASE;
12107
- return `${baseClass} ${position ? `${baseClass}--${position}` : ""} ${propIsOpen ?? isOpen ? EDGE_PANEL.CLASSES.IS_OPEN : ""} ${className}`.trim();
12155
+ const {position: propPosition = position, className: propClassName = className, isOpen: argIsOpen} = props, baseClass = EDGE_PANEL.CLASSES.BASE;
12156
+ return `${baseClass} ${propPosition ? `${baseClass}--${propPosition}` : ""} ${argIsOpen ?? isOpen ? EDGE_PANEL.CLASSES.IS_OPEN : ""} ${propClassName}`.trim();
12108
12157
  },
12109
12158
  openPanel: openPanel,
12110
12159
  closePanel: closePanel,
@@ -12155,7 +12204,7 @@ const EdgePanelCloseButton = React.forwardRef((({className: className = "", onC
12155
12204
 
12156
12205
  EdgePanelCloseButton.displayName = "EdgePanelCloseButton";
12157
12206
 
12158
- const EdgePanel = React.memo((({title: title, children: children, position: position = "start", mode: mode = "slide", isOpen: isOpen = !1, onOpenChange: onOpenChange, backdrop: backdrop = !0, closeOnBackdropClick: closeOnBackdropClick = !0, closeOnEscape: closeOnEscape = !0, className: className = "", style: style, glass: glass}) => {
12207
+ const EdgePanelComponentBase = ({title: title, children: children, position: position = "start", mode: mode = "slide", isOpen: isOpen = !1, onOpenChange: onOpenChange, backdrop: backdrop = !0, closeOnBackdropClick: closeOnBackdropClick = !0, closeOnEscape: closeOnEscape = !0, className: className = "", style: style, glass: glass}) => {
12159
12208
  const {isOpen: isOpenState, containerRef: containerRef, backdropRef: backdropRef, generateEdgePanelClass: generateEdgePanelClass, closePanel: closePanel, handleBackdropClick: handleBackdropClick} = useEdgePanel({
12160
12209
  position: position,
12161
12210
  mode: mode,
@@ -12231,7 +12280,7 @@ const EdgePanel = React.memo((({title: title, children: children, position: pos
12231
12280
  }) : panelContent
12232
12281
  }) ]
12233
12282
  });
12234
- }));
12283
+ }, EdgePanel = React.memo(EdgePanelComponentBase);
12235
12284
 
12236
12285
  /**
12237
12286
  * Form state and functionality
@@ -12486,7 +12535,7 @@ function useHero(initialProps) {
12486
12535
  * @returns Slider state and methods
12487
12536
  */
12488
12537
  function(config) {
12489
- const {slides: slides, autoplay: autoplay, loop: loop = !0, transition: transition = "fade", transitionDuration: transitionDuration = 1e3} = config, [currentIndex, setCurrentIndex] = React.useState(0), [isTransitioning, setIsTransitioning] = React.useState(!1), autoplayRef = React.useRef(null), isPausedRef = React.useRef(!1), callbackRef = React.useRef(), slideRefs = React.useMemo((() => slides.map((() => React__default.default.createRef()))), [ slides.length ]), videoRefs = React.useMemo((() => slides.map((() => React__default.default.createRef()))), [ slides.length ]), handleSlideTransition = React.useCallback((nextIndex => {
12538
+ const {slides: slides, autoplay: autoplay, loop: loop = !0, transition: transition = "fade", transitionDuration: transitionDuration = 1e3} = config, [currentIndex, setCurrentIndex] = React.useState(0), [isTransitioning, setIsTransitioning] = React.useState(!1), autoplayRef = React.useRef(null), isPausedRef = React.useRef(!1), callbackRef = React.useRef(void 0), slideRefs = React.useMemo((() => slides.map((() => React__default.default.createRef()))), [ slides ]), videoRefs = React.useMemo((() => slides.map((() => React__default.default.createRef()))), [ slides ]), handleSlideTransition = React.useCallback((nextIndex => {
12490
12539
  if (nextIndex === currentIndex || isTransitioning) return;
12491
12540
  if (nextIndex < 0 || nextIndex >= slides.length) return;
12492
12541
  setIsTransitioning(!0),
@@ -12805,22 +12854,15 @@ function useHero(initialProps) {
12805
12854
  * @param initialProps - Initial side menu properties
12806
12855
  * @returns SideMenu state and methods
12807
12856
  */ function useSideMenu(initialProps) {
12808
- // Default side menu properties
12809
- const defaultProps = {
12810
- collapsible: !0,
12811
- collapsibleDesktop: !1,
12812
- defaultCollapsedDesktop: !1,
12813
- isOpen: !1,
12814
- ...initialProps
12815
- }, [isOpenState, setIsOpenState] = React.useState(void 0 !== defaultProps.defaultCollapsedDesktop ? !defaultProps.defaultCollapsedDesktop : defaultProps.isOpen || !1), wrapperRef = React.useRef(null), innerRef = React.useRef(null), sideMenuRef = React.useRef(null);
12857
+ const {collapsible: collapsible = !0, collapsibleDesktop: collapsibleDesktop = !1, defaultCollapsedDesktop: defaultCollapsedDesktop = !1, isOpen: isOpen, onToggle: onToggle, disabled: disabled = !1} = initialProps || {}, [isOpenState, setIsOpenState] = React.useState(void 0 !== defaultCollapsedDesktop ? !defaultCollapsedDesktop : isOpen || !1), wrapperRef = React.useRef(null), innerRef = React.useRef(null), sideMenuRef = React.useRef(null);
12816
12858
  // Local open state for when not controlled externally
12817
12859
  // Update local state when external state changes
12818
12860
  React.useEffect((() => {
12819
- void 0 !== defaultProps.isOpen ? setIsOpenState(defaultProps.isOpen) : void 0 !== defaultProps.defaultCollapsedDesktop && setIsOpenState(!defaultProps.defaultCollapsedDesktop);
12820
- }), [ defaultProps.isOpen, defaultProps.defaultCollapsedDesktop ]),
12861
+ void 0 !== isOpen ? setIsOpenState(isOpen) : void 0 !== defaultCollapsedDesktop && setIsOpenState(!defaultCollapsedDesktop);
12862
+ }), [ isOpen, defaultCollapsedDesktop ]),
12821
12863
  // Set initial height on mount
12822
12864
  React.useEffect((() => {
12823
- const shouldCollapse = window.innerWidth < 768 ? defaultProps.collapsible : defaultProps.collapsibleDesktop, currentOpen = void 0 !== defaultProps.isOpen ? defaultProps.isOpen : isOpenState;
12865
+ const shouldCollapse = window.innerWidth < 768 ? collapsible : collapsibleDesktop, currentOpen = void 0 !== isOpen ? isOpen : isOpenState;
12824
12866
  if (shouldCollapse && wrapperRef.current && innerRef.current) {
12825
12867
  // Use setTimeout to ensure DOM is fully rendered
12826
12868
  const timeoutId = setTimeout((() => {
@@ -12829,14 +12871,14 @@ function useHero(initialProps) {
12829
12871
  return () => clearTimeout(timeoutId);
12830
12872
  }
12831
12873
  !shouldCollapse && wrapperRef.current && (wrapperRef.current.style.height = "auto");
12832
- }), []), // Only run on mount
12874
+ }), [ collapsible, collapsibleDesktop, isOpen, isOpenState ]),
12833
12875
  // Handle responsive behavior - vertical collapse for both mobile and desktop
12834
12876
  React.useEffect((() => {
12835
12877
  const handleResize = () => {
12836
- if (window.innerWidth < 768 ? defaultProps.collapsible : defaultProps.collapsibleDesktop) {
12878
+ if (window.innerWidth < 768 ? collapsible : collapsibleDesktop) {
12837
12879
  if (wrapperRef.current && innerRef.current) {
12838
12880
  // Set proper height for vertical animation (both mobile and desktop)
12839
- const currentOpen = void 0 !== defaultProps.isOpen ? defaultProps.isOpen : isOpenState;
12881
+ const currentOpen = void 0 !== isOpen ? isOpen : isOpenState;
12840
12882
  // Use requestAnimationFrame to ensure DOM is ready
12841
12883
  requestAnimationFrame((() => {
12842
12884
  wrapperRef.current && innerRef.current && (wrapperRef.current.style.height = currentOpen ? `${innerRef.current.scrollHeight}px` : "0px");
@@ -12850,12 +12892,12 @@ function useHero(initialProps) {
12850
12892
  return window.addEventListener("resize", handleResize), () => {
12851
12893
  clearTimeout(timeoutId), window.removeEventListener("resize", handleResize);
12852
12894
  };
12853
- }), [ defaultProps.collapsible, defaultProps.collapsibleDesktop, defaultProps.isOpen, defaultProps.onToggle, isOpenState ]),
12895
+ }), [ collapsible, collapsibleDesktop, isOpen, onToggle, isOpenState ]),
12854
12896
  // Update wrapper height when open state changes (both mobile and desktop)
12855
12897
  React.useEffect((() => {
12856
- const shouldCollapse = window.innerWidth < 768 ? defaultProps.collapsible : defaultProps.collapsibleDesktop;
12898
+ const shouldCollapse = window.innerWidth < 768 ? collapsible : collapsibleDesktop;
12857
12899
  if (shouldCollapse && wrapperRef.current && innerRef.current) {
12858
- const currentOpen = void 0 !== defaultProps.isOpen ? defaultProps.isOpen : isOpenState;
12900
+ const currentOpen = void 0 !== isOpen ? isOpen : isOpenState;
12859
12901
  // Use requestAnimationFrame to ensure DOM is ready
12860
12902
  requestAnimationFrame((() => {
12861
12903
  wrapperRef.current && innerRef.current && (wrapperRef.current.style.height = currentOpen ? `${innerRef.current.scrollHeight}px` : "0px");
@@ -12863,26 +12905,25 @@ function useHero(initialProps) {
12863
12905
  } else !shouldCollapse && wrapperRef.current && (
12864
12906
  // Not collapsible - always show content
12865
12907
  wrapperRef.current.style.height = "auto");
12866
- }), [ defaultProps.isOpen, isOpenState, defaultProps.collapsible, defaultProps.collapsibleDesktop ]);
12908
+ }), [ isOpen, isOpenState, collapsible, collapsibleDesktop ]);
12867
12909
  /**
12868
12910
  * Generate side menu class based on properties
12869
12911
  * @param props - Side menu properties
12870
12912
  * @returns Class string
12871
12913
  */
12872
12914
  const handleToggle = () => {
12873
- if (defaultProps.disabled) return;
12874
- const newState = void 0 !== defaultProps.isOpen ? !defaultProps.isOpen : !isOpenState;
12875
- "function" == typeof defaultProps.onToggle ?
12915
+ if (disabled) return;
12916
+ const newState = void 0 !== isOpen ? !isOpen : !isOpenState;
12917
+ "function" == typeof onToggle ?
12876
12918
  // Controlled component
12877
- defaultProps.onToggle(newState) :
12919
+ onToggle(newState) :
12878
12920
  // Uncontrolled component
12879
12921
  setIsOpenState(newState);
12880
- }, getCurrentOpenState = () => void 0 !== defaultProps.isOpen ? defaultProps.isOpen : isOpenState;
12922
+ }, getCurrentOpenState = () => void 0 !== isOpen ? isOpen : isOpenState;
12881
12923
  /**
12882
12924
  * Generate wrapper class
12883
12925
  * @returns Class string
12884
12926
  */ return {
12885
- defaultProps: defaultProps,
12886
12927
  isOpenState: getCurrentOpenState(),
12887
12928
  wrapperRef: wrapperRef,
12888
12929
  innerRef: innerRef,
@@ -13585,7 +13626,7 @@ SelectOption.displayName = "SelectOption";
13585
13626
  /**
13586
13627
  * Select - A component for dropdown selection
13587
13628
  */
13588
- const Select = React.memo((({options: options, value: value, onChange: onChange, onBlur: onBlur, onFocus: onFocus, placeholder: placeholder = "Select an option", className: className = "", style: style, disabled: disabled = !1, required: required = !1, id: id, name: name, size: size = "md", invalid: invalid = !1, valid: valid = !1, multiple: multiple = !1, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, glass: glass, children: children}) => {
13629
+ const SelectComponentBase = ({options: options, value: value, onChange: onChange, onBlur: onBlur, onFocus: onFocus, placeholder: placeholder = "Select an option", className: className = "", style: style, disabled: disabled = !1, required: required = !1, id: id, name: name, size: size = "md", invalid: invalid = !1, valid: valid = !1, multiple: multiple = !1, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, glass: glass, children: children}) => {
13589
13630
  const {generateSelectClass: generateSelectClass} = useSelect({
13590
13631
  size: size,
13591
13632
  disabled: disabled,
@@ -13776,7 +13817,7 @@ const Select = React.memo((({options: options, value: value, onChange: onChange
13776
13817
  });
13777
13818
  }
13778
13819
  return selectContent;
13779
- }));
13820
+ }, Select = React.memo(SelectComponentBase);
13780
13821
 
13781
13822
  Select.displayName = "Select", Select.Option = SelectOption;
13782
13823
 
@@ -14343,7 +14384,7 @@ Footer.displayName = "Footer";
14343
14384
  */
14344
14385
  const MasonryGrid = React.forwardRef((({children: children, className: className = "", xs: xs = 1, sm: sm, md: md, lg: lg, xl: xl, xxl: xxl, gap: gap = 16, animate: animate = !0, imagesLoaded: imagesLoaded = !0, onLayoutComplete: onLayoutComplete, onImageLoad: onImageLoad, ...props}, ref) => {
14345
14386
  // === REFS & STATE ===
14346
- const [columns, setColumns] = React.useState(xs), [positions, setPositions] = React.useState([]), [layoutComplete, setLayoutComplete] = React.useState(!1), [loadingImages, setLoadingImages] = React.useState(!1), containerRef = React.useRef(null), columnHeights = React.useRef([]), imagesLoadedCount = React.useRef(0), totalImagesCount = React.useRef(0), imageElements = React.useRef(new Map);
14387
+ const [columns, setColumns] = React.useState(xs), [positions, setPositions] = React.useState([]), [, setLayoutComplete] = React.useState(!1), [loadingImages, setLoadingImages] = React.useState(!1), containerRef = React.useRef(null), columnHeights = React.useRef([]), imagesLoadedCount = React.useRef(0), totalImagesCount = React.useRef(0), imageElements = React.useRef(new Map);
14347
14388
  React.useEffect((() => {
14348
14389
  setLoadingImages(!!imagesLoaded);
14349
14390
  }), [ columns, imagesLoaded ]),
@@ -14372,34 +14413,45 @@ const MasonryGrid = React.forwardRef((({children: children, className: classNam
14372
14413
  });
14373
14414
  })), setItems(newItems);
14374
14415
  }), [ children ]);
14375
- // === TRACK & MANAGE IMAGES ===
14376
- const handleImageLoad = React.useCallback((img => {
14377
- if (!imageElements.current.get(img)) {
14378
- // Add loaded class for animation
14379
- if (imageElements.current.set(img, !0), imagesLoadedCount.current += 1, containerRef.current && imagesLoaded) {
14380
- const itemElement = img.closest(".o-masonry-grid > div");
14381
- itemElement && (itemElement.offsetHeight, itemElement.classList.add("o-masonry-grid__item-loaded"),
14382
- itemElement.classList.remove("o-masonry-grid__item-loading"));
14416
+ // === MANAGE ITEM LAYOUT ===
14417
+ const calculateLayout = React.useCallback((() => {
14418
+ if (!containerRef.current || 0 === items.length) return;
14419
+ const colWidth = (containerRef.current.offsetWidth - gap * (columns - 1)) / columns;
14420
+ columnHeights.current = Array(columns).fill(0);
14421
+ const newPositions = [];
14422
+ items.forEach(((item, index) => {
14423
+ if (item.ref.current) {
14424
+ // Find the shortest column
14425
+ const shortestCol = columnHeights.current.indexOf(Math.min(...columnHeights.current)), left = shortestCol * (colWidth + gap), top = columnHeights.current[shortestCol] ?? 0, height = item.ref.current.offsetHeight;
14426
+ columnHeights.current[shortestCol] = top + height + gap, newPositions[index] = {
14427
+ left: left,
14428
+ top: top,
14429
+ width: colWidth,
14430
+ height: height
14431
+ };
14383
14432
  }
14384
- // Ensure layout is recalculated after DOM paints the item image (prevents overlap on slow/late image loads)
14385
- requestAnimationFrame((() => {
14386
- requestAnimationFrame((() => {
14387
- calculateLayout();
14388
- }));
14389
- })), onImageLoad?.(imagesLoadedCount.current, totalImagesCount.current),
14390
- // If all images have loaded, update loading state and complete layout
14391
- imagesLoadedCount.current >= totalImagesCount.current && totalImagesCount.current > 0 && (setLayoutComplete(!0),
14392
- setLoadingImages(!1), // This ensures the loading class is removed *immediately* after images load
14393
- // Force a double requestAnimationFrame for final layout calculation after all images are loaded (guarantees DOM paint)
14394
- requestAnimationFrame((() => {
14395
- requestAnimationFrame((() => {
14396
- calculateLayout(),
14397
- // As a failsafe, if still present for some render lag, force another setLoadingImages(false)
14398
- setLoadingImages(!1);
14399
- }));
14400
- })), onLayoutComplete?.());
14433
+ })), setPositions(newPositions);
14434
+ }), [ items, columns, gap ]), handleImageLoad = React.useCallback((img => {
14435
+ if (imageElements.current.get(img)) return;
14436
+ // Add loaded class for animation
14437
+ if (imageElements.current.set(img, !0), imagesLoadedCount.current += 1, containerRef.current && imagesLoaded) {
14438
+ const itemElement = img.closest(".o-masonry-grid > div");
14439
+ itemElement && (itemElement.offsetHeight, itemElement.classList.add("o-masonry-grid__item-loaded"),
14440
+ itemElement.classList.remove("o-masonry-grid__item-loading"));
14401
14441
  }
14402
- }), [ onImageLoad, onLayoutComplete, imagesLoaded ]), trackImages = React.useCallback((() => {
14442
+ // Schedule layout recalculation after next paint to prevent overlap
14443
+ const scheduleLayoutUpdate = () => {
14444
+ const frameId = requestAnimationFrame((() => {
14445
+ onImageLoad?.(imagesLoadedCount.current, totalImagesCount.current), calculateLayout();
14446
+ }));
14447
+ return () => cancelAnimationFrame(frameId);
14448
+ }, cleanup = scheduleLayoutUpdate();
14449
+ // Clean up previous scheduled updates
14450
+ // If all images have loaded, update loading state and complete layout
14451
+ imagesLoadedCount.current >= totalImagesCount.current && totalImagesCount.current > 0 && (setLayoutComplete(!0),
14452
+ setLoadingImages(!1), setTimeout((() => cleanup()), 0), // Clean up after current execution
14453
+ scheduleLayoutUpdate(), onLayoutComplete?.());
14454
+ }), [ onImageLoad, onLayoutComplete, imagesLoaded, calculateLayout ]), trackImages = React.useCallback((() => {
14403
14455
  if (!imagesLoaded || !containerRef.current) return;
14404
14456
  imageElements.current.clear(), imagesLoadedCount.current = 0;
14405
14457
  const images = containerRef.current.querySelectorAll("img");
@@ -14418,30 +14470,21 @@ const MasonryGrid = React.forwardRef((({children: children, className: classNam
14418
14470
  img.removeEventListener("error", masonryImg._masonryLoadHandler), delete masonryImg._masonryLoadHandler);
14419
14471
  }));
14420
14472
  });
14421
- }), [ imagesLoaded, handleImageLoad, onLayoutComplete ]), calculateLayout = React.useCallback((() => {
14422
- if (!containerRef.current || 0 === items.length) return;
14423
- const colWidth = (containerRef.current.offsetWidth - gap * (columns - 1)) / columns;
14424
- columnHeights.current = Array(columns).fill(0);
14425
- const newPositions = [];
14426
- items.forEach(((item, index) => {
14427
- if (item.ref.current) {
14428
- // Find the shortest column
14429
- const shortestCol = columnHeights.current.indexOf(Math.min(...columnHeights.current)), left = shortestCol * (colWidth + gap), top = columnHeights.current[shortestCol] ?? 0, height = item.ref.current.offsetHeight;
14430
- columnHeights.current[shortestCol] = top + height + gap, newPositions[index] = {
14431
- left: left,
14432
- top: top,
14433
- width: colWidth,
14434
- height: height
14435
- };
14436
- }
14437
- })), setPositions(newPositions);
14438
- }), [ items, columns, gap ]);
14439
- // === OBSERVE CONTAINER RESIZE ===
14473
+ }), [ imagesLoaded, handleImageLoad, onLayoutComplete ]);
14474
+ // === TRACK & MANAGE IMAGES ===
14475
+ // === OBSERVE CONTAINER RESIZE ===
14440
14476
  React.useEffect((() => {
14441
14477
  if (!containerRef.current) return;
14442
- let animationFrame = null;
14443
- const observer = new ResizeObserver((() => {
14444
- animationFrame && cancelAnimationFrame(animationFrame), animationFrame = requestAnimationFrame((() => calculateLayout()));
14478
+ let animationFrame = null, lastWidth = 0;
14479
+ const observer = new ResizeObserver((entries => {
14480
+ const entry = entries[0];
14481
+ if (!entry) return;
14482
+ const currentWidth = entry.contentRect.width;
14483
+ // Only recalculate if width actually changed (prevents excessive calculations)
14484
+ Math.abs(currentWidth - lastWidth) > 1 && (animationFrame && cancelAnimationFrame(animationFrame),
14485
+ animationFrame = requestAnimationFrame((() => {
14486
+ calculateLayout(), lastWidth = currentWidth;
14487
+ })));
14445
14488
  }));
14446
14489
  return observer.observe(containerRef.current), () => {
14447
14490
  observer.disconnect(), animationFrame && cancelAnimationFrame(animationFrame);
@@ -14452,24 +14495,21 @@ const MasonryGrid = React.forwardRef((({children: children, className: classNam
14452
14495
  setLayoutComplete(!0), void setLoadingImages(!1))
14453
14496
  // Only reset layoutComplete when items or columns change
14454
14497
  ), [ items, columns, calculateLayout, imagesLoaded, trackImages ]),
14455
- // === NEW: Add ResizeObservers to all grid items for bulletproof image+content measurement ===
14498
+ // === ADD RESIZEOBSERVERS TO GRID ITEMS FOR DYNAMIC CONTENT MEASUREMENT ===
14456
14499
  React__default.default.useEffect((() => {
14457
- // Clean up old observers if items ever change
14458
14500
  const observers = [];
14501
+ let animationFrame = null;
14502
+ // Debounced layout calculation for item resize events
14503
+ const debouncedCalculateLayout = () => {
14504
+ animationFrame && cancelAnimationFrame(animationFrame), animationFrame = requestAnimationFrame(calculateLayout);
14505
+ };
14459
14506
  return items.forEach((item => {
14460
14507
  if (item.ref.current) {
14461
- const obs = new ResizeObserver((() => {
14462
- // Double rAF: ensures layout only runs after DOM/paint/async renders
14463
- requestAnimationFrame((() => {
14464
- requestAnimationFrame((() => {
14465
- calculateLayout();
14466
- }));
14467
- }));
14468
- }));
14508
+ const obs = new ResizeObserver(debouncedCalculateLayout);
14469
14509
  obs.observe(item.ref.current), observers.push(obs);
14470
14510
  }
14471
14511
  })), () => {
14472
- observers.forEach((obs => obs.disconnect()));
14512
+ observers.forEach((obs => obs.disconnect())), animationFrame && cancelAnimationFrame(animationFrame);
14473
14513
  };
14474
14514
  }), [ items, calculateLayout ]);
14475
14515
  // Ensure loadingImages state resets when items/columns/imagesLoaded change
@@ -14954,7 +14994,7 @@ const ListItem = React.forwardRef((({children: children, className: className =
14954
14994
 
14955
14995
  ListItem.displayName = "ListItem";
14956
14996
 
14957
- const List = React.memo((({children: children, variant: variant = "default", className: className = "", style: style, ...props}) => {
14997
+ const ListComponentBase = ({children: children, variant: variant = "default", className: className = "", style: style, ...props}) => {
14958
14998
  var _context;
14959
14999
  // Generate CSS classes
14960
15000
  const listClasses = [ LIST.BASE_CLASS, "default" !== variant && `c-list--${variant}`, className ].filter(Boolean).join(" "), ListElement = _includesInstanceProperty(_context = [ "number", "text" ]).call(_context, variant) ? "ol" : "ul";
@@ -14968,7 +15008,7 @@ const List = React.memo((({children: children, variant: variant = "default", cl
14968
15008
  children: child
14969
15009
  })))
14970
15010
  });
14971
- }));
15011
+ }, List = React.memo(ListComponentBase);
14972
15012
 
14973
15013
  List.displayName = "List", List.Item = ListItem;
14974
15014
 
@@ -15919,12 +15959,12 @@ const SideMenu = React.forwardRef((({title: title, children: children, menuItem
15919
15959
  const index = Number(key);
15920
15960
  index >= currentLength && (delete nestedWrapperRefs.current[index], delete nestedInnerRefs.current[index]);
15921
15961
  })));
15922
- }), [ menuItems?.length ]);
15962
+ }), [ menuItems ]);
15923
15963
  // Helper function to update nested wrapper height
15924
- const updateNestedHeight = (index, isOpen) => {
15964
+ const updateNestedHeight = React.useCallback(((index, isOpen) => {
15925
15965
  const wrapper = nestedWrapperRefs.current[index], inner = nestedInnerRefs.current[index];
15926
15966
  wrapper && inner && (wrapper.style.height = isOpen ? `${inner.scrollHeight}px` : "0px");
15927
- };
15967
+ }), []);
15928
15968
  // Set initial heights for nested wrappers on mount and when menuItems change
15929
15969
  React.useEffect((() => {
15930
15970
  if (!menuItems?.length) return;
@@ -15938,7 +15978,7 @@ const SideMenu = React.forwardRef((({title: title, children: children, menuItem
15938
15978
  // Only run when menuItems change, nestedItemStates is read but not in deps to avoid loops
15939
15979
  // eslint-disable-next-line react-hooks/exhaustive-deps
15940
15980
  ;
15941
- }), [ menuItems?.length ]),
15981
+ }), [ menuItems, updateNestedHeight ]),
15942
15982
  // Update nested wrapper heights when state changes
15943
15983
  React.useEffect((() => {
15944
15984
  if (!menuItems?.length) return;
@@ -15951,7 +15991,7 @@ const SideMenu = React.forwardRef((({title: title, children: children, menuItem
15951
15991
  })), () => {
15952
15992
  frameIds.forEach((id => cancelAnimationFrame(id)));
15953
15993
  };
15954
- }), [ nestedItemStates, menuItems?.length ]);
15994
+ }), [ nestedItemStates, menuItems, updateNestedHeight ]);
15955
15995
  // Combine refs using utility
15956
15996
  const combinedRef = useForkRef(sideMenuRef, ref), sideMenuClass = generateSideMenuClass({
15957
15997
  className: className,
@@ -16854,7 +16894,7 @@ React.useEffect((() => {
16854
16894
  }
16855
16895
  };
16856
16896
  }));
16857
- }), [ isMounted, currentIndex, calculateBounds, constrainPosition ]), setImagePosition = React.useCallback((position => {
16897
+ }), [ currentIndex, calculateBounds, constrainPosition ]), setImagePosition = React.useCallback((position => {
16858
16898
  setImageStates((prev => {
16859
16899
  const currentState = prev[currentIndex] || {
16860
16900
  zoomLevel: 1,
@@ -16904,7 +16944,7 @@ React.useEffect((() => {
16904
16944
  }
16905
16945
  };
16906
16946
  }));
16907
- }), [ isMounted, currentIndex, calculateBounds, constrainPosition ]), handleWheel = React.useCallback((event => {
16947
+ }), [ currentIndex, calculateBounds, constrainPosition ]), handleWheel = React.useCallback((event => {
16908
16948
  var _context;
16909
16949
  if (!isMounted || !event || !event.currentTarget) return;
16910
16950
  // Additional safety check for the target element
@@ -17261,7 +17301,7 @@ React.useEffect((() => {
17261
17301
  }
17262
17302
  return prev;
17263
17303
  }));
17264
- }), [ isMounted, enableGestures, isDragging, startDragPosition, currentIndex, constrainPosition, calculateBounds ]), handleTouchEnd = React.useCallback((() => {
17304
+ }), [ enableGestures, isDragging, startDragPosition, currentIndex, constrainPosition, calculateBounds ]), handleTouchEnd = React.useCallback((() => {
17265
17305
  setIsDragging(!1), lastDistanceRef.current = null, lastMidpointRef.current = null;
17266
17306
  }), []), currentState = imageStates[currentIndex] || {
17267
17307
  zoomLevel: 1,
@@ -17465,9 +17505,9 @@ const PopoverContext = React.createContext({
17465
17505
  triggerType: "click"
17466
17506
  }), Popover = ({content: content, position: position = "top", trigger: trigger = "click", className: className = "", style: style, delay: delay = 0, offset: offset = 12, defaultOpen: defaultOpen = !1, isOpen: controlledIsOpen, onOpenChange: onOpenChange, closeOnClickOutside: closeOnClickOutside = !0, closeOnEscape: closeOnEscape = !0, id: id, children: children, glass: glass}) => {
17467
17507
  const {isOpen: isOpen, setIsOpen: setIsOpen, triggerRef: triggerRef, popoverRef: popoverRef, arrowRef: arrowRef, popoverId: popoverId, currentPosition: currentPosition, updatePosition: updatePosition} = (({position: position = "top", trigger: trigger = "click", offset: offset = 12, delay: delay = 0, defaultOpen: defaultOpen = !1, isOpen: controlledIsOpen, onOpenChange: onOpenChange, closeOnClickOutside: closeOnClickOutside = !0, closeOnEscape: closeOnEscape = !0, id: id}) => {
17468
- const [isOpen, setIsOpenState] = React.useState(defaultOpen), [currentPosition, setCurrentPosition] = React.useState("auto" === position ? "top" : position), triggerRef = React.useRef(null), popoverRef = React.useRef(null), arrowRef = React.useRef(null), timeoutRef = React.useRef(null), popoverId = id || `popover-${Math.random().toString(36).slice(2, 11)}`, isControlled = void 0 !== controlledIsOpen, isOpenState = isControlled ? controlledIsOpen : isOpen, setIsOpen = newIsOpen => {
17508
+ const [isOpen, setIsOpenState] = React.useState(defaultOpen), [currentPosition, setCurrentPosition] = React.useState("auto" === position ? "top" : position), triggerRef = React.useRef(null), popoverRef = React.useRef(null), arrowRef = React.useRef(null), timeoutRef = React.useRef(null), popoverId = id || `popover-${Math.random().toString(36).slice(2, 11)}`, isControlled = void 0 !== controlledIsOpen, isOpenState = isControlled ? controlledIsOpen : isOpen, setIsOpen = React.useCallback((newIsOpen => {
17469
17509
  isControlled || setIsOpenState(newIsOpen), onOpenChange && onOpenChange(newIsOpen);
17470
- };
17510
+ }), [ isControlled, onOpenChange ]);
17471
17511
  // Handle hover events if trigger is hover
17472
17512
  React.useEffect((() => {
17473
17513
  if ("hover" !== trigger || !triggerRef.current || !popoverRef.current) return;
@@ -17487,17 +17527,16 @@ const PopoverContext = React.createContext({
17487
17527
  setIsOpen(!1);
17488
17528
  };
17489
17529
  // Add hover event listeners
17490
- return triggerRef.current.addEventListener("mouseenter", handleTriggerMouseEnter),
17491
- triggerRef.current.addEventListener("mouseleave", handleTriggerMouseLeave), popoverRef.current.addEventListener("mouseenter", handlePopoverMouseEnter),
17492
- popoverRef.current.addEventListener("mouseleave", handlePopoverMouseLeave), () => {
17493
- triggerRef.current && (triggerRef.current.removeEventListener("mouseenter", handleTriggerMouseEnter),
17494
- triggerRef.current.removeEventListener("mouseleave", handleTriggerMouseLeave)),
17495
- popoverRef.current && (popoverRef.current.removeEventListener("mouseenter", handlePopoverMouseEnter),
17496
- popoverRef.current.removeEventListener("mouseleave", handlePopoverMouseLeave)),
17497
- null !== timeoutRef.current && window.clearTimeout(timeoutRef.current);
17530
+ triggerRef.current.addEventListener("mouseenter", handleTriggerMouseEnter), triggerRef.current.addEventListener("mouseleave", handleTriggerMouseLeave),
17531
+ popoverRef.current.addEventListener("mouseenter", handlePopoverMouseEnter), popoverRef.current.addEventListener("mouseleave", handlePopoverMouseLeave);
17532
+ const currentTrigger = triggerRef.current, currentPopover = popoverRef.current;
17533
+ return () => {
17534
+ currentTrigger && (currentTrigger.removeEventListener("mouseenter", handleTriggerMouseEnter),
17535
+ currentTrigger.removeEventListener("mouseleave", handleTriggerMouseLeave)), currentPopover && (currentPopover.removeEventListener("mouseenter", handlePopoverMouseEnter),
17536
+ currentPopover.removeEventListener("mouseleave", handlePopoverMouseLeave)), null !== timeoutRef.current && window.clearTimeout(timeoutRef.current);
17498
17537
  };
17499
- }), [ trigger, delay, isOpenState ]);
17500
- const updatePosition = event => {
17538
+ }), [ trigger, delay, isOpenState, setIsOpen ]);
17539
+ const updatePosition = React.useCallback((event => {
17501
17540
  if (!triggerRef.current || !popoverRef.current) return;
17502
17541
  const triggerRect = triggerRef.current.getBoundingClientRect(), popoverRect = popoverRef.current.getBoundingClientRect(), viewportWidth = window.innerWidth, viewportHeight = window.innerHeight, isNearViewportEdge = triggerRect.top < 50 || triggerRect.bottom > viewportHeight - 50 || triggerRect.left < 50 || triggerRect.right > viewportWidth - 50;
17503
17542
  // If this is a scroll update and trigger isn't near edges, skip repositioning
@@ -17558,9 +17597,9 @@ const PopoverContext = React.createContext({
17558
17597
  // Add scroll position to convert viewport coordinates to absolute position
17559
17598
  const absoluteTop = top + window.scrollY, absoluteLeft = left + window.scrollX;
17560
17599
  // Apply position using absolute positioning to follow when scrolling
17561
- popoverRef.current.style.position = "absolute", popoverRef.current.style.top = `${absoluteTop}px`,
17562
- popoverRef.current.style.left = `${absoluteLeft}px`;
17563
- };
17600
+ popoverRef.current && (popoverRef.current.style.position = "absolute", popoverRef.current.style.top = `${absoluteTop}px`,
17601
+ popoverRef.current.style.left = `${absoluteLeft}px`);
17602
+ }), [ position, offset ]);
17564
17603
  // Position the popover
17565
17604
  return React.useEffect((() => {
17566
17605
  if (!isOpenState || !triggerRef.current || !popoverRef.current) return;
@@ -17586,7 +17625,7 @@ const PopoverContext = React.createContext({
17586
17625
  window.removeEventListener("resize", updatePosition), window.removeEventListener("scroll", handleScroll),
17587
17626
  scrollTimeout && clearTimeout(scrollTimeout), clearInterval(intervalId);
17588
17627
  };
17589
- }), [ isOpenState, position, offset ]),
17628
+ }), [ isOpenState, updatePosition ]),
17590
17629
  // Handle click outside to close popover
17591
17630
  React.useEffect((() => {
17592
17631
  if (!isOpenState || !closeOnClickOutside) return;
@@ -17596,7 +17635,7 @@ const PopoverContext = React.createContext({
17596
17635
  return document.addEventListener("mousedown", handleClickOutside), () => {
17597
17636
  document.removeEventListener("mousedown", handleClickOutside);
17598
17637
  };
17599
- }), [ isOpenState, closeOnClickOutside ]),
17638
+ }), [ isOpenState, closeOnClickOutside, setIsOpen ]),
17600
17639
  // Handle escape key to close popover
17601
17640
  React.useEffect((() => {
17602
17641
  if (!isOpenState || !closeOnEscape) return;
@@ -17606,7 +17645,7 @@ const PopoverContext = React.createContext({
17606
17645
  return document.addEventListener("keydown", handleEscapeKey), () => {
17607
17646
  document.removeEventListener("keydown", handleEscapeKey);
17608
17647
  };
17609
- }), [ isOpenState, closeOnEscape ]),
17648
+ }), [ isOpenState, closeOnEscape, setIsOpen ]),
17610
17649
  // Clean up on unmount
17611
17650
  React.useEffect((() => () => {
17612
17651
  null !== timeoutRef.current && window.clearTimeout(timeoutRef.current);
@@ -17787,10 +17826,11 @@ const calculateStarValue = (e, starValue, allowHalf) => {
17787
17826
  }), [ readOnly, onChange, allowHalf ]);
17788
17827
  // Use vanilla JS implementation if specified
17789
17828
  React.useEffect((() => {
17790
- if (useVanillaJS && "undefined" != typeof window && internalRef.current)
17829
+ if (!useVanillaJS || "undefined" == typeof window || !internalRef.current) return;
17830
+ const currentInstance = ratingInstance.current;
17791
17831
  // Cleanup on unmount
17792
- return () => {
17793
- ratingInstance.current && ratingInstance.current.destroy();
17832
+ return () => {
17833
+ currentInstance && currentInstance.destroy();
17794
17834
  };
17795
17835
  }), [ useVanillaJS, valueProp, defaultValue, maxValue, allowHalf, readOnly, size, variant, onChange ]),
17796
17836
  // Update vanilla JS implementation when props change
@@ -17911,10 +17951,11 @@ const ProductReview = ({productName: productName, productImage: productImage, in
17911
17951
  const [rating, setRating] = React.useState(initialRating), [comment, setComment] = React.useState(""), [submitted, setSubmitted] = React.useState(!1), reviewRef = React.useRef(null), reviewInstance = React.useRef(null);
17912
17952
  React.useEffect((() => {
17913
17953
  // Only run on client-side
17914
- if ("undefined" != typeof window && reviewRef.current)
17954
+ if ("undefined" == typeof window || !reviewRef.current) return;
17955
+ const currentInstance = reviewInstance.current;
17915
17956
  // Cleanup on unmount
17916
- return () => {
17917
- reviewInstance.current && reviewInstance.current.destroy();
17957
+ return () => {
17958
+ currentInstance && currentInstance.destroy();
17918
17959
  };
17919
17960
  }), [ productName, productImage, initialRating, maxRating, allowHalf, ratingColor, onSubmit ]);
17920
17961
  const handleSubmit = e => {
@@ -18159,10 +18200,11 @@ const SectionIntro = ({title: title, label: label, text: text, actions: actions,
18159
18200
  const sectionIntroRef = React.useRef(null), sectionIntroInstance = React.useRef(null);
18160
18201
  React.useEffect((() => {
18161
18202
  // Only run on client-side
18162
- if ("undefined" != typeof window && sectionIntroRef.current)
18203
+ if ("undefined" == typeof window || !sectionIntroRef.current) return;
18204
+ const currentInstance = sectionIntroInstance.current;
18163
18205
  // Cleanup on unmount
18164
- return () => {
18165
- sectionIntroInstance.current && sectionIntroInstance.current.destroy();
18206
+ return () => {
18207
+ currentInstance && currentInstance.destroy();
18166
18208
  };
18167
18209
  }), [ alignment, backgroundImageSrc, showOverlay, size, skeleton ]);
18168
18210
  // Determine CSS classes
@@ -18246,7 +18288,7 @@ SectionIntro.displayName = "SectionIntro";
18246
18288
 
18247
18289
  const Slider = React.forwardRef(((props, ref) => {
18248
18290
  const {slides: slides = [], height: height = 300, width: width = "100%", slidesToShow: slidesToShow = 1, spaceBetween: spaceBetween = 0, loop: loop = !1, initialSlide: initialSlide = 0, direction: direction = "horizontal", speed: speed = 300, allowTouchMove: allowTouchMove = !0, threshold: threshold = 50, grabCursor: grabCursor = !0, autoplay: autoplay, navigation: navigation, pagination: pagination, className: className, style: style, onSlideChange: onSlideChange, ...rest} = props, validSlides = Array.isArray(slides) ? slides : [], slider = function(options) {
18249
- const {slides: rawSlides, slidesToShow: slidesToShow = 1, spaceBetween: spaceBetween = 0, loop: loop = !1, initialSlide: initialSlide = 0, direction: direction = "horizontal", speed: speed = 300, allowTouchMove: allowTouchMove = !0, threshold: threshold = 50, autoplay: autoplay, onSlideChange: onSlideChange} = options, slides = Array.isArray(rawSlides) ? rawSlides : [], containerRef = React.useRef(null), wrapperRef = React.useRef(null), repositioningRef = React.useRef(!1), autoplayRef = React.useRef(null), [autoplayRunning, setAutoplayRunning] = React.useState(!1), sliderStateRef = React.useRef({
18291
+ const {slides: rawSlides, slidesToShow: slidesToShow = 1, spaceBetween: spaceBetween = 0, loop: loop = !1, initialSlide: initialSlide = 0, direction: direction = "horizontal", speed: speed = 300, allowTouchMove: allowTouchMove = !0, threshold: threshold = 50, autoplay: autoplay, onSlideChange: onSlideChange} = options, slides = React.useMemo((() => Array.isArray(rawSlides) ? rawSlides : []), [ rawSlides ]), containerRef = React.useRef(null), wrapperRef = React.useRef(null), repositioningRef = React.useRef(!1), autoplayRef = React.useRef(null), [autoplayRunning, setAutoplayRunning] = React.useState(!1), sliderStateRef = React.useRef({
18250
18292
  isTransitioning: !1,
18251
18293
  loop: loop,
18252
18294
  slides: slides,
@@ -18381,7 +18423,7 @@ const Slider = React.forwardRef(((props, ref) => {
18381
18423
  setIsTransitioning(!1), onSlideChange?.(nextIndex);
18382
18424
  }), speed);
18383
18425
  }
18384
- }), [ realIndex, internalIndex, slides.length, slidesToShow, loop, isTransitioning, speed, onSlideChange, allSlides.length, loopedSlides, autoplay ]), slidePrev = React.useCallback((() => {
18426
+ }), [ realIndex, internalIndex, slides.length, slidesToShow, loop, isTransitioning, speed, onSlideChange, autoplay ]), slidePrev = React.useCallback((() => {
18385
18427
  if (!isTransitioning) if (
18386
18428
  // Stop autoplay on interaction if disableOnInteraction is true
18387
18429
  autoplay && "object" == typeof autoplay && autoplay.disableOnInteraction && autoplayRef.current && (clearInterval(autoplayRef.current),
@@ -18403,7 +18445,7 @@ const Slider = React.forwardRef(((props, ref) => {
18403
18445
  setIsTransitioning(!1), onSlideChange?.(prevIndex);
18404
18446
  }), speed);
18405
18447
  }
18406
- }), [ realIndex, internalIndex, slides.length, loop, isTransitioning, speed, onSlideChange, allSlides.length, loopedSlides, autoplay ]), goToSlide = React.useCallback((index => {
18448
+ }), [ realIndex, internalIndex, slides.length, loop, isTransitioning, speed, onSlideChange, autoplay ]), goToSlide = React.useCallback((index => {
18407
18449
  isTransitioning || index === realIndex || (
18408
18450
  // Stop autoplay on interaction if disableOnInteraction is true
18409
18451
  autoplay && "object" == typeof autoplay && autoplay.disableOnInteraction && autoplayRef.current && (clearInterval(autoplayRef.current),
@@ -18411,7 +18453,7 @@ const Slider = React.forwardRef(((props, ref) => {
18411
18453
  setRealIndex(index), setInternalIndex(loop ? slides.length + index : index), setTimeout((() => {
18412
18454
  setIsTransitioning(!1), onSlideChange?.(index);
18413
18455
  }), speed));
18414
- }), [ realIndex, isTransitioning, speed, onSlideChange, loop, loopedSlides, autoplay ]), handleTouchStart = React.useCallback((e => {
18456
+ }), [ realIndex, isTransitioning, speed, onSlideChange, loop, slides.length, autoplay ]), handleTouchStart = React.useCallback((e => {
18415
18457
  if (!allowTouchMove) return;
18416
18458
  // Stop autoplay on interaction if disableOnInteraction is true
18417
18459
  autoplay && "object" == typeof autoplay && autoplay.disableOnInteraction && autoplayRef.current && (clearInterval(autoplayRef.current),
@@ -18666,7 +18708,7 @@ const Steps = ({items: items, activeIndex: activeIndex = 0, vertical: vertical =
18666
18708
  let content;
18667
18709
  React.useEffect((() => {
18668
18710
  currentStep !== activeIndex && setCurrentStep(activeIndex);
18669
- }), [ activeIndex ]),
18711
+ }), [ activeIndex, currentStep ]),
18670
18712
  // Legacy rendering
18671
18713
  content = items && items.length > 0 ? items.map(((item, index) => jsxRuntime.jsx(StepsItem, {
18672
18714
  index: index,
@@ -18810,7 +18852,7 @@ const TabsPanel = React.forwardRef((({children: children, className: className
18810
18852
 
18811
18853
  TabsPanel.displayName = "TabsPanel";
18812
18854
 
18813
- const Tabs = React.memo((({items: items, activeIndex: activeIndex = TAB.DEFAULTS.ACTIVE_INDEX, onTabChange: onTabChange, className: className = "", style: style, glass: glass, children: children}) => {
18855
+ const TabsComponentBase = ({items: items, activeIndex: activeIndex = TAB.DEFAULTS.ACTIVE_INDEX, onTabChange: onTabChange, className: className = "", style: style, glass: glass, children: children}) => {
18814
18856
  const [currentTab, setCurrentTab] = React.useState(activeIndex), handleTabClick = index => {
18815
18857
  setCurrentTab(index), onTabChange && onTabChange(index);
18816
18858
  }, handleKeyDown = (event, totalTabs) => {
@@ -18926,7 +18968,7 @@ const Tabs = React.memo((({items: items, activeIndex: activeIndex = TAB.DEFAULT
18926
18968
  });
18927
18969
  }
18928
18970
  return wrapper;
18929
- }));
18971
+ }, Tabs = React.memo(TabsComponentBase);
18930
18972
 
18931
18973
  Tabs.displayName = "Tabs", Tabs.List = TabsList, Tabs.Trigger = TabsTrigger, Tabs.Panels = TabsPanels,
18932
18974
  Tabs.Panel = TabsPanel;
@@ -18938,10 +18980,11 @@ const Testimonial = ({quote: quote, author: author, size: size = "", skeleton: s
18938
18980
  const testimonialRef = React.useRef(null), testimonialInstance = React.useRef(null);
18939
18981
  React.useEffect((() => {
18940
18982
  // Only run on client-side
18941
- if ("undefined" != typeof window && testimonialRef.current)
18983
+ if ("undefined" == typeof window || !testimonialRef.current) return;
18984
+ const currentInstance = testimonialInstance.current;
18942
18985
  // Cleanup on unmount
18943
- return () => {
18944
- testimonialInstance.current && testimonialInstance.current.destroy();
18986
+ return () => {
18987
+ currentInstance && currentInstance.destroy();
18945
18988
  };
18946
18989
  }), [ size, skeleton ]);
18947
18990
  // Determine CSS classes
@@ -20082,11 +20125,13 @@ const VideoPlayer = React.forwardRef((({src: src, type: type = "video", youtube
20082
20125
  detectBorderRadius();
20083
20126
  // Create ResizeObserver to watch for style changes
20084
20127
  let resizeObserver = null;
20085
- return "undefined" != typeof ResizeObserver && containerRef.current && (resizeObserver = new ResizeObserver(detectBorderRadius),
20128
+ "undefined" != typeof ResizeObserver && containerRef.current && (resizeObserver = new ResizeObserver(detectBorderRadius),
20086
20129
  resizeObserver.observe(containerRef.current)),
20087
20130
  // Also listen for window resize (in case styles change)
20088
- window.addEventListener("resize", detectBorderRadius), () => {
20089
- window.removeEventListener("resize", detectBorderRadius), resizeObserver && containerRef.current && (resizeObserver.unobserve(containerRef.current),
20131
+ window.addEventListener("resize", detectBorderRadius);
20132
+ const currentContainer = containerRef.current;
20133
+ return () => {
20134
+ window.removeEventListener("resize", detectBorderRadius), resizeObserver && currentContainer && (resizeObserver.unobserve(currentContainer),
20090
20135
  resizeObserver.disconnect());
20091
20136
  };
20092
20137
  }), []);
@@ -22437,7 +22482,7 @@ const logger = getLogger(), ThemeProvider = ({children: children, defaultTheme:
22437
22482
  // If defaultTheme is provided, use it
22438
22483
  return null != defaultTheme ? defaultTheme : "default";
22439
22484
  // Default fallback
22440
- }), [ defaultTheme, enablePersistence, storageKey ]), [currentTheme, setCurrentTheme] = React.useState((() => "string" == typeof initialDefaultTheme ? initialDefaultTheme : "tokens-theme")), [activeTokens, setActiveTokens] = React.useState((() => {
22485
+ }), [ defaultTheme, enablePersistence, storageKey, storageAdapter ]), [currentTheme, setCurrentTheme] = React.useState((() => "string" == typeof initialDefaultTheme ? initialDefaultTheme : "tokens-theme")), [activeTokens, setActiveTokens] = React.useState((() => {
22441
22486
  // If defaultTheme is DesignTokens, validate and store them
22442
22487
  if (defaultTheme && "string" != typeof defaultTheme) {
22443
22488
  const {tokens: tokens, validation: validation} = validateAndMergeTokens(defaultTheme);
@@ -23740,7 +23785,7 @@ class ThemeValidator {
23740
23785
  *
23741
23786
  * Provides detailed inspection and debugging information for themes
23742
23787
  */ const ThemeInspector = ({theme: theme, showValidation: showValidation = !0, showCSSVariables: showCSSVariables = !0, showStructure: showStructure = !0, className: className, style: style}) => {
23743
- const [activeTab, setActiveTab] = React.useState("overview"), [expandedSections, setExpandedSections] = React.useState(new Set([ "palette" ])), [searchQuery, setSearchQuery] = React.useState(""), [debouncedSearchQuery, setDebouncedSearchQuery] = React.useState(""), [copiedPath, setCopiedPath] = React.useState(null), searchTimeoutRef = React.useRef();
23788
+ const [activeTab, setActiveTab] = React.useState("overview"), [expandedSections, setExpandedSections] = React.useState(new Set([ "palette" ])), [searchQuery, setSearchQuery] = React.useState(""), [debouncedSearchQuery, setDebouncedSearchQuery] = React.useState(""), [copiedPath, setCopiedPath] = React.useState(null), searchTimeoutRef = React.useRef(void 0);
23744
23789
  // Debounce search query
23745
23790
  React.useEffect((() => (searchTimeoutRef.current && clearTimeout(searchTimeoutRef.current),
23746
23791
  searchTimeoutRef.current = setTimeout((() => {
@@ -24146,7 +24191,7 @@ class ThemeValidator {
24146
24191
  }) ]
24147
24192
  });
24148
24193
  }, ThemeComparator = ({themeA: themeA, themeB: themeB, showOnlyDifferences: showOnlyDifferences = !1, className: className, style: style}) => {
24149
- const [searchQuery, setSearchQuery] = React.useState(""), [debouncedSearchQuery, setDebouncedSearchQuery] = React.useState(""), [filterType, setFilterType] = React.useState("all"), [filterCategory, setFilterCategory] = React.useState("all"), searchTimeoutRef = React.useRef();
24194
+ const [searchQuery, setSearchQuery] = React.useState(""), [debouncedSearchQuery, setDebouncedSearchQuery] = React.useState(""), [filterType, setFilterType] = React.useState("all"), [filterCategory, setFilterCategory] = React.useState("all"), searchTimeoutRef = React.useRef(void 0);
24150
24195
  // Debounce search query
24151
24196
  React.useEffect((() => (searchTimeoutRef.current && clearTimeout(searchTimeoutRef.current),
24152
24197
  searchTimeoutRef.current = setTimeout((() => {
@@ -24942,7 +24987,7 @@ const ThemeLiveEditor = ({initialTheme: initialTheme, onChange: onChange, classN
24942
24987
  } catch (err) {
24943
24988
  setError(err instanceof Error ? err.message : "Invalid JSON");
24944
24989
  }
24945
- }), [ updateTheme ]), jsonUpdateTimeoutRef = React.useRef();
24990
+ }), [ updateTheme ]), jsonUpdateTimeoutRef = React.useRef(void 0);
24946
24991
  // Debounced JSON update to history
24947
24992
  React.useEffect((() => {
24948
24993
  if (!error) {
@@ -26086,45 +26131,21 @@ function mergePartStyles(base, override) {
26086
26131
  }
26087
26132
 
26088
26133
  /**
26089
- * Render a slot with the given props
26090
- *
26091
- * Priority order:
26092
- * 1. render function
26093
- * 2. component
26094
- * 3. children
26095
- * 4. fallback
26134
+ * Hook to merge theme overrides with component props
26096
26135
  *
26097
26136
  * @example
26098
- * renderSlot(
26099
- * { render: (props) => <CustomButton {...props} /> },
26100
- * { onClick: handleClick, children: 'Click me' }
26101
- * )
26102
- */ function renderSlot(slot, props, fallback) {
26103
- // No slot provided, use fallback
26104
- if (!slot) return fallback;
26105
- // Slot is a plain React node
26106
- if ( React__default.default.isValidElement(slot) || "string" == typeof slot || "number" == typeof slot) return slot;
26107
- // Slot is an object with rendering options
26108
- if ("object" == typeof slot && null !== slot) {
26109
- const slotObj = slot;
26110
- // Priority 1: render function
26111
- if (slotObj.render && "function" == typeof slotObj.render) return slotObj.render(props);
26112
- // Priority 2: component
26113
- if (slotObj.component) {
26114
- const Component = slotObj.component;
26115
- return jsxRuntime.jsx(Component, {
26116
- ...props
26117
- });
26118
- }
26119
- // Priority 3: children
26120
- if (void 0 !== slotObj.children) return slotObj.children;
26121
- }
26122
- // Fallback
26123
- return fallback;
26124
- }
26125
-
26126
- /**
26127
- * Check if a value is a slot configuration
26137
+ * function Button(props: ButtonProps) {
26138
+ * const customization = useComponentCustomization('Button', props);
26139
+ *
26140
+ * return (
26141
+ * <button
26142
+ * className={customization.className}
26143
+ * style={customization.style}
26144
+ * >
26145
+ * {props.children}
26146
+ * </button>
26147
+ * );
26148
+ * }
26128
26149
  */
26129
26150
  // Import and re-export as namespaces with proper typing
26130
26151
  // Export as namespaces with explicit typing
@@ -26527,25 +26548,7 @@ function(theme, selector = ":root") {
26527
26548
  }, exports.types = types, exports.unregisterTheme = unregisterTheme, exports.useAccordion = useAccordion,
26528
26549
  exports.useAtomixGlass = useAtomixGlass, exports.useBadge = useBadge, exports.useBarChart = useBarChart,
26529
26550
  exports.useBlock = useBlock, exports.useChartData = useChartData, exports.useChartInteraction = useChartInteraction,
26530
- exports.useChartScale = useChartScale, exports.useComponentCustomization =
26531
- /**
26532
- * Hook to merge theme overrides with component props
26533
- *
26534
- * @example
26535
- * function Button(props: ButtonProps) {
26536
- * const customization = useComponentCustomization('Button', props);
26537
- *
26538
- * return (
26539
- * <button
26540
- * className={customization.className}
26541
- * style={customization.style}
26542
- * >
26543
- * {props.children}
26544
- * </button>
26545
- * );
26546
- * }
26547
- */
26548
- function(component, props) {
26551
+ exports.useChartScale = useChartScale, exports.useComponentCustomization = function(component, props) {
26549
26552
  const {theme: theme} = useTheme(), cssVars = React.useMemo((() => mergeCSSVars(theme?.components?.[component]?.cssVars || {}, props.cssVars || {})), [ theme, component, props.cssVars ]), parts = React.useMemo((() => {
26550
26553
  const themeParts = theme?.components?.[component]?.parts || {}, propParts = props.parts || {}, merged = {};
26551
26554
  return new Set([ ...Object.keys(themeParts), ...Object.keys(propParts) ]).forEach((partName => {