@shohojdhara/atomix 0.3.0 → 0.3.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 (144) hide show
  1. package/CHANGELOG.md +0 -1
  2. package/README.md +3 -5
  3. package/dist/atomix.css +753 -643
  4. package/dist/atomix.min.css +3 -5
  5. package/dist/index.d.ts +3075 -247
  6. package/dist/index.esm.js +20412 -16601
  7. package/dist/index.esm.js.map +1 -1
  8. package/dist/index.js +20379 -16605
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.min.js +1 -1
  11. package/dist/index.min.js.map +1 -1
  12. package/package.json +1 -11
  13. package/src/components/AtomixGlass/AtomixGlass.test.tsx +21 -32
  14. package/src/components/AtomixGlass/AtomixGlass.tsx +55 -42
  15. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +205 -57
  16. package/src/components/AtomixGlass/GlassFilter.tsx +22 -8
  17. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +221 -0
  18. package/src/components/AtomixGlass/atomixGLass.old.tsx +0 -3
  19. package/src/components/AtomixGlass/shader-utils.ts +8 -0
  20. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +319 -100
  21. package/src/components/AtomixGlass/stories/Examples.stories.tsx +601 -105
  22. package/src/components/AtomixGlass/stories/Modes.stories.tsx +30 -12
  23. package/src/components/AtomixGlass/stories/Playground.stories.tsx +173 -38
  24. package/src/components/AtomixGlass/stories/ShaderVariants.stories.tsx +18 -18
  25. package/src/components/AtomixGlass/stories/shared-components.tsx +27 -5
  26. package/src/components/Button/Button.tsx +62 -17
  27. package/src/components/Callout/Callout.test.tsx +8 -14
  28. package/src/components/Card/Card.tsx +103 -1
  29. package/src/components/Card/index.ts +3 -2
  30. package/src/components/Icon/index.ts +1 -1
  31. package/src/components/Modal/Modal.stories.tsx +29 -38
  32. package/src/components/Modal/Modal.tsx +4 -4
  33. package/src/components/Navigation/SideMenu/SideMenu.tsx +49 -41
  34. package/src/components/Navigation/SideMenu/SideMenuItem.tsx +63 -24
  35. package/src/components/Popover/Popover.tsx +1 -1
  36. package/src/components/VideoPlayer/VideoPlayer.stories.tsx +977 -400
  37. package/src/components/VideoPlayer/VideoPlayer.tsx +1 -6
  38. package/src/lib/composables/shared-mouse-tracker.ts +133 -0
  39. package/src/lib/composables/useAtomixGlass.ts +333 -145
  40. package/src/lib/index.ts +1 -4
  41. package/src/lib/theme/composeTheme.ts +375 -0
  42. package/src/lib/theme/config/index.ts +21 -0
  43. package/src/lib/theme/config/loader.ts +276 -0
  44. package/src/lib/theme/config/types.ts +98 -0
  45. package/src/lib/theme/config/validator.ts +326 -0
  46. package/src/lib/theme/constants.ts +183 -0
  47. package/src/lib/theme/core/ThemeCache.ts +283 -0
  48. package/src/lib/theme/core/ThemeEngine.test.ts +146 -0
  49. package/src/lib/theme/core/ThemeEngine.ts +657 -0
  50. package/src/lib/theme/core/ThemeRegistry.ts +284 -0
  51. package/src/lib/theme/core/ThemeValidator.ts +530 -0
  52. package/src/lib/theme/core/index.ts +24 -0
  53. package/src/lib/theme/createTheme.ts +521 -0
  54. package/src/lib/theme/devtools/CLI.ts +279 -0
  55. package/src/lib/theme/devtools/Inspector.tsx +594 -0
  56. package/src/lib/theme/devtools/Preview.tsx +392 -0
  57. package/src/lib/theme/devtools/index.ts +21 -0
  58. package/src/lib/theme/errors.test.ts +207 -0
  59. package/src/lib/theme/errors.ts +233 -0
  60. package/src/lib/theme/generateCSSVariables.ts +797 -0
  61. package/src/lib/theme/generators/CSSGenerator.ts +311 -0
  62. package/src/lib/theme/generators/ConfigGenerator.ts +287 -0
  63. package/src/lib/theme/generators/TypeGenerator.ts +228 -0
  64. package/src/lib/theme/generators/index.ts +21 -0
  65. package/src/lib/theme/i18n/index.ts +9 -0
  66. package/src/lib/theme/i18n/rtl.ts +325 -0
  67. package/src/lib/theme/index.ts +221 -10
  68. package/src/lib/theme/monitoring/ThemeAnalytics.ts +409 -0
  69. package/src/lib/theme/monitoring/index.ts +17 -0
  70. package/src/lib/theme/overrides/ComponentOverrides.ts +243 -0
  71. package/src/lib/theme/overrides/index.ts +15 -0
  72. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +233 -0
  73. package/src/lib/theme/runtime/ThemeManager.test.ts +176 -0
  74. package/src/lib/theme/runtime/ThemeManager.ts +442 -0
  75. package/src/lib/theme/runtime/ThemeProvider.tsx +318 -0
  76. package/src/lib/theme/runtime/index.ts +17 -0
  77. package/src/lib/theme/runtime/useTheme.ts +52 -0
  78. package/src/lib/theme/studio/ThemeStudio.tsx +312 -0
  79. package/src/lib/theme/studio/index.ts +8 -0
  80. package/src/lib/theme/themeUtils.ts +333 -0
  81. package/src/lib/theme/types.ts +340 -9
  82. package/src/lib/theme/utils.ts +23 -22
  83. package/src/lib/theme/whitelabel/WhiteLabelManager.ts +364 -0
  84. package/src/lib/theme/whitelabel/index.ts +13 -0
  85. package/src/lib/types/components.ts +148 -59
  86. package/src/styles/01-settings/_index.scss +2 -2
  87. package/src/styles/01-settings/_settings.badge.scss +3 -3
  88. package/src/styles/01-settings/_settings.border-radius.scss +1 -1
  89. package/src/styles/01-settings/_settings.callout.scss +1 -1
  90. package/src/styles/01-settings/_settings.card.scss +1 -1
  91. package/src/styles/01-settings/{_settings.maps.scss → _settings.design-tokens.scss} +163 -49
  92. package/src/styles/01-settings/_settings.input.scss +1 -1
  93. package/src/styles/01-settings/_settings.modal.scss +1 -1
  94. package/src/styles/01-settings/_settings.navbar.scss +1 -1
  95. package/src/styles/01-settings/_settings.spacing.scss +14 -13
  96. package/src/styles/01-settings/_settings.upload.scss +1 -1
  97. package/src/styles/03-generic/_generic.root.scss +131 -50
  98. package/src/styles/05-objects/_objects.block.scss +1 -1
  99. package/src/styles/06-components/_components.atomix-glass.scss +20 -22
  100. package/src/styles/06-components/_components.badge.scss +2 -2
  101. package/src/styles/06-components/_components.button.scss +1 -1
  102. package/src/styles/06-components/_components.callout.scss +1 -1
  103. package/src/styles/06-components/_components.card.scss +74 -2
  104. package/src/styles/06-components/_components.chart.scss +3 -3
  105. package/src/styles/06-components/_components.dropdown.scss +6 -0
  106. package/src/styles/06-components/_components.footer.scss +1 -1
  107. package/src/styles/06-components/_components.list-group.scss +1 -1
  108. package/src/styles/06-components/_components.list.scss +1 -1
  109. package/src/styles/06-components/_components.menu.scss +1 -1
  110. package/src/styles/06-components/_components.messages.scss +1 -1
  111. package/src/styles/06-components/_components.modal.scss +7 -2
  112. package/src/styles/06-components/_components.navbar.scss +1 -1
  113. package/src/styles/06-components/_components.popover.scss +10 -0
  114. package/src/styles/06-components/_components.product-review.scss +1 -1
  115. package/src/styles/06-components/_components.progress.scss +1 -1
  116. package/src/styles/06-components/_components.rating.scss +1 -1
  117. package/src/styles/06-components/_components.spinner.scss +1 -1
  118. package/src/styles/99-utilities/_utilities.background.scss +1 -1
  119. package/src/styles/99-utilities/_utilities.border.scss +28 -59
  120. package/src/styles/99-utilities/_utilities.gradient.scss +12 -0
  121. package/src/styles/99-utilities/_utilities.link.scss +1 -1
  122. package/src/styles/99-utilities/_utilities.position.scss +8 -15
  123. package/src/styles/99-utilities/_utilities.scss +2 -0
  124. package/src/styles/99-utilities/_utilities.spacing.scss +76 -121
  125. package/src/styles/99-utilities/_utilities.text.scss +31 -50
  126. package/dist/themes/applemix.css +0 -15411
  127. package/dist/themes/applemix.min.css +0 -72
  128. package/dist/themes/boomdevs.css +0 -15001
  129. package/dist/themes/boomdevs.min.css +0 -405
  130. package/dist/themes/esrar.css +0 -17195
  131. package/dist/themes/esrar.min.css +0 -189
  132. package/dist/themes/flashtrade.css +0 -16408
  133. package/dist/themes/flashtrade.min.css +0 -192
  134. package/dist/themes/mashroom.css +0 -29900
  135. package/dist/themes/mashroom.min.css +0 -403
  136. package/dist/themes/shaj-default.css +0 -16024
  137. package/dist/themes/shaj-default.min.css +0 -500
  138. package/src/lib/theme/ThemeManager.stories.tsx +0 -472
  139. package/src/lib/theme/ThemeManager.test.ts +0 -186
  140. package/src/lib/theme/ThemeManager.ts +0 -501
  141. package/src/lib/theme/ThemeProvider.tsx +0 -227
  142. package/src/lib/theme/useTheme.test.tsx +0 -66
  143. package/src/lib/theme/useTheme.ts +0 -80
  144. package/src/lib/theme/utils.test.ts +0 -140
@@ -150,20 +150,38 @@ export const ModeGallery: Story = {
150
150
  displacementScale={80}
151
151
  blurAmount={1}
152
152
  saturation={130}
153
- cornerRadius={20}
153
+ cornerRadius={24}
154
154
  elasticity={0.12}
155
- className="u-mb-4 d-inline-block"
155
+ style={{ marginBottom: '24px', display: 'inline-block' }}
156
156
  >
157
- Four Rendering Modes
157
+ <div
158
+ style={{
159
+ padding: '12px 24px',
160
+ display: 'inline-flex',
161
+ alignItems: 'center',
162
+ gap: '8px',
163
+ fontSize: '13px',
164
+ fontWeight: 700,
165
+ letterSpacing: '1px',
166
+ textTransform: 'uppercase',
167
+ color: 'rgba(255, 255, 255, 0.9)',
168
+ }}
169
+ >
170
+ <span>🎨</span>
171
+ <span>Four Rendering Modes</span>
172
+ </div>
158
173
  </AtomixGlass>
159
174
  <h1
160
175
  style={{
161
- margin: '0 0 16px 0',
162
- fontSize: '48px',
176
+ margin: '0 0 20px 0',
177
+ fontSize: '56px',
163
178
  fontWeight: 700,
164
- color: '#fff',
165
- letterSpacing: '-1px',
166
- textShadow: '0 4px 12px rgba(0,0,0,0.3)',
179
+ background: 'linear-gradient(135deg, #fff 0%, rgba(255,255,255,0.7) 100%)',
180
+ WebkitBackgroundClip: 'text',
181
+ WebkitTextFillColor: 'transparent',
182
+ backgroundClip: 'text',
183
+ letterSpacing: '-1.5px',
184
+ textShadow: '0 4px 12px rgba(0,0,0,0.1)',
167
185
  }}
168
186
  >
169
187
  AtomixGlass Modes
@@ -171,15 +189,15 @@ export const ModeGallery: Story = {
171
189
  <p
172
190
  style={{
173
191
  fontSize: '18px',
174
- color: 'rgba(255, 255, 255, 0.85)',
175
- maxWidth: '680px',
192
+ color: 'rgba(255, 255, 255, 0.9)',
193
+ maxWidth: '720px',
176
194
  margin: '0 auto',
177
- lineHeight: 1.6,
195
+ lineHeight: 1.7,
178
196
  textShadow: '0 2px 4px rgba(0,0,0,0.2)',
179
197
  }}
180
198
  >
181
199
  Choose from four distinct rendering modes, each optimized for different visual styles
182
- and performance requirements.
200
+ and performance requirements. Click any card to explore the mode in detail.
183
201
  </p>
184
202
  </div>
185
203
 
@@ -520,12 +520,50 @@ export const Playground: Story = {
520
520
  }}
521
521
  >
522
522
  <div className="u-mb-8">
523
- <h2 className="u-mb-2 u-text-white u-fw-bold" style={{ fontSize: '2rem' }}>
524
- Advanced Playground
525
- </h2>
526
- <p className="u-text-white u-opacity-70 u-fs-sm">
527
- Fine-tune every parameter with live preview
528
- </p>
523
+ <div
524
+ style={{
525
+ display: 'flex',
526
+ alignItems: 'center',
527
+ gap: '12px',
528
+ marginBottom: '16px',
529
+ }}
530
+ >
531
+ <div
532
+ style={{
533
+ width: '48px',
534
+ height: '48px',
535
+ borderRadius: '14px',
536
+ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
537
+ display: 'flex',
538
+ alignItems: 'center',
539
+ justifyContent: 'center',
540
+ fontSize: '24px',
541
+ boxShadow: '0 8px 24px rgba(102, 126, 234, 0.4)',
542
+ }}
543
+ >
544
+ 🎮
545
+ </div>
546
+ <div>
547
+ <h2
548
+ className="u-m-0 u-text-white u-fw-bold"
549
+ style={{
550
+ fontSize: '1.75rem',
551
+ background: 'linear-gradient(135deg, #fff 0%, rgba(255,255,255,0.8) 100%)',
552
+ WebkitBackgroundClip: 'text',
553
+ WebkitTextFillColor: 'transparent',
554
+ backgroundClip: 'text',
555
+ }}
556
+ >
557
+ Advanced Playground
558
+ </h2>
559
+ <p
560
+ className="u-m-0 u-text-white u-opacity-80"
561
+ style={{ fontSize: '13px', marginTop: '4px' }}
562
+ >
563
+ Fine-tune every parameter with live preview
564
+ </p>
565
+ </div>
566
+ </div>
529
567
  </div>
530
568
 
531
569
  {/* Performance Indicator */}
@@ -574,8 +612,11 @@ export const Playground: Story = {
574
612
 
575
613
  {/* Quick Presets */}
576
614
  <div className="u-mb-6">
577
- <label className="u-d-block u-mb-3 u-text-white u-fw-semibold">
578
- Quick Presets
615
+ <label
616
+ className="u-d-block u-mb-3 u-text-white u-fw-semibold"
617
+ style={{ fontSize: '14px', letterSpacing: '0.5px' }}
618
+ >
619
+ ⚡ Quick Presets
579
620
  </label>
580
621
  <div
581
622
  style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '0.75rem' }}
@@ -585,28 +626,48 @@ export const Playground: Story = {
585
626
  key={key}
586
627
  onClick={() => applyPreset(key as keyof typeof presets)}
587
628
  style={{
588
- padding: '12px',
589
- background: 'rgba(255,255,255,0.1)',
590
- border: '1px solid rgba(255,255,255,0.2)',
591
- borderRadius: '12px',
629
+ padding: '16px 12px',
630
+ background: 'rgba(255,255,255,0.08)',
631
+ border: '2px solid rgba(255,255,255,0.15)',
632
+ borderRadius: '16px',
592
633
  color: 'white',
593
634
  cursor: 'pointer',
594
- transition: 'all 0.2s',
635
+ transition: 'all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1)',
595
636
  textAlign: 'center',
637
+ position: 'relative',
638
+ overflow: 'hidden',
596
639
  }}
597
640
  onMouseEnter={e => {
598
641
  e.currentTarget.style.background = 'rgba(255,255,255,0.15)';
599
642
  e.currentTarget.style.borderColor = 'rgba(255,255,255,0.3)';
643
+ e.currentTarget.style.transform = 'translateY(-2px) scale(1.02)';
644
+ e.currentTarget.style.boxShadow = '0 8px 24px rgba(0,0,0,0.2)';
600
645
  }}
601
646
  onMouseLeave={e => {
602
- e.currentTarget.style.background = 'rgba(255,255,255,0.1)';
603
- e.currentTarget.style.borderColor = 'rgba(255,255,255,0.2)';
647
+ e.currentTarget.style.background = 'rgba(255,255,255,0.08)';
648
+ e.currentTarget.style.borderColor = 'rgba(255,255,255,0.15)';
649
+ e.currentTarget.style.transform = 'translateY(0) scale(1)';
650
+ e.currentTarget.style.boxShadow = 'none';
604
651
  }}
605
652
  >
606
- <div style={{ fontSize: '1.5rem', marginBottom: '4px' }}>
653
+ <div
654
+ style={{
655
+ fontSize: '2rem',
656
+ marginBottom: '8px',
657
+ filter: 'drop-shadow(0 4px 8px rgba(0,0,0,0.2))',
658
+ }}
659
+ >
607
660
  {preset.icon}
608
661
  </div>
609
- <div style={{ fontSize: '0.875rem', fontWeight: 600 }}>{preset.name}</div>
662
+ <div
663
+ style={{
664
+ fontSize: '0.875rem',
665
+ fontWeight: 700,
666
+ letterSpacing: '0.3px',
667
+ }}
668
+ >
669
+ {preset.name}
670
+ </div>
610
671
  </button>
611
672
  ))}
612
673
  </div>
@@ -838,25 +899,62 @@ export const Playground: Story = {
838
899
  cornerRadius={16}
839
900
  saturation={120}
840
901
  >
841
- <div style={{ padding: '2rem' }}>
842
- <div className="u-d-flex u-justify-content-between u-align-items-center u-mb-4">
843
- <h3 className="u-text-white u-fw-semibold" style={{ fontSize: '1.5rem' }}>
844
- Generated Code
845
- </h3>
846
- <Button variant="primary" size="sm" onClick={copyCode}>
847
- {copiedCode ? '✓ Copied' : 'Copy'}
902
+ <div style={{ padding: '2.5rem' }}>
903
+ <div
904
+ className="u-d-flex u-justify-content-between u-align-items-center u-mb-4"
905
+ style={{ marginBottom: '24px' }}
906
+ >
907
+ <div>
908
+ <h3
909
+ className="u-m-0 u-fw-bold"
910
+ style={{
911
+ fontSize: '1.75rem',
912
+ background: 'linear-gradient(135deg, #fff 0%, rgba(255,255,255,0.8) 100%)',
913
+ WebkitBackgroundClip: 'text',
914
+ WebkitTextFillColor: 'transparent',
915
+ backgroundClip: 'text',
916
+ marginBottom: '8px',
917
+ }}
918
+ >
919
+ 💻 Generated Code
920
+ </h3>
921
+ <p
922
+ className="u-m-0"
923
+ style={{
924
+ fontSize: '13px',
925
+ color: 'rgba(255, 255, 255, 0.7)',
926
+ }}
927
+ >
928
+ Copy this code to use in your project
929
+ </p>
930
+ </div>
931
+ <Button
932
+ variant="primary"
933
+ size="md"
934
+ onClick={copyCode}
935
+ style={{
936
+ minWidth: '120px',
937
+ boxShadow: copiedCode
938
+ ? '0 4px 16px rgba(122, 255, 215, 0.4)'
939
+ : 'none',
940
+ }}
941
+ >
942
+ {copiedCode ? '✓ Copied!' : '📋 Copy Code'}
848
943
  </Button>
849
944
  </div>
850
945
  <pre
851
946
  style={{
852
- background: 'rgba(0,0,0,0.5)',
853
- padding: '1.5rem',
854
- borderRadius: '8px',
947
+ background: 'rgba(0,0,0,0.6)',
948
+ padding: '1.75rem',
949
+ borderRadius: '12px',
855
950
  overflow: 'auto',
856
951
  maxHeight: '500px',
857
952
  color: '#7AFFD7',
858
953
  fontSize: '0.875rem',
859
- lineHeight: 1.6,
954
+ lineHeight: 1.7,
955
+ border: '1px solid rgba(122, 255, 215, 0.2)',
956
+ fontFamily: 'Monaco, "Courier New", monospace',
957
+ boxShadow: 'inset 0 2px 8px rgba(0,0,0,0.3)',
860
958
  }}
861
959
  >
862
960
  <code>{generateCode()}</code>
@@ -882,28 +980,65 @@ export const Playground: Story = {
882
980
  enableBorderEffect={settings.enableBorderEffect}
883
981
  style={{ width: '100%' }}
884
982
  >
885
- <div style={{ padding: '2rem', textAlign: 'center' }}>
983
+ <div style={{ padding: '2.5rem', textAlign: 'center' }}>
886
984
  <div
887
985
  style={{
888
986
  display: 'inline-flex',
889
987
  alignItems: 'center',
890
- padding: '8px 20px',
891
- borderRadius: '24px',
892
- background: 'rgba(122, 255, 215, 0.2)',
988
+ gap: '8px',
989
+ padding: '10px 24px',
990
+ borderRadius: '28px',
991
+ background: 'linear-gradient(135deg, rgba(122, 255, 215, 0.25) 0%, rgba(102, 126, 234, 0.25) 100%)',
992
+ border: '1px solid rgba(122, 255, 215, 0.3)',
893
993
  color: '#7AFFD7',
894
994
  fontSize: '0.875rem',
895
- fontWeight: 600,
896
- marginBottom: '1.5rem',
995
+ fontWeight: 700,
996
+ letterSpacing: '0.5px',
997
+ marginBottom: '2rem',
998
+ boxShadow: '0 4px 16px rgba(122, 255, 215, 0.2)',
897
999
  }}
898
1000
  >
899
- LIVE PREVIEW
1001
+ <span style={{ fontSize: '18px' }}>✨</span>
1002
+ <span>LIVE PREVIEW</span>
900
1003
  </div>
901
- <h2 className="u-mb-4 u-text-white u-fw-bold" style={{ fontSize: '2.5rem' }}>
1004
+ <div
1005
+ style={{
1006
+ width: '96px',
1007
+ height: '96px',
1008
+ margin: '0 auto 24px',
1009
+ borderRadius: '24px',
1010
+ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
1011
+ display: 'flex',
1012
+ alignItems: 'center',
1013
+ justifyContent: 'center',
1014
+ fontSize: '48px',
1015
+ boxShadow: '0 12px 32px rgba(102, 126, 234, 0.4)',
1016
+ }}
1017
+ >
1018
+
1019
+ </div>
1020
+ <h2
1021
+ className="u-mb-4 u-fw-bold"
1022
+ style={{
1023
+ fontSize: '2.75rem',
1024
+ background: 'linear-gradient(135deg, #fff 0%, rgba(255,255,255,0.8) 100%)',
1025
+ WebkitBackgroundClip: 'text',
1026
+ WebkitTextFillColor: 'transparent',
1027
+ backgroundClip: 'text',
1028
+ letterSpacing: '-1px',
1029
+ }}
1030
+ >
902
1031
  AtomixGlass
903
1032
  </h2>
904
1033
  <p
905
- className="u-mb-6 u-opacity-90"
906
- style={{ fontSize: '1.125rem', lineHeight: 1.6 }}
1034
+ className="u-mb-6"
1035
+ style={{
1036
+ fontSize: '1.125rem',
1037
+ lineHeight: 1.7,
1038
+ color: 'rgba(255, 255, 255, 0.9)',
1039
+ maxWidth: '600px',
1040
+ margin: '0 auto 2rem',
1041
+ }}
907
1042
  >
908
1043
  Adjust the controls on the left to see real-time changes. Each parameter
909
1044
  affects the visual appearance and performance characteristics of the glass
@@ -71,7 +71,7 @@ export const LiquidGlass: Story = {
71
71
  <h2
72
72
  style={{
73
73
  margin: '0 0 16px 0',
74
- fontSize: '36px',
74
+ fontSize: '38px',
75
75
  fontWeight: 700,
76
76
  background: 'linear-gradient(135deg, #fff 0%, rgba(255,255,255,0.8) 100%)',
77
77
  WebkitBackgroundClip: 'text',
@@ -84,14 +84,14 @@ export const LiquidGlass: Story = {
84
84
  </h2>
85
85
  <p
86
86
  style={{
87
- margin: '0 0 28px 0',
88
- fontSize: '17px',
89
- lineHeight: 1.7,
90
- color: 'rgba(255, 255, 255, 0.85)',
87
+ margin: '0 0 32px 0',
88
+ fontSize: '18px',
89
+ lineHeight: 1.8,
90
+ color: 'rgba(255, 255, 255, 0.9)',
91
91
  }}
92
92
  >
93
93
  Experience fluid, time-based animations with multi-layered organic distortion and
94
- chromatic aberration effects that create living glass.
94
+ chromatic aberration effects that create living, breathing glass.
95
95
  </p>
96
96
  <div
97
97
  style={{
@@ -192,7 +192,7 @@ export const AppleFluid: Story = {
192
192
  <h2
193
193
  style={{
194
194
  margin: '0 0 16px 0',
195
- fontSize: '36px',
195
+ fontSize: '38px',
196
196
  fontWeight: 700,
197
197
  background: 'linear-gradient(135deg, #fff 0%, rgba(255,255,255,0.8) 100%)',
198
198
  WebkitBackgroundClip: 'text',
@@ -205,14 +205,14 @@ export const AppleFluid: Story = {
205
205
  </h2>
206
206
  <p
207
207
  style={{
208
- margin: '0 0 28px 0',
209
- fontSize: '17px',
210
- lineHeight: 1.7,
211
- color: 'rgba(255, 255, 255, 0.85)',
208
+ margin: '0 0 32px 0',
209
+ fontSize: '18px',
210
+ lineHeight: 1.8,
211
+ color: 'rgba(255, 255, 255, 0.9)',
212
212
  }}
213
213
  >
214
214
  Apple-inspired fluid dynamics with vortex effects and high-quality 5-octave noise. Mouse
215
- interactions create mesmerizing flow patterns.
215
+ interactions create mesmerizing, organic flow patterns.
216
216
  </p>
217
217
  <div
218
218
  style={{
@@ -313,7 +313,7 @@ export const PremiumGlass: Story = {
313
313
  <h2
314
314
  style={{
315
315
  margin: '0 0 16px 0',
316
- fontSize: '36px',
316
+ fontSize: '38px',
317
317
  fontWeight: 700,
318
318
  background: 'linear-gradient(135deg, #fff 0%, rgba(255,255,255,0.8) 100%)',
319
319
  WebkitBackgroundClip: 'text',
@@ -326,14 +326,14 @@ export const PremiumGlass: Story = {
326
326
  </h2>
327
327
  <p
328
328
  style={{
329
- margin: '0 0 28px 0',
330
- fontSize: '17px',
331
- lineHeight: 1.7,
332
- color: 'rgba(255, 255, 255, 0.85)',
329
+ margin: '0 0 32px 0',
330
+ fontSize: '18px',
331
+ lineHeight: 1.8,
332
+ color: 'rgba(255, 255, 255, 0.9)',
333
333
  }}
334
334
  >
335
335
  Advanced refraction with multi-layer depth effects and edge-aware rendering. The optimal
336
- balance of quality and performance.
336
+ balance of quality and performance for production applications.
337
337
  </p>
338
338
  <div
339
339
  style={{
@@ -175,9 +175,7 @@ export const BackgroundWrapper = ({
175
175
  height: height,
176
176
  width: width,
177
177
  backgroundColor: !bgImage ? '#1a1a2e' : undefined, // Fallback color if no image
178
- background: bgImage
179
- ? `url(${bgImage}) ${finalOverlayOpacity && ',' + finalOverlayColor}`
180
- : undefined,
178
+ background: bgImage ? `url(${bgImage})` : undefined,
181
179
  backgroundSize: 'cover',
182
180
  backgroundPosition: 'center',
183
181
  backgroundAttachment: 'fixed',
@@ -189,8 +187,32 @@ export const BackgroundWrapper = ({
189
187
  ...style,
190
188
  }}
191
189
  >
192
-
193
- {children}
190
+ {/* Overlay */}
191
+ {(finalOverlayOpacity > 0 || overlay) && (
192
+ <div
193
+ style={{
194
+ position: 'absolute',
195
+ inset: 0,
196
+ backgroundColor: finalOverlayColor,
197
+ opacity: finalOverlayOpacity,
198
+ borderRadius: borderRadius,
199
+ pointerEvents: 'none',
200
+ }}
201
+ />
202
+ )}
203
+ <div
204
+ style={{
205
+ position: 'relative',
206
+ width: '100%',
207
+ height: '100%',
208
+ display: 'flex',
209
+ alignItems: 'center',
210
+ justifyContent: 'center',
211
+ color: 'white',
212
+ }}
213
+ >
214
+ {children}
215
+ </div>
194
216
  </div>
195
217
  );
196
218
  };
@@ -3,6 +3,7 @@ import { useButton } from '../../lib/composables/useButton';
3
3
  import { ButtonProps } from '../../lib/types/components';
4
4
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
5
5
  import { Spinner } from '../Spinner/Spinner';
6
+ import { Icon, type PhosphorIconsType } from '../Icon/Icon';
6
7
  import { BUTTON } from '../../lib/constants/components';
7
8
 
8
9
  export type ButtonAsProp = {
@@ -13,7 +14,7 @@ export type ButtonAsProp = {
13
14
  };
14
15
 
15
16
  export const Button = React.memo(
16
- forwardRef<HTMLButtonElement, ButtonProps & ButtonAsProp>(
17
+ forwardRef<HTMLButtonElement | HTMLAnchorElement, ButtonProps & ButtonAsProp>(
17
18
  (
18
19
  {
19
20
  label,
@@ -25,6 +26,8 @@ export const Button = React.memo(
25
26
  loading = false,
26
27
  loadingText,
27
28
  icon,
29
+ iconName,
30
+ iconSize = 'sm',
28
31
  iconPosition = 'start',
29
32
  iconOnly = false,
30
33
  rounded = false,
@@ -35,6 +38,8 @@ export const Button = React.memo(
35
38
  type = 'button',
36
39
  className = '',
37
40
  as: Component = 'button',
41
+ href,
42
+ target,
38
43
  glass,
39
44
  onHover,
40
45
  onFocus,
@@ -51,6 +56,18 @@ export const Button = React.memo(
51
56
  ) => {
52
57
  const isDisabled = disabled || loading;
53
58
 
59
+ // Determine if we should render as a link
60
+ const shouldRenderAsLink = Boolean(href && !isDisabled);
61
+
62
+ // Resolve icon element - support both icon (ReactNode) and iconName (string)
63
+ const iconElement = useMemo(() => {
64
+ if (loading) return null;
65
+ if (iconName) {
66
+ return <Icon name={iconName as PhosphorIconsType} size={iconSize} />;
67
+ }
68
+ return icon;
69
+ }, [icon, iconName, iconSize, loading]);
70
+
54
71
  const { generateButtonClass, handleClick } = useButton({
55
72
  variant,
56
73
  size,
@@ -85,21 +102,21 @@ export const Button = React.memo(
85
102
 
86
103
  // Handle click with loading check
87
104
  const handleClickEvent = useCallback(
88
- (event: React.MouseEvent<HTMLButtonElement>) => {
105
+ (event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {
89
106
  if (isDisabled) {
90
107
  event.preventDefault();
91
108
  return;
92
109
  }
93
- onClick?.(event);
110
+ onClick?.(event as React.MouseEvent<HTMLButtonElement>);
94
111
  },
95
112
  [isDisabled, onClick]
96
113
  );
97
114
 
98
115
  // Handle hover
99
116
  const handleMouseEnter = useCallback(
100
- (event: React.MouseEvent<HTMLButtonElement>) => {
117
+ (event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {
101
118
  if (!isDisabled) {
102
- onHover?.(event);
119
+ onHover?.(event as React.MouseEvent<HTMLButtonElement>);
103
120
  }
104
121
  },
105
122
  [isDisabled, onHover]
@@ -107,9 +124,9 @@ export const Button = React.memo(
107
124
 
108
125
  // Handle focus
109
126
  const handleFocusEvent = useCallback(
110
- (event: React.FocusEvent<HTMLButtonElement>) => {
127
+ (event: React.FocusEvent<HTMLButtonElement | HTMLAnchorElement>) => {
111
128
  if (!isDisabled) {
112
- onFocus?.(event);
129
+ onFocus?.(event as React.FocusEvent<HTMLButtonElement>);
113
130
  }
114
131
  },
115
132
  [isDisabled, onFocus]
@@ -117,9 +134,9 @@ export const Button = React.memo(
117
134
 
118
135
  // Handle blur
119
136
  const handleBlurEvent = useCallback(
120
- (event: React.FocusEvent<HTMLButtonElement>) => {
137
+ (event: React.FocusEvent<HTMLButtonElement | HTMLAnchorElement>) => {
121
138
  if (!isDisabled) {
122
- onBlur?.(event);
139
+ onBlur?.(event as React.FocusEvent<HTMLButtonElement>);
123
140
  }
124
141
  },
125
142
  [isDisabled, onBlur]
@@ -141,9 +158,9 @@ export const Button = React.memo(
141
158
 
142
159
  // Button content with icon positioning
143
160
  const buttonContent = useMemo(() => {
144
- const iconElement = icon && !loading && (
161
+ const iconSpan = iconElement && (
145
162
  <span className={BUTTON.ICON_CLASS} aria-hidden="true">
146
- {icon}
163
+ {iconElement}
147
164
  </span>
148
165
  );
149
166
 
@@ -169,7 +186,7 @@ export const Button = React.memo(
169
186
  <>
170
187
  {labelElement}
171
188
  {spinnerElement}
172
- {iconElement}
189
+ {iconSpan}
173
190
  </>
174
191
  );
175
192
  }
@@ -177,23 +194,23 @@ export const Button = React.memo(
177
194
  return (
178
195
  <>
179
196
  {spinnerElement}
180
- {iconElement}
197
+ {iconSpan}
181
198
  {labelElement}
182
199
  </>
183
200
  );
184
- }, [icon, iconPosition, iconOnly, buttonText, loading, spinnerSize, variant]);
201
+ }, [iconElement, iconPosition, iconOnly, buttonText, loading, spinnerSize, variant]);
185
202
 
186
203
  // Button props
187
204
  const buttonProps = useMemo(
188
205
  () => ({
189
206
  ref,
190
207
  className: buttonClass,
191
- type: Component === 'button' ? type : undefined,
208
+ type: Component === 'button' && !shouldRenderAsLink ? type : undefined,
192
209
  onClick: handleClickEvent,
193
210
  onMouseEnter: onHover ? handleMouseEnter : undefined,
194
211
  onFocus: onFocus ? handleFocusEvent : undefined,
195
212
  onBlur: onBlur ? handleBlurEvent : undefined,
196
- disabled: isDisabled && Component === 'button',
213
+ disabled: isDisabled && Component === 'button' && !shouldRenderAsLink,
197
214
  'aria-disabled': isDisabled,
198
215
  'aria-busy': loading,
199
216
  'aria-label': ariaLabel || (iconOnly ? label || children : undefined),
@@ -228,8 +245,36 @@ export const Button = React.memo(
228
245
  ]
229
246
  );
230
247
 
248
+ // Render as anchor if href is provided
249
+ if (shouldRenderAsLink) {
250
+ const { ref: _, ...buttonPropsWithoutRef } = buttonProps;
251
+ const anchorButtonProps = {
252
+ ...buttonPropsWithoutRef,
253
+ type: undefined,
254
+ disabled: undefined,
255
+ };
256
+ const anchorElement = (
257
+ <a {...anchorButtonProps} ref={ref as React.Ref<HTMLAnchorElement>} href={href} target={target} rel={target === '_blank' ? 'noopener noreferrer' : undefined}>
258
+ {buttonContent}
259
+ </a>
260
+ );
261
+
262
+ if (glass) {
263
+ const defaultGlassProps = {
264
+ displacementScale: 20,
265
+ blurAmount: 0,
266
+ saturation: 200,
267
+ elasticity: 0,
268
+ };
269
+ const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
270
+ return <AtomixGlass {...glassProps}>{anchorElement}</AtomixGlass>;
271
+ }
272
+
273
+ return anchorElement;
274
+ }
275
+
276
+ // Default button rendering
231
277
  if (glass) {
232
- // Default glass settings for buttons
233
278
  const defaultGlassProps = {
234
279
  displacementScale: 20,
235
280
  blurAmount: 0,