@shohojdhara/atomix 0.5.1 → 0.5.4

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 (145) hide show
  1. package/atomix.config.ts +45 -33
  2. package/build-tools/webpack-loader.js +5 -4
  3. package/dist/atomix.css +138 -17
  4. package/dist/atomix.css.map +1 -1
  5. package/dist/atomix.min.css +1 -1
  6. package/dist/atomix.min.css.map +1 -1
  7. package/dist/build-tools/webpack-loader.js +5 -4
  8. package/dist/charts.d.ts +23 -23
  9. package/dist/charts.js +40 -37
  10. package/dist/charts.js.map +1 -1
  11. package/dist/config.d.ts +699 -0
  12. package/dist/config.js +17 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/core.d.ts +2 -2
  15. package/dist/core.js +111 -50
  16. package/dist/core.js.map +1 -1
  17. package/dist/forms.d.ts +3 -6
  18. package/dist/forms.js +2 -2
  19. package/dist/forms.js.map +1 -1
  20. package/dist/heavy.d.ts +1 -1
  21. package/dist/heavy.js +173 -111
  22. package/dist/heavy.js.map +1 -1
  23. package/dist/index.d.ts +1881 -790
  24. package/dist/index.esm.js +2713 -816
  25. package/dist/index.esm.js.map +1 -1
  26. package/dist/index.js +2693 -780
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.min.js +1 -1
  29. package/dist/index.min.js.map +1 -1
  30. package/dist/layout.js +59 -60
  31. package/dist/layout.js.map +1 -1
  32. package/dist/theme.d.ts +1390 -276
  33. package/dist/theme.js +2133 -625
  34. package/dist/theme.js.map +1 -1
  35. package/package.json +14 -9
  36. package/scripts/atomix-cli.js +15 -1
  37. package/scripts/cli/__tests__/complexity-utils.test.js +24 -0
  38. package/scripts/cli/__tests__/detector.test.js +50 -0
  39. package/scripts/cli/__tests__/template-engine.test.js +23 -0
  40. package/scripts/cli/__tests__/test-setup.js +3 -0
  41. package/scripts/cli/commands/doctor.js +15 -3
  42. package/scripts/cli/commands/generate.js +113 -51
  43. package/scripts/cli/internal/ai-engine.js +30 -10
  44. package/scripts/cli/internal/complexity-utils.js +60 -0
  45. package/scripts/cli/internal/component-validator.js +49 -16
  46. package/scripts/cli/internal/config-loader.js +30 -20
  47. package/scripts/cli/internal/generator.js +89 -36
  48. package/scripts/cli/internal/hook-generator.js +5 -2
  49. package/scripts/cli/internal/itcss-generator.js +16 -12
  50. package/scripts/cli/templates/next-templates.js +81 -30
  51. package/scripts/cli/templates/storybook-templates.js +12 -2
  52. package/scripts/cli/utils/detector.js +45 -7
  53. package/scripts/cli/utils/diagnostics.js +78 -0
  54. package/scripts/cli/utils/telemetry.js +13 -0
  55. package/src/components/Accordion/Accordion.stories.tsx +4 -0
  56. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +1 -1
  57. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +219 -0
  58. package/src/components/AtomixGlass/glass-utils.ts +1 -1
  59. package/src/components/Button/Button.tsx +114 -57
  60. package/src/components/Callout/Callout.tsx +4 -4
  61. package/src/components/Chart/ChartRenderer.tsx +1 -1
  62. package/src/components/Chart/DonutChart.tsx +11 -8
  63. package/src/components/EdgePanel/EdgePanel.tsx +119 -115
  64. package/src/components/Form/Select.tsx +4 -4
  65. package/src/components/List/List.tsx +4 -4
  66. package/src/components/Navigation/SideMenu/SideMenu.tsx +6 -6
  67. package/src/components/PhotoViewer/PhotoViewerImage.tsx +1 -1
  68. package/src/components/ProductReview/ProductReview.tsx +4 -2
  69. package/src/components/Rating/Rating.tsx +4 -2
  70. package/src/components/SectionIntro/SectionIntro.tsx +4 -2
  71. package/src/components/Steps/Steps.tsx +1 -1
  72. package/src/components/Tabs/Tabs.tsx +5 -5
  73. package/src/components/Testimonial/Testimonial.tsx +4 -2
  74. package/src/components/VideoPlayer/VideoPlayer.tsx +4 -2
  75. package/src/layouts/CssGrid/CssGrid.stories.tsx +464 -0
  76. package/src/layouts/CssGrid/CssGrid.tsx +215 -0
  77. package/src/layouts/CssGrid/index.ts +8 -0
  78. package/src/layouts/CssGrid/scripts/CssGrid.js +284 -0
  79. package/src/layouts/CssGrid/scripts/index.js +43 -0
  80. package/src/layouts/Grid/scripts/Container.js +139 -0
  81. package/src/layouts/Grid/scripts/Grid.js +184 -0
  82. package/src/layouts/Grid/scripts/GridCol.js +273 -0
  83. package/src/layouts/Grid/scripts/Row.js +154 -0
  84. package/src/layouts/Grid/scripts/index.js +48 -0
  85. package/src/layouts/MasonryGrid/MasonryGrid.tsx +71 -59
  86. package/src/lib/composables/atomix-glass/useGlassSize.ts +1 -1
  87. package/src/lib/composables/useAccordion.ts +5 -5
  88. package/src/lib/composables/useAtomixGlass.ts +3 -3
  89. package/src/lib/composables/useBarChart.ts +2 -2
  90. package/src/lib/composables/useChart.ts +3 -2
  91. package/src/lib/composables/useChartToolbar.ts +48 -66
  92. package/src/lib/composables/useDataTable.ts +1 -1
  93. package/src/lib/composables/useDatePicker.ts +2 -2
  94. package/src/lib/composables/useEdgePanel.ts +45 -54
  95. package/src/lib/composables/useHeroBackgroundSlider.ts +5 -5
  96. package/src/lib/composables/usePhotoViewer.ts +2 -3
  97. package/src/lib/composables/usePieChart.ts +1 -1
  98. package/src/lib/composables/usePopover.ts +151 -139
  99. package/src/lib/composables/useSideMenu.ts +28 -41
  100. package/src/lib/composables/useSlider.ts +2 -6
  101. package/src/lib/composables/useTooltip.ts +2 -2
  102. package/src/lib/config/index.ts +38 -323
  103. package/src/lib/config/loader.ts +419 -0
  104. package/src/lib/config/public-api.ts +43 -0
  105. package/src/lib/config/types.ts +389 -0
  106. package/src/lib/config/validator.ts +305 -0
  107. package/src/lib/theme/adapters/index.ts +1 -1
  108. package/src/lib/theme/adapters/themeAdapter.ts +358 -229
  109. package/src/lib/theme/components/ThemeToggle.tsx +276 -0
  110. package/src/lib/theme/config/configLoader.ts +351 -0
  111. package/src/lib/theme/config/loader.ts +221 -0
  112. package/src/lib/theme/core/createTheme.ts +126 -50
  113. package/src/lib/theme/core/createThemeObject.ts +7 -4
  114. package/src/lib/theme/devtools/Comparator.tsx +1 -1
  115. package/src/lib/theme/devtools/Inspector.tsx +1 -1
  116. package/src/lib/theme/devtools/LiveEditor.tsx +1 -1
  117. package/src/lib/theme/hooks/useThemeSwitcher.ts +164 -0
  118. package/src/lib/theme/index.ts +322 -38
  119. package/src/lib/theme/runtime/ThemeProvider.tsx +45 -11
  120. package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +44 -393
  121. package/src/lib/theme/runtime/useTheme.ts +1 -0
  122. package/src/lib/theme/tokens/tokens.ts +101 -1
  123. package/src/lib/theme/types.ts +91 -0
  124. package/src/lib/theme/utils/performanceMonitor.ts +315 -0
  125. package/src/lib/theme/utils/responsive.ts +280 -0
  126. package/src/lib/theme/utils/themeUtils.ts +531 -117
  127. package/src/styles/01-settings/_index.scss +1 -0
  128. package/src/styles/01-settings/_settings.atomix-glass.scss +174 -0
  129. package/src/styles/01-settings/_settings.masonry-grid.scss +42 -6
  130. package/src/styles/02-tools/_tools.glass.scss +6 -0
  131. package/src/styles/05-objects/_objects.masonry-grid.scss +162 -24
  132. package/src/styles/06-components/_components.atomix-glass.scss +4 -4
  133. package/src/lib/composables/useBreadcrumb.ts +0 -81
  134. package/src/lib/composables/useChartInteractions.ts +0 -123
  135. package/src/lib/composables/useChartPerformance.ts +0 -347
  136. package/src/lib/composables/useDropdown.ts +0 -338
  137. package/src/lib/composables/useModal.ts +0 -110
  138. package/src/lib/hooks/usePerformanceMonitor.ts +0 -148
  139. package/src/lib/utils/displacement-generator.ts +0 -92
  140. package/src/lib/utils/memoryMonitor.ts +0 -191
  141. package/src/styles/01-settings/_settings.testtypecheck.scss +0 -53
  142. package/src/styles/01-settings/_settings.typedbutton.scss +0 -53
  143. package/src/styles/06-components/_components.testbutton.scss +0 -212
  144. package/src/styles/06-components/_components.testtypecheck.scss +0 -212
  145. package/src/styles/06-components/_components.typedbutton.scss +0 -212
@@ -3,22 +3,40 @@
3
3
  * Optimized for Server Components and App Router
4
4
  */
5
5
 
6
+ /**
7
+ * Simple Server Component — valid displayName, Props, JSDoc, a11y; no forwardRef (server).
8
+ */
6
9
  export const nextTemplates = {
7
- /**
8
- * Simple Server Component
9
- */
10
- simple: (name) => `/**
11
- * ${name} Component (Server Component)
10
+ simple: (name) => `import React from 'react';
11
+
12
+ export interface ${name}Props {
13
+ /** Optional heading override */
14
+ title?: string;
15
+ children?: React.ReactNode;
16
+ }
17
+
18
+ /**
19
+ * ${name} — presentational server component (Atomix scaffold).
20
+ *
21
+ * @param props - ${name} properties
12
22
  */
13
- import React from 'react';
23
+ export default function ${name}(props: ${name}Props) {
24
+ const { title = '${name}', children } = props;
14
25
 
15
- export default function ${name}() {
16
26
  return (
17
- <div className="${name.toLowerCase()}">
18
- <h1>${name} Component</h1>
19
- </div>
27
+ <section
28
+ className={\`c-${name.toLowerCase()}\`}
29
+ role="region"
30
+ aria-label={title}
31
+ data-testid="${name.toLowerCase()}-root"
32
+ >
33
+ <h1 className={\`c-${name.toLowerCase()}__title\`}>{title}</h1>
34
+ {children}
35
+ </section>
20
36
  );
21
37
  }
38
+
39
+ ${name}.displayName = '${name}';
22
40
  `,
23
41
 
24
42
  /**
@@ -26,47 +44,80 @@ export default function ${name}() {
26
44
  */
27
45
  client: (name) => `'use client';
28
46
 
47
+ import React, { forwardRef, useState } from 'react';
48
+
49
+ export interface ${name}Props {
50
+ title?: string;
51
+ children?: React.ReactNode;
52
+ className?: string;
53
+ }
54
+
29
55
  /**
30
- * ${name} Component (Client Component)
56
+ * ${name} client component with local state (Atomix scaffold).
31
57
  */
32
- import React, { useState } from 'react';
33
-
34
- export default function ${name}() {
58
+ const ${name}Inner = forwardRef<HTMLDivElement, ${name}Props>(function ${name}Inner(
59
+ { title = '${name}', children, className = '' },
60
+ ref
61
+ ) {
35
62
  const [active, setActive] = useState(false);
36
63
 
37
64
  return (
38
- <div className="${name.toLowerCase()}">
39
- <h1>${name} Component</h1>
40
- <button onClick={() => setActive(!active)}>
65
+ <section
66
+ ref={ref}
67
+ className={[\`c-${name.toLowerCase()}\`, className].filter(Boolean).join(' ')}
68
+ role="region"
69
+ aria-label={title}
70
+ data-testid="${name.toLowerCase()}-root"
71
+ >
72
+ <h1 className={\`c-${name.toLowerCase()}__title\`}>{title}</h1>
73
+ {children}
74
+ <button type="button" onClick={() => setActive(!active)} aria-pressed={active}>
41
75
  Toggle: {active ? 'On' : 'Off'}
42
76
  </button>
43
- </div>
77
+ </section>
44
78
  );
45
- }
79
+ });
80
+
81
+ ${name}Inner.displayName = '${name}';
82
+
83
+ export default ${name}Inner;
46
84
  `,
47
85
 
48
86
  /**
49
87
  * Complex Server Component with async data
50
88
  */
51
- complex: (name) => `/**
52
- * ${name} Component (Server Component with Data)
53
- */
54
- import React from 'react';
89
+ complex: (name) => `import React from 'react';
55
90
 
56
- async function getData() {
57
- // Simulating data fetch
91
+ export interface ${name}Props {
92
+ title?: string;
93
+ }
94
+
95
+ async function getData(): Promise<{ title: string }> {
58
96
  return { title: '${name}' };
59
97
  }
60
98
 
61
- export default async function ${name}() {
99
+ /**
100
+ * ${name} — async server component (Atomix scaffold).
101
+ */
102
+ async function ${name}(props: ${name}Props) {
62
103
  const data = await getData();
104
+ const title = props.title ?? data.title;
63
105
 
64
106
  return (
65
- <div className="${name.toLowerCase()}">
66
- <h1>{data.title}</h1>
67
- <p>This is a complex Next.js server component.</p>
68
- </div>
107
+ <section
108
+ className={\`c-${name.toLowerCase()}\`}
109
+ role="region"
110
+ aria-label={title}
111
+ data-testid="${name.toLowerCase()}-root"
112
+ >
113
+ <h1>{title}</h1>
114
+ <p>This is a complex Next.js server component scaffold.</p>
115
+ </section>
69
116
  );
70
117
  }
118
+
119
+ ${name}.displayName = '${name}';
120
+
121
+ export default ${name};
71
122
  `
72
123
  };
@@ -5,8 +5,13 @@
5
5
 
6
6
  /**
7
7
  * Basic Storybook story template
8
+ * @param {string} name - Component name
9
+ * @param {{ storybookCssImport?: string }} [opts]
8
10
  */
9
- export const basicStoryTemplate = (name) => `import type { Meta, StoryObj } from '@storybook/react';
11
+ export const basicStoryTemplate = (name, opts = {}) => {
12
+ const cssImport = opts.storybookCssImport || '@shohojdhara/atomix/scss';
13
+ return `import '${cssImport}';
14
+ import type { Meta, StoryObj } from '@storybook/react';
10
15
  import { ${name} } from './${name}';
11
16
 
12
17
  const meta: Meta<typeof ${name}> = {
@@ -66,11 +71,15 @@ export const Glass: Story = {
66
71
  },
67
72
  };
68
73
  `;
74
+ };
69
75
 
70
76
  /**
71
77
  * Enhanced Storybook story template with detailed documentation
72
78
  */
73
- export const enhancedStoryTemplate = (name) => `import type { Meta, StoryObj } from '@storybook/react';
79
+ export const enhancedStoryTemplate = (name, opts = {}) => {
80
+ const cssImport = opts.storybookCssImport || '@shohojdhara/atomix/scss';
81
+ return `import '${cssImport}';
82
+ import type { Meta, StoryObj } from '@storybook/react';
74
83
  import { ${name} } from './${name}';
75
84
 
76
85
  const meta: Meta<typeof ${name}> = {
@@ -226,6 +235,7 @@ export const CustomContent: Story = {
226
235
  },
227
236
  };
228
237
  `;
238
+ };
229
239
 
230
240
  /**
231
241
  * Storybook templates object
@@ -7,15 +7,52 @@ import { readFile } from 'fs/promises';
7
7
  import { join } from 'path';
8
8
  import { existsSync } from 'fs';
9
9
 
10
+ const NEXT_CONFIG_FILES = [
11
+ 'next.config.js',
12
+ 'next.config.mjs',
13
+ 'next.config.ts',
14
+ 'next.config.cjs'
15
+ ];
16
+
17
+ const VITE_CONFIG_FILES = [
18
+ 'vite.config.js',
19
+ 'vite.config.mjs',
20
+ 'vite.config.ts',
21
+ 'vite.config.cjs'
22
+ ];
23
+
24
+ function hasFileInRoot(projectRoot, filenames) {
25
+ return filenames.some((name) => existsSync(join(projectRoot, name)));
26
+ }
27
+
28
+ function hasNextSignals(projectRoot, allDeps) {
29
+ if (allDeps.next) return true;
30
+ return hasFileInRoot(projectRoot, NEXT_CONFIG_FILES);
31
+ }
32
+
33
+ function hasViteSignals(projectRoot, allDeps) {
34
+ if (allDeps.vite) return true;
35
+ return hasFileInRoot(projectRoot, VITE_CONFIG_FILES);
36
+ }
37
+
10
38
  /**
11
39
  * Detect the framework from package.json and project structure
12
40
  * @param {string} projectRoot - The root directory of the project
41
+ * @param {{ framework?: string }} [options] - Optional override: 'react' | 'next' | 'vanilla'
13
42
  * @returns {Promise<'react' | 'next' | 'vanilla'>}
14
43
  */
15
- export async function detectFramework(projectRoot = process.cwd()) {
44
+ export async function detectFramework(projectRoot = process.cwd(), options = {}) {
45
+ const override = options.framework;
46
+ if (override) {
47
+ const o = String(override).toLowerCase();
48
+ if (o === 'react' || o === 'next' || o === 'vanilla') {
49
+ return o;
50
+ }
51
+ }
52
+
16
53
  try {
17
54
  const packageJsonPath = join(projectRoot, 'package.json');
18
-
55
+
19
56
  if (!existsSync(packageJsonPath)) {
20
57
  return 'vanilla';
21
58
  }
@@ -26,17 +63,18 @@ export async function detectFramework(projectRoot = process.cwd()) {
26
63
  ...(packageJson.devDependencies || {})
27
64
  };
28
65
 
29
- if (allDeps.next) {
66
+ if (hasNextSignals(projectRoot, allDeps)) {
30
67
  return 'next';
31
68
  }
32
69
 
33
- if (allDeps.react) {
70
+ const hasReact = Boolean(allDeps.react);
71
+
72
+ if (hasViteSignals(projectRoot, allDeps) && hasReact) {
34
73
  return 'react';
35
74
  }
36
75
 
37
- // Check for framework specific files
38
- if (existsSync(join(projectRoot, 'next.config.js')) || existsSync(join(projectRoot, 'next.config.mjs'))) {
39
- return 'next';
76
+ if (hasReact) {
77
+ return 'react';
40
78
  }
41
79
 
42
80
  return 'vanilla';
@@ -9,6 +9,7 @@ import { join } from 'path';
9
9
  import { readFile } from 'fs/promises';
10
10
  import { logger } from './logger.js';
11
11
  import { configLoader } from '../internal/config-loader.js';
12
+ import { templateEngine } from '../internal/template-engine.js';
12
13
 
13
14
  /**
14
15
  * Check Node.js and NPM versions
@@ -256,6 +257,83 @@ export async function checkTokens(projectRoot = process.cwd()) {
256
257
  return results;
257
258
  }
258
259
 
260
+ /**
261
+ * Generator: writable output path, optional Storybook, template registry
262
+ */
263
+ export async function checkGenerator(projectRoot = process.cwd()) {
264
+ const results = [];
265
+
266
+ const config = await configLoader.load(projectRoot);
267
+ const gen = config.generator || {};
268
+ const out = gen.outputPath || './src/components';
269
+ const outPath = join(projectRoot, out);
270
+
271
+ if (existsSync(outPath)) {
272
+ try {
273
+ accessSync(outPath, constants.W_OK);
274
+ results.push({
275
+ name: 'Generator: output path',
276
+ status: 'pass',
277
+ message: `Writable: ${out}`,
278
+ suggestion: null
279
+ });
280
+ } catch {
281
+ results.push({
282
+ name: 'Generator: output path',
283
+ status: 'fail',
284
+ message: `Not writable: ${out}`,
285
+ suggestion: 'Fix permissions or set generator.outputPath in atomix.config.'
286
+ });
287
+ }
288
+ } else {
289
+ results.push({
290
+ name: 'Generator: output path',
291
+ status: 'warn',
292
+ message: `Missing (will be created): ${out}`,
293
+ suggestion: 'Create the directory or run generate to scaffold components.'
294
+ });
295
+ }
296
+
297
+ const storybookHints = ['@storybook/react', '@storybook/react-vite', '@storybook/nextjs', 'storybook'];
298
+ let hasStorybook = false;
299
+ const pkgPath = join(projectRoot, 'package.json');
300
+ if (existsSync(pkgPath)) {
301
+ try {
302
+ const pkg = JSON.parse(await readFile(pkgPath, 'utf8'));
303
+ const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
304
+ hasStorybook = storybookHints.some((d) => Boolean(deps[d]));
305
+ } catch {
306
+ /* ignore */
307
+ }
308
+ }
309
+
310
+ results.push({
311
+ name: 'Storybook (optional)',
312
+ status: hasStorybook ? 'pass' : 'warn',
313
+ message: hasStorybook ? 'Storybook-related dependency found' : 'No Storybook in package.json',
314
+ suggestion: hasStorybook ? null : 'Add Storybook if you rely on generated .stories.tsx files.'
315
+ });
316
+
317
+ try {
318
+ const frameworks = templateEngine.getSupportedFrameworks();
319
+ results.push({
320
+ name: 'Generator: template registry',
321
+ status: frameworks.length ? 'pass' : 'fail',
322
+ message: frameworks.length ? `Frameworks: ${frameworks.join(', ')}` : 'Empty registry',
323
+ suggestion: frameworks.length ? null : 'CLI template registry failed to load.'
324
+ });
325
+ } catch (error) {
326
+ results.push({
327
+ name: 'Generator: template registry',
328
+ status: 'fail',
329
+ message: error.message,
330
+ suggestion: 'Reinstall the Atomix package or check scripts/cli installation.'
331
+ });
332
+ }
333
+
334
+ return results;
335
+ }
336
+
259
337
  /**
260
338
  * Check directory permissions
261
339
  */
@@ -14,6 +14,16 @@ class Telemetry {
14
14
  this.logs = [];
15
15
  this.startTime = null;
16
16
  this.currentCommand = null;
17
+ /** @type {Record<string, unknown>} */
18
+ this.pendingExtra = {};
19
+ }
20
+
21
+ /**
22
+ * Merge fields into the next stop() log entry (e.g. generate framework).
23
+ * @param {Record<string, unknown>} extra
24
+ */
25
+ recordExtra(extra) {
26
+ this.pendingExtra = { ...this.pendingExtra, ...extra };
17
27
  }
18
28
 
19
29
  /**
@@ -43,9 +53,12 @@ class Telemetry {
43
53
  duration: parseFloat(duration.toFixed(2)),
44
54
  timestamp: new Date().toISOString(),
45
55
  success,
56
+ ...this.pendingExtra,
46
57
  ...extra
47
58
  };
48
59
 
60
+ this.pendingExtra = {};
61
+
49
62
  // Anonymize if needed
50
63
  if (config.anonymize !== false) {
51
64
  delete logEntry.path;
@@ -263,6 +263,10 @@ export const WithAllProps: Story = {
263
263
  };
264
264
 
265
265
  export const CompoundUsage: Story = {
266
+ args: {
267
+ title: 'Compound Accordion Example',
268
+ children: <p>Compound pattern content</p>
269
+ },
266
270
  render: args => (
267
271
  <Accordion {...args}>
268
272
  <Accordion.Header>
@@ -93,7 +93,7 @@ interface AtomixGlassContainerProps
93
93
  // Phase 1: Animation System props
94
94
  shaderTime?: number;
95
95
 
96
- contentRef?: React.RefObject<HTMLDivElement>;
96
+ contentRef?: React.RefObject<HTMLDivElement | null>;
97
97
  children?: React.ReactNode;
98
98
  }
99
99
 
@@ -0,0 +1,219 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`AtomixGlass Visual Regression > matches snapshot with default props 1`] = `
4
+ <div>
5
+ <div
6
+ class="c-atomix-glass"
7
+ style="--atomix-glass-radius: 16px; --atomix-glass-transform: translate(0px, 0px) scale(1); --atomix-glass-container-position: absolute; --atomix-glass-position: absolute; --atomix-glass-top: 0px; --atomix-glass-left: 0px; --atomix-glass-right: auto; --atomix-glass-bottom: auto; --atomix-glass-width: 100%; --atomix-glass-height: 100%; --atomix-glass-border-width: var(--atomix-spacing-0-5, 0.125rem); --atomix-glass-blend-mode: overlay; --atomix-glass-border-gradient-1: linear-gradient(135deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.08399999999999999) 33%, rgba(255, 255, 255, 0.27999999999999997) 66%, rgba(255, 255, 255, 0) 100%); --atomix-glass-border-gradient-2: linear-gradient(135deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.22399999999999998) 33%, rgba(255, 255, 255, 0.42) 66%, rgba(255, 255, 255, 0) 100%); --atomix-glass-hover-1-opacity: 0; --atomix-glass-hover-1-gradient: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 50%); --atomix-glass-hover-2-opacity: 0; --atomix-glass-hover-2-gradient: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 80%); --atomix-glass-hover-3-opacity: 0; --atomix-glass-hover-3-gradient: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); --atomix-glass-base-opacity: 0; --atomix-glass-base-gradient: rgba(255, 255, 255, 0.1); --atomix-glass-overlay-opacity: 0; --atomix-glass-overlay-gradient: rgba(255, 255, 255, 0.05); --atomix-glass-overlay-highlight-opacity: 0; --atomix-glass-overlay-highlight-bg: radial-gradient(circle at 20% 20%, rgba(255, 255, 255, 0.4) 0%, transparent 60%); --atomix-glass-hover-1-opacity: 0; --atomix-glass-hover-2-opacity: 0; --atomix-glass-hover-3-opacity: 0; --atomix-glass-base-opacity: 0; --atomix-glass-overlay-opacity: 0; --atomix-glass-overlay-highlight-opacity: 0;"
8
+ >
9
+ <div
10
+ class="c-atomix-glass__container "
11
+ style="--atomix-glass-container-radius: 16px; --atomix-glass-container-backdrop: blur(0.1px) saturate(140%) contrast(1.4) brightness(0.9); --atomix-glass-container-shadow: 0 0 20px rgba(0, 0, 0, 0.15) inset, 0 4px 8px rgba(0, 0, 0, 0.08) inset; --atomix-glass-container-shadow-opacity: 1; --atomix-glass-container-bg: none; --atomix-glass-container-text-shadow: 0px 2px 12px rgba(0, 0, 0, 0.4); --atomix-glass-container-box-shadow: 0px 12px 40px rgba(0, 0, 0, 0.25); --atomix-glass-container-padding: 0;"
12
+ >
13
+ <div
14
+ class="c-atomix-glass__inner"
15
+ >
16
+ <div
17
+ class="c-atomix-glass__filter"
18
+ >
19
+ <svg
20
+ aria-hidden="true"
21
+ style="position: absolute; width: 100%; height: 100%; inset: 0;"
22
+ >
23
+ <defs>
24
+ <radialgradient
25
+ cx="50%"
26
+ cy="50%"
27
+ id="atomix-glass-filter-_r_f_-edge-mask"
28
+ r="50%"
29
+ >
30
+ <stop
31
+ offset="0%"
32
+ stop-color="black"
33
+ stop-opacity="0"
34
+ />
35
+ <stop
36
+ offset="76%"
37
+ stop-color="black"
38
+ stop-opacity="0"
39
+ />
40
+ <stop
41
+ offset="100%"
42
+ stop-color="white"
43
+ stop-opacity="1"
44
+ />
45
+ </radialgradient>
46
+ <filter
47
+ color-interpolation-filters="sRGB"
48
+ height="170%"
49
+ id="atomix-glass-filter-_r_f_"
50
+ width="170%"
51
+ x="-35%"
52
+ y="-35%"
53
+ >
54
+ <feimage
55
+ height="100%"
56
+ href="data:image/jpeg;base64,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cUAUAkEkziomgGgkoxZGgxZFQFQlYnQHRdPfj/10KCSCKESCNiVkViPSLpD0h6I0Q0I0A2IoBWBIJIBKBIJoJIJ2R2J0JWBUJ0JUB0XTv479dFZDYiglYigkhEgjZFQjRFQjRFQjQigFYigHYigmgEgmglYlYnQlQlYlQHQlQnQ9P/kf1yVkNiNCNkNiVENiNiViNEViNkVCVgKCViViViSCViSCVgdCViVCViVCdgVCVCdD1D+U/XBWQ2I0I2Q2JUQ2I0JWQ0I2JUQ2JUI2JUI2J0JWJWJWA2R0BWJ0I2JUJ2BUJUJ0P//EABkQAQEBAQEBAAAAAAAAAAAAAAECABEDEP/aAAgBAQABAgB1atWrVq1atWrVq1atWrVq1atWrVq1atWrVq+OrVq1atWrVq1atWrVq1atWrVq1atWrVq1atXxVppppppdWrVq1atWrVq1NNNNNNNNNNNPVWmmmmms6tWrVq1atWpppppppppppppp6q0000uc51atWrVq1ammmmmmmmmmmmmt1Vpppc5znVq1atWrVqaaaaaaaaaaaaaeqtNLnOc51atWrVq1ammmmmmmmmmmmmnqrS5znOc6tWrVq16222mmmmmmlVppp6tKuc5znOrVq1a9TbbbbTTTTTSq000qtLnOc5zq1atWrW0222200000qqqtKqrnOc5zq1atTbbbbbbbbTTTSqqqqqq5znOc6tTTTbbbbbbbbTTTSqqqqrlVznOctNNNtttttttttNNNNKqqqrqznKqrTTTTbbbbbbbbbTTTSqqqqrqznOc5aaaabbbbbbbbbaaaaVVVVVdWc5znVq1NNttttttttttNNKqqqqudWc5znVq16tbbbbbbbbbbTTSqqqq5XVnOc6tWrVrb1tttttttttNNKqqqqrWrK5VWmmm2230bbbbbbaaaXOc5zlVa1KuVVppptttt9G22222mmlzlVznK6tWVVWmmmm2222222222mlznOc5znLWppVVWmmm22222229bTWrOc5znOcq1qaaVpWmm222222229erVqznOc5znKtatStK0rTbTTbbbberXr1as5znOc5aVpppppWlabaabbbb1ta9WrVnOc5znU0rTTTTTTTTTbTTbbbTWvVq1as5znOdTTStNNNNNNNNNtNNtttN6tWvVq1ZznOrU00rTTTTTTTTTTTTTbTWvVq1atWrOc6tTTTStNNNNNNNNNNtNNtNa9WrVq1Z1Z1NNNNNK1q1NNNNNNNNNNNtNatWrVq1atWrU00000rWrVq1atWrVq1alaaa1atWrVq1NNNammmmla1atWrVq1aterVq16tWrVnVqa1NK1qaaaVX/xAAWEAADAAAAAAAAAAAAAAAAAAAhgJD/2gAIAQEAAz8AaExf/8QAGhEBAQEBAQEBAAAAAAAAAAAAAQISEQADEP/aAAgBAgEBAgDx48ePHjx48ePHjx48ePHjx48ePHjx48ePHj86IiIiIiInjx48ePHjx48IiIiIj0oooooooooRERER73ve60UUUUUUVrWiiiiiihERERER73ve97ooooorRWiiiiihKERERER73ve973RRRRWtFFFFFFCIiIiIiPe973ve60UUVrRRRRRRQiIlCIiI973ve973pRRWiiiiiiiiiiiiiiihEe973ve973RRWtFFFFFFFFFFFFFFFFFFa13ve973WitaKKKKKKKKKKKKKKKKKK1rWtd1rutFa1oooooooooooosssooorWta1rWta1rRRRRRRRRRRZZZZZZZZZWta1rWta1rRRRRRRRRZZZZZZZZZZZZe9a1rWta1rWitaKLLLLLLLLLLLLLLLLL3rWta1rWtFbLLLLLLLLLLLLLLLLLLLL3vWta1rWita1ssssssss+hZZZZZZZZe961rWta0Vre97LLLLLLLLLLLPoWWWWWXrWta1oorWta3ssss+hZZZZ9Cyyyyyyyyiita1orWta1ve9llllllllllllllllFFa0VorWta1ve9llllllllllllllllllFFFaK1rWta1rWiyyyyyyyyyyyyiiiiiiitFFa1rWta1oosoosssssoooosoooorRRRWta1rWta0UUUUUWUUUUUUUUUUUVoooorWta1rWtaKKKKKKmiiiiiiiiiiiiiiitd73ve61oSiiipoqaKKKKKKKKKK0UUUVrve973vREREZoSihEooooorRRRRWtd73ve9EREREREoSiiiiitFllllla73ve9ERERERESiiiiiitH0PoWWWWVrXe96IiIiMoiJRRRRRRWjwlFFllllFFd6IiIiIlCUUUUUUUUUePHjx48ePCIiIiIiIiUUUUUUUUUUUePHjx48ePHjx48ePHjx48IiUUUUUUJRRRX//xAAWEQADAAAAAAAAAAAAAAAAAAABYJD/2gAIAQIBAz8AtEV7/8QAFxEBAQEBAAAAAAAAAAAAAAAAAAECEP/aAAgBAwEBAgCtNNNNNNNNNNNNNNNNNNNNNNNNNNNNNcrTTTTTTTTTTTTTTTTTTTTTTTTTTTTTXKrTTTTTTTU000000000000000000001FVpppppqampqaaaaaaaaaaaaaaaaaaaa5Vaaaaampqampqammmmmmmmmmmlaaaaaaiq0001NTU1NTU1NTTTTTTTTTTSqqtNNNcqtNNSyzU1LNTU1NTTTTTTTTTSqqq001ytNLLLLNTU1NTU1NTbbbTTTTTSqqq001ytNLLLLLNTU1NTU3NttttNNNNNKqq001KrSyyyyyzU1NTU3Nzc02220000qqqqrSqqyyyyyzU1NTU3Nzc3NttttNNNKqqqqqqssssss1NTU3Nzc3NzbbbbTTTSqqqqqqrLLLLLNTU1Nzc3Nzc22220000qqqqqqqqssss1NTU3Nzc3NzbbbbbTTSqqqqqqqqqqzU1NTc3Nzc3Nzbc22000qqqqqqqqqqqtTU3Nzc3Nzc3NtzbTTSqqqqrKqqqqqtNNzc23Nzc3Nzc3NTU1KqqqrKqqqqqtNNNNttzc3Nzc3NzU1NLLLLLKqqqqqqqq0022223Nzc3NzU1NSyyyyyyqqqqqqqrTTbbbbc3Nzc3NTU1LLLLLLKsqqqqqqrTTTTbbbc3Nzc1NTUsssssssqqqqqqrTTTTTbbbTc3NTU1NTUsssssqqqqqqqq0000222023NTU1NTUsssssqqqqqqqq000000003NTU1NTU1LLLLLNKrTSqqqqtNNNNNNtNNTU1NSzUssss00qq0qqqqrTTTTTTTTTU1NTUs1LLLNNNKrTTTSqqq00000000001NTU1LNTU0000qtNNNKqqqtNNNNNNNNTU1NTUs1NNNNNKss1NNNK00qtK0000001NNTU0s000000qq000001NKrStNNNNK1NNNNStNNNNNKqtNNNNNNNK0000000rU0000rTTTTTSq00000rTTTTTTTTTTTTTTTTStNNNNKr/xAAUEQEAAAAAAAAAAAAAAAAAAACg/9oACAEDAQM/AAAf/9k="
57
+ id="atomix-glass-filter-_r_f_-image"
58
+ preserveAspectRatio="xMidYMid slice"
59
+ result="DISPLACEMENT_MAP"
60
+ width="100%"
61
+ x="0"
62
+ y="0"
63
+ />
64
+ <fecolormatrix
65
+ in="DISPLACEMENT_MAP"
66
+ result="EDGE_INTENSITY"
67
+ type="matrix"
68
+ values="0.3 0.3 0.3 0 0
69
+ 0.3 0.3 0.3 0 0
70
+ 0.3 0.3 0.3 0 0
71
+ 0 0 0 1 0"
72
+ />
73
+ <fecomponenttransfer
74
+ in="EDGE_INTENSITY"
75
+ result="EDGE_MASK"
76
+ >
77
+ <fefunca
78
+ tableValues="0 0.1 1"
79
+ type="discrete"
80
+ />
81
+ </fecomponenttransfer>
82
+ <feoffset
83
+ dx="0"
84
+ dy="0"
85
+ in="SourceGraphic"
86
+ result="CENTER_ORIGINAL"
87
+ />
88
+ <fedisplacementmap
89
+ in="SourceGraphic"
90
+ in2="DISPLACEMENT_MAP"
91
+ result="RED_DISPLACED"
92
+ scale="-70"
93
+ xChannelSelector="R"
94
+ yChannelSelector="B"
95
+ />
96
+ <fecolormatrix
97
+ in="RED_DISPLACED"
98
+ result="RED_CHANNEL"
99
+ type="matrix"
100
+ values="1 0 0 0 0
101
+ 0 0 0 0 0
102
+ 0 0 0 0 0
103
+ 0 0 0 1 0"
104
+ />
105
+ <fedisplacementmap
106
+ in="SourceGraphic"
107
+ in2="DISPLACEMENT_MAP"
108
+ result="GREEN_DISPLACED"
109
+ scale="-72.8"
110
+ xChannelSelector="R"
111
+ yChannelSelector="B"
112
+ />
113
+ <fecolormatrix
114
+ in="GREEN_DISPLACED"
115
+ result="GREEN_CHANNEL"
116
+ type="matrix"
117
+ values="0 0 0 0 0
118
+ 0 1 0 0 0
119
+ 0 0 0 0 0
120
+ 0 0 0 1 0"
121
+ />
122
+ <fedisplacementmap
123
+ in="SourceGraphic"
124
+ in2="DISPLACEMENT_MAP"
125
+ result="BLUE_DISPLACED"
126
+ scale="-74.2"
127
+ xChannelSelector="R"
128
+ yChannelSelector="B"
129
+ />
130
+ <fecolormatrix
131
+ in="BLUE_DISPLACED"
132
+ result="BLUE_CHANNEL"
133
+ type="matrix"
134
+ values="0 0 0 0 0
135
+ 0 0 0 0 0
136
+ 0 0 1 0 0
137
+ 0 0 0 1 0"
138
+ />
139
+ <feblend
140
+ in="GREEN_CHANNEL"
141
+ in2="BLUE_CHANNEL"
142
+ mode="screen"
143
+ result="GB_COMBINED"
144
+ />
145
+ <feblend
146
+ in="RED_CHANNEL"
147
+ in2="GB_COMBINED"
148
+ mode="screen"
149
+ result="RGB_COMBINED"
150
+ />
151
+ <fegaussianblur
152
+ in="RGB_COMBINED"
153
+ result="ABERRATED_BLURRED"
154
+ stdDeviation="0"
155
+ />
156
+ <fecomposite
157
+ in="ABERRATED_BLURRED"
158
+ in2="EDGE_MASK"
159
+ operator="in"
160
+ result="EDGE_ABERRATION"
161
+ />
162
+ <fecomponenttransfer
163
+ in="EDGE_MASK"
164
+ result="INVERTED_MASK"
165
+ >
166
+ <fefunca
167
+ tableValues="1 0"
168
+ type="table"
169
+ />
170
+ </fecomponenttransfer>
171
+ <fecomposite
172
+ in="CENTER_ORIGINAL"
173
+ in2="INVERTED_MASK"
174
+ operator="in"
175
+ result="CENTER_CLEAN"
176
+ />
177
+ <fecomposite
178
+ in="EDGE_ABERRATION"
179
+ in2="CENTER_CLEAN"
180
+ operator="over"
181
+ />
182
+ </filter>
183
+ </defs>
184
+ </svg>
185
+ <div
186
+ class="c-atomix-glass__filter-overlay"
187
+ style="filter: url(#atomix-glass-filter-_r_f_);"
188
+ />
189
+ <div
190
+ class="c-atomix-glass__filter-shadow"
191
+ />
192
+ </div>
193
+ <div
194
+ class="c-atomix-glass__content"
195
+ >
196
+ <div>
197
+ Default Glass
198
+ </div>
199
+ </div>
200
+ </div>
201
+ </div>
202
+ <div
203
+ class="c-atomix-glass__background-layer c-atomix-glass__background-layer--dark c-atomix-glass__background-layer--hidden"
204
+ />
205
+ <div
206
+ class="c-atomix-glass__background-layer c-atomix-glass__background-layer--black c-atomix-glass__background-layer--hidden"
207
+ />
208
+ <span
209
+ class="c-atomix-glass__border-backdrop"
210
+ />
211
+ <span
212
+ class="c-atomix-glass__border-1"
213
+ />
214
+ <span
215
+ class="c-atomix-glass__border-2"
216
+ />
217
+ </div>
218
+ </div>
219
+ `;
@@ -173,7 +173,7 @@ export const extractBorderRadiusFromDOMElement = (element: HTMLElement | null):
173
173
  /**
174
174
  * Extract border-radius from React element
175
175
  */
176
- export const extractBorderRadiusFromElement = (element: React.ReactElement): number | null => {
176
+ export const extractBorderRadiusFromElement = (element: React.ReactElement<any>): number | null => {
177
177
  if (!element || !element.props) {
178
178
  return null;
179
179
  }