@shohojdhara/atomix 0.3.13 → 0.3.15

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 (249) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +2 -0
  3. package/build-tools/EXAMPLES.md +372 -0
  4. package/build-tools/README.md +242 -0
  5. package/build-tools/__tests__/error-handler.test.js +230 -0
  6. package/build-tools/__tests__/index.test.js +141 -0
  7. package/build-tools/__tests__/rollup-plugin.test.js +194 -0
  8. package/build-tools/__tests__/utils.test.js +161 -0
  9. package/build-tools/__tests__/vite-plugin.test.js +129 -0
  10. package/build-tools/__tests__/webpack-loader.test.js +190 -0
  11. package/build-tools/error-handler.js +308 -0
  12. package/build-tools/index.d.ts +43 -0
  13. package/build-tools/index.js +88 -0
  14. package/build-tools/package.json +67 -0
  15. package/build-tools/rollup-plugin.js +236 -0
  16. package/build-tools/types.d.ts +163 -0
  17. package/build-tools/utils.js +203 -0
  18. package/build-tools/vite-plugin.js +161 -0
  19. package/build-tools/webpack-loader.js +123 -0
  20. package/dist/atomix.css +298 -167
  21. package/dist/atomix.css.map +1 -1
  22. package/dist/atomix.min.css +3 -3
  23. package/dist/atomix.min.css.map +1 -1
  24. package/dist/build-tools/EXAMPLES.md +372 -0
  25. package/dist/build-tools/README.md +242 -0
  26. package/dist/build-tools/__tests__/error-handler.test.js +230 -0
  27. package/dist/build-tools/__tests__/index.test.js +141 -0
  28. package/dist/build-tools/__tests__/rollup-plugin.test.js +194 -0
  29. package/dist/build-tools/__tests__/utils.test.js +161 -0
  30. package/dist/build-tools/__tests__/vite-plugin.test.js +129 -0
  31. package/dist/build-tools/__tests__/webpack-loader.test.js +190 -0
  32. package/dist/build-tools/error-handler.js +308 -0
  33. package/dist/build-tools/index.d.ts +43 -0
  34. package/dist/build-tools/index.js +88 -0
  35. package/dist/build-tools/package.json +67 -0
  36. package/dist/build-tools/rollup-plugin.js +236 -0
  37. package/dist/build-tools/types.d.ts +163 -0
  38. package/dist/build-tools/utils.js +203 -0
  39. package/dist/build-tools/vite-plugin.js +161 -0
  40. package/dist/build-tools/webpack-loader.js +123 -0
  41. package/dist/charts.d.ts +2 -2
  42. package/dist/charts.js +87 -58
  43. package/dist/charts.js.map +1 -1
  44. package/dist/core.d.ts +42 -12
  45. package/dist/core.js +175 -135
  46. package/dist/core.js.map +1 -1
  47. package/dist/forms.d.ts +30 -16
  48. package/dist/forms.js +146 -131
  49. package/dist/forms.js.map +1 -1
  50. package/dist/heavy.d.ts +2 -2
  51. package/dist/heavy.js +151 -118
  52. package/dist/heavy.js.map +1 -1
  53. package/dist/index.d.ts +130 -106
  54. package/dist/index.esm.js +1083 -465
  55. package/dist/index.esm.js.map +1 -1
  56. package/dist/index.js +1102 -483
  57. package/dist/index.js.map +1 -1
  58. package/dist/index.min.js +1 -1
  59. package/dist/index.min.js.map +1 -1
  60. package/dist/theme.d.ts +27 -2
  61. package/dist/theme.js +721 -108
  62. package/dist/theme.js.map +1 -1
  63. package/package.json +23 -8
  64. package/scripts/atomix-cli.js +749 -1153
  65. package/scripts/cli/__tests__/README.md +81 -0
  66. package/scripts/cli/__tests__/basic.test.js +115 -0
  67. package/scripts/cli/__tests__/component-generator.test.js +332 -0
  68. package/scripts/cli/__tests__/integration.test.js +327 -0
  69. package/scripts/cli/__tests__/test-setup.js +133 -0
  70. package/scripts/cli/__tests__/token-manager.test.js +251 -0
  71. package/scripts/cli/__tests__/utils.test.js +78 -118
  72. package/scripts/cli/component-generator.js +564 -0
  73. package/scripts/cli/dependency-checker.js +355 -0
  74. package/scripts/cli/documentation-sync.js +542 -0
  75. package/scripts/cli/interactive-init.js +129 -292
  76. package/scripts/cli/mappings.js +211 -0
  77. package/scripts/cli/migration-tools.js +95 -288
  78. package/scripts/cli/template-manager.js +105 -0
  79. package/scripts/cli/templates/README.md +123 -0
  80. package/scripts/cli/templates/common-templates.js +636 -0
  81. package/scripts/cli/templates/composable-templates.js +171 -0
  82. package/scripts/cli/templates/config-templates.js +126 -0
  83. package/scripts/cli/templates/index.js +102 -0
  84. package/scripts/cli/templates/project-templates.js +342 -0
  85. package/scripts/cli/templates/react-templates.js +331 -0
  86. package/scripts/cli/templates/scss-templates.js +155 -0
  87. package/scripts/cli/templates/storybook-templates.js +236 -0
  88. package/scripts/cli/templates/testing-templates.js +224 -0
  89. package/scripts/cli/templates/testing-utils.js +278 -0
  90. package/scripts/cli/templates/token-templates.js +447 -0
  91. package/scripts/cli/templates/types-templates.js +147 -0
  92. package/scripts/cli/templates.js +35 -0
  93. package/scripts/cli/theme-bridge.js +28 -16
  94. package/scripts/cli/token-manager.js +432 -247
  95. package/scripts/cli/utils.js +37 -26
  96. package/src/components/Accordion/Accordion.stories.tsx +369 -870
  97. package/src/components/Accordion/Accordion.test.tsx +57 -0
  98. package/src/components/Accordion/Accordion.tsx +4 -0
  99. package/src/components/AtomixGlass/AtomixGlass.tsx +80 -39
  100. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +103 -81
  101. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +8 -7
  102. package/src/components/AtomixGlass/glass-utils.ts +2 -2
  103. package/src/components/AtomixGlass/shader-utils.ts +5 -0
  104. package/src/components/AtomixGlass/stories/Customization.stories.tsx +131 -0
  105. package/src/components/AtomixGlass/stories/Examples.stories.tsx +2965 -2861
  106. package/src/components/AtomixGlass/stories/Modes.stories.tsx +1 -1
  107. package/src/components/AtomixGlass/stories/Overview.stories.tsx +348 -0
  108. package/src/components/AtomixGlass/stories/Performance.stories.tsx +103 -0
  109. package/src/components/AtomixGlass/stories/Playground.stories.tsx +73 -59
  110. package/src/components/AtomixGlass/stories/{ShaderVariants.stories.tsx → Shaders.stories.tsx} +1 -1
  111. package/src/components/AtomixGlass/stories/shared-components.tsx +90 -190
  112. package/src/components/Avatar/Avatar.stories.tsx +239 -27
  113. package/src/components/Badge/Badge.stories.tsx +132 -373
  114. package/src/components/Badge/Badge.test.tsx +51 -0
  115. package/src/components/Badge/Badge.tsx +20 -1
  116. package/src/components/Block/Block.stories.tsx +26 -17
  117. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +141 -23
  118. package/src/components/Breadcrumb/Breadcrumb.tsx +2 -2
  119. package/src/components/Button/Button.stories.tsx +463 -1126
  120. package/src/components/Button/Button.test.tsx +107 -0
  121. package/src/components/Button/Button.tsx +50 -54
  122. package/src/components/Button/ButtonGroup.stories.tsx +373 -217
  123. package/src/components/Button/README.md +5 -0
  124. package/src/components/Callout/Callout.stories.tsx +299 -644
  125. package/src/components/Callout/Callout.test.tsx +10 -10
  126. package/src/components/Callout/Callout.tsx +7 -7
  127. package/src/components/Callout/README.md +9 -8
  128. package/src/components/Card/Card.stories.tsx +248 -68
  129. package/src/components/Card/Card.tsx +2 -2
  130. package/src/components/Chart/Chart.stories.tsx +156 -14
  131. package/src/components/Chart/Chart.tsx +1 -1
  132. package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +151 -69
  133. package/src/components/Countdown/Countdown.stories.tsx +115 -8
  134. package/src/components/DataTable/DataTable.stories.tsx +346 -146
  135. package/src/components/DataTable/DataTable.tsx +14 -12
  136. package/src/components/DatePicker/DatePicker.stories.tsx +325 -1066
  137. package/src/components/Dropdown/Dropdown.stories.tsx +157 -37
  138. package/src/components/EdgePanel/EdgePanel.stories.tsx +230 -21
  139. package/src/components/Footer/Footer.stories.tsx +392 -328
  140. package/src/components/Form/Checkbox.stories.tsx +143 -9
  141. package/src/components/Form/Checkbox.test.tsx +63 -0
  142. package/src/components/Form/Checkbox.tsx +90 -52
  143. package/src/components/Form/Form.stories.tsx +121 -22
  144. package/src/components/Form/FormGroup.stories.tsx +128 -5
  145. package/src/components/Form/Input.stories.tsx +28 -16
  146. package/src/components/Form/Input.test.tsx +59 -0
  147. package/src/components/Form/Input.tsx +97 -95
  148. package/src/components/Form/Radio.stories.tsx +232 -97
  149. package/src/components/Form/Radio.tsx +2 -2
  150. package/src/components/Form/Select.stories.tsx +144 -12
  151. package/src/components/Form/Select.tsx +2 -2
  152. package/src/components/Form/Textarea.stories.tsx +171 -13
  153. package/src/components/Form/Textarea.test.tsx +45 -0
  154. package/src/components/Form/Textarea.tsx +88 -86
  155. package/src/components/Hero/Hero.stories.tsx +333 -32
  156. package/src/components/List/List.stories.tsx +143 -5
  157. package/src/components/Modal/Modal.stories.tsx +185 -46
  158. package/src/components/Navigation/Navbar/Navbar.stories.tsx +5 -5
  159. package/src/components/Navigation/Navbar/Navbar.tsx +1 -1
  160. package/src/components/Navigation/README.md +1 -1
  161. package/src/components/Pagination/Pagination.stories.tsx +5 -2
  162. package/src/components/Pagination/Pagination.tsx +1 -1
  163. package/src/components/PhotoViewer/PhotoViewer.stories.tsx +10 -10
  164. package/src/components/Popover/Popover.stories.tsx +449 -99
  165. package/src/components/ProductReview/ProductReview.tsx +1 -1
  166. package/src/components/Progress/Progress.stories.tsx +167 -5
  167. package/src/components/Progress/Progress.tsx +46 -46
  168. package/src/components/Rating/Rating.stories.tsx +4 -4
  169. package/src/components/Rating/Rating.tsx +8 -8
  170. package/src/components/River/River.stories.tsx +1 -1
  171. package/src/components/SectionIntro/SectionIntro.stories.tsx +240 -48
  172. package/src/components/Slider/Slider.stories.tsx +63 -63
  173. package/src/components/Spinner/Spinner.stories.tsx +104 -10
  174. package/src/components/Spinner/Spinner.test.tsx +35 -0
  175. package/src/components/Spinner/Spinner.tsx +9 -2
  176. package/src/components/Steps/Steps.stories.tsx +172 -43
  177. package/src/components/Tabs/Tabs.stories.tsx +136 -10
  178. package/src/components/Testimonial/Testimonial.stories.tsx +121 -4
  179. package/src/components/Todo/Todo.stories.tsx +198 -9
  180. package/src/components/Toggle/Toggle.stories.tsx +153 -43
  181. package/src/components/Toggle/Toggle.test.tsx +91 -0
  182. package/src/components/Toggle/Toggle.tsx +44 -27
  183. package/src/components/Tooltip/Tooltip.stories.tsx +194 -104
  184. package/src/components/Tooltip/Tooltip.tsx +1 -1
  185. package/src/components/Upload/Upload.stories.tsx +113 -24
  186. package/src/layouts/Grid/Grid.stories.tsx +49 -49
  187. package/src/layouts/MasonryGrid/MasonryGrid.stories.tsx +2 -2
  188. package/src/lib/README.md +2 -2
  189. package/src/lib/__tests__/theme-tools.test.ts +193 -0
  190. package/src/lib/composables/index.ts +2 -2
  191. package/src/lib/composables/useAccordion.ts +12 -3
  192. package/src/lib/composables/useAtomixGlass.ts +28 -56
  193. package/src/lib/composables/useBreadcrumb.ts +2 -2
  194. package/src/lib/composables/useCallout.ts +7 -7
  195. package/src/lib/composables/useChartExport.ts +2 -7
  196. package/src/lib/composables/useDataTable.ts +46 -29
  197. package/src/lib/composables/useNavbar.ts +1 -1
  198. package/src/lib/constants/components.ts +10 -33
  199. package/src/lib/storybook/InteractiveDemo.tsx +113 -0
  200. package/src/lib/storybook/PreviewContainer.tsx +36 -0
  201. package/src/lib/storybook/VariantsGrid.tsx +21 -0
  202. package/src/lib/storybook/index.ts +3 -0
  203. package/src/lib/theme/core/createThemeObject.ts +9 -5
  204. package/src/lib/theme/devtools/CLI.ts +155 -0
  205. package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +213 -0
  206. package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +566 -0
  207. package/src/lib/theme/devtools/LiveEditor.tsx +2 -1
  208. package/src/lib/theme/devtools/index.ts +3 -0
  209. package/src/lib/theme/errors/errors.ts +8 -0
  210. package/src/lib/theme/runtime/ThemeProvider.tsx +117 -57
  211. package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +305 -0
  212. package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +588 -0
  213. package/src/lib/theme/utils/__tests__/themeValidation.test.ts +264 -0
  214. package/src/lib/theme/utils/index.ts +1 -0
  215. package/src/lib/theme/utils/themeValidation.ts +501 -0
  216. package/src/lib/theme-tools.ts +32 -3
  217. package/src/lib/types/components.ts +82 -27
  218. package/src/lib/utils/__tests__/csv.test.ts +45 -0
  219. package/src/lib/utils/csv.ts +17 -0
  220. package/src/lib/utils/dataTableExport.ts +1 -10
  221. package/src/lib/utils/themeNaming.ts +1 -1
  222. package/src/styles/01-settings/_index.scss +2 -1
  223. package/src/styles/01-settings/_settings.accordion.scss +28 -7
  224. package/src/styles/01-settings/_settings.colors.scss +11 -11
  225. package/src/styles/01-settings/_settings.typography.scss +5 -5
  226. package/src/styles/02-tools/_tools.utility-api.scss +14 -0
  227. package/src/styles/06-components/_components.accordion.scss +56 -14
  228. package/src/styles/06-components/_components.callout.scss +29 -33
  229. package/src/styles/06-components/_components.checkbox.scss +23 -17
  230. package/src/styles/06-components/_index.scss +1 -1
  231. package/src/styles/99-utilities/_index.scss +2 -0
  232. package/src/styles/99-utilities/_utilities.display.scss +14 -3
  233. package/src/styles/99-utilities/_utilities.flex.scss +10 -10
  234. package/src/styles/99-utilities/_utilities.scss +3 -1
  235. package/src/styles/99-utilities/_utilities.text-gradient.scss +45 -0
  236. package/src/styles/99-utilities/_utilities.text.scss +28 -8
  237. package/themes/dark-complementary/README.md +98 -0
  238. package/themes/dark-complementary/index.scss +158 -0
  239. package/themes/default-light/README.md +81 -0
  240. package/themes/default-light/index.scss +154 -0
  241. package/themes/high-contrast/README.md +105 -0
  242. package/themes/high-contrast/index.scss +172 -0
  243. package/themes/test-theme/README.md +38 -0
  244. package/themes/test-theme/index.scss +47 -0
  245. package/scripts/cli/__tests__/cli-commands.test.js +0 -204
  246. package/scripts/cli/__tests__/vitest.config.js +0 -26
  247. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +0 -1438
  248. package/src/lib/composables/useButton.ts +0 -93
  249. package/src/lib/composables/useCheckbox.ts +0 -70
@@ -235,18 +235,12 @@ export function useAtomixGlass({
235
235
  const effectiveCornerRadius = useMemo(() => {
236
236
  if (cornerRadius !== undefined) {
237
237
  const result = Math.max(0, cornerRadius);
238
- // if (process.env.NODE_ENV !== 'production' && debugCornerRadius) {
239
- // console.log('[AtomixGlass] Using manual cornerRadius prop:', result);
240
- // }
241
238
  return result;
242
239
  }
243
240
 
244
241
  const result = Math.max(0, dynamicCornerRadius);
245
- // if (process.env.NODE_ENV !== 'production' && debugCornerRadius) {
246
- // console.log('[AtomixGlass] Using dynamic cornerRadius:', result);
247
- // }
248
242
  return result;
249
- }, [cornerRadius, dynamicCornerRadius, debugCornerRadius]);
243
+ }, [cornerRadius, dynamicCornerRadius]);
250
244
 
251
245
  const effectiveReducedMotion = useMemo(
252
246
  () => reducedMotion || userPrefersReducedMotion,
@@ -278,7 +272,6 @@ export function useAtomixGlass({
278
272
  const extractRadius = () => {
279
273
  try {
280
274
  let extractedRadius: number | null = null;
281
- let extractionSource = 'default';
282
275
 
283
276
  if (contentRef.current) {
284
277
  const firstChild = contentRef.current.firstElementChild as HTMLElement;
@@ -286,7 +279,6 @@ export function useAtomixGlass({
286
279
  const domRadius = extractBorderRadiusFromDOMElement(firstChild);
287
280
  if (domRadius !== null && domRadius > 0) {
288
281
  extractedRadius = domRadius;
289
- extractionSource = 'DOM element';
290
282
  }
291
283
  }
292
284
  }
@@ -295,25 +287,11 @@ export function useAtomixGlass({
295
287
  const childRadius = extractBorderRadiusFromChildren(children);
296
288
  if (childRadius > 0 && childRadius !== CONSTANTS.DEFAULT_CORNER_RADIUS) {
297
289
  extractedRadius = childRadius;
298
- extractionSource = 'React children';
299
290
  }
300
291
  }
301
292
 
302
293
  if (extractedRadius !== null && extractedRadius > 0) {
303
294
  setDynamicCornerRadius(extractedRadius);
304
-
305
- // if (process.env.NODE_ENV !== 'production' && debugCornerRadius) {
306
- // console.log('[AtomixGlass] Corner radius extracted:', {
307
- // value: extractedRadius,
308
- // source: extractionSource,
309
- // timestamp: new Date().toISOString(),
310
- // });
311
- // }
312
- } else if ((typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') && debugCornerRadius) {
313
- // console.log(
314
- // '[AtomixGlass] No corner radius found, using default:',
315
- // CONSTANTS.DEFAULT_CORNER_RADIUS
316
- // );
317
295
  }
318
296
  } catch (error) {
319
297
  if ((typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') && debugCornerRadius) {
@@ -451,19 +429,6 @@ export function useAtomixGlass({
451
429
  setCachedBackgroundDetection(element.parentElement, overLight, isOverLightDetected, threshold);
452
430
 
453
431
  setDetectedOverLight(isOverLightDetected);
454
-
455
- // Debug logging
456
- // if (process.env.NODE_ENV !== 'production' && debugOverLight) {
457
- // console.log('[AtomixGlass] OverLight Detection:', {
458
- // avgLuminance: avgLuminance.toFixed(3),
459
- // threshold: threshold.toFixed(3),
460
- // detected: isOverLightDetected,
461
- // validSamples,
462
- // totalLuminance: totalLuminance.toFixed(3),
463
- // configType: typeof overLight === 'object' ? 'object' : typeof overLight,
464
- // timestamp: new Date().toISOString(),
465
- // });
466
- // }
467
432
  } else {
468
433
  // Invalid luminance calculation, default to false
469
434
  const result = false;
@@ -501,17 +466,7 @@ export function useAtomixGlass({
501
466
  return () => clearTimeout(timeoutId);
502
467
  } else if (typeof overLight === 'boolean') {
503
468
  // For boolean values, disable auto-detection
504
- // Cache is automatically managed by WeakMap (no manual clearing needed)
505
469
  setDetectedOverLight(false);
506
-
507
- // Debug logging for boolean mode
508
- // if (process.env.NODE_ENV !== 'production' && debugOverLight) {
509
- // console.log('[AtomixGlass] OverLight Mode: boolean', {
510
- // value: overLight,
511
- // autoDetection: false,
512
- // timestamp: new Date().toISOString(),
513
- // });
514
- // }
515
470
  }
516
471
 
517
472
  if (typeof window.matchMedia !== 'function') {
@@ -609,7 +564,7 @@ export function useAtomixGlass({
609
564
 
610
565
  if ((typeof process === 'undefined' || process.env?.NODE_ENV !== 'production') && enablePerformanceMonitoring) {
611
566
  const endTime = performance.now();
612
- const duration = endTime - startTime;
567
+ // const duration = endTime - startTime;
613
568
  // if (duration > 5) {
614
569
  // console.warn(`AtomixGlass: Mouse tracking took ${duration.toFixed(2)}ms`);
615
570
  // }
@@ -684,6 +639,16 @@ export function useAtomixGlass({
684
639
 
685
640
  // Transform calculations
686
641
  const calculateDirectionalScale = useCallback(() => {
642
+ // Disable directional scaling if overLight is active (to prevent zooming/distorting the premium glass effect)
643
+ const isOverLightActive =
644
+ overLight === true ||
645
+ (overLight === 'auto' && detectedOverLight) ||
646
+ (typeof overLight === 'object' && overLight !== null && detectedOverLight);
647
+
648
+ if (isOverLightActive) {
649
+ return 'scale(1)';
650
+ }
651
+
687
652
  if (
688
653
  !globalMousePosition.x ||
689
654
  !globalMousePosition.y ||
@@ -727,7 +692,14 @@ export function useAtomixGlass({
727
692
  Math.abs(normalizedX) * stretchIntensity * 0.15;
728
693
 
729
694
  return `scaleX(${Math.max(0.8, scaleX)}) scaleY(${Math.max(0.8, scaleY)})`;
730
- }, [globalMousePosition, elasticity, glassSize, glassRef]);
695
+ }, [
696
+ globalMousePosition,
697
+ elasticity,
698
+ glassSize,
699
+ glassRef,
700
+ overLight,
701
+ detectedOverLight,
702
+ ]);
731
703
 
732
704
  const calculateFadeInFactor = useCallback(() => {
733
705
  if (
@@ -937,11 +909,11 @@ export function useAtomixGlass({
937
909
  isOverLight,
938
910
  threshold: 0.7,
939
911
  opacity: baseOpacity,
940
- contrast: Math.min(1.8, Math.max(1.0, 1.4 + mouseInfluence * 0.3)),
941
- brightness: Math.min(1.2, Math.max(0.7, 0.85 + mouseInfluence * 0.15)),
942
- saturationBoost: Math.min(2.0, Math.max(1.0, 1.3 + mouseInfluence * 0.4)),
943
- shadowIntensity: Math.min(1.5, Math.max(0.5, 0.9 + mouseInfluence * 0.5)),
944
- borderOpacity: Math.min(1.0, Math.max(0.3, 0.7 + mouseInfluence * 0.3)),
912
+ contrast: Math.min(1.6, Math.max(1.0, 1.4 + mouseInfluence * 0.1)),
913
+ brightness: Math.min(1.1, Math.max(0.8, 0.9 + mouseInfluence * 0.05)),
914
+ saturationBoost: 1.3, // Fixed value dynamic saturation amplifies perceived displacement
915
+ shadowIntensity: Math.min(1.2, Math.max(0.5, 0.9 + mouseInfluence * 0.2)),
916
+ borderOpacity: Math.min(1.0, Math.max(0.3, 0.7 + mouseInfluence * 0.1)),
945
917
  };
946
918
 
947
919
  if (typeof overLight === 'object' && overLight !== null) {
@@ -958,9 +930,9 @@ export function useAtomixGlass({
958
930
  ...baseConfig,
959
931
  threshold: validatedThreshold,
960
932
  opacity: validatedOpacity * hoverIntensity * activeIntensity,
961
- contrast: validatedContrast + mouseInfluence * 0.3,
962
- brightness: validatedBrightness + mouseInfluence * 0.15,
963
- saturationBoost: validatedSaturationBoost + mouseInfluence * 0.4,
933
+ contrast: Math.min(1.6, validatedContrast + mouseInfluence * 0.1),
934
+ brightness: Math.min(1.1, validatedBrightness + mouseInfluence * 0.05),
935
+ saturationBoost: validatedSaturationBoost, // Use validated value directly, no mouse influence
964
936
  };
965
937
 
966
938
  // Debug logging
@@ -5,7 +5,7 @@ interface BreadcrumbOptions {
5
5
  items: BreadcrumbItem[];
6
6
  divider?: React.ReactNode;
7
7
  className?: string;
8
- ariaLabel?: string;
8
+ 'aria-label'?: string;
9
9
  }
10
10
 
11
11
  /**
@@ -19,7 +19,7 @@ export function useBreadcrumb(initialOptions?: Partial<BreadcrumbOptions>) {
19
19
  items: [],
20
20
  divider: BREADCRUMB.DEFAULTS.DIVIDER,
21
21
  className: '',
22
- ariaLabel: 'Breadcrumb',
22
+ 'aria-label': 'Breadcrumb',
23
23
  ...initialOptions,
24
24
  };
25
25
 
@@ -9,8 +9,8 @@ export function useCallout(initialProps?: Partial<CalloutProps>) {
9
9
  // Default callout properties
10
10
  const defaultProps: Partial<CalloutProps> = {
11
11
  variant: 'primary',
12
- oneLine: false,
13
- toast: false,
12
+ compact: false,
13
+ isToast: false,
14
14
  glass: false,
15
15
  ...initialProps,
16
16
  };
@@ -23,18 +23,18 @@ export function useCallout(initialProps?: Partial<CalloutProps>) {
23
23
  const generateCalloutClass = (props: Partial<CalloutProps>): string => {
24
24
  const {
25
25
  variant = defaultProps.variant,
26
- oneLine = defaultProps.oneLine,
27
- toast = defaultProps.toast,
26
+ compact = defaultProps.compact,
27
+ isToast = defaultProps.isToast,
28
28
  glass = defaultProps.glass,
29
29
  className = '',
30
30
  } = props;
31
31
 
32
- const oneLineClass = oneLine ? 'c-callout--oneline' : '';
33
- const toastClass = toast ? 'c-callout--toast' : '';
32
+ const compactClass = compact ? 'c-callout--compact' : '';
33
+ const toastClass = isToast ? 'c-callout--toast' : '';
34
34
  const variantClass = variant ? `c-callout--${variant}` : '';
35
35
  const glassClass = glass ? 'c-callout--glass' : '';
36
36
 
37
- return `c-callout ${variantClass} ${oneLineClass} ${toastClass} ${glassClass} ${className}`.trim();
37
+ return `c-callout ${variantClass} ${compactClass} ${toastClass} ${glassClass} ${className}`.trim();
38
38
  };
39
39
 
40
40
  /**
@@ -1,4 +1,5 @@
1
1
  import { useCallback, useRef } from 'react';
2
+ import { sanitizeCSVCell } from '../utils/csv';
2
3
 
3
4
  export interface ExportOptions {
4
5
  /**
@@ -180,13 +181,7 @@ export function useChartExport() {
180
181
 
181
182
  // Convert to CSV string with sanitization
182
183
  const csvContent = rows
183
- .map(row => row.map(cell => {
184
- // Sanitize cell content to prevent CSV injection
185
- const sanitized = String(cell).replace(/[\r\n\t]/g, ' ').replace(/"/g, '""');
186
- // Prevent formula injection by prefixing dangerous characters
187
- const dangerous = /^[=+\-@]/;
188
- return `"${dangerous.test(sanitized) ? `'${sanitized}` : sanitized}"`;
189
- }).join(','))
184
+ .map(row => row.map(cell => `"${sanitizeCSVCell(cell)}"`).join(','))
190
185
  .join('\n');
191
186
 
192
187
  // Download
@@ -328,47 +328,64 @@ export function useDataTable({
328
328
  setCurrentPage(1);
329
329
  }, []);
330
330
 
331
+ // Pre-process column filters to avoid redundant lookups and transformations
332
+ const activeColumnFilters = useMemo(() => {
333
+ if (!columnFilters) return [];
334
+
335
+ return Object.entries(columnFilterValues)
336
+ .filter(([, value]) => value !== undefined && value !== null && value !== '')
337
+ .map(([columnKey, value]) => {
338
+ const column = columns.find(col => col.key === columnKey);
339
+ if (!column || !column.filterable) return null;
340
+
341
+ return {
342
+ key: columnKey,
343
+ value,
344
+ lowercaseValue: typeof value === 'string' ? value.toLowerCase() : String(value).toLowerCase(),
345
+ column,
346
+ };
347
+ })
348
+ .filter((f): f is NonNullable<typeof f> => f !== null);
349
+ }, [columnFilters, columnFilterValues, columns]);
350
+
331
351
  // Filter data based on search query and column filters
332
352
  const filteredData = useMemo(() => {
333
- let result = data;
353
+ if (!searchQuery && activeColumnFilters.length === 0) {
354
+ return data;
355
+ }
334
356
 
335
- // Apply global search
336
- if (searchQuery) {
337
- const lowercaseQuery = searchQuery.toLowerCase();
338
- result = result.filter(row => {
339
- return visibleColumns.some(column => {
357
+ const lowercaseQuery = searchQuery ? searchQuery.toLowerCase() : '';
358
+
359
+ return data.filter(row => {
360
+ // Apply global search
361
+ if (searchQuery) {
362
+ const matchesGlobal = visibleColumns.some(column => {
340
363
  const value = row[column.key];
341
364
  if (value == null) return false;
342
365
  return String(value).toLowerCase().includes(lowercaseQuery);
343
366
  });
344
- });
345
- }
346
-
347
- // Apply column-specific filters
348
- if (columnFilters) {
349
- result = result.filter(row => {
350
- return Object.entries(columnFilterValues).every(([columnKey, filterValue]) => {
351
- if (!filterValue) return true;
352
-
353
- const column = columns.find(col => col.key === columnKey);
354
- if (!column || !column.filterable) return true;
367
+ if (!matchesGlobal) return false;
368
+ }
355
369
 
356
- const cellValue = row[columnKey];
357
- if (cellValue == null) return false;
370
+ // Apply column-specific filters
371
+ for (let i = 0; i < activeColumnFilters.length; i++) {
372
+ const { key, value, lowercaseValue, column } = activeColumnFilters[i];
373
+ const cellValue = row[key];
358
374
 
359
- // Use custom filter function if provided
360
- if (column.filterFunction) {
361
- return column.filterFunction(cellValue, filterValue);
362
- }
375
+ if (cellValue == null) return false;
363
376
 
377
+ // Use custom filter function if provided
378
+ if (column.filterFunction) {
379
+ if (!column.filterFunction(cellValue, value)) return false;
380
+ } else {
364
381
  // Default text filter
365
- return String(cellValue).toLowerCase().includes(filterValue.toLowerCase());
366
- });
367
- });
368
- }
382
+ if (!String(cellValue).toLowerCase().includes(lowercaseValue)) return false;
383
+ }
384
+ }
369
385
 
370
- return result;
371
- }, [data, visibleColumns, searchQuery, columnFilterValues, columnFilters, columns]);
386
+ return true;
387
+ });
388
+ }, [data, visibleColumns, searchQuery, activeColumnFilters]);
372
389
 
373
390
  // Sort data
374
391
  const sortedData = useMemo(() => {
@@ -17,7 +17,7 @@ export function useNavbar(initialProps?: Partial<NavbarProps>) {
17
17
  backdrop: false,
18
18
  closeOnOutsideClick: true,
19
19
  closeOnEscape: true,
20
- ariaLabel: 'Main navigation',
20
+ 'aria-label': 'Main navigation',
21
21
  ...initialProps,
22
22
  };
23
23
 
@@ -79,7 +79,7 @@ export const CALLOUT = {
79
79
  CLOSE_BTN_CLASS: 'c-callout__close-btn',
80
80
  VARIANT_PREFIX: 'c-callout--',
81
81
  CLASSES: {
82
- ONELINE: 'c-callout--oneline',
82
+ COMPACT: 'c-callout--compact',
83
83
  TOAST: 'c-callout--toast',
84
84
  HIDE: 'is-hide',
85
85
  },
@@ -1522,37 +1522,6 @@ export const BLOCK = {
1522
1522
  },
1523
1523
  };
1524
1524
 
1525
- /**
1526
- * GlassContainer-specific constants
1527
- */
1528
- export const GLASS_CONTAINER = {
1529
- CLASSES: {
1530
- BASE: 'c-glass-container',
1531
- GLASS: 'c-glass-container__glass',
1532
- WARP: 'c-glass-container__warp',
1533
- CONTENT: 'c-glass-container__content',
1534
- OVERLAY: 'c-glass-container__overlay',
1535
- OVERLAY_VISIBLE: 'c-glass-container__overlay--visible',
1536
- OVERLAY_HIDDEN: 'c-glass-container__overlay--hidden',
1537
- OVERLAY_BLEND: 'c-glass-container__overlay-blend',
1538
- BORDER: 'c-glass-container__border',
1539
- BORDER_OVERLAY: 'c-glass-container__border-overlay',
1540
- HOVER_EFFECT: 'c-glass-container__hover-effect',
1541
- ACTIVE_EFFECT: 'c-glass-container__active-effect',
1542
- INTERACTION_EFFECT: 'c-glass-container__interaction-effect',
1543
- ACTIVE: 'c-glass-container--active',
1544
- CLICKABLE: 'c-glass-container--clickable',
1545
- },
1546
- DISPLACEMENT_MAPS: {
1547
- STANDARD:
1548
- 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjcwIiBoZWlnaHQ9IjY5IiB2aWV3Qm94PSIwIDAgMjcwIDY5IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzPjxyYWRpYWxHcmFkaWVudCBpZD0iZ3JhZGllbnQiIGN4PSI1MCUiIGN5PSI1MCUiIHI9IjUwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzgwODA4MCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzgwODA4MCIvPjwvcmFkaWFsR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZGllbnQpIi8+PC9zdmc+',
1549
- POLAR:
1550
- 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjcwIiBoZWlnaHQ9IjY5IiB2aWV3Qm94PSIwIDAgMjcwIDY5IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzPjxyYWRpYWxHcmFkaWVudCBpZD0icG9sYXIiIGN4PSI1MCUiIGN5PSI1MCUiIHI9IjUwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzQwNDA0MCIvPjxzdG9wIG9mZnNldD0iNTAlIiBzdG9wLWNvbG9yPSIjODA4MDgwIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjNDA0MDQwIi8+PC9yYWRpYWxHcmFkaWVudD48L2RlZnM+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNwb2xhcikiLz48L3N2Zz4=',
1551
- PROMINENT:
1552
- 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjcwIiBoZWlnaHQ9IjY5IiB2aWV3Qm94PSIwIDAgMjcwIDY5IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0icHJvbWluZW50IiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj48c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjNDA0MDQwIi8+PHN0b3Agb2Zmc2V0PSI1MCUiIHN0b3AtY29sb3I9IiNjMGMwYzAiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM0MDQwNDAiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI3Byb21pbmVudCkiLz48L3N2Zz4=',
1553
- },
1554
- };
1555
-
1556
1525
  /**
1557
1526
  * Footer-specific constants
1558
1527
  */
@@ -1698,9 +1667,17 @@ export const ATOMIX_GLASS = {
1698
1667
  MIN_BLUR: 0.1,
1699
1668
  MOUSE_INFLUENCE_DIVISOR: 100,
1700
1669
  EDGE_FADE_PIXELS: 2,
1701
- DEFAULT_CORNER_RADIUS: 16, // Fallback value matching design system
1670
+ // Note: This default must match the SCSS variable --atomix-radius-md
1671
+ // @see src/styles/01-settings/_settings.global.scss
1672
+ DEFAULT_CORNER_RADIUS: 16,
1702
1673
  MAX_SIZE: 4096, // Maximum width/height for glass size
1703
1674
 
1675
+ // Palette for internal calculations (matches design system base colors)
1676
+ PALETTE: {
1677
+ WHITE: '255, 255, 255',
1678
+ BLACK: '0, 0, 0',
1679
+ },
1680
+
1704
1681
  // Gradient calculation constants
1705
1682
  GRADIENT: {
1706
1683
  BASE_ANGLE: 135, // Base angle for border gradients (degrees)
@@ -0,0 +1,113 @@
1
+ import React from 'react';
2
+
3
+ interface ControlOption {
4
+ type: 'select' | 'slider' | 'text' | 'checkbox';
5
+ label: string;
6
+ value: any;
7
+ onChange: (value: any) => void;
8
+ options?: string[];
9
+ min?: number;
10
+ max?: number;
11
+ step?: number;
12
+ }
13
+
14
+ interface InteractiveDemoProps {
15
+ controls: ControlOption[];
16
+ children: React.ReactNode;
17
+ }
18
+
19
+ export const InteractiveDemo: React.FC<InteractiveDemoProps> = ({
20
+ controls,
21
+ children,
22
+ }) => {
23
+ const renderControl = (control: ControlOption, index: number) => {
24
+ const baseId = `control-${index}`;
25
+
26
+ switch (control.type) {
27
+ case 'select':
28
+ return (
29
+ <div key={baseId} className="mb-4">
30
+ <label htmlFor={baseId} className="block text-sm font-medium mb-2">
31
+ {control.label}
32
+ </label>
33
+ <select
34
+ id={baseId}
35
+ value={control.value}
36
+ onChange={(e) => control.onChange(e.target.value)}
37
+ className="w-full px-3 py-2 border rounded-lg"
38
+ >
39
+ {control.options?.map((option) => (
40
+ <option key={option} value={option}>
41
+ {option}
42
+ </option>
43
+ ))}
44
+ </select>
45
+ </div>
46
+ );
47
+
48
+ case 'slider':
49
+ return (
50
+ <div key={baseId} className="mb-4">
51
+ <label htmlFor={baseId} className="block text-sm font-medium mb-2">
52
+ {control.label}: {control.value}
53
+ </label>
54
+ <input
55
+ id={baseId}
56
+ type="range"
57
+ min={control.min}
58
+ max={control.max}
59
+ step={control.step}
60
+ value={control.value}
61
+ onChange={(e) => control.onChange(Number(e.target.value))}
62
+ className="w-full"
63
+ />
64
+ </div>
65
+ );
66
+
67
+ case 'text':
68
+ return (
69
+ <div key={baseId} className="mb-4">
70
+ <label htmlFor={baseId} className="block text-sm font-medium mb-2">
71
+ {control.label}
72
+ </label>
73
+ <input
74
+ id={baseId}
75
+ type="text"
76
+ value={control.value}
77
+ onChange={(e) => control.onChange(e.target.value)}
78
+ className="w-full px-3 py-2 border rounded-lg"
79
+ />
80
+ </div>
81
+ );
82
+
83
+ case 'checkbox':
84
+ return (
85
+ <div key={baseId} className="mb-4">
86
+ <label className="flex items-center space-x-2">
87
+ <input
88
+ type="checkbox"
89
+ checked={control.value}
90
+ onChange={(e) => control.onChange(e.target.checked)}
91
+ className="rounded"
92
+ />
93
+ <span className="text-sm font-medium">{control.label}</span>
94
+ </label>
95
+ </div>
96
+ );
97
+
98
+ default:
99
+ return null;
100
+ }
101
+ };
102
+
103
+ return (
104
+ <div className="bg-white rounded-lg shadow-lg p-6 mb-8">
105
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-6">
106
+ {controls.map(renderControl)}
107
+ </div>
108
+ <div className="border-t pt-6">
109
+ {children}
110
+ </div>
111
+ </div>
112
+ );
113
+ };
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+
3
+ interface PreviewContainerProps {
4
+ title: string;
5
+ description: string;
6
+ backgroundImage?: string;
7
+ children: React.ReactNode;
8
+ }
9
+
10
+ export const PreviewContainer: React.FC<PreviewContainerProps> = ({
11
+ title,
12
+ description,
13
+ backgroundImage,
14
+ children,
15
+ }) => {
16
+ const containerStyle = backgroundImage
17
+ ? {
18
+ backgroundImage: `url(${backgroundImage})`,
19
+ backgroundSize: 'cover',
20
+ backgroundPosition: 'center',
21
+ minHeight: '100vh',
22
+ }
23
+ : {};
24
+
25
+ return (
26
+ <div style={containerStyle} className="w-full">
27
+ <div className="max-w-7xl mx-auto p-6">
28
+ <div className="mb-8">
29
+ <h1 className="text-3xl font-bold text-gray-900 mb-2">{title}</h1>
30
+ <p className="text-gray-600">{description}</p>
31
+ </div>
32
+ {children}
33
+ </div>
34
+ </div>
35
+ );
36
+ };
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+
3
+ interface VariantsGridProps {
4
+ children: React.ReactNode;
5
+ columns?: number;
6
+ gap?: string;
7
+ }
8
+
9
+ export const VariantsGrid: React.FC<VariantsGridProps> = ({
10
+ children,
11
+ columns = 4,
12
+ gap = 'gap-4',
13
+ }) => {
14
+ const gridClass = `grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-${columns} ${gap}`;
15
+
16
+ return (
17
+ <div className={gridClass}>
18
+ {children}
19
+ </div>
20
+ );
21
+ };
@@ -0,0 +1,3 @@
1
+ export { PreviewContainer } from './PreviewContainer';
2
+ export { VariantsGrid } from './VariantsGrid';
3
+ export { InteractiveDemo } from './InteractiveDemo';
@@ -296,8 +296,12 @@ function createBreakpoints(breakpointsInput?: BreakpointsOptions): Theme['breakp
296
296
  * @returns Complete theme object
297
297
  */
298
298
  export function createThemeObject(...options: ThemeOptions[]): Theme {
299
- // Merge all options
300
- const mergedOptions = options.reduce((acc, option) => deepMerge(acc, option), {} as ThemeOptions);
299
+ // Merge all options by spreading them into a single object
300
+ const mergedOptions = options.reduce((acc, option) => {
301
+ // Cast option to any to avoid strict typing during merge
302
+ const opt = option as any;
303
+ return deepMerge(acc, opt || {}) as any;
304
+ }, {} as any);
301
305
 
302
306
  // Create palette
303
307
  const palette: Theme['palette'] = {
@@ -342,9 +346,9 @@ export function createThemeObject(...options: ThemeOptions[]): Theme {
342
346
 
343
347
  // Create transitions
344
348
  const transitions: Theme['transitions'] = deepMerge(
345
- { ...DEFAULT_TRANSITIONS },
346
- mergedOptions.transitions || {}
347
- );
349
+ { ...DEFAULT_TRANSITIONS } as Partial<Theme['transitions']>,
350
+ (mergedOptions.transitions || {}) as Partial<Theme['transitions']>
351
+ ) as Theme['transitions'];
348
352
 
349
353
  // Create z-index
350
354
  const zIndex: Theme['zIndex'] = deepMerge({ ...DEFAULT_ZINDEX }, mergedOptions.zIndex || {});