@shohojdhara/atomix 0.4.7 → 0.4.9
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 +58 -1
- package/dist/atomix.css +172 -157
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +4 -4
- package/dist/atomix.min.css.map +1 -1
- package/dist/charts.d.ts +33 -0
- package/dist/charts.js +1274 -164
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +33 -10
- package/dist/core.js +1099 -83
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +33 -0
- package/dist/forms.js +2106 -1050
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +42 -1
- package/dist/heavy.js +1663 -638
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +442 -270
- package/dist/index.esm.js +1947 -680
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1982 -712
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +6 -3
- package/scripts/atomix-cli.js +136 -1827
- package/scripts/cli/__tests__/basic.test.js +3 -2
- package/scripts/cli/__tests__/clean.test.js +278 -0
- package/scripts/cli/__tests__/component-validator.test.js +433 -0
- package/scripts/cli/__tests__/generator.test.js +613 -0
- package/scripts/cli/__tests__/glass-motion.test.js +256 -0
- package/scripts/cli/__tests__/integration.test.js +719 -108
- package/scripts/cli/__tests__/migrate.test.js +74 -0
- package/scripts/cli/__tests__/security.test.js +206 -0
- package/scripts/cli/__tests__/test-setup.js +3 -1
- package/scripts/cli/__tests__/theme-bridge.test.js +507 -0
- package/scripts/cli/__tests__/token-provider.test.js +361 -0
- package/scripts/cli/__tests__/utils.test.js +5 -5
- package/scripts/cli/commands/benchmark.js +105 -0
- package/scripts/cli/commands/build-theme.js +115 -0
- package/scripts/cli/commands/clean.js +109 -0
- package/scripts/cli/commands/doctor.js +88 -0
- package/scripts/cli/commands/generate.js +218 -0
- package/scripts/cli/commands/init.js +73 -0
- package/scripts/cli/commands/migrate.js +106 -0
- package/scripts/cli/commands/sync-tokens.js +206 -0
- package/scripts/cli/commands/theme-bridge.js +248 -0
- package/scripts/cli/commands/tokens.js +157 -0
- package/scripts/cli/commands/validate.js +194 -0
- package/scripts/cli/internal/ai-engine.js +156 -0
- package/scripts/cli/internal/compiler.js +114 -0
- package/scripts/cli/internal/component-validator.js +443 -0
- package/scripts/cli/internal/config-loader.js +162 -0
- package/scripts/cli/internal/filesystem.js +158 -0
- package/scripts/cli/internal/generator.js +430 -0
- package/scripts/cli/internal/glass-generator.js +398 -0
- package/scripts/cli/internal/hook-generator.js +369 -0
- package/scripts/cli/internal/hooks.js +61 -0
- package/scripts/cli/internal/itcss-generator.js +565 -0
- package/scripts/cli/internal/motion-generator.js +679 -0
- package/scripts/cli/internal/template-engine.js +301 -0
- package/scripts/cli/internal/theme-bridge.js +664 -0
- package/scripts/cli/internal/tokens/engine.js +122 -0
- package/scripts/cli/internal/tokens/provider.js +34 -0
- package/scripts/cli/internal/tokens/providers/figma.js +50 -0
- package/scripts/cli/internal/tokens/providers/style-dictionary.js +48 -0
- package/scripts/cli/internal/tokens/providers/w3c.js +48 -0
- package/scripts/cli/internal/tokens/token-provider.js +443 -0
- package/scripts/cli/internal/tokens/token-validator.js +513 -0
- package/scripts/cli/internal/validator.js +276 -0
- package/scripts/cli/internal/wizard.js +115 -0
- package/scripts/cli/mappings.js +23 -0
- package/scripts/cli/migration-tools.js +164 -94
- package/scripts/cli/plugins/style-dictionary.js +46 -0
- package/scripts/cli/templates/README.md +525 -95
- package/scripts/cli/templates/common-templates.js +40 -14
- package/scripts/cli/templates/components/react-component.ts +282 -0
- package/scripts/cli/templates/config/project-config.ts +112 -0
- package/scripts/cli/templates/hooks/use-component.ts +477 -0
- package/scripts/cli/templates/index.js +19 -4
- package/scripts/cli/templates/index.ts +171 -0
- package/scripts/cli/templates/next-templates.js +72 -0
- package/scripts/cli/templates/react-templates.js +70 -126
- package/scripts/cli/templates/scss-templates.js +35 -35
- package/scripts/cli/templates/stories/storybook-story.ts +241 -0
- package/scripts/cli/templates/styles/scss-component.ts +255 -0
- package/scripts/cli/templates/tests/vitest-test.ts +229 -0
- package/scripts/cli/templates/token-templates.js +337 -1
- package/scripts/cli/templates/tokens/token-generators.ts +1088 -0
- package/scripts/cli/templates/types/component-types.ts +145 -0
- package/scripts/cli/templates/utils/testing-utils.ts +144 -0
- package/scripts/cli/templates/vanilla-templates.js +39 -0
- package/scripts/cli/token-manager.js +8 -2
- package/scripts/cli/utils/cache-manager.js +240 -0
- package/scripts/cli/utils/detector.js +46 -0
- package/scripts/cli/utils/diagnostics.js +289 -0
- package/scripts/cli/utils/error.js +89 -0
- package/scripts/cli/utils/helpers.js +67 -0
- package/scripts/cli/utils/logger.js +75 -0
- package/scripts/cli/utils/security.js +302 -0
- package/scripts/cli/utils/telemetry.js +115 -0
- package/scripts/cli/utils/validation.js +37 -0
- package/scripts/cli/utils.js +28 -341
- package/src/components/Accordion/Accordion.stories.tsx +0 -18
- package/src/components/Accordion/Accordion.test.tsx +0 -17
- package/src/components/Accordion/Accordion.tsx +0 -4
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +37 -3
- package/src/components/AtomixGlass/AtomixGlass.tsx +143 -31
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +129 -31
- package/src/components/AtomixGlass/PerformanceDashboard.tsx +219 -0
- package/src/components/AtomixGlass/README.md +25 -10
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +216 -0
- package/src/components/AtomixGlass/animation-system.ts +578 -0
- package/src/components/AtomixGlass/shader-utils.ts +4 -1
- package/src/components/AtomixGlass/stories/Overview.stories.tsx +157 -6
- package/src/components/AtomixGlass/stories/Phase1-Animation.stories.tsx +653 -0
- package/src/components/AtomixGlass/stories/Phase1-Test.stories.tsx +95 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +51 -51
- package/src/components/AtomixGlass/stories/shared-components.tsx +6 -0
- package/src/components/Avatar/Avatar.tsx +1 -1
- package/src/components/Button/Button.stories.disabled-link.tsx +10 -0
- package/src/components/Button/Button.stories.tsx +10 -0
- package/src/components/Button/Button.test.tsx +16 -11
- package/src/components/Button/Button.tsx +4 -4
- package/src/components/Card/Card.tsx +1 -1
- package/src/components/Dropdown/Dropdown.tsx +12 -12
- package/src/components/Form/Select.tsx +62 -3
- package/src/components/Modal/Modal.tsx +14 -3
- package/src/components/Navigation/Navbar/Navbar.tsx +44 -0
- package/src/components/Slider/Slider.stories.tsx +3 -3
- package/src/components/Slider/Slider.tsx +38 -0
- package/src/components/Steps/Steps.tsx +3 -3
- package/src/components/Tabs/Tabs.tsx +77 -8
- package/src/components/Testimonial/Testimonial.tsx +1 -1
- package/src/components/TypedButton/TypedButton.stories.tsx +59 -0
- package/src/components/TypedButton/TypedButton.tsx +39 -0
- package/src/components/TypedButton/index.ts +2 -0
- package/src/components/VideoPlayer/VideoPlayer.tsx +11 -4
- package/src/lib/composables/index.ts +4 -7
- package/src/lib/composables/types.ts +45 -0
- package/src/lib/composables/useAccordion.ts +0 -7
- package/src/lib/composables/useAtomixGlass.ts +148 -6
- package/src/lib/composables/useAtomixGlassStyles.ts +9 -7
- package/src/lib/composables/useChartExport.ts +3 -13
- package/src/lib/composables/useDropdown.ts +66 -0
- package/src/lib/composables/useFocusTrap.ts +80 -0
- package/src/lib/composables/usePerformanceMonitor.ts +448 -0
- package/src/lib/composables/useResponsiveGlass.presets.ts +192 -0
- package/src/lib/composables/useResponsiveGlass.ts +441 -0
- package/src/lib/composables/useTooltip.ts +16 -0
- package/src/lib/composables/useTypedButton.ts +66 -0
- package/src/lib/config/index.ts +62 -5
- package/src/lib/constants/components.ts +62 -7
- package/src/lib/theme/devtools/__tests__/useHistory.test.tsx +150 -0
- package/src/lib/theme/tokens/centralized-tokens.ts +120 -0
- package/src/lib/theme/utils/__tests__/domUtils.test.ts +101 -0
- package/src/lib/types/components.ts +37 -11
- package/src/lib/types/glass.ts +35 -0
- package/src/lib/types/index.ts +1 -0
- package/src/lib/utils/displacement-generator.ts +1 -1
- package/src/styles/01-settings/_settings.testtypecheck.scss +53 -0
- package/src/styles/01-settings/_settings.typedbutton.scss +53 -0
- package/src/styles/06-components/_components.atomix-glass.scss +17 -21
- package/src/styles/06-components/_components.edge-panel.scss +1 -5
- package/src/styles/06-components/_components.modal.scss +1 -4
- package/src/styles/06-components/_components.navbar.scss +1 -1
- package/src/styles/06-components/_components.testbutton.scss +212 -0
- package/src/styles/06-components/_components.testtypecheck.scss +212 -0
- package/src/styles/06-components/_components.tooltip.scss +9 -5
- package/src/styles/06-components/_components.typedbutton.scss +212 -0
- package/src/styles/99-utilities/_index.scss +1 -0
- package/src/styles/99-utilities/_utilities.text.scss +1 -1
- package/src/styles/99-utilities/_utilities.touch-target.scss +36 -0
- package/scripts/cli/component-generator.js +0 -564
- package/scripts/cli/interactive-init.js +0 -357
- package/src/styles/06-components/old.chart.styles.scss +0 -2788
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Glassmorphism Component Generator
|
|
3
|
+
* Generates premium glass effect components following Atomix design patterns
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { filesystem } from './filesystem.js';
|
|
8
|
+
import { logger } from '../utils/logger.js';
|
|
9
|
+
import { AtomixCLIError } from '../utils/error.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Glass effect configuration presets
|
|
13
|
+
*/
|
|
14
|
+
export const GLASS_PRESETS = {
|
|
15
|
+
subtle: {
|
|
16
|
+
name: 'Subtle',
|
|
17
|
+
displacementScale: 10,
|
|
18
|
+
blurAmount: 5,
|
|
19
|
+
saturation: 150,
|
|
20
|
+
elasticity: 0.3,
|
|
21
|
+
opacity: 0.1,
|
|
22
|
+
borderOpacity: 0.2
|
|
23
|
+
},
|
|
24
|
+
default: {
|
|
25
|
+
name: 'Default',
|
|
26
|
+
displacementScale: 20,
|
|
27
|
+
blurAmount: 10,
|
|
28
|
+
saturation: 200,
|
|
29
|
+
elasticity: 0.5,
|
|
30
|
+
opacity: 0.15,
|
|
31
|
+
borderOpacity: 0.3
|
|
32
|
+
},
|
|
33
|
+
strong: {
|
|
34
|
+
name: 'Strong',
|
|
35
|
+
displacementScale: 30,
|
|
36
|
+
blurAmount: 20,
|
|
37
|
+
saturation: 250,
|
|
38
|
+
elasticity: 0.7,
|
|
39
|
+
opacity: 0.2,
|
|
40
|
+
borderOpacity: 0.4
|
|
41
|
+
},
|
|
42
|
+
frost: {
|
|
43
|
+
name: 'Frost',
|
|
44
|
+
displacementScale: 40,
|
|
45
|
+
blurAmount: 30,
|
|
46
|
+
saturation: 300,
|
|
47
|
+
elasticity: 0.8,
|
|
48
|
+
opacity: 0.25,
|
|
49
|
+
borderOpacity: 0.5
|
|
50
|
+
},
|
|
51
|
+
crystal: {
|
|
52
|
+
name: 'Crystal',
|
|
53
|
+
displacementScale: 50,
|
|
54
|
+
blurAmount: 40,
|
|
55
|
+
saturation: 350,
|
|
56
|
+
elasticity: 1,
|
|
57
|
+
opacity: 0.3,
|
|
58
|
+
borderOpacity: 0.6
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Generate glassmorphism CSS styles
|
|
64
|
+
*/
|
|
65
|
+
export function generateGlassStyles(componentName, preset = 'default') {
|
|
66
|
+
const config = typeof preset === 'string' ? GLASS_PRESETS[preset] : preset;
|
|
67
|
+
const componentPrefix = componentName.toLowerCase().replace(/([A-Z])/g, '-$1').replace(/^-/, '');
|
|
68
|
+
|
|
69
|
+
return `// ${componentName} Glassmorphism Styles
|
|
70
|
+
// Generated by Atomix CLI
|
|
71
|
+
// Preset: ${config.name}
|
|
72
|
+
// =============================================================================
|
|
73
|
+
|
|
74
|
+
@use '../../01-settings/settings.${componentPrefix}' as *;
|
|
75
|
+
@use '../../02-tools/mixins' as *;
|
|
76
|
+
|
|
77
|
+
// Glass Effect Base
|
|
78
|
+
// =============================================================================
|
|
79
|
+
|
|
80
|
+
.${componentPrefix}--glass {
|
|
81
|
+
// Glass background
|
|
82
|
+
background: rgba(255, 255, 255, ${config.opacity});
|
|
83
|
+
backdrop-filter: blur(${config.blurAmount}px) saturate(${config.saturation}%);
|
|
84
|
+
-webkit-backdrop-filter: blur(${config.blurAmount}px) saturate(${config.saturation}%);
|
|
85
|
+
|
|
86
|
+
// Glass border
|
|
87
|
+
border: 1px solid rgba(255, 255, 255, ${config.borderOpacity});
|
|
88
|
+
box-shadow:
|
|
89
|
+
0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
|
90
|
+
0 2px 4px -1px rgba(0, 0, 0, 0.06),
|
|
91
|
+
inset 0 1px 0 0 rgba(255, 255, 255, ${config.borderOpacity});
|
|
92
|
+
|
|
93
|
+
// Distortion effect (simulated with CSS)
|
|
94
|
+
transform: scale(1);
|
|
95
|
+
transition: all var(--atomix-duration-base) var(--atomix-easing-smooth);
|
|
96
|
+
|
|
97
|
+
// Hover state - enhanced glass effect
|
|
98
|
+
&:hover:not(:disabled) {
|
|
99
|
+
background: rgba(255, 255, 255, calc(${config.opacity} * 1.2));
|
|
100
|
+
backdrop-filter: blur(calc(${config.blurAmount}px + 5px)) saturate(calc(${config.saturation}% + 50));
|
|
101
|
+
border-color: rgba(255, 255, 255, calc(${config.borderOpacity} * 1.2));
|
|
102
|
+
box-shadow:
|
|
103
|
+
0 10px 15px -3px rgba(0, 0, 0, 0.1),
|
|
104
|
+
0 4px 6px -2px rgba(0, 0, 0, 0.05),
|
|
105
|
+
inset 0 1px 0 0 rgba(255, 255, 255, calc(${config.borderOpacity} * 1.3)),
|
|
106
|
+
0 0 20px rgba(255, 255, 255, 0.1);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Active/pressed state
|
|
110
|
+
&:active:not(:disabled) {
|
|
111
|
+
transform: scale(0.98);
|
|
112
|
+
background: rgba(255, 255, 255, calc(${config.opacity} * 0.9));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Focus state
|
|
116
|
+
&:focus-visible {
|
|
117
|
+
outline: none;
|
|
118
|
+
box-shadow:
|
|
119
|
+
0 0 0 2px rgba(var(--atomix-color-primary-rgb), 0.2),
|
|
120
|
+
0 0 0 4px rgba(var(--atomix-color-primary-rgb), 0.1),
|
|
121
|
+
0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Dark Mode Glass
|
|
126
|
+
// =============================================================================
|
|
127
|
+
|
|
128
|
+
.dark .${componentPrefix}--glass {
|
|
129
|
+
background: rgba(30, 30, 30, ${config.opacity});
|
|
130
|
+
border-color: rgba(255, 255, 255, calc(${config.borderOpacity} * 0.5));
|
|
131
|
+
|
|
132
|
+
&:hover:not(:disabled) {
|
|
133
|
+
background: rgba(40, 40, 40, calc(${config.opacity} * 1.2));
|
|
134
|
+
border-color: rgba(255, 255, 255, calc(${config.borderOpacity} * 0.6));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Glass Variants
|
|
139
|
+
// =============================================================================
|
|
140
|
+
|
|
141
|
+
.${componentPrefix}--glass-light {
|
|
142
|
+
background: rgba(255, 255, 255, calc(${config.opacity} * 0.7));
|
|
143
|
+
backdrop-filter: blur(calc(${config.blurAmount}px - 2px)) saturate(calc(${config.saturation}% - 50));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.${componentPrefix}--glass-dark {
|
|
147
|
+
background: rgba(0, 0, 0, ${config.opacity});
|
|
148
|
+
backdrop-filter: blur(${config.blurAmount}px) saturate(${config.saturation}%);
|
|
149
|
+
border-color: rgba(0, 0, 0, ${config.borderOpacity});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.${componentPrefix}--glass-colored {
|
|
153
|
+
background: rgba(var(--atomix-color-primary-rgb), ${config.opacity});
|
|
154
|
+
backdrop-filter: blur(${config.blurAmount}px) saturate(calc(${config.saturation}% + 100));
|
|
155
|
+
border-color: rgba(var(--atomix-color-primary-rgb), ${config.borderOpacity});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Responsive Glass Adjustments
|
|
159
|
+
// =============================================================================
|
|
160
|
+
|
|
161
|
+
@include atomix-media-breakpoint-up(md) {
|
|
162
|
+
.${componentPrefix}--glass {
|
|
163
|
+
// Enhanced blur on desktop for better performance
|
|
164
|
+
backdrop-filter: blur(calc(${config.blurAmount}px + 5px)) saturate(${config.saturation}%);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Performance Optimization
|
|
169
|
+
// Reduce backdrop-filter on mobile devices
|
|
170
|
+
@media (max-width: 767px) {
|
|
171
|
+
.${componentPrefix}--glass {
|
|
172
|
+
// Fallback for mobile devices
|
|
173
|
+
background: rgba(255, 255, 255, calc(${config.opacity} * 1.5));
|
|
174
|
+
backdrop-filter: blur(calc(${config.blurAmount}px / 2));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Only apply full glass effect if prefers-reduced-motion is not set
|
|
178
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
179
|
+
.${componentPrefix}--glass {
|
|
180
|
+
backdrop-filter: blur(${config.blurAmount}px) saturate(${config.saturation}%);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Accessibility: Reduced Transparency
|
|
186
|
+
// =============================================================================
|
|
187
|
+
|
|
188
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
189
|
+
.${componentPrefix}--glass {
|
|
190
|
+
background: rgba(255, 255, 255, 0.95);
|
|
191
|
+
backdrop-filter: none;
|
|
192
|
+
-webkit-backdrop-filter: none;
|
|
193
|
+
border: 1px solid var(--atomix-color-neutral-300);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.dark .${componentPrefix}--glass {
|
|
197
|
+
background: rgba(30, 30, 30, 0.95);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
`;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Generate glass-enhanced React component wrapper
|
|
205
|
+
*/
|
|
206
|
+
export function generateGlassWrapper(componentName) {
|
|
207
|
+
return `/**
|
|
208
|
+
* Glass Effect Configuration Type
|
|
209
|
+
*/
|
|
210
|
+
export interface GlassConfig {
|
|
211
|
+
/**
|
|
212
|
+
* Displacement scale for distortion effect (0-100)
|
|
213
|
+
* @default 20
|
|
214
|
+
*/
|
|
215
|
+
displacementScale?: number;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Blur amount in pixels (0-50)
|
|
219
|
+
* @default 10
|
|
220
|
+
*/
|
|
221
|
+
blurAmount?: number;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Saturation percentage (100-500)
|
|
225
|
+
* @default 200
|
|
226
|
+
*/
|
|
227
|
+
saturation?: number;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Elasticity factor for hover animation (0-1)
|
|
231
|
+
* @default 0.5
|
|
232
|
+
*/
|
|
233
|
+
elasticity?: number;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Background opacity (0-1)
|
|
237
|
+
* @default 0.15
|
|
238
|
+
*/
|
|
239
|
+
opacity?: number;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Border opacity (0-1)
|
|
243
|
+
* @default 0.3
|
|
244
|
+
*/
|
|
245
|
+
borderOpacity?: number;
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Glass preset name ('subtle' | 'default' | 'strong' | 'frost' | 'crystal')
|
|
249
|
+
*/
|
|
250
|
+
preset?: 'subtle' | 'default' | 'strong' | 'frost' | 'crystal';
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Apply glass effect to component
|
|
255
|
+
* Can be used as HOC or inline wrapper
|
|
256
|
+
*/
|
|
257
|
+
export function withGlass<P extends object>(
|
|
258
|
+
WrappedComponent: React.ComponentType<P>,
|
|
259
|
+
defaultGlassConfig?: GlassConfig
|
|
260
|
+
) {
|
|
261
|
+
return function GlassEnhancedComponent(props: P & { glass?: GlassConfig | boolean }) {
|
|
262
|
+
const { glass, ...restProps } = props as any;
|
|
263
|
+
|
|
264
|
+
if (!glass) {
|
|
265
|
+
return <WrappedComponent {...(restProps as P)} />;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const glassConfig = glass === true ? defaultGlassConfig : glass;
|
|
269
|
+
|
|
270
|
+
return (
|
|
271
|
+
<div className="glass-wrapper" data-glass-config={JSON.stringify(glassConfig)}>
|
|
272
|
+
<WrappedComponent {...(restProps as P)} glass={glass} />
|
|
273
|
+
</div>
|
|
274
|
+
);
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Glass effect CSS-in-JS utility
|
|
280
|
+
* Returns inline styles for glass effect
|
|
281
|
+
*/
|
|
282
|
+
export function getGlassStyles(config: GlassConfig): React.CSSProperties {
|
|
283
|
+
const {
|
|
284
|
+
displacementScale = 20,
|
|
285
|
+
blurAmount = 10,
|
|
286
|
+
saturation = 200,
|
|
287
|
+
opacity = 0.15,
|
|
288
|
+
borderOpacity = 0.3
|
|
289
|
+
} = config;
|
|
290
|
+
|
|
291
|
+
return {
|
|
292
|
+
background: \`rgba(255, 255, 255, \${opacity})\`,
|
|
293
|
+
backdropFilter: \`blur(\${blurAmount}px) saturate(\${saturation}%)\`,
|
|
294
|
+
WebkitBackdropFilter: \`blur(\${blurAmount}px) saturate(\${saturation}%)\`,
|
|
295
|
+
border: \`1px solid rgba(255, 255, 255, \${borderOpacity})\`,
|
|
296
|
+
boxShadow: \`
|
|
297
|
+
0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
|
298
|
+
0 2px 4px -1px rgba(0, 0, 0, 0.06),
|
|
299
|
+
inset 0 1px 0 0 rgba(255, 255, 255, \${borderOpacity})
|
|
300
|
+
\`
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
`;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Generate complete glassmorphism package
|
|
308
|
+
*/
|
|
309
|
+
export async function generateGlassPackage(componentName, projectRoot, options = {}) {
|
|
310
|
+
const {
|
|
311
|
+
preset = 'default',
|
|
312
|
+
outputDir = 'src/styles/06-components',
|
|
313
|
+
force = false
|
|
314
|
+
} = options;
|
|
315
|
+
|
|
316
|
+
const created = [];
|
|
317
|
+
const componentPrefix = componentName.toLowerCase().replace(/([A-Z])/g, '-$1').replace(/^-/, '');
|
|
318
|
+
|
|
319
|
+
try {
|
|
320
|
+
// Create output directory
|
|
321
|
+
await filesystem.createDirectory(outputDir);
|
|
322
|
+
|
|
323
|
+
// Generate glass styles file
|
|
324
|
+
const glassFile = join(outputDir, `_components.${componentPrefix}.glass.scss`);
|
|
325
|
+
|
|
326
|
+
if (force || !await filesystem.exists(glassFile)) {
|
|
327
|
+
const glassContent = generateGlassStyles(componentName, preset);
|
|
328
|
+
await filesystem.writeFile(glassFile, glassContent, 'utf8');
|
|
329
|
+
created.push(`src/styles/06-components/_components.${componentPrefix}.glass.scss`);
|
|
330
|
+
logger.debug(`Created glass styles: ${glassFile}`);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Generate TypeScript utilities
|
|
334
|
+
const typesDir = join(projectRoot, 'src/lib/utils');
|
|
335
|
+
await filesystem.createDirectory(typesDir);
|
|
336
|
+
|
|
337
|
+
const glassUtilsFile = join(typesDir, 'glass.ts');
|
|
338
|
+
if (force || !await filesystem.exists(glassUtilsFile)) {
|
|
339
|
+
const utilsContent = generateGlassWrapper(componentName);
|
|
340
|
+
await filesystem.writeFile(glassUtilsFile, utilsContent, 'utf8');
|
|
341
|
+
created.push('src/lib/utils/glass.ts');
|
|
342
|
+
logger.debug(`Created glass utilities: ${glassUtilsFile}`);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return {
|
|
346
|
+
success: true,
|
|
347
|
+
created,
|
|
348
|
+
preset: GLASS_PRESETS[preset]?.name || preset,
|
|
349
|
+
message: `Generated glassmorphism package with ${created.length} files using ${preset} preset`
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
} catch (error) {
|
|
353
|
+
throw new AtomixCLIError(
|
|
354
|
+
`Failed to generate glassmorphism package: ${error.message}`,
|
|
355
|
+
'GLASS_GENERATION_FAILED',
|
|
356
|
+
[
|
|
357
|
+
'Check you have write permissions for src/styles directory',
|
|
358
|
+
'Verify component name is valid PascalCase',
|
|
359
|
+
'Try running with --force flag to overwrite existing files'
|
|
360
|
+
]
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Get available glass presets
|
|
367
|
+
*/
|
|
368
|
+
export function getGlassPresets() {
|
|
369
|
+
return Object.keys(GLASS_PRESETS);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Validate glass configuration
|
|
374
|
+
*/
|
|
375
|
+
export function validateGlassConfig(config) {
|
|
376
|
+
const issues = [];
|
|
377
|
+
|
|
378
|
+
if (config.displacementScale && (config.displacementScale < 0 || config.displacementScale > 100)) {
|
|
379
|
+
issues.push('displacementScale must be between 0 and 100');
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if (config.blurAmount && (config.blurAmount < 0 || config.blurAmount > 50)) {
|
|
383
|
+
issues.push('blurAmount must be between 0 and 50');
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (config.saturation && (config.saturation < 100 || config.saturation > 500)) {
|
|
387
|
+
issues.push('saturation must be between 100 and 500');
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (config.opacity && (config.opacity < 0 || config.opacity > 1)) {
|
|
391
|
+
issues.push('opacity must be between 0 and 1');
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return {
|
|
395
|
+
valid: issues.length === 0,
|
|
396
|
+
issues
|
|
397
|
+
};
|
|
398
|
+
}
|