@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/core.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 } from "react";
3
+ import React, { useState, useRef, useCallback, useEffect, memo, forwardRef, useId, useMemo, Children, isValidElement, cloneElement } from "react";
4
4
 
5
5
  import * as PhosphorIcons from "@phosphor-icons/react";
6
6
 
@@ -3108,19 +3108,19 @@ const AccordionImpl = memo((({title: title, children: children, defaultOpen: de
3108
3108
  disabled: !1,
3109
3109
  iconPosition: "right",
3110
3110
  ...initialProps
3111
- }, 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 = () => {
3111
+ }, 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((() => {
3112
3112
  if (contentRef.current && panelRef.current) {
3113
3113
  const height = isOpen ? `${contentRef.current.clientHeight}px` : "0px";
3114
3114
  panelRef.current.style.setProperty(ACCORDION.CSS_VARS.PANEL_HEIGHT, height), setPanelHeight(height);
3115
3115
  }
3116
- };
3116
+ }), [ isOpen ]);
3117
3117
  // Controlled/uncontrolled open state
3118
3118
  /**
3119
3119
  * Effect to update panel height when open state changes
3120
3120
  */
3121
3121
  return useEffect((() => {
3122
3122
  updatePanelHeight();
3123
- }), [ isOpen ]),
3123
+ }), [ isOpen, updatePanelHeight ]),
3124
3124
  /**
3125
3125
  * Effect to handle window resize and update panel height
3126
3126
  */
@@ -3129,7 +3129,7 @@ const AccordionImpl = memo((({title: title, children: children, defaultOpen: de
3129
3129
  isOpen && updatePanelHeight();
3130
3130
  };
3131
3131
  return window.addEventListener("resize", handleResize), () => window.removeEventListener("resize", handleResize);
3132
- }), [ isOpen ]), {
3132
+ }), [ isOpen, updatePanelHeight ]), {
3133
3133
  state: {
3134
3134
  isOpen: isOpen,
3135
3135
  panelHeight: panelHeight
@@ -3672,9 +3672,48 @@ class ThemeNaming {
3672
3672
  }
3673
3673
  }
3674
3674
 
3675
+ /**
3676
+ * Render a slot with the given props
3677
+ *
3678
+ * Priority order:
3679
+ * 1. render function
3680
+ * 2. component
3681
+ * 3. children
3682
+ * 4. fallback
3683
+ *
3684
+ * @example
3685
+ * renderSlot(
3686
+ * { render: (props) => <CustomButton {...props} /> },
3687
+ * { onClick: handleClick, children: 'Click me' }
3688
+ * )
3689
+ */
3690
+ function renderSlot(slot, props, fallback) {
3691
+ // No slot provided, use fallback
3692
+ if (!slot) return fallback;
3693
+ // Slot is a plain React node
3694
+ if ( React.isValidElement(slot) || "string" == typeof slot || "number" == typeof slot) return slot;
3695
+ // Slot is an object with rendering options
3696
+ if ("object" == typeof slot && null !== slot) {
3697
+ const slotObj = slot;
3698
+ // Priority 1: render function
3699
+ if (slotObj.render && "function" == typeof slotObj.render) return slotObj.render(props);
3700
+ // Priority 2: component
3701
+ if (slotObj.component) {
3702
+ const Component = slotObj.component;
3703
+ return jsx(Component, {
3704
+ ...props
3705
+ });
3706
+ }
3707
+ // Priority 3: children
3708
+ if (void 0 !== slotObj.children) return slotObj.children;
3709
+ }
3710
+ // Fallback
3711
+ return fallback;
3712
+ }
3713
+
3675
3714
  ThemeNaming.prefix = "atomix";
3676
3715
 
3677
- 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) => {
3716
+ 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) => {
3678
3717
  const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href), iconElement = iconName ? jsx(Icon, {
3679
3718
  name: iconName,
3680
3719
  size: iconSize
@@ -3690,17 +3729,28 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
3690
3729
  children: [ loading && jsx("span", {
3691
3730
  className: ThemeNaming.bemClass("btn", "spinner"),
3692
3731
  "aria-hidden": "true",
3693
- children: jsx(Spinner, {
3732
+ children: renderSlot(slots?.spinner, {
3733
+ className: ThemeNaming.bemClass("btn", "spinner"),
3694
3734
  size: spinnerSize,
3695
3735
  variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
3696
- })
3736
+ }, jsx(Spinner, {
3737
+ size: spinnerSize,
3738
+ variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
3739
+ }))
3697
3740
  }), iconElement && !loading && jsx("span", {
3698
3741
  className: ThemeNaming.bemClass("btn", "icon"),
3699
3742
  "aria-hidden": "true",
3700
- children: iconElement
3743
+ children: renderSlot(slots?.icon, {
3744
+ className: ThemeNaming.bemClass("btn", "icon"),
3745
+ children: iconElement,
3746
+ size: iconSize
3747
+ }, iconElement)
3701
3748
  }), !iconOnly && buttonText && jsx("span", {
3702
3749
  className: ThemeNaming.bemClass("btn", "label"),
3703
- children: buttonText
3750
+ children: renderSlot(slots?.label, {
3751
+ className: ThemeNaming.bemClass("btn", "label"),
3752
+ children: buttonText
3753
+ }, buttonText)
3704
3754
  }) ]
3705
3755
  }), buttonProps = {
3706
3756
  className: buttonClass,
@@ -3717,48 +3767,59 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
3717
3767
  tabIndex: void 0 !== tabIndex ? tabIndex : isDisabled ? -1 : 0,
3718
3768
  style: style,
3719
3769
  ...props
3720
- };
3721
- // Determine if we should render as a link
3722
- // If disabled, we still check href, but we might want to render as button or anchor with aria-disabled
3723
- // The previous logic was Boolean(href && !isDisabled). This meant if disabled, it renders as <button>.
3724
- // This is a safe fallback for disabled links.
3725
- let content;
3726
- // Render as anchor if href is provided
3727
- if (shouldRenderAsLink)
3728
- // Use custom linkComponent if provided (e.g., Next.js Link)
3729
- if (linkComponent) {
3730
- const LinkComp = linkComponent, linkProps = {
3770
+ }, buttonChildren = renderSlot(slots?.root, {
3771
+ className: buttonClass,
3772
+ children: buttonContent,
3773
+ disabled: isDisabled,
3774
+ loading: loading,
3775
+ onClick: handleClickEvent,
3776
+ type: type,
3777
+ "aria-label": safeAriaLabel,
3778
+ "aria-disabled": isDisabled,
3779
+ "aria-busy": loading
3780
+ }, (() => {
3781
+ // Render as anchor if href is provided
3782
+ if (shouldRenderAsLink) {
3783
+ // Use custom linkComponent if provided (e.g., Next.js Link)
3784
+ if (linkComponent) {
3785
+ const LinkComp = linkComponent, linkProps = {
3786
+ ...buttonProps,
3787
+ ref: ref,
3788
+ // linkComponent usually forwards ref to anchor
3789
+ href: isDisabled ? void 0 : href,
3790
+ to: isDisabled ? void 0 : href,
3791
+ target: target,
3792
+ rel: "_blank" === target ? "noopener noreferrer" : void 0
3793
+ };
3794
+ return jsx(LinkComp, {
3795
+ ...linkProps,
3796
+ children: buttonContent
3797
+ });
3798
+ }
3799
+ // Fallback to regular anchor tag
3800
+ return jsx("a", {
3801
+ ...buttonProps,
3802
+ ref: ref,
3803
+ href: isDisabled ? void 0 : href,
3804
+ target: target,
3805
+ rel: "_blank" === target ? "noopener noreferrer" : void 0,
3806
+ children: buttonContent
3807
+ });
3808
+ }
3809
+ // Default button rendering
3810
+ return jsx(Component, {
3731
3811
  ...buttonProps,
3732
3812
  ref: ref,
3733
- // linkComponent usually forwards ref to anchor
3734
- href: isDisabled ? void 0 : href,
3735
- to: isDisabled ? void 0 : href,
3736
- target: target,
3737
- rel: "_blank" === target ? "noopener noreferrer" : void 0
3738
- };
3739
- content = jsx(LinkComp, {
3740
- ...linkProps,
3813
+ type: "button" === Component ? type : void 0,
3814
+ disabled: isDisabled,
3741
3815
  children: buttonContent
3742
3816
  });
3743
- } else
3744
- // Fallback to regular anchor tag
3745
- content = jsx("a", {
3746
- ...buttonProps,
3747
- ref: ref,
3748
- href: isDisabled ? void 0 : href,
3749
- target: target,
3750
- rel: "_blank" === target ? "noopener noreferrer" : void 0,
3751
- children: buttonContent
3752
- }); else
3753
- // Default button rendering
3754
- content = jsx(Component, {
3755
- ...buttonProps,
3756
- ref: ref,
3757
- type: "button" === Component ? type : void 0,
3758
- disabled: isDisabled,
3759
- children: buttonContent
3760
- });
3761
- if (glass) {
3817
+ })());
3818
+ // Determine if we should render as a link
3819
+ // If disabled, we still check href, but we might want to render as button or anchor with aria-disabled
3820
+ // The previous logic was Boolean(href && !isDisabled). This meant if disabled, it renders as <button>.
3821
+ // This is a safe fallback for disabled links.
3822
+ if (glass) {
3762
3823
  // Default glass props
3763
3824
  const defaultGlassProps = {
3764
3825
  displacementScale: 20,
@@ -3771,10 +3832,10 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
3771
3832
  };
3772
3833
  return jsx(AtomixGlass, {
3773
3834
  ...glassProps,
3774
- children: content
3835
+ children: buttonChildren
3775
3836
  });
3776
3837
  }
3777
- return content;
3838
+ return buttonChildren;
3778
3839
  })));
3779
3840
 
3780
3841
  Button.displayName = "Button";