@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.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
 
3
- import React, { useState, useRef, useEffect, memo, forwardRef, useId, useMemo, useCallback, Children, isValidElement, cloneElement, createContext, useContext, useImperativeHandle, Component } from "react";
3
+ import React, { useState, useRef, useCallback, useEffect, memo, forwardRef, useId, useMemo, Children, isValidElement, cloneElement, createContext, useContext, useImperativeHandle, Component } from "react";
4
4
 
5
5
  import * as PhosphorIcons from "@phosphor-icons/react";
6
6
 
@@ -1965,19 +1965,19 @@ function useAccordion(initialProps) {
1965
1965
  disabled: !1,
1966
1966
  iconPosition: "right",
1967
1967
  ...initialProps
1968
- }, isControlled = "boolean" == typeof defaultProps.isOpen, [internalOpen, setInternalOpen] = useState(defaultProps.defaultOpen || !1), isOpen = isControlled ? defaultProps.isOpen : internalOpen, [panelHeight, setPanelHeight] = useState(isOpen ? "auto" : "0px"), panelRef = useRef(null), contentRef = useRef(null), updatePanelHeight = () => {
1968
+ }, isControlled = "boolean" == typeof defaultProps.isOpen, [internalOpen, setInternalOpen] = useState(defaultProps.defaultOpen || !1), isOpen = isControlled ? defaultProps.isOpen : internalOpen, [panelHeight, setPanelHeight] = useState(isOpen ? "auto" : "0px"), panelRef = useRef(null), contentRef = useRef(null), updatePanelHeight = useCallback((() => {
1969
1969
  if (contentRef.current && panelRef.current) {
1970
1970
  const height = isOpen ? `${contentRef.current.clientHeight}px` : "0px";
1971
1971
  panelRef.current.style.setProperty(ACCORDION.CSS_VARS.PANEL_HEIGHT, height), setPanelHeight(height);
1972
1972
  }
1973
- };
1973
+ }), [ isOpen ]);
1974
1974
  // Controlled/uncontrolled open state
1975
1975
  /**
1976
1976
  * Effect to update panel height when open state changes
1977
1977
  */
1978
1978
  return useEffect((() => {
1979
1979
  updatePanelHeight();
1980
- }), [ isOpen ]),
1980
+ }), [ isOpen, updatePanelHeight ]),
1981
1981
  /**
1982
1982
  * Effect to handle window resize and update panel height
1983
1983
  */
@@ -1986,7 +1986,7 @@ function useAccordion(initialProps) {
1986
1986
  isOpen && updatePanelHeight();
1987
1987
  };
1988
1988
  return window.addEventListener("resize", handleResize), () => window.removeEventListener("resize", handleResize);
1989
- }), [ isOpen ]), {
1989
+ }), [ isOpen, updatePanelHeight ]), {
1990
1990
  state: {
1991
1991
  isOpen: isOpen,
1992
1992
  panelHeight: panelHeight
@@ -5311,7 +5311,152 @@ class ThemeNaming {
5311
5311
 
5312
5312
  ThemeNaming.prefix = "atomix";
5313
5313
 
5314
- const Button = React.memo( 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) => {
5314
+ 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) {
5315
+ return function(that, callbackfn, argumentsLength, memo) {
5316
+ var O = toObject(that), self = IndexedObject(O), length = lengthOfArrayLike(O);
5317
+ if (aCallable(callbackfn), 0 === length && argumentsLength < 2) throw new $TypeError(REDUCE_EMPTY);
5318
+ var index = IS_RIGHT ? length - 1 : 0, i = IS_RIGHT ? -1 : 1;
5319
+ if (argumentsLength < 2) for (;;) {
5320
+ if (index in self) {
5321
+ memo = self[index], index += i;
5322
+ break;
5323
+ }
5324
+ if (index += i, IS_RIGHT ? index < 0 : length <= index) throw new $TypeError(REDUCE_EMPTY);
5325
+ }
5326
+ for (;IS_RIGHT ? index >= 0 : length > index; index += i) index in self && (memo = callbackfn(memo, self[index], index, O));
5327
+ return memo;
5328
+ };
5329
+ }, arrayReduce = {
5330
+ // `Array.prototype.reduce` method
5331
+ // https://tc39.es/ecma262/#sec-array.prototype.reduce
5332
+ left: createMethod(!1),
5333
+ // `Array.prototype.reduceRight` method
5334
+ // https://tc39.es/ecma262/#sec-array.prototype.reduceright
5335
+ right: createMethod(!0)
5336
+ }, fails = fails$9, globalThis$1 = globalThis_1, userAgent = environmentUserAgent, classof = classofRaw$2, userAgentStartsWith = function(string) {
5337
+ return userAgent.slice(0, string.length) === string;
5338
+ }, 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;
5339
+
5340
+ // `Array.prototype.reduce` method
5341
+ // https://tc39.es/ecma262/#sec-array.prototype.reduce
5342
+ _export({
5343
+ target: "Array",
5344
+ proto: !0,
5345
+ forced: !("NODE" === environment) && environmentV8Version > 79 && environmentV8Version < 83 || !function(METHOD_NAME, argument) {
5346
+ var method = [][METHOD_NAME];
5347
+ return !!method && fails((function() {
5348
+ // eslint-disable-next-line no-useless-call -- required for testing
5349
+ method.call(null, argument || function() {
5350
+ return 1;
5351
+ }, 1);
5352
+ }));
5353
+ }("reduce")
5354
+ }, {
5355
+ reduce: function(callbackfn /* , initialValue */) {
5356
+ var length = arguments.length;
5357
+ return $reduce(this, callbackfn, length, length > 1 ? arguments[1] : void 0);
5358
+ }
5359
+ });
5360
+
5361
+ var reduce$3 = getBuiltInPrototypeMethod$3("Array", "reduce"), isPrototypeOf = objectIsPrototypeOf, method = reduce$3, ArrayPrototype = Array.prototype;
5362
+
5363
+ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
5364
+ var own = it.reduce;
5365
+ return it === ArrayPrototype || isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.reduce ? method : own;
5366
+ }));
5367
+
5368
+ /**
5369
+ * Render a slot with the given props
5370
+ *
5371
+ * Priority order:
5372
+ * 1. render function
5373
+ * 2. component
5374
+ * 3. children
5375
+ * 4. fallback
5376
+ *
5377
+ * @example
5378
+ * renderSlot(
5379
+ * { render: (props) => <CustomButton {...props} /> },
5380
+ * { onClick: handleClick, children: 'Click me' }
5381
+ * )
5382
+ */ function renderSlot(slot, props, fallback) {
5383
+ // No slot provided, use fallback
5384
+ if (!slot) return fallback;
5385
+ // Slot is a plain React node
5386
+ if ( React.isValidElement(slot) || "string" == typeof slot || "number" == typeof slot) return slot;
5387
+ // Slot is an object with rendering options
5388
+ if ("object" == typeof slot && null !== slot) {
5389
+ const slotObj = slot;
5390
+ // Priority 1: render function
5391
+ if (slotObj.render && "function" == typeof slotObj.render) return slotObj.render(props);
5392
+ // Priority 2: component
5393
+ if (slotObj.component) {
5394
+ const Component = slotObj.component;
5395
+ return jsx(Component, {
5396
+ ...props
5397
+ });
5398
+ }
5399
+ // Priority 3: children
5400
+ if (void 0 !== slotObj.children) return slotObj.children;
5401
+ }
5402
+ // Fallback
5403
+ return fallback;
5404
+ }
5405
+
5406
+ /**
5407
+ * Check if a value is a slot configuration
5408
+ */ function isSlot(value) {
5409
+ return "object" == typeof value && null !== value && ("render" in value || "component" in value || "children" in value);
5410
+ }
5411
+
5412
+ /**
5413
+ * Merge multiple slot configurations
5414
+ * Later slots override earlier ones
5415
+ */ function mergeSlots(...slots) {
5416
+ const filtered = slots.filter((s => void 0 !== s));
5417
+ if (0 !== filtered.length) return 1 === filtered.length ? filtered[0] : _reduceInstanceProperty(filtered).call(filtered, ((acc, slot) => ({
5418
+ ...acc,
5419
+ ...slot
5420
+ })));
5421
+ }
5422
+
5423
+ /**
5424
+ * Create a slot wrapper component
5425
+ *
5426
+ * @example
5427
+ * const ButtonSlot = createSlotComponent<ButtonSlotProps>('button')
5428
+ *
5429
+ * <ButtonSlot slot={customSlot} {...props}>
5430
+ * Default content
5431
+ * </ButtonSlot>
5432
+ */ function createSlotComponent(defaultElement = "div") {
5433
+ return function({slot: slot, children: children, ...props}) {
5434
+ const slotProps = props;
5435
+ return slot ? jsx(Fragment, {
5436
+ children: renderSlot(slot, slotProps, children)
5437
+ }) : jsx(defaultElement, "string" == typeof defaultElement ? {
5438
+ ...props,
5439
+ children: children
5440
+ } : {
5441
+ ...slotProps,
5442
+ children: children
5443
+ });
5444
+ };
5445
+ }
5446
+
5447
+ /**
5448
+ * Utility to create typed slot props
5449
+ */ function createSlotProps(props) {
5450
+ return props;
5451
+ }
5452
+
5453
+ /**
5454
+ * Hook to manage slot rendering
5455
+ */ function useSlot(slot, props, fallback) {
5456
+ return React.useMemo((() => renderSlot(slot, props, fallback)), [ slot, props, fallback ]);
5457
+ }
5458
+
5459
+ const Button = React.memo( 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) => {
5315
5460
  const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href), iconElement = iconName ? jsx(Icon, {
5316
5461
  name: iconName,
5317
5462
  size: iconSize
@@ -5327,17 +5472,28 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
5327
5472
  children: [ loading && jsx("span", {
5328
5473
  className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.SPINNER_ELEMENT),
5329
5474
  "aria-hidden": "true",
5330
- children: jsx(Spinner, {
5475
+ children: renderSlot(slots?.spinner, {
5476
+ className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.SPINNER_ELEMENT),
5331
5477
  size: spinnerSize,
5332
5478
  variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
5333
- })
5479
+ }, jsx(Spinner, {
5480
+ size: spinnerSize,
5481
+ variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
5482
+ }))
5334
5483
  }), iconElement && !loading && jsx("span", {
5335
5484
  className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.ICON_ELEMENT),
5336
5485
  "aria-hidden": "true",
5337
- children: iconElement
5486
+ children: renderSlot(slots?.icon, {
5487
+ className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.ICON_ELEMENT),
5488
+ children: iconElement,
5489
+ size: iconSize
5490
+ }, iconElement)
5338
5491
  }), !iconOnly && buttonText && jsx("span", {
5339
5492
  className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.LABEL_ELEMENT),
5340
- children: buttonText
5493
+ children: renderSlot(slots?.label, {
5494
+ className: ThemeNaming.bemClass(THEME_NAMING.BUTTON_PREFIX, THEME_NAMING.LABEL_ELEMENT),
5495
+ children: buttonText
5496
+ }, buttonText)
5341
5497
  }) ]
5342
5498
  }), buttonProps = {
5343
5499
  className: buttonClass,
@@ -5354,48 +5510,59 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
5354
5510
  tabIndex: void 0 !== tabIndex ? tabIndex : isDisabled ? -1 : 0,
5355
5511
  style: style,
5356
5512
  ...props
5357
- };
5358
- // Determine if we should render as a link
5359
- // If disabled, we still check href, but we might want to render as button or anchor with aria-disabled
5360
- // The previous logic was Boolean(href && !isDisabled). This meant if disabled, it renders as <button>.
5361
- // This is a safe fallback for disabled links.
5362
- let content;
5363
- // Render as anchor if href is provided
5364
- if (shouldRenderAsLink)
5365
- // Use custom linkComponent if provided (e.g., Next.js Link)
5366
- if (linkComponent) {
5367
- const LinkComp = linkComponent, linkProps = {
5513
+ }, buttonChildren = renderSlot(slots?.root, {
5514
+ className: buttonClass,
5515
+ children: buttonContent,
5516
+ disabled: isDisabled,
5517
+ loading: loading,
5518
+ onClick: handleClickEvent,
5519
+ type: type,
5520
+ "aria-label": safeAriaLabel,
5521
+ "aria-disabled": isDisabled,
5522
+ "aria-busy": loading
5523
+ }, (() => {
5524
+ // Render as anchor if href is provided
5525
+ if (shouldRenderAsLink) {
5526
+ // Use custom linkComponent if provided (e.g., Next.js Link)
5527
+ if (linkComponent) {
5528
+ const LinkComp = linkComponent, linkProps = {
5529
+ ...buttonProps,
5530
+ ref: ref,
5531
+ // linkComponent usually forwards ref to anchor
5532
+ href: isDisabled ? void 0 : href,
5533
+ to: isDisabled ? void 0 : href,
5534
+ target: target,
5535
+ rel: "_blank" === target ? "noopener noreferrer" : void 0
5536
+ };
5537
+ return jsx(LinkComp, {
5538
+ ...linkProps,
5539
+ children: buttonContent
5540
+ });
5541
+ }
5542
+ // Fallback to regular anchor tag
5543
+ return jsx("a", {
5544
+ ...buttonProps,
5545
+ ref: ref,
5546
+ href: isDisabled ? void 0 : href,
5547
+ target: target,
5548
+ rel: "_blank" === target ? "noopener noreferrer" : void 0,
5549
+ children: buttonContent
5550
+ });
5551
+ }
5552
+ // Default button rendering
5553
+ return jsx(Component, {
5368
5554
  ...buttonProps,
5369
5555
  ref: ref,
5370
- // linkComponent usually forwards ref to anchor
5371
- href: isDisabled ? void 0 : href,
5372
- to: isDisabled ? void 0 : href,
5373
- target: target,
5374
- rel: "_blank" === target ? "noopener noreferrer" : void 0
5375
- };
5376
- content = jsx(LinkComp, {
5377
- ...linkProps,
5556
+ type: "button" === Component ? type : void 0,
5557
+ disabled: isDisabled,
5378
5558
  children: buttonContent
5379
5559
  });
5380
- } else
5381
- // Fallback to regular anchor tag
5382
- content = jsx("a", {
5383
- ...buttonProps,
5384
- ref: ref,
5385
- href: isDisabled ? void 0 : href,
5386
- target: target,
5387
- rel: "_blank" === target ? "noopener noreferrer" : void 0,
5388
- children: buttonContent
5389
- }); else
5390
- // Default button rendering
5391
- content = jsx(Component, {
5392
- ...buttonProps,
5393
- ref: ref,
5394
- type: "button" === Component ? type : void 0,
5395
- disabled: isDisabled,
5396
- children: buttonContent
5397
- });
5398
- if (glass) {
5560
+ })());
5561
+ // Determine if we should render as a link
5562
+ // If disabled, we still check href, but we might want to render as button or anchor with aria-disabled
5563
+ // The previous logic was Boolean(href && !isDisabled). This meant if disabled, it renders as <button>.
5564
+ // This is a safe fallback for disabled links.
5565
+ if (glass) {
5399
5566
  // Default glass props
5400
5567
  const defaultGlassProps = {
5401
5568
  displacementScale: 20,
@@ -5408,10 +5575,10 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
5408
5575
  };
5409
5576
  return jsx(AtomixGlass, {
5410
5577
  ...glassProps,
5411
- children: content
5578
+ children: buttonChildren
5412
5579
  });
5413
5580
  }
5414
- return content;
5581
+ return buttonChildren;
5415
5582
  })));
5416
5583
 
5417
5584
  Button.displayName = "Button";
@@ -5923,67 +6090,12 @@ const ElevationCard = ({elevationClass: elevationClass = "is-elevated", classNam
5923
6090
  });
5924
6091
  };
5925
6092
 
5926
- ElevationCard.displayName = "ElevationCard";
5927
-
5928
- 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) {
5929
- return function(that, callbackfn, argumentsLength, memo) {
5930
- var O = toObject(that), self = IndexedObject(O), length = lengthOfArrayLike(O);
5931
- if (aCallable(callbackfn), 0 === length && argumentsLength < 2) throw new $TypeError(REDUCE_EMPTY);
5932
- var index = IS_RIGHT ? length - 1 : 0, i = IS_RIGHT ? -1 : 1;
5933
- if (argumentsLength < 2) for (;;) {
5934
- if (index in self) {
5935
- memo = self[index], index += i;
5936
- break;
5937
- }
5938
- if (index += i, IS_RIGHT ? index < 0 : length <= index) throw new $TypeError(REDUCE_EMPTY);
5939
- }
5940
- for (;IS_RIGHT ? index >= 0 : length > index; index += i) index in self && (memo = callbackfn(memo, self[index], index, O));
5941
- return memo;
5942
- };
5943
- }, arrayReduce = {
5944
- // `Array.prototype.reduce` method
5945
- // https://tc39.es/ecma262/#sec-array.prototype.reduce
5946
- left: createMethod(!1),
5947
- // `Array.prototype.reduceRight` method
5948
- // https://tc39.es/ecma262/#sec-array.prototype.reduceright
5949
- right: createMethod(!0)
5950
- }, fails = fails$9, globalThis$1 = globalThis_1, userAgent = environmentUserAgent, classof = classofRaw$2, userAgentStartsWith = function(string) {
5951
- return userAgent.slice(0, string.length) === string;
5952
- }, 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;
5953
-
5954
- // `Array.prototype.reduce` method
5955
- // https://tc39.es/ecma262/#sec-array.prototype.reduce
5956
- _export({
5957
- target: "Array",
5958
- proto: !0,
5959
- forced: !("NODE" === environment) && environmentV8Version > 79 && environmentV8Version < 83 || !function(METHOD_NAME, argument) {
5960
- var method = [][METHOD_NAME];
5961
- return !!method && fails((function() {
5962
- // eslint-disable-next-line no-useless-call -- required for testing
5963
- method.call(null, argument || function() {
5964
- return 1;
5965
- }, 1);
5966
- }));
5967
- }("reduce")
5968
- }, {
5969
- reduce: function(callbackfn /* , initialValue */) {
5970
- var length = arguments.length;
5971
- return $reduce(this, callbackfn, length, length > 1 ? arguments[1] : void 0);
5972
- }
5973
- });
5974
-
5975
- var reduce$3 = getBuiltInPrototypeMethod$3("Array", "reduce"), isPrototypeOf = objectIsPrototypeOf, method = reduce$3, ArrayPrototype = Array.prototype;
5976
-
5977
- const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
5978
- var own = it.reduce;
5979
- return it === ArrayPrototype || isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.reduce ? method : own;
5980
- }));
5981
-
5982
6093
  /**
5983
6094
  * Comprehensive chart hook with shared functionality
5984
6095
  * @param initialProps - Initial chart properties
5985
6096
  * @returns Chart state and methods
5986
- */ function useChart(initialProps) {
6097
+ */
6098
+ function useChart(initialProps) {
5987
6099
  const [interactionState, setInteractionState] = useState({
5988
6100
  hoveredPoint: null,
5989
6101
  selectedPoints: [],
@@ -6015,8 +6127,11 @@ const _reduceInstanceProperty = getDefaultExportFromCjs((function(it) {
6015
6127
  }), animationFrameRef = useRef(null);
6016
6128
  // Default chart properties
6017
6129
  // Cleanup animation frame on unmount
6018
- useEffect((() => () => {
6019
- animationFrameRef.current && cancelAnimationFrame(animationFrameRef.current);
6130
+ useEffect((() => {
6131
+ const currentRef = animationFrameRef.current;
6132
+ return () => {
6133
+ currentRef && cancelAnimationFrame(currentRef);
6134
+ };
6020
6135
  }), []);
6021
6136
  /**
6022
6137
  * Point interaction handlers
@@ -6407,7 +6522,9 @@ function getDatasetBounds(data) {
6407
6522
 
6408
6523
  /**
6409
6524
  * Hook for managing chart toolbar state and generating chart-specific configurations
6410
- */ const ChartToolbar = memo( forwardRef((({chartType: chartType = "line", groups: groups = [], enableDefaults: enableDefaults = !0, defaults: defaults = {
6525
+ */ ElevationCard.displayName = "ElevationCard";
6526
+
6527
+ const ChartToolbar = memo( forwardRef((({chartType: chartType = "line", groups: groups = [], enableDefaults: enableDefaults = !0, defaults: defaults = {
6411
6528
  refresh: !0,
6412
6529
  export: !0,
6413
6530
  fullscreen: !0,
@@ -6897,8 +7014,8 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
6897
7014
  }), [ chartType ]), finalDefaults = useMemo((() => ({
6898
7015
  ...getChartDefaults(),
6899
7016
  ...defaults
6900
- })), [ getChartDefaults, defaults ]), enhancedHandlers = {
6901
- onRefresh: useCallback((() => {
7017
+ })), [ getChartDefaults, defaults ]), enhancedHandlers = useMemo((() => ({
7018
+ onRefresh: () => {
6902
7019
  setState((prev => ({
6903
7020
  ...prev,
6904
7021
  isRefreshing: !0
@@ -6908,8 +7025,8 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
6908
7025
  isRefreshing: !1
6909
7026
  })));
6910
7027
  }), 1e3);
6911
- }), [ handlers.onRefresh ]),
6912
- onExport: useCallback((async format => {
7028
+ },
7029
+ onExport: async format => {
6913
7030
  setState((prev => ({
6914
7031
  ...prev,
6915
7032
  isExporting: !0
@@ -6922,70 +7039,70 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
6922
7039
  isExporting: !1
6923
7040
  })));
6924
7041
  }
6925
- }), [ handlers.onExport ]),
6926
- onFullscreen: useCallback((isFullscreen => {
7042
+ },
7043
+ onFullscreen: isFullscreen => {
6927
7044
  setState((prev => ({
6928
7045
  ...prev,
6929
7046
  isFullscreen: isFullscreen
6930
7047
  }))), handlers.onFullscreen?.(isFullscreen);
6931
- }), [ handlers.onFullscreen ]),
6932
- onZoomIn: useCallback((() => {
7048
+ },
7049
+ onZoomIn: () => {
6933
7050
  setState((prev => ({
6934
7051
  ...prev,
6935
7052
  zoomLevel: Math.min(1.2 * prev.zoomLevel, 5)
6936
7053
  }))), handlers.onZoomIn?.();
6937
- }), [ handlers.onZoomIn ]),
6938
- onZoomOut: useCallback((() => {
7054
+ },
7055
+ onZoomOut: () => {
6939
7056
  setState((prev => ({
6940
7057
  ...prev,
6941
7058
  zoomLevel: Math.max(prev.zoomLevel / 1.2, .2)
6942
7059
  }))), handlers.onZoomOut?.();
6943
- }), [ handlers.onZoomOut ]),
6944
- onZoomReset: useCallback((() => {
7060
+ },
7061
+ onZoomReset: () => {
6945
7062
  setState((prev => ({
6946
7063
  ...prev,
6947
7064
  zoomLevel: 1
6948
7065
  }))), handlers.onZoomReset?.();
6949
- }), [ handlers.onZoomReset ]),
6950
- onPanToggle: useCallback((enabled => {
7066
+ },
7067
+ onPanToggle: enabled => {
6951
7068
  setState((prev => ({
6952
7069
  ...prev,
6953
7070
  panEnabled: enabled
6954
7071
  }))), handlers.onPanToggle?.(enabled);
6955
- }), [ handlers.onPanToggle ]),
6956
- onReset: useCallback((() => {
7072
+ },
7073
+ onReset: () => {
6957
7074
  setState((prev => ({
6958
7075
  ...prev,
6959
7076
  zoomLevel: 1,
6960
7077
  panEnabled: !1
6961
7078
  }))), handlers.onReset?.();
6962
- }), [ handlers.onReset ]),
6963
- onGridToggle: useCallback((show => {
7079
+ },
7080
+ onGridToggle: show => {
6964
7081
  setState((prev => ({
6965
7082
  ...prev,
6966
7083
  showGrid: show
6967
7084
  }))), handlers.onGridToggle?.(show);
6968
- }), [ handlers.onGridToggle ]),
6969
- onLegendToggle: useCallback((show => {
7085
+ },
7086
+ onLegendToggle: show => {
6970
7087
  setState((prev => ({
6971
7088
  ...prev,
6972
7089
  showLegend: show
6973
7090
  }))), handlers.onLegendToggle?.(show);
6974
- }), [ handlers.onLegendToggle ]),
6975
- onTooltipsToggle: useCallback((show => {
7091
+ },
7092
+ onTooltipsToggle: show => {
6976
7093
  setState((prev => ({
6977
7094
  ...prev,
6978
7095
  showTooltips: show
6979
7096
  }))), handlers.onTooltipsToggle?.(show);
6980
- }), [ handlers.onTooltipsToggle ]),
6981
- onAnimationsToggle: useCallback((enabled => {
7097
+ },
7098
+ onAnimationsToggle: enabled => {
6982
7099
  setState((prev => ({
6983
7100
  ...prev,
6984
7101
  animationsEnabled: enabled
6985
7102
  }))), handlers.onAnimationsToggle?.(enabled);
6986
- }), [ handlers.onAnimationsToggle ]),
6987
- onSettings: useCallback((() => {}), [])
6988
- }, generateToolbarGroups = useCallback((() => {
7103
+ },
7104
+ onSettings: () => {}
7105
+ })), [ handlers ]), generateToolbarGroups = useCallback((() => {
6989
7106
  const groups = [], dataActions = [];
6990
7107
  // Data actions group
6991
7108
  finalDefaults.refresh && dataActions.push({
@@ -7110,7 +7227,7 @@ toolbarConfig: toolbarConfig, customToolbarActions: customToolbarActions, custom
7110
7227
  actions: customActions
7111
7228
  });
7112
7229
  return groups;
7113
- }), [ chartType, finalDefaults, state, enhancedHandlers, customActions, customGroups ]);
7230
+ }), [ finalDefaults, state, enhancedHandlers, customActions, customGroups ]);
7114
7231
  // Keyboard shortcuts
7115
7232
  return useEffect((() => {
7116
7233
  const handleKeyDown = event => {
@@ -7702,7 +7819,7 @@ const ChartRenderer = memo( forwardRef((({datasets: datasets = [], config: conf
7702
7819
  announcement: announcement,
7703
7820
  focusedPoint: focusedPoint,
7704
7821
  getAccessibleDescription: () => "Chart description"
7705
- })), [ announcement, focusedPoint ]), transform = useMemo((() => chartContext ? `translate(${chartContext.panOffset.x}px, ${chartContext.panOffset.y}px) scale(${chartContext.zoomLevel})` : ""), [ chartContext?.panOffset.x, chartContext?.panOffset.y, chartContext?.zoomLevel ]), chartData = useMemo((() => {
7822
+ })), [ announcement, focusedPoint ]), transform = useMemo((() => chartContext ? `translate(${chartContext.panOffset.x}px, ${chartContext.panOffset.y}px) scale(${chartContext.zoomLevel})` : ""), [ chartContext ]), chartData = useMemo((() => {
7706
7823
  // Return null if dimensions not ready to prevent calculation with invalid dimensions
7707
7824
  if (!isInitialized || 0 === dimensions.width || 0 === dimensions.height) return null;
7708
7825
  const scales = calculateScales(processedData, dimensions.width, dimensions.height, void 0, config);
@@ -8115,7 +8232,7 @@ function useBarChart(datasets, options = {}) {
8115
8232
  opacity: .4
8116
8233
  } ]
8117
8234
  };
8118
- })) : []), [ options.useGradients ]), formatValue = useCallback((value => options.valueFormatter ? options.valueFormatter(value) : value.toString()), [ options.valueFormatter ]);
8235
+ })) : []), [ options.useGradients ]), formatValue = useCallback((value => options.valueFormatter ? options.valueFormatter(value) : value.toString()), [ options ]);
8119
8236
  return {
8120
8237
  // State
8121
8238
  hoveredBar: hoveredBar,
@@ -8141,7 +8258,7 @@ function useBarChart(datasets, options = {}) {
8141
8258
  y: horizontal ? y + height / 2 : y - 5
8142
8259
  };
8143
8260
  }
8144
- }), [ options.dataLabelPosition ]),
8261
+ }), [ options ]),
8145
8262
  // Handlers
8146
8263
  handleBarHover: handleBarHover,
8147
8264
  handleBarLeave: handleBarLeave,
@@ -8450,13 +8567,13 @@ const DonutChart = memo( forwardRef((({datasets: datasets = [], config: config
8450
8567
  roundedCorners: !0
8451
8568
  }, onDataPointClick: onDataPointClick, ...props}, ref) => {
8452
8569
  // Use the first dataset for donut chart
8453
- const dataset = datasets.length > 0 ? datasets[0] : {
8570
+ const dataset = useMemo((() => datasets.length > 0 ? datasets[0] : {
8454
8571
  label: "",
8455
8572
  data: []
8456
- }, chartData = useMemo((() => {
8573
+ }), [ datasets ]), chartData = useMemo((() => {
8457
8574
  if (!dataset?.data?.length) return null;
8458
8575
  // Filter out invalid data points
8459
- const validDataPoints = dataset?.data?.filter((point => "number" == typeof point.value && !isNaN(point.value) && isFinite(point.value) && point.value > 0));
8576
+ const validDataPoints = (dataset?.data || []).filter((point => "number" == typeof point.value && !isNaN(point.value) && isFinite(point.value) && point.value > 0));
8460
8577
  return validDataPoints.length ? {
8461
8578
  validDataPoints: validDataPoints
8462
8579
  } : null;
@@ -9412,7 +9529,7 @@ function usePieChart(data, options = {}) {
9412
9529
  const parts = [];
9413
9530
  return !1 !== options.showLabels && parts.push(slice.label), options.showPercentages && parts.push(`${Math.round(slice.percentage)}%`),
9414
9531
  options.showValues && parts.push(slice.value.toString()), parts.join(" - ");
9415
- }), [ options.labelFormatter, options.showLabels, options.showPercentages, options.showValues ]), getSliceTransform = 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 = useCallback((index => selectedSlices.has(index)), [ selectedSlices ]);
9532
+ }), [ options ]), getSliceTransform = 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 = useCallback((index => selectedSlices.has(index)), [ selectedSlices ]);
9416
9533
  return {
9417
9534
  // Data
9418
9535
  processedData: processedData,
@@ -10839,7 +10956,7 @@ const DataTable = memo((({data: data, columns: columns, className: className, s
10839
10956
  const newOrder = columns.map((col => col.key)), currentOrderSet = new Set(columnOrder), newOrderSet = new Set(newOrder);
10840
10957
  // Only update if there are actual differences
10841
10958
  newOrder.length === columnOrder.length && newOrder.every((key => currentOrderSet.has(key))) && columnOrder.every((key => newOrderSet.has(key))) || setColumnOrder(newOrder);
10842
- }), [ columns ]),
10959
+ }), [ columns, columnOrder ]),
10843
10960
  // Update column visibility when columns prop changes
10844
10961
  useEffect((() => {
10845
10962
  setColumnVisibility((prev => {
@@ -11384,7 +11501,7 @@ function formatDate(date, format) {
11384
11501
  /**
11385
11502
  * Check if a date is within a min and max range
11386
11503
  */ 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} = {}) {
11387
- const [isOpen, setIsOpen] = useState(inline), [inputValue, setInputValue] = useState(value ? formatDate(value, format) : ""), [rangeInputValue, setRangeInputValue] = useState(startDate && endDate ? `${formatDate(startDate, format)} - ${formatDate(endDate, format)}` : startDate ? `${formatDate(startDate, format)} - Select end date` : ""), [viewDate, setViewDate] = useState(value || startDate || new Date), [viewMode, setViewMode] = useState("days"), [rangeSelectionState, setRangeSelectionState] = useState(!startDate || startDate && endDate ? "start" : "end"), datePickerRef = useRef(null), inputRef = useRef(null), today = new Date, currentMonth = viewDate.getMonth(), currentYear = viewDate.getFullYear(), daysInMonth = getDaysInMonth(currentYear, currentMonth), firstDayOfMonth = new Date(currentYear, currentMonth, 1).getDay();
11504
+ const [isOpen, setIsOpen] = useState(inline), [inputValue, setInputValue] = useState(value ? formatDate(value, format) : ""), [rangeInputValue, setRangeInputValue] = useState(startDate && endDate ? `${formatDate(startDate, format)} - ${formatDate(endDate, format)}` : startDate ? `${formatDate(startDate, format)} - Select end date` : ""), [viewDate, setViewDate] = useState(value || startDate || new Date), [viewMode, setViewMode] = useState("days"), [rangeSelectionState, setRangeSelectionState] = useState(!startDate || startDate && endDate ? "start" : "end"), datePickerRef = useRef(null), inputRef = useRef(null), today = useMemo((() => new Date), []), currentMonth = viewDate.getMonth(), currentYear = viewDate.getFullYear(), daysInMonth = getDaysInMonth(currentYear, currentMonth), firstDayOfMonth = new Date(currentYear, currentMonth, 1).getDay();
11388
11505
  // Update input value when value or range dates change externally
11389
11506
  useEffect((() => {
11390
11507
  "single" === selectionMode ? setInputValue(value ? formatDate(value, format) : "") : (setRangeInputValue(startDate && endDate ? `${formatDate(startDate, format)} - ${formatDate(endDate, format)}` : startDate ? `${formatDate(startDate, format)} - Select end date` : ""),
@@ -11907,21 +12024,11 @@ const DatePicker = forwardRef((({value: value, onChange: onChange, selectionMod
11907
12024
  * @returns EdgePanel state and methods
11908
12025
  */
11909
12026
  function useEdgePanel(initialProps) {
11910
- // Default EdgePanel properties
11911
- const defaultProps = {
11912
- position: "start",
11913
- mode: "slide",
11914
- isOpen: !1,
11915
- backdrop: !0,
11916
- closeOnBackdropClick: !0,
11917
- closeOnEscape: !0,
11918
- glass: void 0,
11919
- ...initialProps
11920
- }, [isOpen, setIsOpen] = useState(defaultProps.isOpen || !1), containerRef = useRef(null), backdropRef = useRef(null), adjustBodyPadding = useCallback((() => {
11921
- if (!containerRef.current || "push" !== defaultProps.mode) return;
11922
- const {position: position} = defaultProps, size = "top" === position || "bottom" === position ? containerRef.current.clientHeight : containerRef.current.clientWidth;
12027
+ 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] = useState(propIsOpen || !1), containerRef = useRef(null), backdropRef = useRef(null), adjustBodyPadding = useCallback((() => {
12028
+ if (!containerRef.current || "push" !== mode) return;
12029
+ const size = "top" === position || "bottom" === position ? containerRef.current.clientHeight : containerRef.current.clientWidth;
11923
12030
  // Map position to CSS padding property
11924
- let paddingProperty;
12031
+ let paddingProperty;
11925
12032
  switch (position) {
11926
12033
  case "start":
11927
12034
  paddingProperty = "paddingLeft";
@@ -11936,9 +12043,8 @@ function useEdgePanel(initialProps) {
11936
12043
  paddingProperty = `padding${position.charAt(0).toUpperCase() + position.slice(1)}`;
11937
12044
  }
11938
12045
  document.body.style[paddingProperty] = `${size}px`, document.body.classList.add("is-pushed");
11939
- }), [ defaultProps.mode, defaultProps.position ]), resetBodyPadding = useCallback((() => {
11940
- if ("push" !== defaultProps.mode) return;
11941
- const {position: position} = defaultProps;
12046
+ }), [ mode, position ]), resetBodyPadding = useCallback((() => {
12047
+ if ("push" !== mode) return;
11942
12048
  // Map position to CSS padding property
11943
12049
  let paddingProperty;
11944
12050
  switch (position) {
@@ -11955,11 +12061,10 @@ function useEdgePanel(initialProps) {
11955
12061
  paddingProperty = `padding${position.charAt(0).toUpperCase() + position.slice(1)}`;
11956
12062
  }
11957
12063
  document.body.style[paddingProperty] = "", document.body.classList.remove("is-pushed");
11958
- }), [ defaultProps.mode, defaultProps.position ]), openPanel = useCallback(((useFadeAnimation = !1) => {
12064
+ }), [ mode, position ]), openPanel = useCallback(((useFadeAnimation = !1) => {
11959
12065
  if (setIsOpen(!0), document.body.classList.add("is-edgepanel-open"), containerRef.current) {
11960
- const {mode: mode} = defaultProps;
11961
12066
  // Only add animation if not in 'none' mode
11962
- if ("none" !== mode) if (useFadeAnimation) {
12067
+ if ("none" !== mode) if (useFadeAnimation) {
11963
12068
  // Add fade animation class
11964
12069
  containerRef.current.classList.add("is-fade-animating"), containerRef.current.offsetHeight;
11965
12070
  // Remove animation class after animation completes
@@ -11979,14 +12084,13 @@ function useEdgePanel(initialProps) {
11979
12084
  // Set transform or opacity based on animation type
11980
12085
  useFadeAnimation ? (containerRef.current.style.opacity = "1", containerRef.current.style.transform = "") : containerRef.current.style.transform = "translate(0)",
11981
12086
  // If push mode, adjust body padding
11982
- "push" === defaultProps.mode && adjustBodyPadding();
12087
+ "push" === mode && adjustBodyPadding();
11983
12088
  }
11984
- defaultProps.onOpenChange && defaultProps.onOpenChange(!0);
11985
- }), [ defaultProps, adjustBodyPadding ]), closePanel = useCallback(((useFadeAnimation = !1) => {
12089
+ onOpenChange && onOpenChange(!0);
12090
+ }), [ mode, adjustBodyPadding, onOpenChange ]), closePanel = useCallback(((useFadeAnimation = !1) => {
11986
12091
  if (containerRef.current) {
11987
- const {position: position, mode: mode} = defaultProps;
11988
12092
  // Only add animation if not in 'none' mode
11989
- if ("none" !== mode) if (useFadeAnimation) {
12093
+ if ("none" !== mode) if (useFadeAnimation) {
11990
12094
  // Add fade out animation class
11991
12095
  containerRef.current.classList.add("is-fade-animating-out");
11992
12096
  // Capture container for setTimeout
@@ -12008,46 +12112,42 @@ function useEdgePanel(initialProps) {
12008
12112
  // Then set transform
12009
12113
  containerRef.current.style.transform = position ? EDGE_PANEL.TRANSFORM_VALUES[position] : "",
12010
12114
  // Reset body padding if push mode
12011
- "push" === defaultProps.mode && resetBodyPadding(), setTimeout((() => {
12012
- setIsOpen(!1), document.body.classList.remove("is-edgepanel-open"), defaultProps.onOpenChange && defaultProps.onOpenChange(!1);
12115
+ "push" === mode && resetBodyPadding(), setTimeout((() => {
12116
+ setIsOpen(!1), document.body.classList.remove("is-edgepanel-open"), onOpenChange && onOpenChange(!1);
12013
12117
  }), "none" === mode ? 0 : EDGE_PANEL.ANIMATION_DURATION);
12014
- } else setIsOpen(!1), document.body.classList.remove("is-edgepanel-open"), defaultProps.onOpenChange && defaultProps.onOpenChange(!1);
12015
- }), [ defaultProps, resetBodyPadding ]), handleEscapeKey = useCallback((event => {
12016
- defaultProps.closeOnEscape && "Escape" === event.key && isOpen && closePanel();
12017
- }), [ closePanel, defaultProps.closeOnEscape, isOpen ]), handleBackdropClick = useCallback((event => {
12018
- defaultProps.closeOnBackdropClick && event.target === event.currentTarget && closePanel();
12019
- }), [ closePanel, defaultProps.closeOnBackdropClick ]);
12118
+ } else setIsOpen(!1), document.body.classList.remove("is-edgepanel-open"), onOpenChange && onOpenChange(!1);
12119
+ }), [ mode, position, onOpenChange, resetBodyPadding ]), handleEscapeKey = useCallback((event => {
12120
+ closeOnEscape && "Escape" === event.key && isOpen && closePanel();
12121
+ }), [ closePanel, closeOnEscape, isOpen ]), handleBackdropClick = useCallback((event => {
12122
+ closeOnBackdropClick && event.target === event.currentTarget && closePanel();
12123
+ }), [ closePanel, closeOnBackdropClick ]);
12020
12124
  /**
12021
12125
  * Set up event listeners for keyboard events
12022
12126
  */
12023
- return useEffect((() => (isOpen && defaultProps.closeOnEscape && document.addEventListener("keydown", handleEscapeKey),
12127
+ return useEffect((() => (isOpen && closeOnEscape && document.addEventListener("keydown", handleEscapeKey),
12024
12128
  () => {
12025
12129
  document.removeEventListener("keydown", handleEscapeKey);
12026
- })), [ isOpen, handleEscapeKey, defaultProps.closeOnEscape ]),
12130
+ })), [ isOpen, handleEscapeKey, closeOnEscape ]),
12027
12131
  /**
12028
12132
  * Set initial transform values
12029
12133
  */
12030
12134
  useEffect((() => {
12031
- if (containerRef.current) {
12032
- const {position: position, mode: mode} = defaultProps;
12033
- isOpen || "slide" !== mode && "push" !== mode || !position || (containerRef.current.style.transform = EDGE_PANEL.TRANSFORM_VALUES[position],
12034
- // Set initial opacity for fade animations
12035
- defaultProps.glass && (containerRef.current.style.opacity = "0"));
12036
- }
12037
- }), [ defaultProps.mode, defaultProps.position, defaultProps.glass, isOpen ]),
12135
+ containerRef.current && (isOpen || "slide" !== mode && "push" !== mode || !position || (containerRef.current.style.transform = EDGE_PANEL.TRANSFORM_VALUES[position],
12136
+ // Set initial opacity for fade animations
12137
+ glass && (containerRef.current.style.opacity = "0")));
12138
+ }), [ mode, position, glass, isOpen ]),
12038
12139
  /**
12039
12140
  * Sync with prop changes
12040
12141
  */
12041
12142
  useEffect((() => {
12042
- void 0 !== defaultProps.isOpen && defaultProps.isOpen !== isOpen && (defaultProps.isOpen ? openPanel(!!defaultProps.glass) : closePanel(!!defaultProps.glass));
12043
- }), [ defaultProps.isOpen, closePanel, isOpen, openPanel, defaultProps.glass ]),
12044
- {
12143
+ void 0 !== propIsOpen && propIsOpen !== isOpen && (propIsOpen ? openPanel(!!glass) : closePanel(!!glass));
12144
+ }), [ propIsOpen, closePanel, isOpen, openPanel, glass ]), {
12045
12145
  isOpen: isOpen,
12046
12146
  containerRef: containerRef,
12047
12147
  backdropRef: backdropRef,
12048
12148
  generateEdgePanelClass: props => {
12049
- const {position: position = defaultProps.position, className: className = "", isOpen: propIsOpen} = props, baseClass = EDGE_PANEL.CLASSES.BASE;
12050
- return `${baseClass} ${position ? `${baseClass}--${position}` : ""} ${propIsOpen ?? isOpen ? EDGE_PANEL.CLASSES.IS_OPEN : ""} ${className}`.trim();
12149
+ const {position: propPosition = position, className: propClassName = className, isOpen: argIsOpen} = props, baseClass = EDGE_PANEL.CLASSES.BASE;
12150
+ return `${baseClass} ${propPosition ? `${baseClass}--${propPosition}` : ""} ${argIsOpen ?? isOpen ? EDGE_PANEL.CLASSES.IS_OPEN : ""} ${propClassName}`.trim();
12051
12151
  },
12052
12152
  openPanel: openPanel,
12053
12153
  closePanel: closePanel,
@@ -12429,7 +12529,7 @@ function useHero(initialProps) {
12429
12529
  * @returns Slider state and methods
12430
12530
  */
12431
12531
  function(config) {
12432
- const {slides: slides, autoplay: autoplay, loop: loop = !0, transition: transition = "fade", transitionDuration: transitionDuration = 1e3} = config, [currentIndex, setCurrentIndex] = useState(0), [isTransitioning, setIsTransitioning] = useState(!1), autoplayRef = useRef(null), isPausedRef = useRef(!1), callbackRef = useRef(), slideRefs = useMemo((() => slides.map((() => React.createRef()))), [ slides.length ]), videoRefs = useMemo((() => slides.map((() => React.createRef()))), [ slides.length ]), handleSlideTransition = useCallback((nextIndex => {
12532
+ const {slides: slides, autoplay: autoplay, loop: loop = !0, transition: transition = "fade", transitionDuration: transitionDuration = 1e3} = config, [currentIndex, setCurrentIndex] = useState(0), [isTransitioning, setIsTransitioning] = useState(!1), autoplayRef = useRef(null), isPausedRef = useRef(!1), callbackRef = useRef(void 0), slideRefs = useMemo((() => slides.map((() => React.createRef()))), [ slides ]), videoRefs = useMemo((() => slides.map((() => React.createRef()))), [ slides ]), handleSlideTransition = useCallback((nextIndex => {
12433
12533
  if (nextIndex === currentIndex || isTransitioning) return;
12434
12534
  if (nextIndex < 0 || nextIndex >= slides.length) return;
12435
12535
  setIsTransitioning(!0),
@@ -12748,22 +12848,15 @@ function useHero(initialProps) {
12748
12848
  * @param initialProps - Initial side menu properties
12749
12849
  * @returns SideMenu state and methods
12750
12850
  */ function useSideMenu(initialProps) {
12751
- // Default side menu properties
12752
- const defaultProps = {
12753
- collapsible: !0,
12754
- collapsibleDesktop: !1,
12755
- defaultCollapsedDesktop: !1,
12756
- isOpen: !1,
12757
- ...initialProps
12758
- }, [isOpenState, setIsOpenState] = useState(void 0 !== defaultProps.defaultCollapsedDesktop ? !defaultProps.defaultCollapsedDesktop : defaultProps.isOpen || !1), wrapperRef = useRef(null), innerRef = useRef(null), sideMenuRef = useRef(null);
12851
+ const {collapsible: collapsible = !0, collapsibleDesktop: collapsibleDesktop = !1, defaultCollapsedDesktop: defaultCollapsedDesktop = !1, isOpen: isOpen, onToggle: onToggle, disabled: disabled = !1} = initialProps || {}, [isOpenState, setIsOpenState] = useState(void 0 !== defaultCollapsedDesktop ? !defaultCollapsedDesktop : isOpen || !1), wrapperRef = useRef(null), innerRef = useRef(null), sideMenuRef = useRef(null);
12759
12852
  // Local open state for when not controlled externally
12760
12853
  // Update local state when external state changes
12761
12854
  useEffect((() => {
12762
- void 0 !== defaultProps.isOpen ? setIsOpenState(defaultProps.isOpen) : void 0 !== defaultProps.defaultCollapsedDesktop && setIsOpenState(!defaultProps.defaultCollapsedDesktop);
12763
- }), [ defaultProps.isOpen, defaultProps.defaultCollapsedDesktop ]),
12855
+ void 0 !== isOpen ? setIsOpenState(isOpen) : void 0 !== defaultCollapsedDesktop && setIsOpenState(!defaultCollapsedDesktop);
12856
+ }), [ isOpen, defaultCollapsedDesktop ]),
12764
12857
  // Set initial height on mount
12765
12858
  useEffect((() => {
12766
- const shouldCollapse = window.innerWidth < 768 ? defaultProps.collapsible : defaultProps.collapsibleDesktop, currentOpen = void 0 !== defaultProps.isOpen ? defaultProps.isOpen : isOpenState;
12859
+ const shouldCollapse = window.innerWidth < 768 ? collapsible : collapsibleDesktop, currentOpen = void 0 !== isOpen ? isOpen : isOpenState;
12767
12860
  if (shouldCollapse && wrapperRef.current && innerRef.current) {
12768
12861
  // Use setTimeout to ensure DOM is fully rendered
12769
12862
  const timeoutId = setTimeout((() => {
@@ -12772,14 +12865,14 @@ function useHero(initialProps) {
12772
12865
  return () => clearTimeout(timeoutId);
12773
12866
  }
12774
12867
  !shouldCollapse && wrapperRef.current && (wrapperRef.current.style.height = "auto");
12775
- }), []), // Only run on mount
12868
+ }), [ collapsible, collapsibleDesktop, isOpen, isOpenState ]),
12776
12869
  // Handle responsive behavior - vertical collapse for both mobile and desktop
12777
12870
  useEffect((() => {
12778
12871
  const handleResize = () => {
12779
- if (window.innerWidth < 768 ? defaultProps.collapsible : defaultProps.collapsibleDesktop) {
12872
+ if (window.innerWidth < 768 ? collapsible : collapsibleDesktop) {
12780
12873
  if (wrapperRef.current && innerRef.current) {
12781
12874
  // Set proper height for vertical animation (both mobile and desktop)
12782
- const currentOpen = void 0 !== defaultProps.isOpen ? defaultProps.isOpen : isOpenState;
12875
+ const currentOpen = void 0 !== isOpen ? isOpen : isOpenState;
12783
12876
  // Use requestAnimationFrame to ensure DOM is ready
12784
12877
  requestAnimationFrame((() => {
12785
12878
  wrapperRef.current && innerRef.current && (wrapperRef.current.style.height = currentOpen ? `${innerRef.current.scrollHeight}px` : "0px");
@@ -12793,12 +12886,12 @@ function useHero(initialProps) {
12793
12886
  return window.addEventListener("resize", handleResize), () => {
12794
12887
  clearTimeout(timeoutId), window.removeEventListener("resize", handleResize);
12795
12888
  };
12796
- }), [ defaultProps.collapsible, defaultProps.collapsibleDesktop, defaultProps.isOpen, defaultProps.onToggle, isOpenState ]),
12889
+ }), [ collapsible, collapsibleDesktop, isOpen, onToggle, isOpenState ]),
12797
12890
  // Update wrapper height when open state changes (both mobile and desktop)
12798
12891
  useEffect((() => {
12799
- const shouldCollapse = window.innerWidth < 768 ? defaultProps.collapsible : defaultProps.collapsibleDesktop;
12892
+ const shouldCollapse = window.innerWidth < 768 ? collapsible : collapsibleDesktop;
12800
12893
  if (shouldCollapse && wrapperRef.current && innerRef.current) {
12801
- const currentOpen = void 0 !== defaultProps.isOpen ? defaultProps.isOpen : isOpenState;
12894
+ const currentOpen = void 0 !== isOpen ? isOpen : isOpenState;
12802
12895
  // Use requestAnimationFrame to ensure DOM is ready
12803
12896
  requestAnimationFrame((() => {
12804
12897
  wrapperRef.current && innerRef.current && (wrapperRef.current.style.height = currentOpen ? `${innerRef.current.scrollHeight}px` : "0px");
@@ -12806,26 +12899,25 @@ function useHero(initialProps) {
12806
12899
  } else !shouldCollapse && wrapperRef.current && (
12807
12900
  // Not collapsible - always show content
12808
12901
  wrapperRef.current.style.height = "auto");
12809
- }), [ defaultProps.isOpen, isOpenState, defaultProps.collapsible, defaultProps.collapsibleDesktop ]);
12902
+ }), [ isOpen, isOpenState, collapsible, collapsibleDesktop ]);
12810
12903
  /**
12811
12904
  * Generate side menu class based on properties
12812
12905
  * @param props - Side menu properties
12813
12906
  * @returns Class string
12814
12907
  */
12815
12908
  const handleToggle = () => {
12816
- if (defaultProps.disabled) return;
12817
- const newState = void 0 !== defaultProps.isOpen ? !defaultProps.isOpen : !isOpenState;
12818
- "function" == typeof defaultProps.onToggle ?
12909
+ if (disabled) return;
12910
+ const newState = void 0 !== isOpen ? !isOpen : !isOpenState;
12911
+ "function" == typeof onToggle ?
12819
12912
  // Controlled component
12820
- defaultProps.onToggle(newState) :
12913
+ onToggle(newState) :
12821
12914
  // Uncontrolled component
12822
12915
  setIsOpenState(newState);
12823
- }, getCurrentOpenState = () => void 0 !== defaultProps.isOpen ? defaultProps.isOpen : isOpenState;
12916
+ }, getCurrentOpenState = () => void 0 !== isOpen ? isOpen : isOpenState;
12824
12917
  /**
12825
12918
  * Generate wrapper class
12826
12919
  * @returns Class string
12827
12920
  */ return {
12828
- defaultProps: defaultProps,
12829
12921
  isOpenState: getCurrentOpenState(),
12830
12922
  wrapperRef: wrapperRef,
12831
12923
  innerRef: innerRef,
@@ -13530,7 +13622,7 @@ SelectOption.displayName = "SelectOption";
13530
13622
  /**
13531
13623
  * Select - A component for dropdown selection
13532
13624
  */
13533
- const Select = 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}) => {
13625
+ 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}) => {
13534
13626
  const {generateSelectClass: generateSelectClass} = useSelect({
13535
13627
  size: size,
13536
13628
  disabled: disabled,
@@ -13721,7 +13813,7 @@ const Select = memo((({options: options, value: value, onChange: onChange, onBl
13721
13813
  });
13722
13814
  }
13723
13815
  return selectContent;
13724
- }));
13816
+ }, Select = memo(SelectComponentBase);
13725
13817
 
13726
13818
  Select.displayName = "Select", Select.Option = SelectOption;
13727
13819
 
@@ -14288,7 +14380,7 @@ Footer.displayName = "Footer";
14288
14380
  */
14289
14381
  const MasonryGrid = 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) => {
14290
14382
  // === REFS & STATE ===
14291
- const [columns, setColumns] = useState(xs), [positions, setPositions] = useState([]), [layoutComplete, setLayoutComplete] = useState(!1), [loadingImages, setLoadingImages] = useState(!1), containerRef = useRef(null), columnHeights = useRef([]), imagesLoadedCount = useRef(0), totalImagesCount = useRef(0), imageElements = useRef(new Map);
14383
+ const [columns, setColumns] = useState(xs), [positions, setPositions] = useState([]), [, setLayoutComplete] = useState(!1), [loadingImages, setLoadingImages] = useState(!1), containerRef = useRef(null), columnHeights = useRef([]), imagesLoadedCount = useRef(0), totalImagesCount = useRef(0), imageElements = useRef(new Map);
14292
14384
  useEffect((() => {
14293
14385
  setLoadingImages(!!imagesLoaded);
14294
14386
  }), [ columns, imagesLoaded ]),
@@ -14317,34 +14409,45 @@ const MasonryGrid = forwardRef((({children: children, className: className = ""
14317
14409
  });
14318
14410
  })), setItems(newItems);
14319
14411
  }), [ children ]);
14320
- // === TRACK & MANAGE IMAGES ===
14321
- const handleImageLoad = useCallback((img => {
14322
- if (!imageElements.current.get(img)) {
14323
- // Add loaded class for animation
14324
- if (imageElements.current.set(img, !0), imagesLoadedCount.current += 1, containerRef.current && imagesLoaded) {
14325
- const itemElement = img.closest(".o-masonry-grid > div");
14326
- itemElement && (itemElement.offsetHeight, itemElement.classList.add("o-masonry-grid__item-loaded"),
14327
- itemElement.classList.remove("o-masonry-grid__item-loading"));
14412
+ // === MANAGE ITEM LAYOUT ===
14413
+ const calculateLayout = useCallback((() => {
14414
+ if (!containerRef.current || 0 === items.length) return;
14415
+ const colWidth = (containerRef.current.offsetWidth - gap * (columns - 1)) / columns;
14416
+ columnHeights.current = Array(columns).fill(0);
14417
+ const newPositions = [];
14418
+ items.forEach(((item, index) => {
14419
+ if (item.ref.current) {
14420
+ // Find the shortest column
14421
+ const shortestCol = columnHeights.current.indexOf(Math.min(...columnHeights.current)), left = shortestCol * (colWidth + gap), top = columnHeights.current[shortestCol] ?? 0, height = item.ref.current.offsetHeight;
14422
+ columnHeights.current[shortestCol] = top + height + gap, newPositions[index] = {
14423
+ left: left,
14424
+ top: top,
14425
+ width: colWidth,
14426
+ height: height
14427
+ };
14328
14428
  }
14329
- // Ensure layout is recalculated after DOM paints the item image (prevents overlap on slow/late image loads)
14330
- requestAnimationFrame((() => {
14331
- requestAnimationFrame((() => {
14332
- calculateLayout();
14333
- }));
14334
- })), onImageLoad?.(imagesLoadedCount.current, totalImagesCount.current),
14335
- // If all images have loaded, update loading state and complete layout
14336
- imagesLoadedCount.current >= totalImagesCount.current && totalImagesCount.current > 0 && (setLayoutComplete(!0),
14337
- setLoadingImages(!1), // This ensures the loading class is removed *immediately* after images load
14338
- // Force a double requestAnimationFrame for final layout calculation after all images are loaded (guarantees DOM paint)
14339
- requestAnimationFrame((() => {
14340
- requestAnimationFrame((() => {
14341
- calculateLayout(),
14342
- // As a failsafe, if still present for some render lag, force another setLoadingImages(false)
14343
- setLoadingImages(!1);
14344
- }));
14345
- })), onLayoutComplete?.());
14429
+ })), setPositions(newPositions);
14430
+ }), [ items, columns, gap ]), handleImageLoad = useCallback((img => {
14431
+ if (imageElements.current.get(img)) return;
14432
+ // Add loaded class for animation
14433
+ if (imageElements.current.set(img, !0), imagesLoadedCount.current += 1, containerRef.current && imagesLoaded) {
14434
+ const itemElement = img.closest(".o-masonry-grid > div");
14435
+ itemElement && (itemElement.offsetHeight, itemElement.classList.add("o-masonry-grid__item-loaded"),
14436
+ itemElement.classList.remove("o-masonry-grid__item-loading"));
14346
14437
  }
14347
- }), [ onImageLoad, onLayoutComplete, imagesLoaded ]), trackImages = useCallback((() => {
14438
+ // Schedule layout recalculation after next paint to prevent overlap
14439
+ const scheduleLayoutUpdate = () => {
14440
+ const frameId = requestAnimationFrame((() => {
14441
+ onImageLoad?.(imagesLoadedCount.current, totalImagesCount.current), calculateLayout();
14442
+ }));
14443
+ return () => cancelAnimationFrame(frameId);
14444
+ }, cleanup = scheduleLayoutUpdate();
14445
+ // Clean up previous scheduled updates
14446
+ // If all images have loaded, update loading state and complete layout
14447
+ imagesLoadedCount.current >= totalImagesCount.current && totalImagesCount.current > 0 && (setLayoutComplete(!0),
14448
+ setLoadingImages(!1), setTimeout((() => cleanup()), 0), // Clean up after current execution
14449
+ scheduleLayoutUpdate(), onLayoutComplete?.());
14450
+ }), [ onImageLoad, onLayoutComplete, imagesLoaded, calculateLayout ]), trackImages = useCallback((() => {
14348
14451
  if (!imagesLoaded || !containerRef.current) return;
14349
14452
  imageElements.current.clear(), imagesLoadedCount.current = 0;
14350
14453
  const images = containerRef.current.querySelectorAll("img");
@@ -14363,30 +14466,21 @@ const MasonryGrid = forwardRef((({children: children, className: className = ""
14363
14466
  img.removeEventListener("error", masonryImg._masonryLoadHandler), delete masonryImg._masonryLoadHandler);
14364
14467
  }));
14365
14468
  });
14366
- }), [ imagesLoaded, handleImageLoad, onLayoutComplete ]), calculateLayout = useCallback((() => {
14367
- if (!containerRef.current || 0 === items.length) return;
14368
- const colWidth = (containerRef.current.offsetWidth - gap * (columns - 1)) / columns;
14369
- columnHeights.current = Array(columns).fill(0);
14370
- const newPositions = [];
14371
- items.forEach(((item, index) => {
14372
- if (item.ref.current) {
14373
- // Find the shortest column
14374
- const shortestCol = columnHeights.current.indexOf(Math.min(...columnHeights.current)), left = shortestCol * (colWidth + gap), top = columnHeights.current[shortestCol] ?? 0, height = item.ref.current.offsetHeight;
14375
- columnHeights.current[shortestCol] = top + height + gap, newPositions[index] = {
14376
- left: left,
14377
- top: top,
14378
- width: colWidth,
14379
- height: height
14380
- };
14381
- }
14382
- })), setPositions(newPositions);
14383
- }), [ items, columns, gap ]);
14384
- // === OBSERVE CONTAINER RESIZE ===
14469
+ }), [ imagesLoaded, handleImageLoad, onLayoutComplete ]);
14470
+ // === TRACK & MANAGE IMAGES ===
14471
+ // === OBSERVE CONTAINER RESIZE ===
14385
14472
  useEffect((() => {
14386
14473
  if (!containerRef.current) return;
14387
- let animationFrame = null;
14388
- const observer = new ResizeObserver((() => {
14389
- animationFrame && cancelAnimationFrame(animationFrame), animationFrame = requestAnimationFrame((() => calculateLayout()));
14474
+ let animationFrame = null, lastWidth = 0;
14475
+ const observer = new ResizeObserver((entries => {
14476
+ const entry = entries[0];
14477
+ if (!entry) return;
14478
+ const currentWidth = entry.contentRect.width;
14479
+ // Only recalculate if width actually changed (prevents excessive calculations)
14480
+ Math.abs(currentWidth - lastWidth) > 1 && (animationFrame && cancelAnimationFrame(animationFrame),
14481
+ animationFrame = requestAnimationFrame((() => {
14482
+ calculateLayout(), lastWidth = currentWidth;
14483
+ })));
14390
14484
  }));
14391
14485
  return observer.observe(containerRef.current), () => {
14392
14486
  observer.disconnect(), animationFrame && cancelAnimationFrame(animationFrame);
@@ -14397,24 +14491,21 @@ const MasonryGrid = forwardRef((({children: children, className: className = ""
14397
14491
  setLayoutComplete(!0), void setLoadingImages(!1))
14398
14492
  // Only reset layoutComplete when items or columns change
14399
14493
  ), [ items, columns, calculateLayout, imagesLoaded, trackImages ]),
14400
- // === NEW: Add ResizeObservers to all grid items for bulletproof image+content measurement ===
14494
+ // === ADD RESIZEOBSERVERS TO GRID ITEMS FOR DYNAMIC CONTENT MEASUREMENT ===
14401
14495
  React.useEffect((() => {
14402
- // Clean up old observers if items ever change
14403
14496
  const observers = [];
14497
+ let animationFrame = null;
14498
+ // Debounced layout calculation for item resize events
14499
+ const debouncedCalculateLayout = () => {
14500
+ animationFrame && cancelAnimationFrame(animationFrame), animationFrame = requestAnimationFrame(calculateLayout);
14501
+ };
14404
14502
  return items.forEach((item => {
14405
14503
  if (item.ref.current) {
14406
- const obs = new ResizeObserver((() => {
14407
- // Double rAF: ensures layout only runs after DOM/paint/async renders
14408
- requestAnimationFrame((() => {
14409
- requestAnimationFrame((() => {
14410
- calculateLayout();
14411
- }));
14412
- }));
14413
- }));
14504
+ const obs = new ResizeObserver(debouncedCalculateLayout);
14414
14505
  obs.observe(item.ref.current), observers.push(obs);
14415
14506
  }
14416
14507
  })), () => {
14417
- observers.forEach((obs => obs.disconnect()));
14508
+ observers.forEach((obs => obs.disconnect())), animationFrame && cancelAnimationFrame(animationFrame);
14418
14509
  };
14419
14510
  }), [ items, calculateLayout ]);
14420
14511
  // Ensure loadingImages state resets when items/columns/imagesLoaded change
@@ -15851,12 +15942,12 @@ const SideMenu = forwardRef((({title: title, children: children, menuItems: men
15851
15942
  const index = Number(key);
15852
15943
  index >= currentLength && (delete nestedWrapperRefs.current[index], delete nestedInnerRefs.current[index]);
15853
15944
  })));
15854
- }), [ menuItems?.length ]);
15945
+ }), [ menuItems ]);
15855
15946
  // Helper function to update nested wrapper height
15856
- const updateNestedHeight = (index, isOpen) => {
15947
+ const updateNestedHeight = useCallback(((index, isOpen) => {
15857
15948
  const wrapper = nestedWrapperRefs.current[index], inner = nestedInnerRefs.current[index];
15858
15949
  wrapper && inner && (wrapper.style.height = isOpen ? `${inner.scrollHeight}px` : "0px");
15859
- };
15950
+ }), []);
15860
15951
  // Set initial heights for nested wrappers on mount and when menuItems change
15861
15952
  useEffect((() => {
15862
15953
  if (!menuItems?.length) return;
@@ -15870,7 +15961,7 @@ const SideMenu = forwardRef((({title: title, children: children, menuItems: men
15870
15961
  // Only run when menuItems change, nestedItemStates is read but not in deps to avoid loops
15871
15962
  // eslint-disable-next-line react-hooks/exhaustive-deps
15872
15963
  ;
15873
- }), [ menuItems?.length ]),
15964
+ }), [ menuItems, updateNestedHeight ]),
15874
15965
  // Update nested wrapper heights when state changes
15875
15966
  useEffect((() => {
15876
15967
  if (!menuItems?.length) return;
@@ -15883,7 +15974,7 @@ const SideMenu = forwardRef((({title: title, children: children, menuItems: men
15883
15974
  })), () => {
15884
15975
  frameIds.forEach((id => cancelAnimationFrame(id)));
15885
15976
  };
15886
- }), [ nestedItemStates, menuItems?.length ]);
15977
+ }), [ nestedItemStates, menuItems, updateNestedHeight ]);
15887
15978
  // Combine refs using utility
15888
15979
  const combinedRef = useForkRef(sideMenuRef, ref), sideMenuClass = generateSideMenuClass({
15889
15980
  className: className,
@@ -16770,7 +16861,7 @@ useEffect((() => {
16770
16861
  }
16771
16862
  };
16772
16863
  }));
16773
- }), [ isMounted, currentIndex, calculateBounds, constrainPosition ]), setImagePosition = useCallback((position => {
16864
+ }), [ currentIndex, calculateBounds, constrainPosition ]), setImagePosition = useCallback((position => {
16774
16865
  setImageStates((prev => {
16775
16866
  const currentState = prev[currentIndex] || {
16776
16867
  zoomLevel: 1,
@@ -16820,7 +16911,7 @@ useEffect((() => {
16820
16911
  }
16821
16912
  };
16822
16913
  }));
16823
- }), [ isMounted, currentIndex, calculateBounds, constrainPosition ]), handleWheel = useCallback((event => {
16914
+ }), [ currentIndex, calculateBounds, constrainPosition ]), handleWheel = useCallback((event => {
16824
16915
  var _context;
16825
16916
  if (!isMounted || !event || !event.currentTarget) return;
16826
16917
  // Additional safety check for the target element
@@ -17177,7 +17268,7 @@ useEffect((() => {
17177
17268
  }
17178
17269
  return prev;
17179
17270
  }));
17180
- }), [ isMounted, enableGestures, isDragging, startDragPosition, currentIndex, constrainPosition, calculateBounds ]), handleTouchEnd = useCallback((() => {
17271
+ }), [ enableGestures, isDragging, startDragPosition, currentIndex, constrainPosition, calculateBounds ]), handleTouchEnd = useCallback((() => {
17181
17272
  setIsDragging(!1), lastDistanceRef.current = null, lastMidpointRef.current = null;
17182
17273
  }), []), currentState = imageStates[currentIndex] || {
17183
17274
  zoomLevel: 1,
@@ -17381,9 +17472,9 @@ const PopoverContext = createContext({
17381
17472
  triggerType: "click"
17382
17473
  }), 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}) => {
17383
17474
  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}) => {
17384
- const [isOpen, setIsOpenState] = useState(defaultOpen), [currentPosition, setCurrentPosition] = useState("auto" === position ? "top" : position), triggerRef = useRef(null), popoverRef = useRef(null), arrowRef = useRef(null), timeoutRef = useRef(null), popoverId = id || `popover-${Math.random().toString(36).slice(2, 11)}`, isControlled = void 0 !== controlledIsOpen, isOpenState = isControlled ? controlledIsOpen : isOpen, setIsOpen = newIsOpen => {
17475
+ const [isOpen, setIsOpenState] = useState(defaultOpen), [currentPosition, setCurrentPosition] = useState("auto" === position ? "top" : position), triggerRef = useRef(null), popoverRef = useRef(null), arrowRef = useRef(null), timeoutRef = useRef(null), popoverId = id || `popover-${Math.random().toString(36).slice(2, 11)}`, isControlled = void 0 !== controlledIsOpen, isOpenState = isControlled ? controlledIsOpen : isOpen, setIsOpen = useCallback((newIsOpen => {
17385
17476
  isControlled || setIsOpenState(newIsOpen), onOpenChange && onOpenChange(newIsOpen);
17386
- };
17477
+ }), [ isControlled, onOpenChange ]);
17387
17478
  // Handle hover events if trigger is hover
17388
17479
  useEffect((() => {
17389
17480
  if ("hover" !== trigger || !triggerRef.current || !popoverRef.current) return;
@@ -17403,17 +17494,16 @@ const PopoverContext = createContext({
17403
17494
  setIsOpen(!1);
17404
17495
  };
17405
17496
  // Add hover event listeners
17406
- return triggerRef.current.addEventListener("mouseenter", handleTriggerMouseEnter),
17407
- triggerRef.current.addEventListener("mouseleave", handleTriggerMouseLeave), popoverRef.current.addEventListener("mouseenter", handlePopoverMouseEnter),
17408
- popoverRef.current.addEventListener("mouseleave", handlePopoverMouseLeave), () => {
17409
- triggerRef.current && (triggerRef.current.removeEventListener("mouseenter", handleTriggerMouseEnter),
17410
- triggerRef.current.removeEventListener("mouseleave", handleTriggerMouseLeave)),
17411
- popoverRef.current && (popoverRef.current.removeEventListener("mouseenter", handlePopoverMouseEnter),
17412
- popoverRef.current.removeEventListener("mouseleave", handlePopoverMouseLeave)),
17413
- null !== timeoutRef.current && window.clearTimeout(timeoutRef.current);
17497
+ triggerRef.current.addEventListener("mouseenter", handleTriggerMouseEnter), triggerRef.current.addEventListener("mouseleave", handleTriggerMouseLeave),
17498
+ popoverRef.current.addEventListener("mouseenter", handlePopoverMouseEnter), popoverRef.current.addEventListener("mouseleave", handlePopoverMouseLeave);
17499
+ const currentTrigger = triggerRef.current, currentPopover = popoverRef.current;
17500
+ return () => {
17501
+ currentTrigger && (currentTrigger.removeEventListener("mouseenter", handleTriggerMouseEnter),
17502
+ currentTrigger.removeEventListener("mouseleave", handleTriggerMouseLeave)), currentPopover && (currentPopover.removeEventListener("mouseenter", handlePopoverMouseEnter),
17503
+ currentPopover.removeEventListener("mouseleave", handlePopoverMouseLeave)), null !== timeoutRef.current && window.clearTimeout(timeoutRef.current);
17414
17504
  };
17415
- }), [ trigger, delay, isOpenState ]);
17416
- const updatePosition = event => {
17505
+ }), [ trigger, delay, isOpenState, setIsOpen ]);
17506
+ const updatePosition = useCallback((event => {
17417
17507
  if (!triggerRef.current || !popoverRef.current) return;
17418
17508
  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;
17419
17509
  // If this is a scroll update and trigger isn't near edges, skip repositioning
@@ -17474,9 +17564,9 @@ const PopoverContext = createContext({
17474
17564
  // Add scroll position to convert viewport coordinates to absolute position
17475
17565
  const absoluteTop = top + window.scrollY, absoluteLeft = left + window.scrollX;
17476
17566
  // Apply position using absolute positioning to follow when scrolling
17477
- popoverRef.current.style.position = "absolute", popoverRef.current.style.top = `${absoluteTop}px`,
17478
- popoverRef.current.style.left = `${absoluteLeft}px`;
17479
- };
17567
+ popoverRef.current && (popoverRef.current.style.position = "absolute", popoverRef.current.style.top = `${absoluteTop}px`,
17568
+ popoverRef.current.style.left = `${absoluteLeft}px`);
17569
+ }), [ position, offset ]);
17480
17570
  // Position the popover
17481
17571
  return useEffect((() => {
17482
17572
  if (!isOpenState || !triggerRef.current || !popoverRef.current) return;
@@ -17502,7 +17592,7 @@ const PopoverContext = createContext({
17502
17592
  window.removeEventListener("resize", updatePosition), window.removeEventListener("scroll", handleScroll),
17503
17593
  scrollTimeout && clearTimeout(scrollTimeout), clearInterval(intervalId);
17504
17594
  };
17505
- }), [ isOpenState, position, offset ]),
17595
+ }), [ isOpenState, updatePosition ]),
17506
17596
  // Handle click outside to close popover
17507
17597
  useEffect((() => {
17508
17598
  if (!isOpenState || !closeOnClickOutside) return;
@@ -17512,7 +17602,7 @@ const PopoverContext = createContext({
17512
17602
  return document.addEventListener("mousedown", handleClickOutside), () => {
17513
17603
  document.removeEventListener("mousedown", handleClickOutside);
17514
17604
  };
17515
- }), [ isOpenState, closeOnClickOutside ]),
17605
+ }), [ isOpenState, closeOnClickOutside, setIsOpen ]),
17516
17606
  // Handle escape key to close popover
17517
17607
  useEffect((() => {
17518
17608
  if (!isOpenState || !closeOnEscape) return;
@@ -17522,7 +17612,7 @@ const PopoverContext = createContext({
17522
17612
  return document.addEventListener("keydown", handleEscapeKey), () => {
17523
17613
  document.removeEventListener("keydown", handleEscapeKey);
17524
17614
  };
17525
- }), [ isOpenState, closeOnEscape ]),
17615
+ }), [ isOpenState, closeOnEscape, setIsOpen ]),
17526
17616
  // Clean up on unmount
17527
17617
  useEffect((() => () => {
17528
17618
  null !== timeoutRef.current && window.clearTimeout(timeoutRef.current);
@@ -17703,10 +17793,11 @@ const calculateStarValue = (e, starValue, allowHalf) => {
17703
17793
  }), [ readOnly, onChange, allowHalf ]);
17704
17794
  // Use vanilla JS implementation if specified
17705
17795
  useEffect((() => {
17706
- if (useVanillaJS && "undefined" != typeof window && internalRef.current)
17796
+ if (!useVanillaJS || "undefined" == typeof window || !internalRef.current) return;
17797
+ const currentInstance = ratingInstance.current;
17707
17798
  // Cleanup on unmount
17708
- return () => {
17709
- ratingInstance.current && ratingInstance.current.destroy();
17799
+ return () => {
17800
+ currentInstance && currentInstance.destroy();
17710
17801
  };
17711
17802
  }), [ useVanillaJS, valueProp, defaultValue, maxValue, allowHalf, readOnly, size, variant, onChange ]),
17712
17803
  // Update vanilla JS implementation when props change
@@ -17827,10 +17918,11 @@ const ProductReview = ({productName: productName, productImage: productImage, in
17827
17918
  const [rating, setRating] = useState(initialRating), [comment, setComment] = useState(""), [submitted, setSubmitted] = useState(!1), reviewRef = useRef(null), reviewInstance = useRef(null);
17828
17919
  useEffect((() => {
17829
17920
  // Only run on client-side
17830
- if ("undefined" != typeof window && reviewRef.current)
17921
+ if ("undefined" == typeof window || !reviewRef.current) return;
17922
+ const currentInstance = reviewInstance.current;
17831
17923
  // Cleanup on unmount
17832
- return () => {
17833
- reviewInstance.current && reviewInstance.current.destroy();
17924
+ return () => {
17925
+ currentInstance && currentInstance.destroy();
17834
17926
  };
17835
17927
  }), [ productName, productImage, initialRating, maxRating, allowHalf, ratingColor, onSubmit ]);
17836
17928
  const handleSubmit = e => {
@@ -18075,10 +18167,11 @@ const SectionIntro = ({title: title, label: label, text: text, actions: actions,
18075
18167
  const sectionIntroRef = useRef(null), sectionIntroInstance = useRef(null);
18076
18168
  useEffect((() => {
18077
18169
  // Only run on client-side
18078
- if ("undefined" != typeof window && sectionIntroRef.current)
18170
+ if ("undefined" == typeof window || !sectionIntroRef.current) return;
18171
+ const currentInstance = sectionIntroInstance.current;
18079
18172
  // Cleanup on unmount
18080
- return () => {
18081
- sectionIntroInstance.current && sectionIntroInstance.current.destroy();
18173
+ return () => {
18174
+ currentInstance && currentInstance.destroy();
18082
18175
  };
18083
18176
  }), [ alignment, backgroundImageSrc, showOverlay, size, skeleton ]);
18084
18177
  // Determine CSS classes
@@ -18162,7 +18255,7 @@ SectionIntro.displayName = "SectionIntro";
18162
18255
 
18163
18256
  const Slider = forwardRef(((props, ref) => {
18164
18257
  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) {
18165
- 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 = useRef(null), wrapperRef = useRef(null), repositioningRef = useRef(!1), autoplayRef = useRef(null), [autoplayRunning, setAutoplayRunning] = useState(!1), sliderStateRef = useRef({
18258
+ 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 = useMemo((() => Array.isArray(rawSlides) ? rawSlides : []), [ rawSlides ]), containerRef = useRef(null), wrapperRef = useRef(null), repositioningRef = useRef(!1), autoplayRef = useRef(null), [autoplayRunning, setAutoplayRunning] = useState(!1), sliderStateRef = useRef({
18166
18259
  isTransitioning: !1,
18167
18260
  loop: loop,
18168
18261
  slides: slides,
@@ -18297,7 +18390,7 @@ const Slider = forwardRef(((props, ref) => {
18297
18390
  setIsTransitioning(!1), onSlideChange?.(nextIndex);
18298
18391
  }), speed);
18299
18392
  }
18300
- }), [ realIndex, internalIndex, slides.length, slidesToShow, loop, isTransitioning, speed, onSlideChange, allSlides.length, loopedSlides, autoplay ]), slidePrev = useCallback((() => {
18393
+ }), [ realIndex, internalIndex, slides.length, slidesToShow, loop, isTransitioning, speed, onSlideChange, autoplay ]), slidePrev = useCallback((() => {
18301
18394
  if (!isTransitioning) if (
18302
18395
  // Stop autoplay on interaction if disableOnInteraction is true
18303
18396
  autoplay && "object" == typeof autoplay && autoplay.disableOnInteraction && autoplayRef.current && (clearInterval(autoplayRef.current),
@@ -18319,7 +18412,7 @@ const Slider = forwardRef(((props, ref) => {
18319
18412
  setIsTransitioning(!1), onSlideChange?.(prevIndex);
18320
18413
  }), speed);
18321
18414
  }
18322
- }), [ realIndex, internalIndex, slides.length, loop, isTransitioning, speed, onSlideChange, allSlides.length, loopedSlides, autoplay ]), goToSlide = useCallback((index => {
18415
+ }), [ realIndex, internalIndex, slides.length, loop, isTransitioning, speed, onSlideChange, autoplay ]), goToSlide = useCallback((index => {
18323
18416
  isTransitioning || index === realIndex || (
18324
18417
  // Stop autoplay on interaction if disableOnInteraction is true
18325
18418
  autoplay && "object" == typeof autoplay && autoplay.disableOnInteraction && autoplayRef.current && (clearInterval(autoplayRef.current),
@@ -18327,7 +18420,7 @@ const Slider = forwardRef(((props, ref) => {
18327
18420
  setRealIndex(index), setInternalIndex(loop ? slides.length + index : index), setTimeout((() => {
18328
18421
  setIsTransitioning(!1), onSlideChange?.(index);
18329
18422
  }), speed));
18330
- }), [ realIndex, isTransitioning, speed, onSlideChange, loop, loopedSlides, autoplay ]), handleTouchStart = useCallback((e => {
18423
+ }), [ realIndex, isTransitioning, speed, onSlideChange, loop, slides.length, autoplay ]), handleTouchStart = useCallback((e => {
18331
18424
  if (!allowTouchMove) return;
18332
18425
  // Stop autoplay on interaction if disableOnInteraction is true
18333
18426
  autoplay && "object" == typeof autoplay && autoplay.disableOnInteraction && autoplayRef.current && (clearInterval(autoplayRef.current),
@@ -18582,7 +18675,7 @@ const Steps = ({items: items, activeIndex: activeIndex = 0, vertical: vertical =
18582
18675
  let content;
18583
18676
  useEffect((() => {
18584
18677
  currentStep !== activeIndex && setCurrentStep(activeIndex);
18585
- }), [ activeIndex ]),
18678
+ }), [ activeIndex, currentStep ]),
18586
18679
  // Legacy rendering
18587
18680
  content = items && items.length > 0 ? items.map(((item, index) => jsx(StepsItem, {
18588
18681
  index: index,
@@ -18854,10 +18947,11 @@ const Testimonial = ({quote: quote, author: author, size: size = "", skeleton: s
18854
18947
  const testimonialRef = useRef(null), testimonialInstance = useRef(null);
18855
18948
  useEffect((() => {
18856
18949
  // Only run on client-side
18857
- if ("undefined" != typeof window && testimonialRef.current)
18950
+ if ("undefined" == typeof window || !testimonialRef.current) return;
18951
+ const currentInstance = testimonialInstance.current;
18858
18952
  // Cleanup on unmount
18859
- return () => {
18860
- testimonialInstance.current && testimonialInstance.current.destroy();
18953
+ return () => {
18954
+ currentInstance && currentInstance.destroy();
18861
18955
  };
18862
18956
  }), [ size, skeleton ]);
18863
18957
  // Determine CSS classes
@@ -19998,11 +20092,13 @@ const VideoPlayer = forwardRef((({src: src, type: type = "video", youtubeId: yo
19998
20092
  detectBorderRadius();
19999
20093
  // Create ResizeObserver to watch for style changes
20000
20094
  let resizeObserver = null;
20001
- return "undefined" != typeof ResizeObserver && containerRef.current && (resizeObserver = new ResizeObserver(detectBorderRadius),
20095
+ "undefined" != typeof ResizeObserver && containerRef.current && (resizeObserver = new ResizeObserver(detectBorderRadius),
20002
20096
  resizeObserver.observe(containerRef.current)),
20003
20097
  // Also listen for window resize (in case styles change)
20004
- window.addEventListener("resize", detectBorderRadius), () => {
20005
- window.removeEventListener("resize", detectBorderRadius), resizeObserver && containerRef.current && (resizeObserver.unobserve(containerRef.current),
20098
+ window.addEventListener("resize", detectBorderRadius);
20099
+ const currentContainer = containerRef.current;
20100
+ return () => {
20101
+ window.removeEventListener("resize", detectBorderRadius), resizeObserver && currentContainer && (resizeObserver.unobserve(currentContainer),
20006
20102
  resizeObserver.disconnect());
20007
20103
  };
20008
20104
  }), []);
@@ -22342,7 +22438,7 @@ const logger = getLogger(), ThemeProvider = ({children: children, defaultTheme:
22342
22438
  // If defaultTheme is provided, use it
22343
22439
  return null != defaultTheme ? defaultTheme : "default";
22344
22440
  // Default fallback
22345
- }), [ defaultTheme, enablePersistence, storageKey ]), [currentTheme, setCurrentTheme] = useState((() => "string" == typeof initialDefaultTheme ? initialDefaultTheme : "tokens-theme")), [activeTokens, setActiveTokens] = useState((() => {
22441
+ }), [ defaultTheme, enablePersistence, storageKey, storageAdapter ]), [currentTheme, setCurrentTheme] = useState((() => "string" == typeof initialDefaultTheme ? initialDefaultTheme : "tokens-theme")), [activeTokens, setActiveTokens] = useState((() => {
22346
22442
  // If defaultTheme is DesignTokens, validate and store them
22347
22443
  if (defaultTheme && "string" != typeof defaultTheme) {
22348
22444
  const {tokens: tokens, validation: validation} = validateAndMergeTokens(defaultTheme);
@@ -23643,7 +23739,7 @@ class ThemeValidator {
23643
23739
  *
23644
23740
  * Provides detailed inspection and debugging information for themes
23645
23741
  */ const ThemeInspector = ({theme: theme, showValidation: showValidation = !0, showCSSVariables: showCSSVariables = !0, showStructure: showStructure = !0, className: className, style: style}) => {
23646
- const [activeTab, setActiveTab] = useState("overview"), [expandedSections, setExpandedSections] = useState(new Set([ "palette" ])), [searchQuery, setSearchQuery] = useState(""), [debouncedSearchQuery, setDebouncedSearchQuery] = useState(""), [copiedPath, setCopiedPath] = useState(null), searchTimeoutRef = useRef();
23742
+ const [activeTab, setActiveTab] = useState("overview"), [expandedSections, setExpandedSections] = useState(new Set([ "palette" ])), [searchQuery, setSearchQuery] = useState(""), [debouncedSearchQuery, setDebouncedSearchQuery] = useState(""), [copiedPath, setCopiedPath] = useState(null), searchTimeoutRef = useRef(void 0);
23647
23743
  // Debounce search query
23648
23744
  useEffect((() => (searchTimeoutRef.current && clearTimeout(searchTimeoutRef.current),
23649
23745
  searchTimeoutRef.current = setTimeout((() => {
@@ -24049,7 +24145,7 @@ class ThemeValidator {
24049
24145
  }) ]
24050
24146
  });
24051
24147
  }, ThemeComparator = ({themeA: themeA, themeB: themeB, showOnlyDifferences: showOnlyDifferences = !1, className: className, style: style}) => {
24052
- const [searchQuery, setSearchQuery] = useState(""), [debouncedSearchQuery, setDebouncedSearchQuery] = useState(""), [filterType, setFilterType] = useState("all"), [filterCategory, setFilterCategory] = useState("all"), searchTimeoutRef = useRef();
24148
+ const [searchQuery, setSearchQuery] = useState(""), [debouncedSearchQuery, setDebouncedSearchQuery] = useState(""), [filterType, setFilterType] = useState("all"), [filterCategory, setFilterCategory] = useState("all"), searchTimeoutRef = useRef(void 0);
24053
24149
  // Debounce search query
24054
24150
  useEffect((() => (searchTimeoutRef.current && clearTimeout(searchTimeoutRef.current),
24055
24151
  searchTimeoutRef.current = setTimeout((() => {
@@ -24845,7 +24941,7 @@ const ThemeLiveEditor = ({initialTheme: initialTheme, onChange: onChange, classN
24845
24941
  } catch (err) {
24846
24942
  setError(err instanceof Error ? err.message : "Invalid JSON");
24847
24943
  }
24848
- }), [ updateTheme ]), jsonUpdateTimeoutRef = useRef();
24944
+ }), [ updateTheme ]), jsonUpdateTimeoutRef = useRef(void 0);
24849
24945
  // Debounced JSON update to history
24850
24946
  useEffect((() => {
24851
24947
  if (!error) {
@@ -26052,97 +26148,6 @@ function getComponentCSSVars(component) {
26052
26148
  } : base : override;
26053
26149
  }
26054
26150
 
26055
- /**
26056
- * Render a slot with the given props
26057
- *
26058
- * Priority order:
26059
- * 1. render function
26060
- * 2. component
26061
- * 3. children
26062
- * 4. fallback
26063
- *
26064
- * @example
26065
- * renderSlot(
26066
- * { render: (props) => <CustomButton {...props} /> },
26067
- * { onClick: handleClick, children: 'Click me' }
26068
- * )
26069
- */ function renderSlot(slot, props, fallback) {
26070
- // No slot provided, use fallback
26071
- if (!slot) return fallback;
26072
- // Slot is a plain React node
26073
- if ( React.isValidElement(slot) || "string" == typeof slot || "number" == typeof slot) return slot;
26074
- // Slot is an object with rendering options
26075
- if ("object" == typeof slot && null !== slot) {
26076
- const slotObj = slot;
26077
- // Priority 1: render function
26078
- if (slotObj.render && "function" == typeof slotObj.render) return slotObj.render(props);
26079
- // Priority 2: component
26080
- if (slotObj.component) {
26081
- const Component = slotObj.component;
26082
- return jsx(Component, {
26083
- ...props
26084
- });
26085
- }
26086
- // Priority 3: children
26087
- if (void 0 !== slotObj.children) return slotObj.children;
26088
- }
26089
- // Fallback
26090
- return fallback;
26091
- }
26092
-
26093
- /**
26094
- * Check if a value is a slot configuration
26095
- */ function isSlot(value) {
26096
- return "object" == typeof value && null !== value && ("render" in value || "component" in value || "children" in value);
26097
- }
26098
-
26099
- /**
26100
- * Merge multiple slot configurations
26101
- * Later slots override earlier ones
26102
- */ function mergeSlots(...slots) {
26103
- const filtered = slots.filter((s => void 0 !== s));
26104
- if (0 !== filtered.length) return 1 === filtered.length ? filtered[0] : _reduceInstanceProperty(filtered).call(filtered, ((acc, slot) => ({
26105
- ...acc,
26106
- ...slot
26107
- })));
26108
- }
26109
-
26110
- /**
26111
- * Create a slot wrapper component
26112
- *
26113
- * @example
26114
- * const ButtonSlot = createSlotComponent<ButtonSlotProps>('button')
26115
- *
26116
- * <ButtonSlot slot={customSlot} {...props}>
26117
- * Default content
26118
- * </ButtonSlot>
26119
- */ function createSlotComponent(defaultElement = "div") {
26120
- return function({slot: slot, children: children, ...props}) {
26121
- const slotProps = props;
26122
- return slot ? jsx(Fragment, {
26123
- children: renderSlot(slot, slotProps, children)
26124
- }) : jsx(defaultElement, "string" == typeof defaultElement ? {
26125
- ...props,
26126
- children: children
26127
- } : {
26128
- ...slotProps,
26129
- children: children
26130
- });
26131
- };
26132
- }
26133
-
26134
- /**
26135
- * Utility to create typed slot props
26136
- */ function createSlotProps(props) {
26137
- return props;
26138
- }
26139
-
26140
- /**
26141
- * Hook to manage slot rendering
26142
- */ function useSlot(slot, props, fallback) {
26143
- return React.useMemo((() => renderSlot(slot, props, fallback)), [ slot, props, fallback ]);
26144
- }
26145
-
26146
26151
  /**
26147
26152
  * Hook to merge theme overrides with component props
26148
26153
  *