@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.
- package/CHANGELOG.md +39 -0
- package/README.md +2 -0
- package/build-tools/EXAMPLES.md +372 -0
- package/build-tools/README.md +242 -0
- package/build-tools/__tests__/error-handler.test.js +230 -0
- package/build-tools/__tests__/index.test.js +141 -0
- package/build-tools/__tests__/rollup-plugin.test.js +194 -0
- package/build-tools/__tests__/utils.test.js +161 -0
- package/build-tools/__tests__/vite-plugin.test.js +129 -0
- package/build-tools/__tests__/webpack-loader.test.js +190 -0
- package/build-tools/error-handler.js +308 -0
- package/build-tools/index.d.ts +43 -0
- package/build-tools/index.js +88 -0
- package/build-tools/package.json +67 -0
- package/build-tools/rollup-plugin.js +236 -0
- package/build-tools/types.d.ts +163 -0
- package/build-tools/utils.js +203 -0
- package/build-tools/vite-plugin.js +161 -0
- package/build-tools/webpack-loader.js +123 -0
- package/dist/atomix.css +298 -167
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +3 -3
- package/dist/atomix.min.css.map +1 -1
- package/dist/build-tools/EXAMPLES.md +372 -0
- package/dist/build-tools/README.md +242 -0
- package/dist/build-tools/__tests__/error-handler.test.js +230 -0
- package/dist/build-tools/__tests__/index.test.js +141 -0
- package/dist/build-tools/__tests__/rollup-plugin.test.js +194 -0
- package/dist/build-tools/__tests__/utils.test.js +161 -0
- package/dist/build-tools/__tests__/vite-plugin.test.js +129 -0
- package/dist/build-tools/__tests__/webpack-loader.test.js +190 -0
- package/dist/build-tools/error-handler.js +308 -0
- package/dist/build-tools/index.d.ts +43 -0
- package/dist/build-tools/index.js +88 -0
- package/dist/build-tools/package.json +67 -0
- package/dist/build-tools/rollup-plugin.js +236 -0
- package/dist/build-tools/types.d.ts +163 -0
- package/dist/build-tools/utils.js +203 -0
- package/dist/build-tools/vite-plugin.js +161 -0
- package/dist/build-tools/webpack-loader.js +123 -0
- package/dist/charts.d.ts +2 -2
- package/dist/charts.js +87 -58
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +42 -12
- package/dist/core.js +175 -135
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +30 -16
- package/dist/forms.js +146 -131
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +2 -2
- package/dist/heavy.js +151 -118
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +130 -106
- package/dist/index.esm.js +1083 -465
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1102 -483
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/theme.d.ts +27 -2
- package/dist/theme.js +721 -108
- package/dist/theme.js.map +1 -1
- package/package.json +23 -8
- package/scripts/atomix-cli.js +749 -1153
- package/scripts/cli/__tests__/README.md +81 -0
- package/scripts/cli/__tests__/basic.test.js +115 -0
- package/scripts/cli/__tests__/component-generator.test.js +332 -0
- package/scripts/cli/__tests__/integration.test.js +327 -0
- package/scripts/cli/__tests__/test-setup.js +133 -0
- package/scripts/cli/__tests__/token-manager.test.js +251 -0
- package/scripts/cli/__tests__/utils.test.js +78 -118
- package/scripts/cli/component-generator.js +564 -0
- package/scripts/cli/dependency-checker.js +355 -0
- package/scripts/cli/documentation-sync.js +542 -0
- package/scripts/cli/interactive-init.js +129 -292
- package/scripts/cli/mappings.js +211 -0
- package/scripts/cli/migration-tools.js +95 -288
- package/scripts/cli/template-manager.js +105 -0
- package/scripts/cli/templates/README.md +123 -0
- package/scripts/cli/templates/common-templates.js +636 -0
- package/scripts/cli/templates/composable-templates.js +171 -0
- package/scripts/cli/templates/config-templates.js +126 -0
- package/scripts/cli/templates/index.js +102 -0
- package/scripts/cli/templates/project-templates.js +342 -0
- package/scripts/cli/templates/react-templates.js +331 -0
- package/scripts/cli/templates/scss-templates.js +155 -0
- package/scripts/cli/templates/storybook-templates.js +236 -0
- package/scripts/cli/templates/testing-templates.js +224 -0
- package/scripts/cli/templates/testing-utils.js +278 -0
- package/scripts/cli/templates/token-templates.js +447 -0
- package/scripts/cli/templates/types-templates.js +147 -0
- package/scripts/cli/templates.js +35 -0
- package/scripts/cli/theme-bridge.js +28 -16
- package/scripts/cli/token-manager.js +432 -247
- package/scripts/cli/utils.js +37 -26
- package/src/components/Accordion/Accordion.stories.tsx +369 -870
- package/src/components/Accordion/Accordion.test.tsx +57 -0
- package/src/components/Accordion/Accordion.tsx +4 -0
- package/src/components/AtomixGlass/AtomixGlass.tsx +80 -39
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +103 -81
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +8 -7
- package/src/components/AtomixGlass/glass-utils.ts +2 -2
- package/src/components/AtomixGlass/shader-utils.ts +5 -0
- package/src/components/AtomixGlass/stories/Customization.stories.tsx +131 -0
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +2965 -2861
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +1 -1
- package/src/components/AtomixGlass/stories/Overview.stories.tsx +348 -0
- package/src/components/AtomixGlass/stories/Performance.stories.tsx +103 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +73 -59
- package/src/components/AtomixGlass/stories/{ShaderVariants.stories.tsx → Shaders.stories.tsx} +1 -1
- package/src/components/AtomixGlass/stories/shared-components.tsx +90 -190
- package/src/components/Avatar/Avatar.stories.tsx +239 -27
- package/src/components/Badge/Badge.stories.tsx +132 -373
- package/src/components/Badge/Badge.test.tsx +51 -0
- package/src/components/Badge/Badge.tsx +20 -1
- package/src/components/Block/Block.stories.tsx +26 -17
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +141 -23
- package/src/components/Breadcrumb/Breadcrumb.tsx +2 -2
- package/src/components/Button/Button.stories.tsx +463 -1126
- package/src/components/Button/Button.test.tsx +107 -0
- package/src/components/Button/Button.tsx +50 -54
- package/src/components/Button/ButtonGroup.stories.tsx +373 -217
- package/src/components/Button/README.md +5 -0
- package/src/components/Callout/Callout.stories.tsx +299 -644
- package/src/components/Callout/Callout.test.tsx +10 -10
- package/src/components/Callout/Callout.tsx +7 -7
- package/src/components/Callout/README.md +9 -8
- package/src/components/Card/Card.stories.tsx +248 -68
- package/src/components/Card/Card.tsx +2 -2
- package/src/components/Chart/Chart.stories.tsx +156 -14
- package/src/components/Chart/Chart.tsx +1 -1
- package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +151 -69
- package/src/components/Countdown/Countdown.stories.tsx +115 -8
- package/src/components/DataTable/DataTable.stories.tsx +346 -146
- package/src/components/DataTable/DataTable.tsx +14 -12
- package/src/components/DatePicker/DatePicker.stories.tsx +325 -1066
- package/src/components/Dropdown/Dropdown.stories.tsx +157 -37
- package/src/components/EdgePanel/EdgePanel.stories.tsx +230 -21
- package/src/components/Footer/Footer.stories.tsx +392 -328
- package/src/components/Form/Checkbox.stories.tsx +143 -9
- package/src/components/Form/Checkbox.test.tsx +63 -0
- package/src/components/Form/Checkbox.tsx +90 -52
- package/src/components/Form/Form.stories.tsx +121 -22
- package/src/components/Form/FormGroup.stories.tsx +128 -5
- package/src/components/Form/Input.stories.tsx +28 -16
- package/src/components/Form/Input.test.tsx +59 -0
- package/src/components/Form/Input.tsx +97 -95
- package/src/components/Form/Radio.stories.tsx +232 -97
- package/src/components/Form/Radio.tsx +2 -2
- package/src/components/Form/Select.stories.tsx +144 -12
- package/src/components/Form/Select.tsx +2 -2
- package/src/components/Form/Textarea.stories.tsx +171 -13
- package/src/components/Form/Textarea.test.tsx +45 -0
- package/src/components/Form/Textarea.tsx +88 -86
- package/src/components/Hero/Hero.stories.tsx +333 -32
- package/src/components/List/List.stories.tsx +143 -5
- package/src/components/Modal/Modal.stories.tsx +185 -46
- package/src/components/Navigation/Navbar/Navbar.stories.tsx +5 -5
- package/src/components/Navigation/Navbar/Navbar.tsx +1 -1
- package/src/components/Navigation/README.md +1 -1
- package/src/components/Pagination/Pagination.stories.tsx +5 -2
- package/src/components/Pagination/Pagination.tsx +1 -1
- package/src/components/PhotoViewer/PhotoViewer.stories.tsx +10 -10
- package/src/components/Popover/Popover.stories.tsx +449 -99
- package/src/components/ProductReview/ProductReview.tsx +1 -1
- package/src/components/Progress/Progress.stories.tsx +167 -5
- package/src/components/Progress/Progress.tsx +46 -46
- package/src/components/Rating/Rating.stories.tsx +4 -4
- package/src/components/Rating/Rating.tsx +8 -8
- package/src/components/River/River.stories.tsx +1 -1
- package/src/components/SectionIntro/SectionIntro.stories.tsx +240 -48
- package/src/components/Slider/Slider.stories.tsx +63 -63
- package/src/components/Spinner/Spinner.stories.tsx +104 -10
- package/src/components/Spinner/Spinner.test.tsx +35 -0
- package/src/components/Spinner/Spinner.tsx +9 -2
- package/src/components/Steps/Steps.stories.tsx +172 -43
- package/src/components/Tabs/Tabs.stories.tsx +136 -10
- package/src/components/Testimonial/Testimonial.stories.tsx +121 -4
- package/src/components/Todo/Todo.stories.tsx +198 -9
- package/src/components/Toggle/Toggle.stories.tsx +153 -43
- package/src/components/Toggle/Toggle.test.tsx +91 -0
- package/src/components/Toggle/Toggle.tsx +44 -27
- package/src/components/Tooltip/Tooltip.stories.tsx +194 -104
- package/src/components/Tooltip/Tooltip.tsx +1 -1
- package/src/components/Upload/Upload.stories.tsx +113 -24
- package/src/layouts/Grid/Grid.stories.tsx +49 -49
- package/src/layouts/MasonryGrid/MasonryGrid.stories.tsx +2 -2
- package/src/lib/README.md +2 -2
- package/src/lib/__tests__/theme-tools.test.ts +193 -0
- package/src/lib/composables/index.ts +2 -2
- package/src/lib/composables/useAccordion.ts +12 -3
- package/src/lib/composables/useAtomixGlass.ts +28 -56
- package/src/lib/composables/useBreadcrumb.ts +2 -2
- package/src/lib/composables/useCallout.ts +7 -7
- package/src/lib/composables/useChartExport.ts +2 -7
- package/src/lib/composables/useDataTable.ts +46 -29
- package/src/lib/composables/useNavbar.ts +1 -1
- package/src/lib/constants/components.ts +10 -33
- package/src/lib/storybook/InteractiveDemo.tsx +113 -0
- package/src/lib/storybook/PreviewContainer.tsx +36 -0
- package/src/lib/storybook/VariantsGrid.tsx +21 -0
- package/src/lib/storybook/index.ts +3 -0
- package/src/lib/theme/core/createThemeObject.ts +9 -5
- package/src/lib/theme/devtools/CLI.ts +155 -0
- package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +213 -0
- package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +566 -0
- package/src/lib/theme/devtools/LiveEditor.tsx +2 -1
- package/src/lib/theme/devtools/index.ts +3 -0
- package/src/lib/theme/errors/errors.ts +8 -0
- package/src/lib/theme/runtime/ThemeProvider.tsx +117 -57
- package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +305 -0
- package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +588 -0
- package/src/lib/theme/utils/__tests__/themeValidation.test.ts +264 -0
- package/src/lib/theme/utils/index.ts +1 -0
- package/src/lib/theme/utils/themeValidation.ts +501 -0
- package/src/lib/theme-tools.ts +32 -3
- package/src/lib/types/components.ts +82 -27
- package/src/lib/utils/__tests__/csv.test.ts +45 -0
- package/src/lib/utils/csv.ts +17 -0
- package/src/lib/utils/dataTableExport.ts +1 -10
- package/src/lib/utils/themeNaming.ts +1 -1
- package/src/styles/01-settings/_index.scss +2 -1
- package/src/styles/01-settings/_settings.accordion.scss +28 -7
- package/src/styles/01-settings/_settings.colors.scss +11 -11
- package/src/styles/01-settings/_settings.typography.scss +5 -5
- package/src/styles/02-tools/_tools.utility-api.scss +14 -0
- package/src/styles/06-components/_components.accordion.scss +56 -14
- package/src/styles/06-components/_components.callout.scss +29 -33
- package/src/styles/06-components/_components.checkbox.scss +23 -17
- package/src/styles/06-components/_index.scss +1 -1
- package/src/styles/99-utilities/_index.scss +2 -0
- package/src/styles/99-utilities/_utilities.display.scss +14 -3
- package/src/styles/99-utilities/_utilities.flex.scss +10 -10
- package/src/styles/99-utilities/_utilities.scss +3 -1
- package/src/styles/99-utilities/_utilities.text-gradient.scss +45 -0
- package/src/styles/99-utilities/_utilities.text.scss +28 -8
- package/themes/dark-complementary/README.md +98 -0
- package/themes/dark-complementary/index.scss +158 -0
- package/themes/default-light/README.md +81 -0
- package/themes/default-light/index.scss +154 -0
- package/themes/high-contrast/README.md +105 -0
- package/themes/high-contrast/index.scss +172 -0
- package/themes/test-theme/README.md +38 -0
- package/themes/test-theme/index.scss +47 -0
- package/scripts/cli/__tests__/cli-commands.test.js +0 -204
- package/scripts/cli/__tests__/vitest.config.js +0 -26
- package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +0 -1438
- package/src/lib/composables/useButton.ts +0 -93
- package/src/lib/composables/useCheckbox.ts +0 -70
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SCSS Component and Settings Templates
|
|
3
|
+
* Templates for SCSS files generation following ITCSS methodology
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* SCSS component template
|
|
8
|
+
*/
|
|
9
|
+
export const scssComponentTemplate = (name) => `// ${name} Component Styles
|
|
10
|
+
// Generated by Atomix CLI
|
|
11
|
+
// Located in src/styles/06-components/_components.${name.toLowerCase()}.scss
|
|
12
|
+
|
|
13
|
+
@use '../01-settings/settings.config' as config;
|
|
14
|
+
|
|
15
|
+
.c-${name.toLowerCase()} {
|
|
16
|
+
// Using CSS custom properties defined in settings
|
|
17
|
+
--#{config.$prefix}${name.toLowerCase()}-padding: var(--atomix-spacing-4);
|
|
18
|
+
--#{config.$prefix}${name.toLowerCase()}-margin: var(--atomix-spacing-2);
|
|
19
|
+
--#{config.$prefix}${name.toLowerCase()}-border: var(--atomix-border-default);
|
|
20
|
+
--#{config.$prefix}${name.toLowerCase()}-border-radius: var(--atomix-border-radius-md);
|
|
21
|
+
--#{config.$prefix}${name.toLowerCase()}-bg: var(--atomix-bg-surface);
|
|
22
|
+
--#{config.$prefix}${name.toLowerCase()}-color: var(--atomix-text-primary);
|
|
23
|
+
--#{config.$prefix}${name.toLowerCase()}-font-size: var(--atomix-font-size-base);
|
|
24
|
+
--#{config.$prefix}${name.toLowerCase()}-transition: var(--atomix-transition-all);
|
|
25
|
+
|
|
26
|
+
// State-specific properties
|
|
27
|
+
--#{config.$prefix}${name.toLowerCase()}-hover-bg: var(--atomix-bg-surface-hover);
|
|
28
|
+
--#{config.$prefix}${name.toLowerCase()}-focus-bg: var(--atomix-bg-surface-focus);
|
|
29
|
+
--#{config.$prefix}${name.toLowerCase()}-disabled-bg: var(--atomix-bg-surface-disabled);
|
|
30
|
+
--#{config.$prefix}${name.toLowerCase()}-disabled-color: var(--atomix-text-disabled);
|
|
31
|
+
--#{config.$prefix}${name.toLowerCase()}-disabled-opacity: var(--atomix-opacity-disabled);
|
|
32
|
+
|
|
33
|
+
padding: var(--#{config.$prefix}${name.toLowerCase()}-padding);
|
|
34
|
+
margin: var(--#{config.$prefix}${name.toLowerCase()}-margin);
|
|
35
|
+
border: var(--#{config.$prefix}${name.toLowerCase()}-border);
|
|
36
|
+
border-radius: var(--#{config.$prefix}${name.toLowerCase()}-border-radius);
|
|
37
|
+
background: var(--#{config.$prefix}${name.toLowerCase()}-bg);
|
|
38
|
+
color: var(--#{config.$prefix}${name.toLowerCase()}-color);
|
|
39
|
+
font-size: var(--#{config.$prefix}${name.toLowerCase()}-font-size);
|
|
40
|
+
transition: var(--#{config.$prefix}${name.toLowerCase()}-transition);
|
|
41
|
+
|
|
42
|
+
// Size variants
|
|
43
|
+
&--sm {
|
|
44
|
+
--#{config.$prefix}${name.toLowerCase()}-padding: var(--atomix-spacing-2);
|
|
45
|
+
--#{config.$prefix}${name.toLowerCase()}-font-size: var(--atomix-font-size-sm);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&--lg {
|
|
49
|
+
--#{config.$prefix}${name.toLowerCase()}-padding: var(--atomix-spacing-6);
|
|
50
|
+
--#{config.$prefix}${name.toLowerCase()}-font-size: var(--atomix-font-size-lg);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Interactive states
|
|
54
|
+
&:hover {
|
|
55
|
+
background: var(--#{config.$prefix}${name.toLowerCase()}-hover-bg);
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&:focus {
|
|
60
|
+
background: var(--#{config.$prefix}${name.toLowerCase()}-focus-bg);
|
|
61
|
+
outline: 2px solid var(--atomix-focus-color);
|
|
62
|
+
outline-offset: 2px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Disabled state
|
|
66
|
+
&.is-disabled {
|
|
67
|
+
background: var(--#{config.$prefix}${name.toLowerCase()}-disabled-bg);
|
|
68
|
+
color: var(--#{config.$prefix}${name.toLowerCase()}-disabled-color);
|
|
69
|
+
opacity: var(--#{config.$prefix}${name.toLowerCase()}-disabled-opacity);
|
|
70
|
+
cursor: not-allowed;
|
|
71
|
+
pointer-events: none;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Glass variant
|
|
75
|
+
&--glass {
|
|
76
|
+
background: var(--#{config.$prefix}${name.toLowerCase()}-glass-bg, rgba(255, 255, 255, 0.1));
|
|
77
|
+
backdrop-filter: var(--#{config.$prefix}${name.toLowerCase()}-glass-backdrop, blur(10px));
|
|
78
|
+
border-color: var(--#{config.$prefix}${name.toLowerCase()}-glass-border, rgba(255, 255, 255, 0.2));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Data states for JavaScript interaction
|
|
82
|
+
&[data-state="open"] {
|
|
83
|
+
// Styles for open state
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
&[data-state="closed"] {
|
|
87
|
+
// Styles for closed state
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
`;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* SCSS settings template
|
|
94
|
+
*/
|
|
95
|
+
export const scssSettingsTemplate = (name) => `// ${name} Component Settings
|
|
96
|
+
// Generated by Atomix CLI
|
|
97
|
+
// Located in src/styles/01-settings/_settings.${name.toLowerCase()}.scss
|
|
98
|
+
|
|
99
|
+
@use 'sass:map';
|
|
100
|
+
@use 'settings.colors' as *;
|
|
101
|
+
@use 'settings.spacing' as spacing;
|
|
102
|
+
@use 'settings.border-radius' as *;
|
|
103
|
+
@use 'settings.typography' as *;
|
|
104
|
+
@use '../02-tools/tools.color-functions' as *;
|
|
105
|
+
|
|
106
|
+
// Component-specific variables
|
|
107
|
+
$${name.toLowerCase()}-padding-x: map.get(spacing.$spacing-sizes, 3) !default;
|
|
108
|
+
$${name.toLowerCase()}-padding-y: map.get(spacing.$spacing-sizes, 2) !default;
|
|
109
|
+
$${name.toLowerCase()}-gap: map.get(spacing.$spacing-sizes, 2) !default;
|
|
110
|
+
$${name.toLowerCase()}-border-radius: $border-radius-md !default;
|
|
111
|
+
$${name.toLowerCase()}-transition: all 0.2s ease !default;
|
|
112
|
+
|
|
113
|
+
// Size variants
|
|
114
|
+
$${name.toLowerCase()}-sm-padding-x: map.get(spacing.$spacing-sizes, 2) !default;
|
|
115
|
+
$${name.toLowerCase()}-sm-padding-y: map.get(spacing.$spacing-sizes, 1) !default;
|
|
116
|
+
$${name.toLowerCase()}-sm-font-size: $font-size-sm !default;
|
|
117
|
+
|
|
118
|
+
$${name.toLowerCase()}-lg-padding-x: map.get(spacing.$spacing-sizes, 4) !default;
|
|
119
|
+
$${name.toLowerCase()}-lg-padding-y: map.get(spacing.$spacing-sizes, 3) !default;
|
|
120
|
+
$${name.toLowerCase()}-lg-font-size: $font-size-lg !default;
|
|
121
|
+
|
|
122
|
+
// Color variants
|
|
123
|
+
$${name.toLowerCase()}-primary-bg: $primary !default;
|
|
124
|
+
$${name.toLowerCase()}-primary-color: color-contrast($primary) !default;
|
|
125
|
+
$${name.toLowerCase()}-primary-border: shade($primary, 10%) !default;
|
|
126
|
+
|
|
127
|
+
$${name.toLowerCase()}-secondary-bg: $secondary !default;
|
|
128
|
+
$${name.toLowerCase()}-secondary-color: color-contrast($secondary) !default;
|
|
129
|
+
$${name.toLowerCase()}-secondary-border: shade($secondary, 10%) !default;
|
|
130
|
+
|
|
131
|
+
// State variables
|
|
132
|
+
$${name.toLowerCase()}-disabled-opacity: 0.6 !default;
|
|
133
|
+
$${name.toLowerCase()}-disabled-cursor: not-allowed !default;
|
|
134
|
+
|
|
135
|
+
// Glass variant
|
|
136
|
+
$${name.toLowerCase()}-glass-bg: rgba(255, 255, 255, 0.1) !default;
|
|
137
|
+
$${name.toLowerCase()}-glass-border: rgba(255, 255, 255, 0.2) !default;
|
|
138
|
+
$${name.toLowerCase()}-glass-backdrop: blur(10px) !default;
|
|
139
|
+
`;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* SCSS template combining both
|
|
143
|
+
*/
|
|
144
|
+
export const scssTemplate = (name) => {
|
|
145
|
+
return {
|
|
146
|
+
component: scssComponentTemplate(name),
|
|
147
|
+
settings: scssSettingsTemplate(name)
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const scssTemplates = {
|
|
152
|
+
component: scssComponentTemplate,
|
|
153
|
+
settings: scssSettingsTemplate,
|
|
154
|
+
full: scssTemplate
|
|
155
|
+
};
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storybook Templates
|
|
3
|
+
* Templates for Storybook stories and documentation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Basic Storybook story template
|
|
8
|
+
*/
|
|
9
|
+
export const basicStoryTemplate = (name) => `import type { Meta, StoryObj } from '@storybook/react';
|
|
10
|
+
import { ${name} } from './${name}';
|
|
11
|
+
|
|
12
|
+
const meta: Meta<typeof ${name}> = {
|
|
13
|
+
title: 'Components/${name}',
|
|
14
|
+
component: ${name},
|
|
15
|
+
parameters: {
|
|
16
|
+
layout: 'centered',
|
|
17
|
+
},
|
|
18
|
+
tags: ['autodocs'],
|
|
19
|
+
argTypes: {
|
|
20
|
+
size: {
|
|
21
|
+
control: 'select',
|
|
22
|
+
options: ['sm', 'md', 'lg'],
|
|
23
|
+
},
|
|
24
|
+
variant: {
|
|
25
|
+
control: 'select',
|
|
26
|
+
options: ['primary', 'secondary', 'success', 'error'],
|
|
27
|
+
},
|
|
28
|
+
disabled: {
|
|
29
|
+
control: 'boolean',
|
|
30
|
+
},
|
|
31
|
+
glass: {
|
|
32
|
+
control: 'boolean',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default meta;
|
|
38
|
+
type Story = StoryObj<typeof meta>;
|
|
39
|
+
|
|
40
|
+
export const Default: Story = {
|
|
41
|
+
args: {
|
|
42
|
+
children: '${name} Component',
|
|
43
|
+
size: 'md',
|
|
44
|
+
variant: 'primary',
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const Small: Story = {
|
|
49
|
+
args: {
|
|
50
|
+
...Default.args,
|
|
51
|
+
size: 'sm',
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const Large: Story = {
|
|
56
|
+
args: {
|
|
57
|
+
...Default.args,
|
|
58
|
+
size: 'lg',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const Glass: Story = {
|
|
63
|
+
args: {
|
|
64
|
+
...Default.args,
|
|
65
|
+
glass: true,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
`;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Enhanced Storybook story template with detailed documentation
|
|
72
|
+
*/
|
|
73
|
+
export const enhancedStoryTemplate = (name) => `import type { Meta, StoryObj } from '@storybook/react';
|
|
74
|
+
import { ${name} } from './${name}';
|
|
75
|
+
|
|
76
|
+
const meta: Meta<typeof ${name}> = {
|
|
77
|
+
title: 'Components/${name}',
|
|
78
|
+
component: ${name},
|
|
79
|
+
parameters: {
|
|
80
|
+
layout: 'centered',
|
|
81
|
+
docs: {
|
|
82
|
+
description: {
|
|
83
|
+
component: 'A versatile ${name.toLowerCase()} component built with Atomix Design System.',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
tags: ['autodocs'],
|
|
88
|
+
argTypes: {
|
|
89
|
+
children: {
|
|
90
|
+
control: 'text',
|
|
91
|
+
description: 'Content to be rendered inside the component',
|
|
92
|
+
},
|
|
93
|
+
size: {
|
|
94
|
+
control: 'select',
|
|
95
|
+
options: ['sm', 'md', 'lg'],
|
|
96
|
+
description: 'Size variant of the component',
|
|
97
|
+
},
|
|
98
|
+
variant: {
|
|
99
|
+
control: 'select',
|
|
100
|
+
options: ['primary', 'secondary', 'success', 'error'],
|
|
101
|
+
description: 'Color variant of the component',
|
|
102
|
+
},
|
|
103
|
+
disabled: {
|
|
104
|
+
control: 'boolean',
|
|
105
|
+
description: 'Whether the component is disabled',
|
|
106
|
+
},
|
|
107
|
+
glass: {
|
|
108
|
+
control: 'boolean',
|
|
109
|
+
description: 'Whether to apply glass effect',
|
|
110
|
+
},
|
|
111
|
+
className: {
|
|
112
|
+
control: 'text',
|
|
113
|
+
description: 'Additional CSS classes',
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export default meta;
|
|
119
|
+
type Story = StoryObj<typeof meta>;
|
|
120
|
+
|
|
121
|
+
export const Default: Story = {
|
|
122
|
+
args: {
|
|
123
|
+
children: '${name} Component',
|
|
124
|
+
size: 'md',
|
|
125
|
+
variant: 'primary',
|
|
126
|
+
},
|
|
127
|
+
parameters: {
|
|
128
|
+
docs: {
|
|
129
|
+
description: {
|
|
130
|
+
story: 'Default ${name.toLowerCase()} component with primary variant and medium size.',
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export const Playground: Story = {
|
|
137
|
+
args: {
|
|
138
|
+
children: 'Interactive ${name}',
|
|
139
|
+
size: 'md',
|
|
140
|
+
variant: 'primary',
|
|
141
|
+
},
|
|
142
|
+
parameters: {
|
|
143
|
+
docs: {
|
|
144
|
+
description: {
|
|
145
|
+
story: 'Interactive playground to test different combinations of props.',
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const Small: Story = {
|
|
152
|
+
args: {
|
|
153
|
+
...Default.args,
|
|
154
|
+
size: 'sm',
|
|
155
|
+
children: 'Small ${name}',
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export const Large: Story = {
|
|
160
|
+
args: {
|
|
161
|
+
...Default.args,
|
|
162
|
+
size: 'lg',
|
|
163
|
+
children: 'Large ${name}',
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export const Secondary: Story = {
|
|
168
|
+
args: {
|
|
169
|
+
...Default.args,
|
|
170
|
+
variant: 'secondary',
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export const Success: Story = {
|
|
175
|
+
args: {
|
|
176
|
+
...Default.args,
|
|
177
|
+
variant: 'success',
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
export const Error: Story = {
|
|
182
|
+
args: {
|
|
183
|
+
...Default.args,
|
|
184
|
+
variant: 'error',
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
export const Disabled: Story = {
|
|
189
|
+
args: {
|
|
190
|
+
...Default.args,
|
|
191
|
+
disabled: true,
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
export const Glass: Story = {
|
|
196
|
+
args: {
|
|
197
|
+
...Default.args,
|
|
198
|
+
glass: true,
|
|
199
|
+
},
|
|
200
|
+
parameters: {
|
|
201
|
+
docs: {
|
|
202
|
+
description: {
|
|
203
|
+
story: '${name} with glass morphism effect applied.',
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
export const CustomContent: Story = {
|
|
210
|
+
args: {
|
|
211
|
+
children: (
|
|
212
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
213
|
+
<span>🎨</span>
|
|
214
|
+
<span>Custom ${name} Content</span>
|
|
215
|
+
</div>
|
|
216
|
+
),
|
|
217
|
+
size: 'lg',
|
|
218
|
+
variant: 'primary',
|
|
219
|
+
},
|
|
220
|
+
parameters: {
|
|
221
|
+
docs: {
|
|
222
|
+
description: {
|
|
223
|
+
story: 'Example with custom content including icons and complex markup.',
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
`;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Storybook templates object
|
|
232
|
+
*/
|
|
233
|
+
export const storybookTemplates = {
|
|
234
|
+
story: basicStoryTemplate,
|
|
235
|
+
storyEnhanced: enhancedStoryTemplate,
|
|
236
|
+
};
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced Testing Templates
|
|
3
|
+
* Comprehensive test templates with accessibility and advanced patterns
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Enhanced Vitest test template for React components
|
|
8
|
+
*/
|
|
9
|
+
export const testTemplate = (name) => `import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
10
|
+
import { render, screen, fireEvent, act } from '@testing-library/react';
|
|
11
|
+
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
12
|
+
import { ${name} } from './${name}';
|
|
13
|
+
|
|
14
|
+
// Extend Vitest matchers
|
|
15
|
+
expect.extend(toHaveNoViolations);
|
|
16
|
+
|
|
17
|
+
// Mock IntersectionObserver
|
|
18
|
+
global.IntersectionObserver = vi.fn(() => ({
|
|
19
|
+
observe: vi.fn(),
|
|
20
|
+
unobserve: vi.fn(),
|
|
21
|
+
disconnect: vi.fn()
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
// Mock ResizeObserver
|
|
25
|
+
global.ResizeObserver = vi.fn().mockImplementation(() => ({
|
|
26
|
+
observe: vi.fn(),
|
|
27
|
+
unobserve: vi.fn(),
|
|
28
|
+
disconnect: vi.fn()
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
describe('${name}', () => {
|
|
32
|
+
// Accessibility Tests
|
|
33
|
+
describe('Accessibility', () => {
|
|
34
|
+
it('should have no accessibility violations', async () => {
|
|
35
|
+
const { container } = render(<${name}>Accessible Content</${name}>);
|
|
36
|
+
const results = await axe(container);
|
|
37
|
+
expect(results).toHaveNoViolations();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should have proper aria attributes', () => {
|
|
41
|
+
render(<${name} aria-label="Test component">Content</${name}>);
|
|
42
|
+
const element = screen.getByLabelText('Test component');
|
|
43
|
+
expect(element).toBeInTheDocument();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should support keyboard navigation', () => {
|
|
47
|
+
render(<${name}>Focusable Content</${name}>);
|
|
48
|
+
const element = screen.getByText('Focusable Content');
|
|
49
|
+
element.focus();
|
|
50
|
+
expect(element).toHaveFocus();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Rendering Tests
|
|
55
|
+
describe('Rendering', () => {
|
|
56
|
+
it('renders children correctly', () => {
|
|
57
|
+
render(<${name}>Test Content</${name}>);
|
|
58
|
+
expect(screen.getByText('Test Content')).toBeInTheDocument();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('applies className prop', () => {
|
|
62
|
+
const { container } = render(<${name} className="custom-class">Content</${name}>);
|
|
63
|
+
const element = container.firstChild;
|
|
64
|
+
expect(element).toHaveClass('custom-class');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('renders with custom attributes', () => {
|
|
68
|
+
render(<${name} data-testid="test-${name.toLowerCase()}">Content</${name}>);
|
|
69
|
+
expect(screen.getByTestId('test-${name.toLowerCase()}')).toBeInTheDocument();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Props Tests
|
|
74
|
+
describe('Props', () => {
|
|
75
|
+
it('applies size variant classes', () => {
|
|
76
|
+
const { container } = render(<${name} size="lg">Content</${name}>);
|
|
77
|
+
const element = container.firstChild;
|
|
78
|
+
expect(element).toHaveClass('c-${name.toLowerCase()}--lg');
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('handles disabled state', () => {
|
|
82
|
+
const { container } = render(<${name} disabled>Content</${name}>);
|
|
83
|
+
const element = container.firstChild;
|
|
84
|
+
expect(element).toHaveAttribute('aria-disabled', 'true');
|
|
85
|
+
expect(element).toHaveClass('is-disabled');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('passes through data attributes', () => {
|
|
89
|
+
const { container } = render(<${name} data-custom="value">Content</${name}>);
|
|
90
|
+
const element = container.firstChild;
|
|
91
|
+
expect(element).toHaveAttribute('data-custom', 'value');
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Event Handling Tests
|
|
96
|
+
describe('Event Handling', () => {
|
|
97
|
+
it('calls onClick handler when clicked', () => {
|
|
98
|
+
const handleClick = vi.fn();
|
|
99
|
+
render(<${name} onClick={handleClick}>Clickable</${name}>);
|
|
100
|
+
|
|
101
|
+
fireEvent.click(screen.getByText('Clickable'));
|
|
102
|
+
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('does not call onClick when disabled', () => {
|
|
106
|
+
const handleClick = vi.fn();
|
|
107
|
+
render(<${name} onClick={handleClick} disabled>Disabled</${name}>);
|
|
108
|
+
|
|
109
|
+
fireEvent.click(screen.getByText('Disabled'));
|
|
110
|
+
expect(handleClick).not.toHaveBeenCalled();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('handles mouse events', () => {
|
|
114
|
+
const handleMouseEnter = vi.fn();
|
|
115
|
+
const handleMouseLeave = vi.fn();
|
|
116
|
+
|
|
117
|
+
render(
|
|
118
|
+
<${name}
|
|
119
|
+
onMouseEnter={handleMouseEnter}
|
|
120
|
+
onMouseLeave={handleMouseLeave}
|
|
121
|
+
>
|
|
122
|
+
Hoverable
|
|
123
|
+
</${name}>
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
const element = screen.getByText('Hoverable');
|
|
127
|
+
fireEvent.mouseEnter(element);
|
|
128
|
+
fireEvent.mouseLeave(element);
|
|
129
|
+
|
|
130
|
+
expect(handleMouseEnter).toHaveBeenCalledTimes(1);
|
|
131
|
+
expect(handleMouseLeave).toHaveBeenCalledTimes(1);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Ref Forwarding Tests
|
|
136
|
+
describe('Ref Forwarding', () => {
|
|
137
|
+
it('forwards ref correctly', () => {
|
|
138
|
+
const ref = React.createRef<HTMLDivElement>();
|
|
139
|
+
render(<${name} ref={ref}>Content</${name}>);
|
|
140
|
+
expect(ref.current).toBeInstanceOf(HTMLDivElement);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('allows imperative methods access', () => {
|
|
144
|
+
const ref = React.createRef<{ focus: () => void }>();
|
|
145
|
+
render(<${name} ref={ref}>Focusable</${name}>);
|
|
146
|
+
|
|
147
|
+
// Assuming component exposes focus method
|
|
148
|
+
if (ref.current && ref.current.focus) {
|
|
149
|
+
const spy = vi.spyOn(ref.current, 'focus');
|
|
150
|
+
ref.current.focus();
|
|
151
|
+
expect(spy).toHaveBeenCalled();
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Performance Tests
|
|
157
|
+
describe('Performance', () => {
|
|
158
|
+
it('renders efficiently without unnecessary re-renders', () => {
|
|
159
|
+
const renderSpy = vi.fn();
|
|
160
|
+
const TestWrapper = () => {
|
|
161
|
+
renderSpy();
|
|
162
|
+
return <${name}>Performance Test</${name}>;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
render(<TestWrapper />);
|
|
166
|
+
expect(renderSpy).toHaveBeenCalledTimes(1);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Edge Cases
|
|
171
|
+
describe('Edge Cases', () => {
|
|
172
|
+
it('handles empty children gracefully', () => {
|
|
173
|
+
const { container } = render(<${name}></${name}>);
|
|
174
|
+
expect(container.firstChild).toBeInTheDocument();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('handles null children', () => {
|
|
178
|
+
const { container } = render(<${name}>{null}</${name}>);
|
|
179
|
+
expect(container.firstChild).toBeInTheDocument();
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('handles undefined props', () => {
|
|
183
|
+
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
184
|
+
|
|
185
|
+
expect(() => {
|
|
186
|
+
render(<${name} size={undefined}>Content</${name}>);
|
|
187
|
+
}).not.toThrow();
|
|
188
|
+
|
|
189
|
+
consoleSpy.mockRestore();
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// Async Behavior Tests
|
|
194
|
+
describe('Async Behavior', () => {
|
|
195
|
+
it('handles async state changes', async () => {
|
|
196
|
+
const AsyncComponent = () => {
|
|
197
|
+
const [loaded, setLoaded] = React.useState(false);
|
|
198
|
+
|
|
199
|
+
React.useEffect(() => {
|
|
200
|
+
setTimeout(() => setLoaded(true), 100);
|
|
201
|
+
}, []);
|
|
202
|
+
|
|
203
|
+
return <${name}>{loaded ? 'Loaded' : 'Loading...'}</${name}>;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
render(<AsyncComponent />);
|
|
207
|
+
expect(screen.getByText('Loading...')).toBeInTheDocument();
|
|
208
|
+
|
|
209
|
+
await act(async () => {
|
|
210
|
+
await new Promise(resolve => setTimeout(resolve, 150));
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
expect(screen.getByText('Loaded')).toBeInTheDocument();
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
`;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Testing templates object
|
|
221
|
+
*/
|
|
222
|
+
export const testingTemplates = {
|
|
223
|
+
test: testTemplate,
|
|
224
|
+
};
|