@shohojdhara/atomix 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/atomix.config.ts +12 -0
- package/build-tools/webpack-loader.js +5 -4
- package/dist/atomix.css +230 -83
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +1 -1
- package/dist/atomix.min.css.map +1 -1
- package/dist/build-tools/webpack-loader.js +5 -4
- package/dist/charts.d.ts +24 -23
- package/dist/charts.js +271 -369
- package/dist/charts.js.map +1 -1
- package/dist/config.d.ts +624 -0
- package/dist/config.js +59 -0
- package/dist/config.js.map +1 -0
- package/dist/core.d.ts +3 -2
- package/dist/core.js +342 -382
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +4 -6
- package/dist/forms.js +233 -334
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +11 -2
- package/dist/heavy.js +406 -445
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +109 -65
- package/dist/index.esm.js +654 -748
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +621 -717
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/layout.js +59 -60
- package/dist/layout.js.map +1 -1
- package/dist/theme.js +4 -4
- package/dist/theme.js.map +1 -1
- package/package.json +24 -9
- package/scripts/atomix-cli.js +15 -1
- package/scripts/cli/__tests__/complexity-utils.test.js +24 -0
- package/scripts/cli/__tests__/detector.test.js +50 -0
- package/scripts/cli/__tests__/template-engine.test.js +23 -0
- package/scripts/cli/__tests__/test-setup.js +1 -133
- package/scripts/cli/commands/doctor.js +15 -3
- package/scripts/cli/commands/generate.js +113 -51
- package/scripts/cli/internal/ai-engine.js +30 -10
- package/scripts/cli/internal/complexity-utils.js +60 -0
- package/scripts/cli/internal/component-validator.js +49 -16
- package/scripts/cli/internal/generator.js +89 -36
- package/scripts/cli/internal/hook-generator.js +5 -2
- package/scripts/cli/internal/itcss-generator.js +16 -12
- package/scripts/cli/templates/next-templates.js +81 -30
- package/scripts/cli/templates/storybook-templates.js +12 -2
- package/scripts/cli/utils/detector.js +45 -7
- package/scripts/cli/utils/diagnostics.js +78 -0
- package/scripts/cli/utils/telemetry.js +13 -0
- package/src/components/Accordion/Accordion.stories.tsx +4 -0
- package/src/components/AtomixGlass/AtomixGlass.tsx +188 -128
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +63 -91
- package/src/components/AtomixGlass/PerformanceDashboard.tsx +153 -201
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +9 -6
- package/src/components/AtomixGlass/glass-utils.ts +51 -1
- package/src/components/AtomixGlass/stories/AnimationFeatures.stories.tsx +52 -46
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +573 -236
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +88 -41
- package/src/components/AtomixGlass/stories/argTypes.ts +19 -19
- package/src/components/AtomixGlass/stories/shared-components.tsx +7 -12
- package/src/components/AtomixGlass/stories/types.ts +3 -3
- package/src/components/Button/Button.tsx +114 -57
- package/src/components/Callout/Callout.tsx +4 -4
- package/src/components/Chart/ChartRenderer.tsx +1 -1
- package/src/components/Chart/DonutChart.tsx +11 -8
- package/src/components/EdgePanel/EdgePanel.tsx +119 -115
- package/src/components/Form/Select.tsx +4 -4
- package/src/components/List/List.tsx +4 -4
- package/src/components/Navigation/SideMenu/SideMenu.tsx +6 -6
- package/src/components/PhotoViewer/PhotoViewerImage.tsx +1 -1
- package/src/components/ProductReview/ProductReview.tsx +4 -2
- package/src/components/Rating/Rating.tsx +4 -2
- package/src/components/SectionIntro/SectionIntro.tsx +4 -2
- package/src/components/Steps/Steps.tsx +1 -1
- package/src/components/Tabs/Tabs.tsx +5 -5
- package/src/components/Testimonial/Testimonial.tsx +4 -2
- package/src/components/VideoPlayer/VideoPlayer.tsx +4 -2
- package/src/layouts/CssGrid/CssGrid.stories.tsx +464 -0
- package/src/layouts/CssGrid/CssGrid.tsx +215 -0
- package/src/layouts/CssGrid/index.ts +8 -0
- package/src/layouts/CssGrid/scripts/CssGrid.js +284 -0
- package/src/layouts/CssGrid/scripts/index.js +43 -0
- package/src/layouts/Grid/scripts/Container.js +139 -0
- package/src/layouts/Grid/scripts/Grid.js +184 -0
- package/src/layouts/Grid/scripts/GridCol.js +273 -0
- package/src/layouts/Grid/scripts/Row.js +154 -0
- package/src/layouts/Grid/scripts/index.js +48 -0
- package/src/layouts/MasonryGrid/MasonryGrid.tsx +71 -59
- package/src/lib/composables/atomix-glass/useGlassSize.ts +1 -1
- package/src/lib/composables/useAccordion.ts +5 -5
- package/src/lib/composables/useAtomixGlass.ts +111 -74
- package/src/lib/composables/useAtomixGlassStyles.ts +0 -2
- package/src/lib/composables/useBarChart.ts +2 -2
- package/src/lib/composables/useChart.ts +3 -2
- package/src/lib/composables/useChartToolbar.ts +48 -66
- package/src/lib/composables/useDataTable.ts +1 -1
- package/src/lib/composables/useDatePicker.ts +2 -2
- package/src/lib/composables/useEdgePanel.ts +45 -54
- package/src/lib/composables/useHeroBackgroundSlider.ts +5 -5
- package/src/lib/composables/usePhotoViewer.ts +2 -3
- package/src/lib/composables/usePieChart.ts +1 -1
- package/src/lib/composables/usePopover.ts +151 -139
- package/src/lib/composables/useSideMenu.ts +28 -41
- package/src/lib/composables/useSlider.ts +2 -6
- package/src/lib/composables/useTooltip.ts +2 -2
- package/src/lib/config/index.ts +39 -0
- package/src/lib/constants/components.ts +1 -0
- package/src/lib/theme/devtools/Comparator.tsx +1 -1
- package/src/lib/theme/devtools/Inspector.tsx +1 -1
- package/src/lib/theme/devtools/LiveEditor.tsx +1 -1
- package/src/lib/theme/runtime/ThemeProvider.tsx +1 -1
- package/src/lib/types/components.ts +1 -0
- package/src/styles/01-settings/_index.scss +1 -0
- package/src/styles/01-settings/_settings.atomix-glass.scss +174 -0
- package/src/styles/01-settings/_settings.masonry-grid.scss +42 -6
- package/src/styles/02-tools/_tools.glass.scss +6 -0
- package/src/styles/05-objects/_objects.masonry-grid.scss +162 -24
- package/src/styles/06-components/_components.atomix-glass.scss +160 -99
- package/scripts/cli/__tests__/README.md +0 -81
- package/scripts/cli/__tests__/basic.test.js +0 -116
- package/scripts/cli/__tests__/clean.test.js +0 -278
- package/scripts/cli/__tests__/component-generator.test.js +0 -332
- package/scripts/cli/__tests__/component-validator.test.js +0 -433
- package/scripts/cli/__tests__/generator.test.js +0 -613
- package/scripts/cli/__tests__/glass-motion.test.js +0 -256
- package/scripts/cli/__tests__/integration.test.js +0 -938
- package/scripts/cli/__tests__/migrate.test.js +0 -74
- package/scripts/cli/__tests__/security.test.js +0 -206
- package/scripts/cli/__tests__/theme-bridge.test.js +0 -507
- package/scripts/cli/__tests__/token-manager.test.js +0 -251
- package/scripts/cli/__tests__/token-provider.test.js +0 -361
- package/scripts/cli/__tests__/utils.test.js +0 -165
- package/src/components/AtomixGlass/stories/AnimationTests.stories.tsx +0 -95
- package/src/components/AtomixGlass/stories/CardExamples.stories.tsx +0 -212
- package/src/components/AtomixGlass/stories/Customization.stories.tsx +0 -131
- package/src/components/AtomixGlass/stories/DashboardExamples.stories.tsx +0 -348
- package/src/components/AtomixGlass/stories/EcommerceExamples.stories.tsx +0 -410
- package/src/components/AtomixGlass/stories/FormExamples.stories.tsx +0 -436
- package/src/components/AtomixGlass/stories/HeroExamples.stories.tsx +0 -264
- package/src/components/AtomixGlass/stories/InteractivePlayground.stories.tsx +0 -247
- package/src/components/AtomixGlass/stories/MobileUIExamples.stories.tsx +0 -418
- package/src/components/AtomixGlass/stories/ModalExamples.stories.tsx +0 -402
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +0 -1082
- package/src/components/AtomixGlass/stories/Overview.stories.tsx +0 -497
- package/src/components/AtomixGlass/stories/Performance.stories.tsx +0 -103
- package/src/components/AtomixGlass/stories/PresetGallery.stories.tsx +0 -335
- package/src/components/AtomixGlass/stories/Shaders.stories.tsx +0 -395
- package/src/components/AtomixGlass/stories/WidgetExamples.stories.tsx +0 -441
- package/src/components/TypedButton/TypedButton.stories.tsx +0 -59
- package/src/components/TypedButton/TypedButton.tsx +0 -39
- package/src/components/TypedButton/index.ts +0 -2
- package/src/lib/composables/useBreadcrumb.ts +0 -81
- package/src/lib/composables/useChartInteractions.ts +0 -123
- package/src/lib/composables/useChartPerformance.ts +0 -347
- package/src/lib/composables/useDropdown.ts +0 -338
- package/src/lib/composables/useModal.ts +0 -110
- package/src/lib/composables/useTypedButton.ts +0 -66
- package/src/lib/hooks/usePerformanceMonitor.ts +0 -148
- package/src/lib/utils/displacement-generator.ts +0 -92
- package/src/lib/utils/memoryMonitor.ts +0 -191
- package/src/styles/01-settings/_settings.testtypecheck.scss +0 -53
- package/src/styles/01-settings/_settings.typedbutton.scss +0 -53
- package/src/styles/06-components/_components.testbutton.scss +0 -212
- package/src/styles/06-components/_components.testtypecheck.scss +0 -212
- 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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
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}
|
|
56
|
+
* ${name} — client component with local state (Atomix scaffold).
|
|
31
57
|
*/
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
</
|
|
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
|
-
|
|
57
|
-
|
|
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
|
-
|
|
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
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
|
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
|
|
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
|
|
66
|
+
if (hasNextSignals(projectRoot, allDeps)) {
|
|
30
67
|
return 'next';
|
|
31
68
|
}
|
|
32
69
|
|
|
33
|
-
|
|
70
|
+
const hasReact = Boolean(allDeps.react);
|
|
71
|
+
|
|
72
|
+
if (hasViteSignals(projectRoot, allDeps) && hasReact) {
|
|
34
73
|
return 'react';
|
|
35
74
|
}
|
|
36
75
|
|
|
37
|
-
|
|
38
|
-
|
|
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>
|