@shohojdhara/atomix 0.3.5 → 0.3.6

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 (173) hide show
  1. package/README.md +101 -199
  2. package/atomix.config.ts +241 -0
  3. package/dist/atomix.css +260 -179
  4. package/dist/atomix.css.map +1 -1
  5. package/dist/atomix.min.css +250 -179
  6. package/dist/atomix.min.css.map +1 -1
  7. package/dist/charts.js +61 -66
  8. package/dist/charts.js.map +1 -1
  9. package/dist/core.js +47 -31
  10. package/dist/core.js.map +1 -1
  11. package/dist/forms.js +47 -31
  12. package/dist/forms.js.map +1 -1
  13. package/dist/heavy.js +47 -31
  14. package/dist/heavy.js.map +1 -1
  15. package/dist/index.d.ts +1841 -1633
  16. package/dist/index.esm.js +4975 -4113
  17. package/dist/index.esm.js.map +1 -1
  18. package/dist/index.js +5151 -4290
  19. package/dist/index.js.map +1 -1
  20. package/dist/index.min.js +1 -1
  21. package/dist/index.min.js.map +1 -1
  22. package/dist/theme.d.ts +1572 -1442
  23. package/dist/theme.js +4816 -4080
  24. package/dist/theme.js.map +1 -1
  25. package/package.json +6 -20
  26. package/src/components/Accordion/Accordion.stories.tsx +50 -17
  27. package/src/components/AtomixGlass/AtomixGlass.tsx +65 -31
  28. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +11 -4
  29. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +1 -32
  30. package/src/components/AtomixGlass/stories/Examples.stories.tsx +2 -2
  31. package/src/components/AtomixGlass/stories/shared-components.tsx +0 -31
  32. package/src/components/Avatar/Avatar.stories.tsx +7 -0
  33. package/src/components/Badge/Badge.stories.tsx +91 -13
  34. package/src/components/Block/Block.stories.tsx +7 -23
  35. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +7 -0
  36. package/src/components/Button/Button.stories.tsx +141 -22
  37. package/src/components/Button/ButtonGroup.stories.tsx +315 -0
  38. package/src/components/Button/ButtonGroup.tsx +67 -0
  39. package/src/components/Button/index.ts +2 -0
  40. package/src/components/Callout/Callout.stories.tsx +8 -6
  41. package/src/components/Card/Card.stories.tsx +82 -28
  42. package/src/components/Chart/AnimatedChart.tsx +0 -1
  43. package/src/components/Chart/AreaChart.tsx +0 -1
  44. package/src/components/Chart/BarChart.tsx +0 -1
  45. package/src/components/Chart/BubbleChart.tsx +0 -1
  46. package/src/components/Chart/CandlestickChart.tsx +0 -1
  47. package/src/components/Chart/Chart.stories.tsx +5 -7
  48. package/src/components/Chart/Chart.tsx +0 -16
  49. package/src/components/Chart/ChartRenderer.tsx +1 -1
  50. package/src/components/Chart/DonutChart.tsx +0 -1
  51. package/src/components/Chart/FunnelChart.tsx +0 -1
  52. package/src/components/Chart/GaugeChart.tsx +0 -1
  53. package/src/components/Chart/HeatmapChart.tsx +0 -1
  54. package/src/components/Chart/LineChart.tsx +0 -1
  55. package/src/components/Chart/MultiAxisChart.tsx +0 -1
  56. package/src/components/Chart/PieChart.tsx +0 -1
  57. package/src/components/Chart/RadarChart.tsx +0 -1
  58. package/src/components/Chart/ScatterChart.tsx +0 -1
  59. package/src/components/Chart/WaterfallChart.tsx +0 -1
  60. package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +7 -0
  61. package/src/components/DataTable/DataTable.stories.tsx +23 -16
  62. package/src/components/DatePicker/DatePicker.stories.tsx +27 -19
  63. package/src/components/Dropdown/Dropdown.stories.tsx +11 -19
  64. package/src/components/EdgePanel/EdgePanel.stories.tsx +1 -0
  65. package/src/components/Footer/Footer.stories.tsx +8 -6
  66. package/src/components/Footer/FooterLink.tsx +9 -2
  67. package/src/components/Form/Checkbox.stories.tsx +7 -0
  68. package/src/components/Form/Form.stories.tsx +7 -0
  69. package/src/components/Form/FormGroup.stories.tsx +9 -1
  70. package/src/components/Form/Input.stories.tsx +69 -16
  71. package/src/components/Form/Radio.stories.tsx +9 -1
  72. package/src/components/Form/Select.stories.tsx +9 -1
  73. package/src/components/Form/Textarea.stories.tsx +10 -2
  74. package/src/components/Hero/Hero.stories.tsx +7 -0
  75. package/src/components/List/List.stories.tsx +7 -0
  76. package/src/components/Messages/Messages.stories.tsx +8 -7
  77. package/src/components/Modal/Modal.stories.tsx +17 -6
  78. package/src/components/Navigation/Menu/Menu.stories.tsx +7 -0
  79. package/src/components/Navigation/Nav/Nav.stories.tsx +7 -0
  80. package/src/components/Navigation/Navbar/Navbar.stories.tsx +1 -0
  81. package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +1 -1
  82. package/src/components/Pagination/Pagination.stories.tsx +188 -111
  83. package/src/components/Pagination/Pagination.tsx +83 -3
  84. package/src/components/PhotoViewer/PhotoViewer.stories.tsx +10 -5
  85. package/src/components/Popover/Popover.stories.tsx +191 -115
  86. package/src/components/ProductReview/ProductReview.stories.tsx +80 -58
  87. package/src/components/Progress/Progress.stories.tsx +79 -49
  88. package/src/components/Rating/Rating.stories.tsx +109 -84
  89. package/src/components/River/River.stories.tsx +194 -114
  90. package/src/components/SectionIntro/SectionIntro.stories.tsx +19 -9
  91. package/src/components/Slider/Slider.stories.tsx +7 -0
  92. package/src/components/Spinner/Spinner.stories.tsx +15 -11
  93. package/src/components/Steps/Steps.stories.tsx +132 -98
  94. package/src/components/Tabs/Tabs.stories.tsx +163 -112
  95. package/src/components/Testimonial/Testimonial.stories.tsx +114 -68
  96. package/src/components/Todo/Todo.stories.tsx +38 -12
  97. package/src/components/Toggle/Toggle.stories.tsx +61 -28
  98. package/src/components/Tooltip/Tooltip.stories.tsx +318 -200
  99. package/src/components/Upload/Upload.stories.tsx +122 -84
  100. package/src/components/VideoPlayer/VideoPlayer.stories.tsx +7 -24
  101. package/src/components/index.ts +1 -0
  102. package/src/lib/composables/useAtomixGlass.ts +2 -3
  103. package/src/lib/composables/useNavbar.ts +0 -10
  104. package/src/lib/config/loader.ts +2 -1
  105. package/src/lib/constants/components.ts +10 -0
  106. package/src/lib/hooks/useComponentCustomization.ts +1 -1
  107. package/src/lib/theme/README.md +174 -0
  108. package/src/lib/theme/adapters/index.ts +31 -0
  109. package/src/lib/theme/adapters/themeAdapter.ts +287 -0
  110. package/src/lib/theme/config/__tests__/configLoader.test.ts +207 -0
  111. package/src/lib/theme/config/configLoader.ts +254 -0
  112. package/src/lib/theme/config/loader.ts +37 -48
  113. package/src/lib/theme/config/types.ts +2 -2
  114. package/src/lib/theme/config/validator.ts +15 -91
  115. package/src/lib/theme/{constants.ts → constants/constants.ts} +0 -18
  116. package/src/lib/theme/constants/index.ts +8 -0
  117. package/src/lib/theme/core/ThemeRegistry.ts +19 -6
  118. package/src/lib/theme/core/__tests__/createTheme.test.ts +132 -0
  119. package/src/lib/theme/core/composeTheme.ts +155 -0
  120. package/src/lib/theme/core/createTheme.ts +94 -0
  121. package/src/lib/theme/{createTheme.ts → core/createThemeObject.ts} +10 -6
  122. package/src/lib/theme/core/index.ts +5 -19
  123. package/src/lib/theme/devtools/Comparator.tsx +346 -22
  124. package/src/lib/theme/devtools/IMPROVEMENTS.md +139 -38
  125. package/src/lib/theme/devtools/Inspector.tsx +335 -51
  126. package/src/lib/theme/devtools/LiveEditor.tsx +478 -107
  127. package/src/lib/theme/devtools/Preview.tsx +471 -221
  128. package/src/lib/theme/{core → devtools}/ThemeValidator.ts +1 -1
  129. package/src/lib/theme/devtools/index.ts +14 -4
  130. package/src/lib/theme/devtools/useHistory.ts +130 -0
  131. package/src/lib/theme/errors/index.ts +12 -0
  132. package/src/lib/theme/generators/cssFile.ts +79 -0
  133. package/src/lib/theme/generators/generateCSS.ts +89 -0
  134. package/src/lib/theme/{generateCSSVariables.ts → generators/generateCSSVariables.ts} +3 -13
  135. package/src/lib/theme/generators/index.ts +19 -0
  136. package/src/lib/theme/i18n/rtl.ts +5 -6
  137. package/src/lib/theme/index.ts +120 -15
  138. package/src/lib/theme/runtime/ThemeApplicator.ts +52 -111
  139. package/src/lib/theme/{ThemeContext.tsx → runtime/ThemeContext.tsx} +1 -1
  140. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +1 -1
  141. package/src/lib/theme/runtime/ThemeProvider.tsx +456 -179
  142. package/src/lib/theme/runtime/index.ts +1 -2
  143. package/src/lib/theme/runtime/useTheme.ts +1 -2
  144. package/src/lib/theme/test/testTheme.ts +385 -0
  145. package/src/lib/theme/tokens/index.ts +12 -0
  146. package/src/lib/theme/tokens/tokens.ts +721 -0
  147. package/src/lib/theme/types.ts +6 -42
  148. package/src/lib/theme/{utils.ts → utils/domUtils.ts} +2 -2
  149. package/src/lib/theme/utils/index.ts +11 -0
  150. package/src/lib/theme/utils/injectCSS.ts +90 -0
  151. package/src/lib/theme/utils/themeHelpers.ts +78 -0
  152. package/src/lib/theme/{themeUtils.ts → utils/themeUtils.ts} +1 -1
  153. package/src/lib/theme-tools.ts +7 -8
  154. package/src/lib/types/components.ts +40 -130
  155. package/src/lib/utils/componentUtils.ts +1 -1
  156. package/src/styles/01-settings/_settings.design-tokens.scss +4 -1
  157. package/src/styles/02-tools/_tools.button.scss +66 -79
  158. package/src/styles/06-components/_components.atomix-glass.scss +13 -3
  159. package/src/styles/06-components/_components.pagination.scss +88 -0
  160. package/scripts/sync-theme-config.js +0 -309
  161. package/src/lib/theme/composeTheme.ts +0 -370
  162. package/src/lib/theme/core/ThemeCache.ts +0 -283
  163. package/src/lib/theme/core/ThemeEngine.test.ts +0 -146
  164. package/src/lib/theme/core/ThemeEngine.ts +0 -665
  165. package/src/lib/theme/createThemeFromConfig.ts +0 -132
  166. package/src/lib/theme/devtools/CLI.ts +0 -364
  167. package/src/lib/theme/runtime/ThemeManager.test.ts +0 -192
  168. package/src/lib/theme/runtime/ThemeManager.ts +0 -446
  169. package/src/styles/03-generic/_generated-root.css +0 -26
  170. package/src/themes/README.md +0 -442
  171. package/src/themes/themes.config.js +0 -68
  172. /package/src/lib/theme/{cssVariableMapper.ts → adapters/cssVariableMapper.ts} +0 -0
  173. /package/src/lib/theme/{errors.ts → errors/errors.ts} +0 -0
@@ -1,7 +1,9 @@
1
1
  @use 'sass:color';
2
+ @use 'sass:map';
2
3
  @use '../01-settings/settings.config' as config;
3
4
  @use '../01-settings/settings.button' as button;
4
5
  @use '../01-settings/settings.colors' as colors;
6
+ @use '../01-settings/settings.design-tokens' as tokens;
5
7
  @use '../01-settings/settings.border-radius' as *;
6
8
  @use 'tools.to-rgb' as *;
7
9
  @use 'tools.border-radius' as *;
@@ -16,99 +18,84 @@
16
18
  $active-background: null,
17
19
  $active-border: null
18
20
  ) {
19
- $btn-text-color: colors.$white;
20
- $btn-text-hover-color: colors.$white;
21
+ $btn-text-color: var(--#{config.$prefix}white, #{colors.$white});
22
+ $btn-text-hover-color: var(--#{config.$prefix}white, #{colors.$white});
21
23
 
22
24
  @if ($color == 'light') {
23
- $btn-text-color: var(--#{config.$prefix}dark-text-emphasis);
24
- $btn-text-hover-color: var(--#{config.$prefix}dark-text-emphasis);
25
- }
26
-
27
- @if ($color == 'secondary') {
28
- $btn-text-color: var(--#{config.$prefix}dark-text-emphasis);
29
- $btn-text-hover-color: var(--#{config.$prefix}dark-text-emphasis);
25
+ $btn-text-color: var(--#{config.$prefix}dark-text-emphasis, #{colors.$dark-text});
26
+ $btn-text-hover-color: var(--#{config.$prefix}dark-text-emphasis, #{colors.$dark-text});
27
+ } @else if ($color == 'secondary') {
28
+ $btn-text-color: var(--#{config.$prefix}dark-text-emphasis, #{colors.$dark-text});
29
+ $btn-text-hover-color: var(--#{config.$prefix}dark-text-emphasis, #{colors.$dark-text});
30
30
  }
31
31
 
32
32
  --#{config.$prefix}btn-color: #{$btn-text-color};
33
- --#{config.$prefix}btn-bg: #{$background};
34
- --#{config.$prefix}btn-border-color: #{$border};
33
+ --#{config.$prefix}btn-bg: var(--#{config.$prefix}#{$color}, #{$background});
34
+ --#{config.$prefix}btn-border-color: var(--#{config.$prefix}#{$color}, #{$border});
35
35
  --#{config.$prefix}btn-hover-color: #{$btn-text-hover-color};
36
- --#{config.$prefix}btn-hover-bg: #{if(
37
- $hover-background,
38
- $hover-background,
39
- color.scale($background, $lightness: -15%)
40
- )};
41
- --#{config.$prefix}btn-hover-border-color: #{if(
42
- $hover-border,
43
- $hover-border,
44
- color.scale($border, $lightness: -10%)
45
- )};
46
- --#{config.$prefix}btn-active-color: #{colors.$white};
47
- --#{config.$prefix}btn-active-bg: #{if(
48
- $active-background,
49
- $active-background,
50
- color.scale($background, $lightness: -20%)
51
- )};
52
- --#{config.$prefix}btn-active-border-color: #{if(
53
- $active-border,
54
- $active-border,
55
- color.scale($border, $lightness: -25%)
56
- )};
57
- --#{config.$prefix}btn-disabled-color: #{colors.$white};
58
- --#{config.$prefix}btn-disabled-bg: #{$background};
59
- --#{config.$prefix}btn-disabled-border-color: #{$background};
36
+ --#{config.$prefix}btn-hover-bg: var(--#{config.$prefix}#{$color}-hover, #{color.scale($background, $lightness: -15%)});
37
+ --#{config.$prefix}btn-hover-border-color: var(--#{config.$prefix}#{$color}-hover, #{color.scale($border, $lightness: -10%)});
38
+ --#{config.$prefix}btn-active-color: var(--#{config.$prefix}white, #{colors.$white});
39
+ --#{config.$prefix}btn-active-bg: var(--#{config.$prefix}#{$color}-hover, #{color.scale($background, $lightness: -20%)});
40
+ --#{config.$prefix}btn-active-border-color: var(--#{config.$prefix}#{$color}-hover, #{color.scale($border, $lightness: -25%)});
41
+ --#{config.$prefix}btn-disabled-color: var(--#{config.$prefix}white, #{colors.$white});
42
+ --#{config.$prefix}btn-disabled-bg: var(--#{config.$prefix}#{$color}, #{$background});
43
+ --#{config.$prefix}btn-disabled-border-color: var(--#{config.$prefix}#{$color}, #{$border});
60
44
  }
61
45
 
62
46
  // Button outline variant mixin
63
47
  @mixin btn-outline-variant(
64
48
  $color,
65
- $color-hover: 'light',
66
- $hover-background: $color,
67
- $hover-border: $color,
68
- $active-background: $color,
69
- $active-border: $color
49
+ $color-hover: null,
50
+ $hover-background: null,
51
+ $hover-border: null,
52
+ $active-background: null,
53
+ $active-border: null
70
54
  ) {
71
- @if ($hover-background == 'primary') {
72
- $hover-background: 'primary';
73
- }
74
-
75
- @if ($hover-background == 'light') {
76
- $hover-background: 'secondary';
77
- }
78
-
79
- @if ($hover-background == 'dark') {
80
- $hover-background: 'secondary';
81
- }
82
-
83
- $btn-color: $color;
84
-
85
- @if ($color == 'secondary') {
86
- $btn-color: 'invert';
87
- $color-hover: 'invert';
88
- }
89
-
90
- @if ($color == 'dark') {
91
- $btn-color: 'invert';
92
- $color-hover: 'invert';
93
- }
55
+ $btn-color: var(--#{config.$prefix}#{$color}, #{map.get(tokens.$theme-colors, $color)});
56
+ $btn-hover-color: if(
57
+ $color-hover,
58
+ var(--#{config.$prefix}#{$color-hover}, #{map.get(tokens.$theme-colors, $color-hover)}),
59
+ var(--#{config.$prefix}white, #{colors.$white})
60
+ );
61
+ $btn-hover-bg: if(
62
+ $hover-background,
63
+ var(--#{config.$prefix}#{$hover-background}, #{map.get(tokens.$theme-colors, $hover-background)}),
64
+ var(--#{config.$prefix}#{$color}-hover, #{color.scale(map.get(tokens.$theme-colors, $color), $lightness: -15%)})
65
+ );
66
+ $btn-hover-border: if(
67
+ $hover-border,
68
+ var(--#{config.$prefix}#{$hover-border}, #{map.get(tokens.$theme-colors, $hover-border)}),
69
+ var(--#{config.$prefix}#{$color}-hover, #{color.scale(map.get(tokens.$theme-colors, $color), $lightness: -10%)})
70
+ );
71
+ $btn-active-color: if(
72
+ $color-hover,
73
+ var(--#{config.$prefix}#{$color-hover}, #{map.get(tokens.$theme-colors, $color-hover)}),
74
+ var(--#{config.$prefix}white, #{colors.$white})
75
+ );
76
+ $btn-active-bg: if(
77
+ $active-background,
78
+ var(--#{config.$prefix}#{$active-background}, #{map.get(tokens.$theme-colors, $active-background)}),
79
+ var(--#{config.$prefix}#{$color}-hover, #{color.scale(map.get(tokens.$theme-colors, $color), $lightness: -20%)})
80
+ );
81
+ $btn-active-border: if(
82
+ $active-border,
83
+ var(--#{config.$prefix}#{$active-border}, #{map.get(tokens.$theme-colors, $active-border)}),
84
+ var(--#{config.$prefix}#{$color}-hover, #{color.scale(map.get(tokens.$theme-colors, $color), $lightness: -25%)})
85
+ );
94
86
 
95
- @if ($color == 'light') {
96
- $btn-color: 'invert';
97
- $color-hover: 'invert';
98
- }
99
-
100
- --#{config.$prefix}btn-color: var(--#{config.$prefix}#{$btn-color});
87
+ --#{config.$prefix}btn-color: #{$btn-color};
101
88
  --#{config.$prefix}btn-bg: transparent;
102
- --#{config.$prefix}btn-border-color: var(--#{config.$prefix}#{$color});
103
- --#{config.$prefix}btn-hover-color: var(--#{config.$prefix}#{$color-hover});
104
- --#{config.$prefix}btn-hover-bg: var(--#{config.$prefix}#{$hover-background});
105
- --#{config.$prefix}btn-hover-border-color: var(--#{config.$prefix}#{$hover-border});
106
- --#{config.$prefix}btn-active-color: var(--#{config.$prefix}#{$color-hover});
107
- --#{config.$prefix}btn-active-bg: var(--#{config.$prefix}#{$active-background});
108
- --#{config.$prefix}btn-active-border-color: var(--#{config.$prefix}#{$active-border});
109
- --#{config.$prefix}btn-disabled-color: var(--#{config.$prefix}#{$color});
89
+ --#{config.$prefix}btn-border-color: #{$btn-color};
90
+ --#{config.$prefix}btn-hover-color: #{$btn-hover-color};
91
+ --#{config.$prefix}btn-hover-bg: #{$btn-hover-bg};
92
+ --#{config.$prefix}btn-hover-border-color: #{$btn-hover-border};
93
+ --#{config.$prefix}btn-active-color: #{$btn-active-color};
94
+ --#{config.$prefix}btn-active-bg: #{$btn-active-bg};
95
+ --#{config.$prefix}btn-active-border-color: #{$btn-active-border};
96
+ --#{config.$prefix}btn-disabled-color: #{$btn-color};
110
97
  --#{config.$prefix}btn-disabled-bg: transparent;
111
- --#{config.$prefix}btn-disabled-border-color: var(--#{config.$prefix}#{$color});
98
+ --#{config.$prefix}btn-disabled-border-color: #{$btn-color};
112
99
  }
113
100
 
114
101
  // Button size mixin
@@ -117,4 +104,4 @@
117
104
  --#{config.$prefix}btn-padding-x: #{$padding-x};
118
105
  --#{config.$prefix}btn-font-size: #{$font-size};
119
106
  --#{config.$prefix}btn-border-radius: #{$border-radius};
120
- }
107
+ }
@@ -1,6 +1,8 @@
1
1
  // Component: AtomixGlass
2
2
  // =============================================================================
3
3
 
4
+ @use '../02-tools/tools.component' as *;
5
+
4
6
  .c-atomix-glass {
5
7
  position: relative;
6
8
 
@@ -38,19 +40,19 @@
38
40
  }
39
41
 
40
42
  &__hover-1 {
41
- transition: opacity 0.2s ease-out;
43
+ transition: opacity var(--atomix-transition-duration-fast, 0.15s) ease-out;
42
44
  opacity: var(--atomix-glass-hover-1-opacity, 0);
43
45
  background: var(--atomix-glass-hover-1-gradient, none);
44
46
  }
45
47
 
46
48
  &__hover-2 {
47
- transition: opacity 0.4s ease-out;
49
+ transition: opacity var(--atomix-transition-duration-base, 0.3s) ease-out;
48
50
  opacity: var(--atomix-glass-hover-2-opacity, 0);
49
51
  background: var(--atomix-glass-hover-2-gradient, none);
50
52
  }
51
53
 
52
54
  &__hover-3 {
53
- transition: opacity 0.6s ease-out;
55
+ transition: opacity var(--atomix-transition-duration-slow, 0.5s) ease-out;
54
56
  opacity: var(--atomix-glass-hover-3-opacity, 0);
55
57
  background: var(--atomix-glass-hover-3-gradient, none);
56
58
  }
@@ -91,6 +93,7 @@
91
93
  box-sizing: border-box;
92
94
  overflow: hidden;
93
95
  pointer-events: none;
96
+ /* postcss-ignore-start */
94
97
  -webkit-mask:
95
98
  linear-gradient(var(--atomix-black, #000000) 0 0) content-box,
96
99
  linear-gradient(var(--atomix-black, #000000) 0 0);
@@ -99,6 +102,7 @@
99
102
  linear-gradient(var(--atomix-black, #000000) 0 0) content-box,
100
103
  linear-gradient(var(--atomix-black, #000000) 0 0);
101
104
  mask-composite: exclude;
105
+ /* postcss-ignore-end */
102
106
 
103
107
  position: var(--atomix-glass-position);
104
108
  top: var(--atomix-glass-top);
@@ -233,6 +237,12 @@
233
237
  --atomix-glass-transition: none;
234
238
  }
235
239
 
240
+ // Focus ring for interactive elements (when onClick is provided)
241
+ &[role='button'],
242
+ &[tabindex]:not([tabindex='-1']) {
243
+ @include focus-ring;
244
+ }
245
+
236
246
  // Responsive and accessibility
237
247
  @media (prefers-reduced-motion: reduce) {
238
248
  --atomix-glass-transition: none;
@@ -153,4 +153,92 @@
153
153
  &__icon-skip-forward::before {
154
154
  content: 'ā­';
155
155
  }
156
+
157
+ // Search functionality
158
+ &__search {
159
+ margin-top: 1rem;
160
+ display: flex;
161
+ flex-direction: column;
162
+ align-items: center;
163
+ gap: 0.5rem;
164
+ }
165
+
166
+ &__search-wrapper {
167
+ display: flex;
168
+ align-items: center;
169
+ gap: 0.5rem;
170
+ }
171
+
172
+ &__search-label {
173
+ display: flex;
174
+ align-items: center;
175
+ gap: 0.5rem;
176
+ }
177
+
178
+ &__search-label-text {
179
+ font-size: var(--#{config.$prefix}pagination-font-size);
180
+ color: var(--#{config.$prefix}pagination-color);
181
+ white-space: nowrap;
182
+ }
183
+
184
+ &__search-input {
185
+ width: 80px;
186
+ padding: var(--#{config.$prefix}pagination-padding-y)
187
+ var(--#{config.$prefix}pagination-padding-x);
188
+ font-size: var(--#{config.$prefix}pagination-font-size);
189
+ text-align: center;
190
+ border: 1px solid var(--#{config.$prefix}pagination-color);
191
+ border-radius: var(--#{config.$prefix}pagination-border-radius);
192
+ @include dynamic-background(var(--#{config.$prefix}pagination-bg));
193
+ color: var(--#{config.$prefix}pagination-color);
194
+ transition: all 0.2s ease-in-out;
195
+
196
+ &:focus {
197
+ outline: none;
198
+ border-color: var(--#{config.$prefix}pagination-focus-border-color);
199
+ border-width: var(--#{config.$prefix}pagination-focus-border-width);
200
+ }
201
+
202
+ &.is-error {
203
+ border-color: var(--#{config.$prefix}error-color, #dc3545);
204
+ background-color: var(--#{config.$prefix}error-bg-subtle, rgba(220, 53, 69, 0.1));
205
+ }
206
+ }
207
+
208
+ &__search-button {
209
+ display: flex;
210
+ align-items: center;
211
+ justify-content: center;
212
+ @include size.square(var(--#{config.$prefix}pagination-size));
213
+ padding: var(--#{config.$prefix}pagination-padding-y)
214
+ var(--#{config.$prefix}pagination-padding-x);
215
+ @include dynamic-background(var(--#{config.$prefix}pagination-bg));
216
+ border: 1px solid var(--#{config.$prefix}pagination-color);
217
+ border-radius: var(--#{config.$prefix}pagination-border-radius);
218
+ color: var(--#{config.$prefix}pagination-color);
219
+ cursor: pointer;
220
+ transition: all 0.2s ease-in-out;
221
+
222
+ &:hover {
223
+ --#{config.$prefix}pagination-color: var(--#{config.$prefix}pagination-hover-color);
224
+ --#{config.$prefix}pagination-bg: var(--#{config.$prefix}pagination-hover-bg);
225
+ }
226
+
227
+ &:focus-visible {
228
+ outline: none;
229
+ border-color: var(--#{config.$prefix}pagination-focus-border-color);
230
+ border-width: var(--#{config.$prefix}pagination-focus-border-width);
231
+ }
232
+
233
+ .c-icon {
234
+ color: inherit;
235
+ }
236
+ }
237
+
238
+ &__search-error {
239
+ font-size: 0.75rem;
240
+ color: var(--#{config.$prefix}error-color, #dc3545);
241
+ text-align: center;
242
+ margin-top: 0.25rem;
243
+ }
156
244
  }
@@ -1,309 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Sync Theme Configuration
5
- *
6
- * This script generates src/themes/themes.config.js from theme.config.ts
7
- * to maintain a single source of truth for theme configuration.
8
- */
9
-
10
- import { readFile, writeFile } from 'fs/promises';
11
- import { join, dirname } from 'path';
12
- import { fileURLToPath } from 'url';
13
-
14
- const __filename = fileURLToPath(import.meta.url);
15
- const __dirname = dirname(__filename);
16
-
17
- // File paths
18
- const THEME_CONFIG_TS = join(__dirname, '../theme.config.ts');
19
- const THEMES_CONFIG_JS = join(__dirname, '../src/themes/themes.config.js');
20
-
21
- /**
22
- * Parse theme.config.ts to extract configuration
23
- * Note: This is a simplified parser that works with the current structure
24
- */
25
- async function parseThemeConfigTS() {
26
- try {
27
- const content = await readFile(THEME_CONFIG_TS, 'utf8');
28
-
29
- // Extract themes object
30
- const themesMatch = content.match(/themes:\s*{([^}]+(?:{[^}]*}[^}]*)*[^}]+)}/s);
31
- if (!themesMatch) {
32
- throw new Error('Could not find themes configuration');
33
- }
34
-
35
- // Extract individual theme configurations
36
- const themes = {};
37
- const themeRegex = /['"]([^'"]+)['"]\s*:\s*{([^}]+(?:{[^}]*}[^}]*)*[^}]+)}/gs;
38
- let match;
39
-
40
- while ((match = themeRegex.exec(themesMatch[1])) !== null) {
41
- const [, themeName, themeConfig] = match;
42
-
43
- // Parse theme properties
44
- const theme = {
45
- name: extractValue(themeConfig, 'name'),
46
- description: extractValue(themeConfig, 'description'),
47
- author: extractValue(themeConfig, 'author'),
48
- version: extractValue(themeConfig, 'version'),
49
- tags: extractArray(themeConfig, 'tags'),
50
- supportsDarkMode: extractBoolean(themeConfig, 'supportsDarkMode'),
51
- status: extractValue(themeConfig, 'status'),
52
- color: extractValue(themeConfig, 'color'),
53
- };
54
-
55
- // Parse features if present
56
- const featuresMatch = themeConfig.match(/features:\s*\[([^\]]*)\]/s);
57
- if (featuresMatch) {
58
- theme.features = featuresMatch[1]
59
- .split(',')
60
- .map(f => f.trim().replace(/['"]/g, ''))
61
- .filter(f => f.length > 0);
62
- }
63
-
64
- // Parse a11y if present
65
- const a11yMatch = themeConfig.match(/a11y:\s*{([^}]*)}/);
66
- if (a11yMatch) {
67
- theme.a11y = {
68
- contrastTarget: extractNumber(a11yMatch[1], 'contrastTarget'),
69
- modes: extractArray(a11yMatch[1], 'modes'),
70
- };
71
- }
72
-
73
- themes[themeName] = theme;
74
- }
75
-
76
- // Extract build configuration
77
- const buildMatch = content.match(/build:\s*(defaultBuildConfig|{[^}]+})/);
78
- const build = buildMatch && buildMatch[1] === 'defaultBuildConfig'
79
- ? getDefaultBuildConfig()
80
- : parseBuildConfig(buildMatch?.[1]);
81
-
82
- // Extract runtime configuration
83
- const runtimeMatch = content.match(/runtime:\s*(defaultRuntimeConfig|{[^}]+})/);
84
- const runtime = runtimeMatch && runtimeMatch[1] === 'defaultRuntimeConfig'
85
- ? getDefaultRuntimeConfig()
86
- : parseRuntimeConfig(runtimeMatch?.[1]);
87
-
88
- // Extract integration configuration
89
- const integrationMatch = content.match(/integration:\s*(defaultIntegrationConfig|{[^}]+})/);
90
- const integration = integrationMatch && integrationMatch[1] === 'defaultIntegrationConfig'
91
- ? getDefaultIntegrationConfig()
92
- : parseIntegrationConfig(integrationMatch?.[1]);
93
-
94
- return {
95
- themes,
96
- build,
97
- runtime,
98
- integration,
99
- dependencies: {},
100
- };
101
- } catch (error) {
102
- console.error('āŒ Failed to parse theme.config.ts:', error.message);
103
- throw error;
104
- }
105
- }
106
-
107
- /**
108
- * Helper function to extract string values
109
- */
110
- function extractValue(text, key) {
111
- const regex = new RegExp(`${key}:\\s*['"]([^'"]+)['"]`);
112
- const match = text.match(regex);
113
- return match ? match[1] : undefined;
114
- }
115
-
116
- /**
117
- * Helper function to extract number values
118
- */
119
- function extractNumber(text, key) {
120
- const regex = new RegExp(`${key}:\\s*(\\d+(?:\\.\\d+)?)`);
121
- const match = text.match(regex);
122
- return match ? parseFloat(match[1]) : undefined;
123
- }
124
-
125
- /**
126
- * Helper function to extract boolean values
127
- */
128
- function extractBoolean(text, key) {
129
- const regex = new RegExp(`${key}:\\s*(true|false)`);
130
- const match = text.match(regex);
131
- return match ? match[1] === 'true' : undefined;
132
- }
133
-
134
- /**
135
- * Helper function to extract array values
136
- */
137
- function extractArray(text, key) {
138
- const regex = new RegExp(`${key}:\\s*\\[([^\\]]*)\\]`);
139
- const match = text.match(regex);
140
- if (!match) return undefined;
141
-
142
- return match[1]
143
- .split(',')
144
- .map(item => item.trim().replace(/['"]/g, ''))
145
- .filter(item => item.length > 0);
146
- }
147
-
148
- /**
149
- * Get default build configuration
150
- */
151
- function getDefaultBuildConfig() {
152
- return {
153
- output: {
154
- directory: 'themes',
155
- formats: {
156
- expanded: '.css',
157
- compressed: '.min.css',
158
- },
159
- },
160
- sass: {
161
- style: 'expanded',
162
- sourceMap: true,
163
- loadPaths: ['src'],
164
- },
165
- };
166
- }
167
-
168
- /**
169
- * Get default runtime configuration
170
- */
171
- function getDefaultRuntimeConfig() {
172
- return {
173
- basePath: '/themes',
174
- cdnPath: null,
175
- preload: [],
176
- lazy: true,
177
- defaultTheme: '',
178
- storageKey: 'atomix-theme',
179
- useMinified: "process.env.NODE_ENV === 'production'",
180
- };
181
- }
182
-
183
- /**
184
- * Get default integration configuration
185
- */
186
- function getDefaultIntegrationConfig() {
187
- return {
188
- cssVariables: {
189
- colorMode: '--storybook-color-mode',
190
- },
191
- classNames: {
192
- theme: 'data-theme',
193
- colorMode: 'data-atomix-color-mode',
194
- },
195
- };
196
- }
197
-
198
- /**
199
- * Parse build configuration
200
- */
201
- function parseBuildConfig(configText) {
202
- if (!configText) return getDefaultBuildConfig();
203
- // For now, return default config
204
- // A more sophisticated parser would be needed for complex objects
205
- return getDefaultBuildConfig();
206
- }
207
-
208
- /**
209
- * Parse runtime configuration
210
- */
211
- function parseRuntimeConfig(configText) {
212
- if (!configText) return getDefaultRuntimeConfig();
213
- // For now, return default config
214
- // A more sophisticated parser would be needed for complex objects
215
- return getDefaultRuntimeConfig();
216
- }
217
-
218
- /**
219
- * Parse integration configuration
220
- */
221
- function parseIntegrationConfig(configText) {
222
- if (!configText) return getDefaultIntegrationConfig();
223
- // For now, return default config
224
- // A more sophisticated parser would be needed for complex objects
225
- return getDefaultIntegrationConfig();
226
- }
227
-
228
- /**
229
- * Generate themes.config.js content
230
- */
231
- function generateThemesConfigJS(config) {
232
- const { themes, build, runtime, integration, dependencies } = config;
233
-
234
- // Convert themes to metadata format
235
- const metadata = {};
236
- for (const [key, theme] of Object.entries(themes)) {
237
- metadata[key] = { ...theme };
238
- // Remove undefined values
239
- Object.keys(metadata[key]).forEach(k => {
240
- if (metadata[key][k] === undefined) {
241
- delete metadata[key][k];
242
- }
243
- });
244
- }
245
-
246
- return `/**
247
- * Theme Configuration
248
- *
249
- * This file is auto-generated from theme.config.ts
250
- * DO NOT EDIT MANUALLY - Edit theme.config.ts instead
251
- *
252
- * Generated on: ${new Date().toISOString()}
253
- */
254
-
255
- export const themesConfig = {
256
- // Theme metadata
257
- metadata: ${JSON.stringify(metadata, null, 4).replace(/"([^"]+)":/g, '$1:')},
258
-
259
- // Build configuration
260
- build: ${JSON.stringify(build, null, 4).replace(/"([^"]+)":/g, '$1:')},
261
-
262
- // Export configuration for package.json
263
- exports: {
264
- './themes/*': './dist/themes/*.css',
265
- './themes/*.min': './dist/themes/*.min.css',
266
- },
267
-
268
- // Theme integration settings
269
- integration: ${JSON.stringify(integration, null, 4).replace(/"([^"]+)":/g, '$1:')},
270
-
271
- // Runtime theme loading configuration
272
- runtime: ${JSON.stringify(runtime, null, 4).replace(/"([^"]+)":/g, '$1:').replace(/"process\.env\.NODE_ENV === 'production'"/g, "process.env.NODE_ENV === 'production'")},
273
-
274
- // Theme dependencies (if a theme requires another theme to be loaded)
275
- dependencies: ${JSON.stringify(dependencies, null, 4).replace(/"([^"]+)":/g, '$1:')},
276
- };`;
277
- }
278
-
279
- /**
280
- * Main function
281
- */
282
- async function main() {
283
- console.log('šŸ”„ Syncing theme configuration...\n');
284
-
285
- try {
286
- // Parse theme.config.ts
287
- console.log('šŸ“– Reading theme.config.ts...');
288
- const config = await parseThemeConfigTS();
289
- console.log(` āœ… Found ${Object.keys(config.themes).length} themes`);
290
-
291
- // Generate themes.config.js
292
- console.log('\nšŸ“ Generating themes.config.js...');
293
- const jsContent = generateThemesConfigJS(config);
294
-
295
- // Write to file
296
- await writeFile(THEMES_CONFIG_JS, jsContent, 'utf8');
297
- console.log(' āœ… Written to src/themes/themes.config.js');
298
-
299
- console.log('\n✨ Configuration sync complete!');
300
- console.log(' themes.config.js has been updated from theme.config.ts');
301
-
302
- } catch (error) {
303
- console.error('\nšŸ’„ Sync failed:', error.message);
304
- process.exit(1);
305
- }
306
- }
307
-
308
- // Run the sync
309
- main();