@shohojdhara/atomix 0.4.7 → 0.4.9

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 (176) hide show
  1. package/atomix.config.ts +58 -1
  2. package/dist/atomix.css +172 -157
  3. package/dist/atomix.css.map +1 -1
  4. package/dist/atomix.min.css +4 -4
  5. package/dist/atomix.min.css.map +1 -1
  6. package/dist/charts.d.ts +33 -0
  7. package/dist/charts.js +1274 -164
  8. package/dist/charts.js.map +1 -1
  9. package/dist/core.d.ts +33 -10
  10. package/dist/core.js +1099 -83
  11. package/dist/core.js.map +1 -1
  12. package/dist/forms.d.ts +33 -0
  13. package/dist/forms.js +2106 -1050
  14. package/dist/forms.js.map +1 -1
  15. package/dist/heavy.d.ts +42 -1
  16. package/dist/heavy.js +1663 -638
  17. package/dist/heavy.js.map +1 -1
  18. package/dist/index.d.ts +442 -270
  19. package/dist/index.esm.js +1947 -680
  20. package/dist/index.esm.js.map +1 -1
  21. package/dist/index.js +1982 -712
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.min.js +1 -1
  24. package/dist/index.min.js.map +1 -1
  25. package/package.json +6 -3
  26. package/scripts/atomix-cli.js +136 -1827
  27. package/scripts/cli/__tests__/basic.test.js +3 -2
  28. package/scripts/cli/__tests__/clean.test.js +278 -0
  29. package/scripts/cli/__tests__/component-validator.test.js +433 -0
  30. package/scripts/cli/__tests__/generator.test.js +613 -0
  31. package/scripts/cli/__tests__/glass-motion.test.js +256 -0
  32. package/scripts/cli/__tests__/integration.test.js +719 -108
  33. package/scripts/cli/__tests__/migrate.test.js +74 -0
  34. package/scripts/cli/__tests__/security.test.js +206 -0
  35. package/scripts/cli/__tests__/test-setup.js +3 -1
  36. package/scripts/cli/__tests__/theme-bridge.test.js +507 -0
  37. package/scripts/cli/__tests__/token-provider.test.js +361 -0
  38. package/scripts/cli/__tests__/utils.test.js +5 -5
  39. package/scripts/cli/commands/benchmark.js +105 -0
  40. package/scripts/cli/commands/build-theme.js +115 -0
  41. package/scripts/cli/commands/clean.js +109 -0
  42. package/scripts/cli/commands/doctor.js +88 -0
  43. package/scripts/cli/commands/generate.js +218 -0
  44. package/scripts/cli/commands/init.js +73 -0
  45. package/scripts/cli/commands/migrate.js +106 -0
  46. package/scripts/cli/commands/sync-tokens.js +206 -0
  47. package/scripts/cli/commands/theme-bridge.js +248 -0
  48. package/scripts/cli/commands/tokens.js +157 -0
  49. package/scripts/cli/commands/validate.js +194 -0
  50. package/scripts/cli/internal/ai-engine.js +156 -0
  51. package/scripts/cli/internal/compiler.js +114 -0
  52. package/scripts/cli/internal/component-validator.js +443 -0
  53. package/scripts/cli/internal/config-loader.js +162 -0
  54. package/scripts/cli/internal/filesystem.js +158 -0
  55. package/scripts/cli/internal/generator.js +430 -0
  56. package/scripts/cli/internal/glass-generator.js +398 -0
  57. package/scripts/cli/internal/hook-generator.js +369 -0
  58. package/scripts/cli/internal/hooks.js +61 -0
  59. package/scripts/cli/internal/itcss-generator.js +565 -0
  60. package/scripts/cli/internal/motion-generator.js +679 -0
  61. package/scripts/cli/internal/template-engine.js +301 -0
  62. package/scripts/cli/internal/theme-bridge.js +664 -0
  63. package/scripts/cli/internal/tokens/engine.js +122 -0
  64. package/scripts/cli/internal/tokens/provider.js +34 -0
  65. package/scripts/cli/internal/tokens/providers/figma.js +50 -0
  66. package/scripts/cli/internal/tokens/providers/style-dictionary.js +48 -0
  67. package/scripts/cli/internal/tokens/providers/w3c.js +48 -0
  68. package/scripts/cli/internal/tokens/token-provider.js +443 -0
  69. package/scripts/cli/internal/tokens/token-validator.js +513 -0
  70. package/scripts/cli/internal/validator.js +276 -0
  71. package/scripts/cli/internal/wizard.js +115 -0
  72. package/scripts/cli/mappings.js +23 -0
  73. package/scripts/cli/migration-tools.js +164 -94
  74. package/scripts/cli/plugins/style-dictionary.js +46 -0
  75. package/scripts/cli/templates/README.md +525 -95
  76. package/scripts/cli/templates/common-templates.js +40 -14
  77. package/scripts/cli/templates/components/react-component.ts +282 -0
  78. package/scripts/cli/templates/config/project-config.ts +112 -0
  79. package/scripts/cli/templates/hooks/use-component.ts +477 -0
  80. package/scripts/cli/templates/index.js +19 -4
  81. package/scripts/cli/templates/index.ts +171 -0
  82. package/scripts/cli/templates/next-templates.js +72 -0
  83. package/scripts/cli/templates/react-templates.js +70 -126
  84. package/scripts/cli/templates/scss-templates.js +35 -35
  85. package/scripts/cli/templates/stories/storybook-story.ts +241 -0
  86. package/scripts/cli/templates/styles/scss-component.ts +255 -0
  87. package/scripts/cli/templates/tests/vitest-test.ts +229 -0
  88. package/scripts/cli/templates/token-templates.js +337 -1
  89. package/scripts/cli/templates/tokens/token-generators.ts +1088 -0
  90. package/scripts/cli/templates/types/component-types.ts +145 -0
  91. package/scripts/cli/templates/utils/testing-utils.ts +144 -0
  92. package/scripts/cli/templates/vanilla-templates.js +39 -0
  93. package/scripts/cli/token-manager.js +8 -2
  94. package/scripts/cli/utils/cache-manager.js +240 -0
  95. package/scripts/cli/utils/detector.js +46 -0
  96. package/scripts/cli/utils/diagnostics.js +289 -0
  97. package/scripts/cli/utils/error.js +89 -0
  98. package/scripts/cli/utils/helpers.js +67 -0
  99. package/scripts/cli/utils/logger.js +75 -0
  100. package/scripts/cli/utils/security.js +302 -0
  101. package/scripts/cli/utils/telemetry.js +115 -0
  102. package/scripts/cli/utils/validation.js +37 -0
  103. package/scripts/cli/utils.js +28 -341
  104. package/src/components/Accordion/Accordion.stories.tsx +0 -18
  105. package/src/components/Accordion/Accordion.test.tsx +0 -17
  106. package/src/components/Accordion/Accordion.tsx +0 -4
  107. package/src/components/AtomixGlass/AtomixGlass.test.tsx +37 -3
  108. package/src/components/AtomixGlass/AtomixGlass.tsx +143 -31
  109. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +129 -31
  110. package/src/components/AtomixGlass/PerformanceDashboard.tsx +219 -0
  111. package/src/components/AtomixGlass/README.md +25 -10
  112. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +216 -0
  113. package/src/components/AtomixGlass/animation-system.ts +578 -0
  114. package/src/components/AtomixGlass/shader-utils.ts +4 -1
  115. package/src/components/AtomixGlass/stories/Overview.stories.tsx +157 -6
  116. package/src/components/AtomixGlass/stories/Phase1-Animation.stories.tsx +653 -0
  117. package/src/components/AtomixGlass/stories/Phase1-Test.stories.tsx +95 -0
  118. package/src/components/AtomixGlass/stories/Playground.stories.tsx +51 -51
  119. package/src/components/AtomixGlass/stories/shared-components.tsx +6 -0
  120. package/src/components/Avatar/Avatar.tsx +1 -1
  121. package/src/components/Button/Button.stories.disabled-link.tsx +10 -0
  122. package/src/components/Button/Button.stories.tsx +10 -0
  123. package/src/components/Button/Button.test.tsx +16 -11
  124. package/src/components/Button/Button.tsx +4 -4
  125. package/src/components/Card/Card.tsx +1 -1
  126. package/src/components/Dropdown/Dropdown.tsx +12 -12
  127. package/src/components/Form/Select.tsx +62 -3
  128. package/src/components/Modal/Modal.tsx +14 -3
  129. package/src/components/Navigation/Navbar/Navbar.tsx +44 -0
  130. package/src/components/Slider/Slider.stories.tsx +3 -3
  131. package/src/components/Slider/Slider.tsx +38 -0
  132. package/src/components/Steps/Steps.tsx +3 -3
  133. package/src/components/Tabs/Tabs.tsx +77 -8
  134. package/src/components/Testimonial/Testimonial.tsx +1 -1
  135. package/src/components/TypedButton/TypedButton.stories.tsx +59 -0
  136. package/src/components/TypedButton/TypedButton.tsx +39 -0
  137. package/src/components/TypedButton/index.ts +2 -0
  138. package/src/components/VideoPlayer/VideoPlayer.tsx +11 -4
  139. package/src/lib/composables/index.ts +4 -7
  140. package/src/lib/composables/types.ts +45 -0
  141. package/src/lib/composables/useAccordion.ts +0 -7
  142. package/src/lib/composables/useAtomixGlass.ts +148 -6
  143. package/src/lib/composables/useAtomixGlassStyles.ts +9 -7
  144. package/src/lib/composables/useChartExport.ts +3 -13
  145. package/src/lib/composables/useDropdown.ts +66 -0
  146. package/src/lib/composables/useFocusTrap.ts +80 -0
  147. package/src/lib/composables/usePerformanceMonitor.ts +448 -0
  148. package/src/lib/composables/useResponsiveGlass.presets.ts +192 -0
  149. package/src/lib/composables/useResponsiveGlass.ts +441 -0
  150. package/src/lib/composables/useTooltip.ts +16 -0
  151. package/src/lib/composables/useTypedButton.ts +66 -0
  152. package/src/lib/config/index.ts +62 -5
  153. package/src/lib/constants/components.ts +62 -7
  154. package/src/lib/theme/devtools/__tests__/useHistory.test.tsx +150 -0
  155. package/src/lib/theme/tokens/centralized-tokens.ts +120 -0
  156. package/src/lib/theme/utils/__tests__/domUtils.test.ts +101 -0
  157. package/src/lib/types/components.ts +37 -11
  158. package/src/lib/types/glass.ts +35 -0
  159. package/src/lib/types/index.ts +1 -0
  160. package/src/lib/utils/displacement-generator.ts +1 -1
  161. package/src/styles/01-settings/_settings.testtypecheck.scss +53 -0
  162. package/src/styles/01-settings/_settings.typedbutton.scss +53 -0
  163. package/src/styles/06-components/_components.atomix-glass.scss +17 -21
  164. package/src/styles/06-components/_components.edge-panel.scss +1 -5
  165. package/src/styles/06-components/_components.modal.scss +1 -4
  166. package/src/styles/06-components/_components.navbar.scss +1 -1
  167. package/src/styles/06-components/_components.testbutton.scss +212 -0
  168. package/src/styles/06-components/_components.testtypecheck.scss +212 -0
  169. package/src/styles/06-components/_components.tooltip.scss +9 -5
  170. package/src/styles/06-components/_components.typedbutton.scss +212 -0
  171. package/src/styles/99-utilities/_index.scss +1 -0
  172. package/src/styles/99-utilities/_utilities.text.scss +1 -1
  173. package/src/styles/99-utilities/_utilities.touch-target.scss +36 -0
  174. package/scripts/cli/component-generator.js +0 -564
  175. package/scripts/cli/interactive-init.js +0 -357
  176. package/src/styles/06-components/old.chart.styles.scss +0 -2788
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Quick Test Story for Phase 1 Animations
3
+ *
4
+ * This is a minimal test to verify the animation pipeline is working
5
+ */
6
+
7
+ import type { Meta, StoryObj } from '@storybook/react';
8
+ import { AtomixGlass } from '../AtomixGlass';
9
+
10
+ const meta = {
11
+ title: 'Testing/Phase 1 Animation Quick Test',
12
+ component: AtomixGlass,
13
+ parameters: {
14
+ layout: 'centered',
15
+ },
16
+ tags: ['autodocs'],
17
+ argTypes: {
18
+ withTimeAnimation: { control: 'boolean' },
19
+ animationSpeed: { control: { type: 'range', min: 0.1, max: 5.0, step: 0.1 } },
20
+ distortionOctaves: { control: { type: 'range', min: 1, max: 8, step: 1 } },
21
+ distortionQuality: {
22
+ control: 'select',
23
+ options: ['low', 'medium', 'high', 'ultra']
24
+ },
25
+ },
26
+ } satisfies Meta<typeof AtomixGlass>;
27
+
28
+ export default meta;
29
+ type Story = StoryObj<typeof meta>;
30
+
31
+ // Default test with animations enabled
32
+ export const Animated: Story = {
33
+ args: {
34
+ children: (
35
+ <div style={{ padding: '40px', color: 'white', textAlign: 'center' }}>
36
+ <h2>Phase 1 Animation Test</h2>
37
+ <p>If you see flowing liquid glass effects, it's working!</p>
38
+ </div>
39
+ ),
40
+ mode: 'shader',
41
+ withTimeAnimation: true,
42
+ animationSpeed: 1.0,
43
+ distortionOctaves: 4,
44
+ distortionQuality: 'high',
45
+ displacementScale: 30,
46
+ blurAmount: 8,
47
+ saturation: 180,
48
+ aberrationIntensity: 3,
49
+ // Dark background to make effects visible
50
+ style: {
51
+ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
52
+ },
53
+ },
54
+ };
55
+
56
+ // Comparison: Same config without animations
57
+ export const Static: Story = {
58
+ args: {
59
+ ...Animated.args,
60
+ withTimeAnimation: false,
61
+ },
62
+ };
63
+
64
+ // Speed comparison
65
+ export const FastAnimation: Story = {
66
+ args: {
67
+ ...Animated.args,
68
+ animationSpeed: 3.0,
69
+ },
70
+ };
71
+
72
+ export const SlowAnimation: Story = {
73
+ args: {
74
+ ...Animated.args,
75
+ animationSpeed: 0.3,
76
+ },
77
+ };
78
+
79
+ // High complexity FBM
80
+ export const HighDetailFBM: Story = {
81
+ args: {
82
+ ...Animated.args,
83
+ distortionOctaves: 7,
84
+ distortionQuality: 'ultra',
85
+ },
86
+ };
87
+
88
+ // Mobile optimized (low quality)
89
+ export const MobileOptimized: Story = {
90
+ args: {
91
+ ...Animated.args,
92
+ distortionOctaves: 2,
93
+ distortionQuality: 'low',
94
+ },
95
+ };
@@ -723,7 +723,7 @@ export const Playground: Story = {
723
723
  </div>
724
724
  <div>
725
725
  <div
726
- className="u-font-bold u-fs-sm"
726
+ className="u-font-bold u-text-sm"
727
727
  style={{
728
728
  background:
729
729
  'linear-gradient(90deg, #fff 0%, rgba(122,255,215,0.9) 100%)',
@@ -735,7 +735,7 @@ export const Playground: Story = {
735
735
  >
736
736
  AtomixGlass Playground
737
737
  </div>
738
- <div className="u-fs-xs u-opacity-60 u-mt-1">Live parameter editor</div>
738
+ <div className="u-text-xs u-opacity-60 u-mt-1">Live parameter editor</div>
739
739
  </div>
740
740
  </div>
741
741
  </div>
@@ -750,11 +750,11 @@ export const Playground: Story = {
750
750
  }}
751
751
  >
752
752
  <div className="u-flex u-justify-between u-items-center u-mb-2">
753
- <span className="u-text-white u-font-semibold u-fs-xs">
753
+ <span className="u-text-white u-font-semibold u-text-xs">
754
754
  Performance Score
755
755
  </span>
756
756
  <span
757
- className="u-font-bold u-fs-sm"
757
+ className="u-font-bold u-text-sm"
758
758
  style={{ color: getPerformanceColor() }}
759
759
  >
760
760
  {Math.round(performanceScore)}/100
@@ -792,7 +792,7 @@ export const Playground: Story = {
792
792
  {/* Quick Presets */}
793
793
  <div className="u-mb-4">
794
794
  <label
795
- className="u-block u-mb-2 u-text-white u-font-semibold u-fs-xs"
795
+ className="u-block u-mb-2 u-text-white u-font-semibold u-text-xs"
796
796
  style={{ letterSpacing: '0.5px' }}
797
797
  >
798
798
  ⚡ Quick Presets
@@ -855,7 +855,7 @@ export const Playground: Story = {
855
855
  <button
856
856
  key={tab}
857
857
  onClick={() => setControlTab(tab)}
858
- className="u-flex-grow-1 u-py-2 u-fs-xs u-font-bold u-rounded-pill u-cursor-pointer"
858
+ className="u-flex-grow-1 u-py-2 u-text-xs u-font-bold u-rounded-pill u-cursor-pointer"
859
859
  style={{
860
860
  background: controlTab === tab ? 'rgba(255,255,255,0.1)' : 'transparent',
861
861
  color: controlTab === tab ? '#fff' : 'rgba(255,255,255,0.5)',
@@ -885,7 +885,7 @@ export const Playground: Story = {
885
885
  }}
886
886
  />
887
887
  <span
888
- className="u-fs-xs u-font-bold u-opacity-60"
888
+ className="u-text-xs u-font-bold u-opacity-60"
889
889
  style={{ letterSpacing: '1px', textTransform: 'uppercase' }}
890
890
  >
891
891
  Optics
@@ -918,11 +918,11 @@ export const Playground: Story = {
918
918
  return (
919
919
  <div key={key} className="u-mb-4">
920
920
  <div className="u-flex u-justify-between u-items-baseline u-mb-1">
921
- <label className="u-fs-xs u-font-medium u-opacity-80">
921
+ <label className="u-text-xs u-font-medium u-opacity-80">
922
922
  {label}
923
923
  </label>
924
924
  <span
925
- className="u-fs-xs u-font-bold u-px-2 u-py-1 u-rounded"
925
+ className="u-text-xs u-font-bold u-px-2 u-py-1 u-rounded"
926
926
  style={{
927
927
  background: 'rgba(122,255,215,0.12)',
928
928
  color: '#7AFFD7',
@@ -982,7 +982,7 @@ export const Playground: Story = {
982
982
  }}
983
983
  />
984
984
  <span
985
- className="u-fs-xs u-font-bold u-opacity-60"
985
+ className="u-text-xs u-font-bold u-opacity-60"
986
986
  style={{ letterSpacing: '1px', textTransform: 'uppercase' }}
987
987
  >
988
988
  Physics
@@ -998,11 +998,11 @@ export const Playground: Story = {
998
998
  return (
999
999
  <div key={key} className="u-mb-4">
1000
1000
  <div className="u-flex u-justify-between u-items-baseline u-mb-1">
1001
- <label className="u-fs-xs u-font-medium u-opacity-80">
1001
+ <label className="u-text-xs u-font-medium u-opacity-80">
1002
1002
  {label}
1003
1003
  </label>
1004
1004
  <span
1005
- className="u-fs-xs u-font-bold u-px-2 u-py-1 u-rounded"
1005
+ className="u-text-xs u-font-bold u-px-2 u-py-1 u-rounded"
1006
1006
  style={{
1007
1007
  background: 'rgba(167,139,250,0.12)',
1008
1008
  color: '#a78bfa',
@@ -1060,7 +1060,7 @@ export const Playground: Story = {
1060
1060
  }}
1061
1061
  />
1062
1062
  <span
1063
- className="u-fs-xs u-font-bold u-opacity-60"
1063
+ className="u-text-xs u-font-bold u-opacity-60"
1064
1064
  style={{ letterSpacing: '1px', textTransform: 'uppercase' }}
1065
1065
  >
1066
1066
  Flags
@@ -1110,7 +1110,7 @@ export const Playground: Story = {
1110
1110
  }}
1111
1111
  />
1112
1112
  <span
1113
- className="u-fs-xs u-font-medium"
1113
+ className="u-text-xs u-font-medium"
1114
1114
  style={{ color: isOn ? '#7AFFD7' : 'rgba(255,255,255,0.6)' }}
1115
1115
  >
1116
1116
  {label}
@@ -1136,7 +1136,7 @@ export const Playground: Story = {
1136
1136
  }}
1137
1137
  />
1138
1138
  <span
1139
- className="u-fs-xs u-font-bold u-opacity-60"
1139
+ className="u-text-xs u-font-bold u-opacity-60"
1140
1140
  style={{ letterSpacing: '1px', textTransform: 'uppercase' }}
1141
1141
  >
1142
1142
  Glass Mode
@@ -1150,7 +1150,7 @@ export const Playground: Story = {
1150
1150
  <button
1151
1151
  key={mode}
1152
1152
  onClick={() => setSelectedMode(mode)}
1153
- className="u-py-2 u-rounded u-text-center u-fs-xs u-font-bold"
1153
+ className="u-py-2 u-rounded u-text-center u-text-xs u-font-bold"
1154
1154
  style={{
1155
1155
  background:
1156
1156
  selectedMode === mode
@@ -1189,7 +1189,7 @@ export const Playground: Story = {
1189
1189
  }}
1190
1190
  />
1191
1191
  <span
1192
- className="u-fs-xs u-font-bold u-opacity-60"
1192
+ className="u-text-xs u-font-bold u-opacity-60"
1193
1193
  style={{ letterSpacing: '1px', textTransform: 'uppercase' }}
1194
1194
  >
1195
1195
  Shader Variant
@@ -1200,7 +1200,7 @@ export const Playground: Story = {
1200
1200
  <button
1201
1201
  key={opt.value}
1202
1202
  onClick={() => setSelectedShader(opt.value as any)}
1203
- className="u-py-2 u-px-3 u-rounded u-text-start u-fs-xs u-font-medium"
1203
+ className="u-py-2 u-px-3 u-rounded u-text-start u-text-xs u-font-medium"
1204
1204
  style={{
1205
1205
  background:
1206
1206
  selectedShader === opt.value
@@ -1228,7 +1228,7 @@ export const Playground: Story = {
1228
1228
  <div className="u-mb-4">
1229
1229
  {/* Header row: label + nav controls */}
1230
1230
  <div className="u-flex u-items-center u-justify-between u-mb-2">
1231
- <label className="u-block u-text-white u-font-semibold u-fs-sm">
1231
+ <label className="u-block u-text-white u-font-semibold u-text-sm">
1232
1232
  🌄 Background
1233
1233
  </label>
1234
1234
  <div className="u-flex u-items-center u-gap-2">
@@ -1264,7 +1264,7 @@ export const Playground: Story = {
1264
1264
 
1265
1265
  </button>
1266
1266
  <span
1267
- className="u-fs-xs u-opacity-60"
1267
+ className="u-text-xs u-opacity-60"
1268
1268
  style={{
1269
1269
  minWidth: '36px',
1270
1270
  textAlign: 'center',
@@ -1454,17 +1454,17 @@ export const Playground: Story = {
1454
1454
  flexShrink: 0,
1455
1455
  }}
1456
1456
  />
1457
- <span className="u-fs-xs u-opacity-70" style={{ fontWeight: 600 }}>
1457
+ <span className="u-text-xs u-opacity-70" style={{ fontWeight: 600 }}>
1458
1458
  {backgrounds[backgroundIndex]?.label}
1459
1459
  </span>
1460
1460
  <span
1461
- className="u-fs-xs u-opacity-40"
1461
+ className="u-text-xs u-opacity-40"
1462
1462
  style={{ textTransform: 'capitalize', marginLeft: 'auto' }}
1463
1463
  >
1464
1464
  {backgrounds[backgroundIndex]?.tag}
1465
1465
  </span>
1466
1466
  </div>
1467
- <div className="u-mt-1 u-fs-xs u-opacity-35" style={{ letterSpacing: '0.3px' }}>
1467
+ <div className="u-mt-1 u-text-xs u-opacity-35" style={{ letterSpacing: '0.3px' }}>
1468
1468
  Use ← → arrow keys to navigate
1469
1469
  </div>
1470
1470
  </div>
@@ -1543,7 +1543,7 @@ export const Playground: Story = {
1543
1543
  <div className="u-flex u-justify-between u-items-center u-mb-6">
1544
1544
  <div>
1545
1545
  <h3
1546
- className="u-m-0 u-font-bold u-fs-xl"
1546
+ className="u-m-0 u-font-bold u-text-xl"
1547
1547
  style={{
1548
1548
  background:
1549
1549
  'linear-gradient(135deg, #fff 0%, rgba(255,255,255,0.8) 100%)',
@@ -1554,7 +1554,7 @@ export const Playground: Story = {
1554
1554
  >
1555
1555
  💻 Generated Code
1556
1556
  </h3>
1557
- <p className="u-m-0 u-fs-sm u-text-white u-opacity-70 u-mt-1">
1557
+ <p className="u-m-0 u-text-sm u-text-white u-opacity-70 u-mt-1">
1558
1558
  Copy this code to use in your project
1559
1559
  </p>
1560
1560
  </div>
@@ -1573,7 +1573,7 @@ export const Playground: Story = {
1573
1573
  </Button>
1574
1574
  </div>
1575
1575
  <pre
1576
- className="custom-scrollbar u-rounded u-fs-sm"
1576
+ className="custom-scrollbar u-rounded u-text-sm"
1577
1577
  style={{
1578
1578
  overflowX: 'auto',
1579
1579
  overflowY: 'auto',
@@ -1612,7 +1612,7 @@ export const Playground: Story = {
1612
1612
  <div className="u-h-100 u-w-100 custom-scrollbar" style={{ overflowY: 'auto' }}>
1613
1613
  <div className="u-p-4 u-p-lg-5 u-text-center">
1614
1614
  <div
1615
- className="u-inline-flex u-items-center u-gap-2 u-px-3 u-py-1 u-rounded-pill u-mb-4 u-fs-xs u-font-bold"
1615
+ className="u-inline-flex u-items-center u-gap-2 u-px-3 u-py-1 u-rounded-pill u-mb-4 u-text-xs u-font-bold"
1616
1616
  style={{
1617
1617
  background:
1618
1618
  'linear-gradient(135deg, rgba(122, 255, 215, 0.2) 0%, rgba(102, 126, 234, 0.2) 100%)',
@@ -1623,7 +1623,7 @@ export const Playground: Story = {
1623
1623
  backdropFilter: 'blur(8px)',
1624
1624
  }}
1625
1625
  >
1626
- <span className="u-fs-base">✨</span>
1626
+ <span className="u-text-base">✨</span>
1627
1627
  <span>LIVE PREVIEW</span>
1628
1628
  </div>
1629
1629
 
@@ -1713,7 +1713,7 @@ export const Playground: Story = {
1713
1713
  }}
1714
1714
  >
1715
1715
  <div
1716
- className="u-mb-3 u-font-bold u-fs-sm"
1716
+ className="u-mb-3 u-font-bold u-text-sm"
1717
1717
  style={{ color: '#7AFFD7', letterSpacing: '0.5px' }}
1718
1718
  >
1719
1719
  📊 Current Configuration Stack
@@ -1723,50 +1723,50 @@ export const Playground: Story = {
1723
1723
  style={{ gridTemplateColumns: 'repeat(6, 1fr)' }}
1724
1724
  >
1725
1725
  <div className="u-flex u-flex-column u-gap-1">
1726
- <span className="u-fs-xs u-opacity-60 u-font-medium">Mode</span>
1726
+ <span className="u-text-xs u-opacity-60 u-font-medium">Mode</span>
1727
1727
  <span
1728
- className="u-fs-sm u-font-bold u-text-white"
1728
+ className="u-text-sm u-font-bold u-text-white"
1729
1729
  style={{ textTransform: 'capitalize' }}
1730
1730
  >
1731
1731
  {selectedMode}
1732
1732
  </span>
1733
1733
  </div>
1734
1734
  <div className="u-flex u-flex-column u-gap-1">
1735
- <span className="u-fs-xs u-opacity-60 u-font-medium">Shader</span>
1735
+ <span className="u-text-xs u-opacity-60 u-font-medium">Shader</span>
1736
1736
  <span
1737
- className="u-fs-sm u-font-bold u-text-white"
1737
+ className="u-text-sm u-font-bold u-text-white"
1738
1738
  style={{ textTransform: 'capitalize' }}
1739
1739
  >
1740
1740
  {selectedShader}
1741
1741
  </span>
1742
1742
  </div>
1743
1743
  <div className="u-flex u-flex-column u-gap-1">
1744
- <span className="u-fs-xs u-opacity-60 u-font-medium">
1744
+ <span className="u-text-xs u-opacity-60 u-font-medium">
1745
1745
  Displacement
1746
1746
  </span>
1747
- <span className="u-fs-sm u-font-bold u-text-white">
1747
+ <span className="u-text-sm u-font-bold u-text-white">
1748
1748
  {settings.displacementScale}px
1749
1749
  </span>
1750
1750
  </div>
1751
1751
  <div className="u-flex u-flex-column u-gap-1">
1752
- <span className="u-fs-xs u-opacity-60 u-font-medium">
1752
+ <span className="u-text-xs u-opacity-60 u-font-medium">
1753
1753
  Aberration
1754
1754
  </span>
1755
- <span className="u-fs-sm u-font-bold u-text-white">
1755
+ <span className="u-text-sm u-font-bold u-text-white">
1756
1756
  {settings.aberrationIntensity.toFixed(1)}
1757
1757
  </span>
1758
1758
  </div>
1759
1759
  <div className="u-flex u-flex-column u-gap-1">
1760
- <span className="u-fs-xs u-opacity-60 u-font-medium">Blur</span>
1761
- <span className="u-fs-sm u-font-bold u-text-white">
1760
+ <span className="u-text-xs u-opacity-60 u-font-medium">Blur</span>
1761
+ <span className="u-text-sm u-font-bold u-text-white">
1762
1762
  {settings.blurAmount.toFixed(2)}
1763
1763
  </span>
1764
1764
  </div>
1765
1765
  <div className="u-flex u-flex-column u-gap-1">
1766
- <span className="u-fs-xs u-opacity-60 u-font-medium">
1766
+ <span className="u-text-xs u-opacity-60 u-font-medium">
1767
1767
  Elasticity
1768
1768
  </span>
1769
- <span className="u-fs-sm u-font-bold u-text-white">
1769
+ <span className="u-text-sm u-font-bold u-text-white">
1770
1770
  {settings.elasticity.toFixed(2)}
1771
1771
  </span>
1772
1772
  </div>
@@ -1783,14 +1783,14 @@ export const Playground: Story = {
1783
1783
  }}
1784
1784
  >
1785
1785
  <div
1786
- className="u-mb-3 u-font-bold u-fs-sm"
1786
+ className="u-mb-3 u-font-bold u-text-sm"
1787
1787
  style={{ color: '#7AFFD7', letterSpacing: '0.5px' }}
1788
1788
  >
1789
1789
  🎨 Visual Characteristics
1790
1790
  </div>
1791
1791
  <div className="u-flex u-flex-wrap u-gap-2">
1792
1792
  <div
1793
- className="u-px-3 u-py-1 u-rounded-pill u-fs-xs u-font-bold"
1793
+ className="u-px-3 u-py-1 u-rounded-pill u-text-xs u-font-bold"
1794
1794
  style={{
1795
1795
  background: settings.withLiquidBlur
1796
1796
  ? 'rgba(122, 255, 215, 0.15)'
@@ -1807,7 +1807,7 @@ export const Playground: Story = {
1807
1807
  {settings.withLiquidBlur ? '✓' : '○'} Liquid Blur
1808
1808
  </div>
1809
1809
  <div
1810
- className="u-px-3 u-py-1 u-rounded-pill u-fs-xs u-font-bold"
1810
+ className="u-px-3 u-py-1 u-rounded-pill u-text-xs u-font-bold"
1811
1811
  style={{
1812
1812
  background: settings.withBorder
1813
1813
  ? 'rgba(122, 255, 215, 0.15)'
@@ -1822,7 +1822,7 @@ export const Playground: Story = {
1822
1822
  {settings.withBorder ? '✓' : '○'} Border Effect
1823
1823
  </div>
1824
1824
  <div
1825
- className="u-px-3 u-py-1 u-rounded-pill u-fs-xs u-font-bold"
1825
+ className="u-px-3 u-py-1 u-rounded-pill u-text-xs u-font-bold"
1826
1826
  style={{
1827
1827
  background: settings.reducedMotion
1828
1828
  ? 'rgba(239, 68, 68, 0.15)'
@@ -1839,7 +1839,7 @@ export const Playground: Story = {
1839
1839
  {settings.reducedMotion ? '✓' : '○'} Reduced Motion
1840
1840
  </div>
1841
1841
  <div
1842
- className="u-px-3 u-py-1 u-rounded-pill u-fs-xs u-font-bold"
1842
+ className="u-px-3 u-py-1 u-rounded-pill u-text-xs u-font-bold"
1843
1843
  style={{
1844
1844
  background: settings.highContrast
1845
1845
  ? 'rgba(245, 158, 11, 0.15)'
@@ -1868,7 +1868,7 @@ export const Playground: Story = {
1868
1868
  }}
1869
1869
  >
1870
1870
  <div
1871
- className="u-mb-3 u-font-bold u-fs-sm"
1871
+ className="u-mb-3 u-font-bold u-text-sm"
1872
1872
  style={{ color: '#7AFFD7', letterSpacing: '0.5px' }}
1873
1873
  >
1874
1874
  📈 Quick Stats
@@ -1877,23 +1877,23 @@ export const Playground: Story = {
1877
1877
  className="u-grid u-gap-3"
1878
1878
  style={{ gridTemplateColumns: 'repeat(4, 1fr)' }}
1879
1879
  >
1880
- <div className="u-flex u-items-center u-fs-sm">
1880
+ <div className="u-flex u-items-center u-text-sm">
1881
1881
  <span className="u-opacity-60 u-font-medium">Saturation:</span>
1882
1882
  <span className="u-font-bold u-ml-2">{settings.saturation}%</span>
1883
1883
  </div>
1884
- <div className="u-flex u-items-center u-fs-sm">
1884
+ <div className="u-flex u-items-center u-text-sm">
1885
1885
  <span className="u-opacity-60 u-font-medium">Radius:</span>
1886
1886
  <span className="u-font-bold u-ml-2">
1887
1887
  {settings.borderRadius}px
1888
1888
  </span>
1889
1889
  </div>
1890
- <div className="u-flex u-items-center u-fs-sm">
1890
+ <div className="u-flex u-items-center u-text-sm">
1891
1891
  <span className="u-opacity-60 u-font-medium">Bg:</span>
1892
1892
  <span className="u-font-bold u-ml-2">
1893
1893
  {backgroundIndex + 1}/{backgrounds.length}
1894
1894
  </span>
1895
1895
  </div>
1896
- <div className="u-flex u-items-center u-fs-sm">
1896
+ <div className="u-flex u-items-center u-text-sm">
1897
1897
  <span className="u-opacity-60 u-font-medium">Effects:</span>
1898
1898
  <span className="u-font-bold u-ml-2">
1899
1899
  {settings.withoutEffects ? 'Off' : 'On'}
@@ -97,6 +97,9 @@ export const BackgroundWrapper: React.FC<BackgroundWrapperProps> = ({
97
97
  backgroundColor: overlayColor,
98
98
  opacity: overlayOpacity,
99
99
  padding,
100
+ objectPosition: 'center',
101
+ objectFit: 'cover',
102
+ backgroundPosition: 'fixed'
100
103
  }}
101
104
  />
102
105
  )}
@@ -193,7 +196,10 @@ export const StoryContainer: React.FC<StoryContainerProps> = ({
193
196
  * Collection of high-quality background images for different moods and scenarios
194
197
  */
195
198
  export const backgroundImages = [
199
+ 'https://images.unsplash.com/photo-1773609108583-4f0040c75e7f?q=80&w=2532&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
200
+ 'https://images.unsplash.com/photo-1593433073755-4233a78ee359?q=80&w=987&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
196
201
  'https://images.unsplash.com/photo-1637825891028-564f672aa42c?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2670',
202
+ 'https://images.unsplash.com/photo-1773062278803-0643c4782445?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
197
203
  'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
198
204
  'https://images.unsplash.com/photo-1519681393784-d120267933ba?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2670',
199
205
  'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
@@ -6,7 +6,7 @@ import { Icon } from '../Icon/Icon';
6
6
  export const Avatar: React.FC<AvatarProps> = memo(
7
7
  ({
8
8
  src,
9
- alt = 'Avatar',
9
+ alt = 'User avatar',
10
10
  initials,
11
11
  icon,
12
12
  size = 'md',
@@ -0,0 +1,10 @@
1
+ import { Button } from './Button';
2
+
3
+ export const DisabledLinkExample = {
4
+ render: () => (
5
+ <div style={{ padding: '20px', display: 'flex', gap: '10px' }}>
6
+ <Button href="/home" disabled>Disabled Link Button</Button>
7
+ <Button href="/home">Normal Link Button</Button>
8
+ </div>
9
+ ),
10
+ };
@@ -406,6 +406,16 @@ export const DisabledState: Story = {
406
406
  },
407
407
  };
408
408
 
409
+ export const DisabledLinkState: Story = {
410
+ args: {
411
+ label: 'Disabled Link Button',
412
+ variant: 'primary',
413
+ size: 'md',
414
+ disabled: true,
415
+ href: '/home',
416
+ },
417
+ };
418
+
409
419
  /**
410
420
  * Shows button in active state
411
421
  */
@@ -75,22 +75,27 @@ describe('Button Component', () => {
75
75
  });
76
76
 
77
77
  it('renders as disabled link when disabled and href provided', () => {
78
- // Current implementation might be buggy here, let's see
79
78
  render(
80
79
  <Button href="/home" disabled>
81
80
  Home
82
81
  </Button>
83
82
  );
84
- const link = screen.queryByRole('link');
85
- const button = screen.queryByRole('button');
86
-
87
- // If it renders as button when disabled (which logic suggested), then:
88
- if (button) {
89
- expect(button).toBeDisabled();
90
- } else if (link) {
91
- expect(link).toHaveAttribute('aria-disabled', 'true');
92
- // Should not navigate
93
- }
83
+
84
+ // An anchor tag without an href attribute is not considered a 'link' role.
85
+ // It's considered a generic text element, but in our component it has role='link' implicitly? No.
86
+ // Actually, an anchor without href is generic. But it might have button styles.
87
+ // Let's get it by text and assert it's an anchor without href.
88
+ const element = screen.getByText('Home').closest('a');
89
+ expect(element).toBeInTheDocument();
90
+
91
+ // It shouldn't have an href attribute because it's disabled.
92
+ expect(element).not.toHaveAttribute('href');
93
+
94
+ // It should have aria-disabled true
95
+ expect(element).toHaveAttribute('aria-disabled', 'true');
96
+
97
+ // It should have disabled class
98
+ expect(element).toHaveClass('c-btn--disabled');
94
99
  });
95
100
 
96
101
  it('forwards ref', () => {
@@ -62,7 +62,7 @@ export const Button = React.memo(
62
62
  // If disabled, we still check href, but we might want to render as button or anchor with aria-disabled
63
63
  // The previous logic was Boolean(href && !isDisabled). This meant if disabled, it renders as <button>.
64
64
  // This is a safe fallback for disabled links.
65
- const shouldRenderAsLink = Boolean(href && !isDisabled);
65
+ const shouldRenderAsLink = Boolean(href);
66
66
 
67
67
  // Resolve icon element - support both icon (ReactNode) and iconName (string)
68
68
  const iconElement = iconName ? (
@@ -226,8 +226,8 @@ export const Button = React.memo(
226
226
  const linkProps = {
227
227
  ...buttonProps,
228
228
  ref: ref as any, // linkComponent usually forwards ref to anchor
229
- href,
230
- to: href,
229
+ href: isDisabled ? undefined : href,
230
+ to: isDisabled ? undefined : href,
231
231
  target,
232
232
  rel: target === '_blank' ? 'noopener noreferrer' : undefined,
233
233
  };
@@ -239,7 +239,7 @@ export const Button = React.memo(
239
239
  <a
240
240
  {...buttonProps}
241
241
  ref={ref as React.Ref<HTMLAnchorElement>}
242
- href={href}
242
+ href={isDisabled ? undefined : href}
243
243
  target={target}
244
244
  rel={target === '_blank' ? 'noopener noreferrer' : undefined}
245
245
  >
@@ -26,7 +26,7 @@ export const Card = React.memo(
26
26
  // Content
27
27
  header,
28
28
  image,
29
- imageAlt = '',
29
+ imageAlt = 'Card image',
30
30
  title,
31
31
  text,
32
32
  actions,