@shohojdhara/atomix 0.5.1 → 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 +138 -17
- 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 +23 -23
- package/dist/charts.js +40 -37
- 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 +2 -2
- package/dist/core.js +111 -50
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +3 -6
- package/dist/forms.js +2 -2
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +1 -1
- package/dist/heavy.js +173 -111
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +98 -65
- package/dist/index.esm.js +427 -422
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +394 -391
- 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 +14 -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 +3 -0
- 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/AtomixGlassContainer.tsx +1 -1
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +219 -0
- package/src/components/AtomixGlass/glass-utils.ts +1 -1
- 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 +3 -3
- 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/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/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 +4 -4
- 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/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
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { useState, useCallback, useEffect } from 'react';
|
|
2
|
-
|
|
3
|
-
export interface UseModalProps {
|
|
4
|
-
/**
|
|
5
|
-
* Whether the modal is open
|
|
6
|
-
*/
|
|
7
|
-
isOpen?: boolean;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Callback when modal state changes
|
|
11
|
-
*/
|
|
12
|
-
onOpenChange?: (isOpen: boolean) => void;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Callback when modal opens
|
|
16
|
-
*/
|
|
17
|
-
onOpen?: () => void;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Callback when modal closes
|
|
21
|
-
*/
|
|
22
|
-
onClose?: () => void;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface UseModalReturn {
|
|
26
|
-
/**
|
|
27
|
-
* Current open state
|
|
28
|
-
*/
|
|
29
|
-
isOpen: boolean;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Function to open the modal
|
|
33
|
-
*/
|
|
34
|
-
open: () => void;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Function to close the modal
|
|
38
|
-
*/
|
|
39
|
-
close: () => void;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Function to toggle the modal
|
|
43
|
-
*/
|
|
44
|
-
toggle: () => void;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Hook for managing modal state
|
|
49
|
-
*/
|
|
50
|
-
export function useModal({
|
|
51
|
-
isOpen: isOpenProp,
|
|
52
|
-
onOpenChange,
|
|
53
|
-
onOpen,
|
|
54
|
-
onClose,
|
|
55
|
-
}: UseModalProps = {}): UseModalReturn {
|
|
56
|
-
// For uncontrolled usage
|
|
57
|
-
const [isOpenState, setIsOpenState] = useState(false);
|
|
58
|
-
|
|
59
|
-
// Determine if we're in controlled or uncontrolled mode
|
|
60
|
-
const isControlled = isOpenProp !== undefined;
|
|
61
|
-
const isOpen = isControlled ? !!isOpenProp : isOpenState;
|
|
62
|
-
|
|
63
|
-
// Update internal state when prop changes (for controlled mode)
|
|
64
|
-
useEffect(() => {
|
|
65
|
-
if (isControlled) {
|
|
66
|
-
setIsOpenState(!!isOpenProp);
|
|
67
|
-
}
|
|
68
|
-
}, [isOpenProp, isControlled]);
|
|
69
|
-
|
|
70
|
-
const updateOpen = useCallback(
|
|
71
|
-
(nextIsOpen: boolean) => {
|
|
72
|
-
// For uncontrolled mode, update internal state
|
|
73
|
-
if (!isControlled) {
|
|
74
|
-
setIsOpenState(nextIsOpen);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Call the change handler in either mode
|
|
78
|
-
if (onOpenChange) {
|
|
79
|
-
onOpenChange(nextIsOpen);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Call the specific handler
|
|
83
|
-
if (nextIsOpen && onOpen) {
|
|
84
|
-
onOpen();
|
|
85
|
-
} else if (!nextIsOpen && onClose) {
|
|
86
|
-
onClose();
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
[isControlled, onOpenChange, onOpen, onClose]
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
const open = useCallback(() => {
|
|
93
|
-
updateOpen(true);
|
|
94
|
-
}, [updateOpen]);
|
|
95
|
-
|
|
96
|
-
const close = useCallback(() => {
|
|
97
|
-
updateOpen(false);
|
|
98
|
-
}, [updateOpen]);
|
|
99
|
-
|
|
100
|
-
const toggle = useCallback(() => {
|
|
101
|
-
updateOpen(!isOpen);
|
|
102
|
-
}, [isOpen, updateOpen]);
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
isOpen,
|
|
106
|
-
open,
|
|
107
|
-
close,
|
|
108
|
-
toggle,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Performance Monitoring Hook
|
|
3
|
-
*
|
|
4
|
-
* Tracks component render times and re-render counts
|
|
5
|
-
* for performance analysis and optimization
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { useEffect, useRef } from 'react';
|
|
9
|
-
|
|
10
|
-
export interface PerformanceMetrics {
|
|
11
|
-
/**
|
|
12
|
-
* Component name
|
|
13
|
-
*/
|
|
14
|
-
componentName: string;
|
|
15
|
-
/**
|
|
16
|
-
* Number of renders
|
|
17
|
-
*/
|
|
18
|
-
renderCount: number;
|
|
19
|
-
/**
|
|
20
|
-
* Average render time in milliseconds
|
|
21
|
-
*/
|
|
22
|
-
averageRenderTime: number;
|
|
23
|
-
/**
|
|
24
|
-
* Total render time in milliseconds
|
|
25
|
-
*/
|
|
26
|
-
totalRenderTime: number;
|
|
27
|
-
/**
|
|
28
|
-
* Maximum render time in milliseconds
|
|
29
|
-
*/
|
|
30
|
-
maxRenderTime: number;
|
|
31
|
-
/**
|
|
32
|
-
* Minimum render time in milliseconds
|
|
33
|
-
*/
|
|
34
|
-
minRenderTime: number;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Options for performance monitoring
|
|
39
|
-
*/
|
|
40
|
-
export interface UsePerformanceMonitorOptions {
|
|
41
|
-
/**
|
|
42
|
-
* Component name to track
|
|
43
|
-
*/
|
|
44
|
-
componentName: string;
|
|
45
|
-
/**
|
|
46
|
-
* Whether to log metrics to console (development only)
|
|
47
|
-
*/
|
|
48
|
-
logToConsole?: boolean;
|
|
49
|
-
/**
|
|
50
|
-
* Threshold in milliseconds to warn about slow renders
|
|
51
|
-
*/
|
|
52
|
-
warnThreshold?: number;
|
|
53
|
-
/**
|
|
54
|
-
* Callback to report metrics (e.g., to analytics)
|
|
55
|
-
*/
|
|
56
|
-
onMetrics?: (metrics: PerformanceMetrics) => void;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Hook to monitor component performance
|
|
61
|
-
*
|
|
62
|
-
* @param options - Performance monitoring options
|
|
63
|
-
* @returns Performance metrics
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* ```tsx
|
|
67
|
-
* function MyComponent() {
|
|
68
|
-
* usePerformanceMonitor({
|
|
69
|
-
* componentName: 'MyComponent',
|
|
70
|
-
* warnThreshold: 16, // Warn if render takes > 16ms (1 frame)
|
|
71
|
-
* });
|
|
72
|
-
*
|
|
73
|
-
* return <div>Content</div>;
|
|
74
|
-
* }
|
|
75
|
-
* ```
|
|
76
|
-
*/
|
|
77
|
-
export function usePerformanceMonitor(options: UsePerformanceMonitorOptions) {
|
|
78
|
-
const {
|
|
79
|
-
componentName,
|
|
80
|
-
logToConsole = typeof process === 'undefined' || process.env?.NODE_ENV === 'development',
|
|
81
|
-
warnThreshold = 16,
|
|
82
|
-
onMetrics,
|
|
83
|
-
} = options;
|
|
84
|
-
|
|
85
|
-
const metricsRef = useRef<PerformanceMetrics>({
|
|
86
|
-
componentName,
|
|
87
|
-
renderCount: 0,
|
|
88
|
-
averageRenderTime: 0,
|
|
89
|
-
totalRenderTime: 0,
|
|
90
|
-
maxRenderTime: 0,
|
|
91
|
-
minRenderTime: Infinity,
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
const renderStartRef = useRef<number>(0);
|
|
95
|
-
|
|
96
|
-
useEffect(() => {
|
|
97
|
-
// Start timing the render
|
|
98
|
-
renderStartRef.current = performance.now();
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
useEffect(() => {
|
|
102
|
-
// Calculate render time
|
|
103
|
-
const renderTime = performance.now() - renderStartRef.current;
|
|
104
|
-
const metrics = metricsRef.current;
|
|
105
|
-
|
|
106
|
-
// Update metrics
|
|
107
|
-
metrics.renderCount += 1;
|
|
108
|
-
metrics.totalRenderTime += renderTime;
|
|
109
|
-
metrics.averageRenderTime = metrics.totalRenderTime / metrics.renderCount;
|
|
110
|
-
metrics.maxRenderTime = Math.max(metrics.maxRenderTime, renderTime);
|
|
111
|
-
metrics.minRenderTime = Math.min(metrics.minRenderTime, renderTime);
|
|
112
|
-
|
|
113
|
-
// Warn if render is slow
|
|
114
|
-
if (renderTime > warnThreshold && logToConsole) {
|
|
115
|
-
console.warn(
|
|
116
|
-
`[Performance] ${componentName} render took ${renderTime.toFixed(2)}ms ` +
|
|
117
|
-
`(threshold: ${warnThreshold}ms)`
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Log metrics in development
|
|
122
|
-
if (logToConsole && metrics.renderCount % 10 === 0) {
|
|
123
|
-
console.log(`[Performance] ${componentName} metrics:`, {
|
|
124
|
-
renderCount: metrics.renderCount,
|
|
125
|
-
averageRenderTime: metrics.averageRenderTime.toFixed(2) + 'ms',
|
|
126
|
-
maxRenderTime: metrics.maxRenderTime.toFixed(2) + 'ms',
|
|
127
|
-
minRenderTime: metrics.minRenderTime.toFixed(2) + 'ms',
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Report metrics via callback
|
|
132
|
-
if (onMetrics) {
|
|
133
|
-
onMetrics({ ...metrics });
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
return metricsRef.current;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Get all performance metrics for all monitored components
|
|
142
|
-
* (useful for debugging and analytics)
|
|
143
|
-
*/
|
|
144
|
-
export function getPerformanceMetrics(): PerformanceMetrics[] {
|
|
145
|
-
// This would need to be implemented with a global store
|
|
146
|
-
// For now, this is a placeholder
|
|
147
|
-
return [];
|
|
148
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
export interface Vec2 {
|
|
2
|
-
x: number;
|
|
3
|
-
y: number;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export interface ShaderOptions {
|
|
7
|
-
width: number;
|
|
8
|
-
height: number;
|
|
9
|
-
fragment: (uv: Vec2) => Vec2;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function smoothStep(a: number, b: number, t: number): number {
|
|
13
|
-
t = Math.max(0, Math.min(1, (t - a) / (b - a)));
|
|
14
|
-
return t * t * (3 - 2 * t);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function length(x: number, y: number): number {
|
|
18
|
-
return Math.sqrt(x * x + y * y);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function roundedRectSDF(
|
|
22
|
-
x: number,
|
|
23
|
-
y: number,
|
|
24
|
-
width: number,
|
|
25
|
-
height: number,
|
|
26
|
-
radius: number
|
|
27
|
-
): number {
|
|
28
|
-
const qx = Math.abs(x) - width + radius;
|
|
29
|
-
const qy = Math.abs(y) - height + radius;
|
|
30
|
-
return Math.min(Math.max(qx, qy), 0) + length(Math.max(qx, 0), Math.max(qy, 0)) - radius;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export const fragmentShaders = {
|
|
34
|
-
liquidGlass: (uv: Vec2): Vec2 => {
|
|
35
|
-
const ix = uv.x - 0.5;
|
|
36
|
-
const iy = uv.y - 0.5;
|
|
37
|
-
const distanceToEdge = roundedRectSDF(ix, iy, 0.3, 0.2, 0.6);
|
|
38
|
-
const displacement = smoothStep(0.8, 0, distanceToEdge - 0.15);
|
|
39
|
-
const scaled = smoothStep(0, 1, displacement);
|
|
40
|
-
return { x: ix * scaled + 0.5, y: iy * scaled + 0.5 };
|
|
41
|
-
},
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export class ShaderDisplacementGenerator {
|
|
45
|
-
private canvas: HTMLCanvasElement;
|
|
46
|
-
private context: CanvasRenderingContext2D;
|
|
47
|
-
|
|
48
|
-
constructor(private options: ShaderOptions) {
|
|
49
|
-
this.canvas = document.createElement('canvas');
|
|
50
|
-
this.canvas.width = options.width;
|
|
51
|
-
this.canvas.height = options.height;
|
|
52
|
-
this.canvas.style.display = 'none';
|
|
53
|
-
|
|
54
|
-
const context = this.canvas.getContext('2d');
|
|
55
|
-
if (!context) {
|
|
56
|
-
throw new Error('Could not get 2D context');
|
|
57
|
-
}
|
|
58
|
-
this.context = context;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
updateShader(): string {
|
|
62
|
-
const { width, height } = this.options;
|
|
63
|
-
const imageData = this.context.createImageData(width, height);
|
|
64
|
-
const data = imageData.data;
|
|
65
|
-
|
|
66
|
-
for (let y = 0; y < height; y++) {
|
|
67
|
-
for (let x = 0; x < width; x++) {
|
|
68
|
-
const uv: Vec2 = { x: x / width, y: y / height };
|
|
69
|
-
const pos = this.options.fragment(uv);
|
|
70
|
-
|
|
71
|
-
const dx = pos.x * width - x;
|
|
72
|
-
const dy = pos.y * height - y;
|
|
73
|
-
|
|
74
|
-
const r = dx / 10 + 0.5;
|
|
75
|
-
const g = dy / 10 + 0.5;
|
|
76
|
-
|
|
77
|
-
const pixelIndex = (y * width + x) * 4;
|
|
78
|
-
data[pixelIndex] = Math.max(0, Math.min(255, r * 255));
|
|
79
|
-
data[pixelIndex + 1] = Math.max(0, Math.min(255, g * 255));
|
|
80
|
-
data[pixelIndex + 2] = Math.max(0, Math.min(255, g * 255));
|
|
81
|
-
data[pixelIndex + 3] = 255;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
this.context.putImageData(imageData, 0, 0);
|
|
86
|
-
return this.canvas.toDataURL();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
destroy(): void {
|
|
90
|
-
this.canvas.remove();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory Monitoring Utilities
|
|
3
|
-
*
|
|
4
|
-
* Detects memory leaks and tracks component lifecycle memory usage
|
|
5
|
-
* Only available in development mode
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Memory snapshot for comparison
|
|
10
|
-
*/
|
|
11
|
-
export interface MemorySnapshot {
|
|
12
|
-
/**
|
|
13
|
-
* Used JavaScript heap size in bytes
|
|
14
|
-
*/
|
|
15
|
-
usedJSHeapSize: number;
|
|
16
|
-
/**
|
|
17
|
-
* Total JavaScript heap size in bytes
|
|
18
|
-
*/
|
|
19
|
-
totalJSHeapSize: number;
|
|
20
|
-
/**
|
|
21
|
-
* JavaScript heap size limit in bytes
|
|
22
|
-
*/
|
|
23
|
-
jsHeapSizeLimit: number;
|
|
24
|
-
/**
|
|
25
|
-
* Timestamp of the snapshot
|
|
26
|
-
*/
|
|
27
|
-
timestamp: number;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Check if memory monitoring is available
|
|
32
|
-
*/
|
|
33
|
-
export function isMemoryMonitoringAvailable(): boolean {
|
|
34
|
-
return (
|
|
35
|
-
typeof performance !== 'undefined' &&
|
|
36
|
-
'memory' in performance &&
|
|
37
|
-
(typeof process === 'undefined' || process.env?.NODE_ENV === 'development')
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Get current memory usage snapshot
|
|
43
|
-
*
|
|
44
|
-
* @returns Memory snapshot or null if not available
|
|
45
|
-
*/
|
|
46
|
-
export function getMemorySnapshot(): MemorySnapshot | null {
|
|
47
|
-
if (!isMemoryMonitoringAvailable()) {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const memory = (performance as any).memory;
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
usedJSHeapSize: memory.usedJSHeapSize,
|
|
55
|
-
totalJSHeapSize: memory.totalJSHeapSize,
|
|
56
|
-
jsHeapSizeLimit: memory.jsHeapSizeLimit,
|
|
57
|
-
timestamp: performance.now(),
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Format bytes to human-readable string
|
|
63
|
-
*
|
|
64
|
-
* @param bytes - Number of bytes
|
|
65
|
-
* @returns Formatted string (e.g., "1.5 MB")
|
|
66
|
-
*/
|
|
67
|
-
export function formatBytes(bytes: number): string {
|
|
68
|
-
if (bytes === 0) return '0 Bytes';
|
|
69
|
-
|
|
70
|
-
const k = 1024;
|
|
71
|
-
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
72
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
73
|
-
|
|
74
|
-
return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Compare two memory snapshots and detect potential leaks
|
|
79
|
-
*
|
|
80
|
-
* @param before - Snapshot before operation
|
|
81
|
-
* @param after - Snapshot after operation
|
|
82
|
-
* @param threshold - Threshold in bytes to consider a leak (default: 5MB)
|
|
83
|
-
* @returns Object with leak detection results
|
|
84
|
-
*/
|
|
85
|
-
export function detectMemoryLeak(
|
|
86
|
-
before: MemorySnapshot | null,
|
|
87
|
-
after: MemorySnapshot | null,
|
|
88
|
-
threshold: number = 5 * 1024 * 1024 // 5MB
|
|
89
|
-
): {
|
|
90
|
-
hasLeak: boolean;
|
|
91
|
-
memoryIncrease: number;
|
|
92
|
-
formattedIncrease: string;
|
|
93
|
-
percentageIncrease: number;
|
|
94
|
-
} {
|
|
95
|
-
if (!before || !after) {
|
|
96
|
-
return {
|
|
97
|
-
hasLeak: false,
|
|
98
|
-
memoryIncrease: 0,
|
|
99
|
-
formattedIncrease: '0 Bytes',
|
|
100
|
-
percentageIncrease: 0,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const memoryIncrease = after.usedJSHeapSize - before.usedJSHeapSize;
|
|
105
|
-
const percentageIncrease = (memoryIncrease / before.usedJSHeapSize) * 100;
|
|
106
|
-
|
|
107
|
-
return {
|
|
108
|
-
hasLeak: memoryIncrease > threshold,
|
|
109
|
-
memoryIncrease,
|
|
110
|
-
formattedIncrease: formatBytes(memoryIncrease),
|
|
111
|
-
percentageIncrease,
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Monitor memory usage over time
|
|
117
|
-
*
|
|
118
|
-
* @param interval - Interval in milliseconds to check memory
|
|
119
|
-
* @param callback - Callback function called with each snapshot
|
|
120
|
-
* @returns Function to stop monitoring
|
|
121
|
-
*/
|
|
122
|
-
export function monitorMemoryUsage(
|
|
123
|
-
interval: number = 5000,
|
|
124
|
-
callback?: (snapshot: MemorySnapshot) => void
|
|
125
|
-
): () => void {
|
|
126
|
-
if (!isMemoryMonitoringAvailable()) {
|
|
127
|
-
console.warn('[Memory Monitor] Memory monitoring is not available');
|
|
128
|
-
return () => {};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const checkMemory = () => {
|
|
132
|
-
const snapshot = getMemorySnapshot();
|
|
133
|
-
if (snapshot) {
|
|
134
|
-
if (callback) {
|
|
135
|
-
callback(snapshot);
|
|
136
|
-
} else if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') {
|
|
137
|
-
console.log('[Memory Monitor]', {
|
|
138
|
-
used: formatBytes(snapshot.usedJSHeapSize),
|
|
139
|
-
total: formatBytes(snapshot.totalJSHeapSize),
|
|
140
|
-
limit: formatBytes(snapshot.jsHeapSizeLimit),
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
const intervalId = setInterval(checkMemory, interval);
|
|
147
|
-
|
|
148
|
-
// Initial check
|
|
149
|
-
checkMemory();
|
|
150
|
-
|
|
151
|
-
// Return cleanup function
|
|
152
|
-
return () => {
|
|
153
|
-
clearInterval(intervalId);
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Track component lifecycle memory usage
|
|
159
|
-
*
|
|
160
|
-
* @param componentName - Name of the component
|
|
161
|
-
* @returns Object with start and end tracking functions
|
|
162
|
-
*/
|
|
163
|
-
export function trackComponentMemory(componentName: string) {
|
|
164
|
-
const before = getMemorySnapshot();
|
|
165
|
-
|
|
166
|
-
return {
|
|
167
|
-
/**
|
|
168
|
-
* Get memory snapshot at component mount
|
|
169
|
-
*/
|
|
170
|
-
getBeforeSnapshot: () => before,
|
|
171
|
-
/**
|
|
172
|
-
* Get memory snapshot at component unmount and detect leaks
|
|
173
|
-
*/
|
|
174
|
-
getAfterSnapshot: () => {
|
|
175
|
-
const after = getMemorySnapshot();
|
|
176
|
-
if (before && after) {
|
|
177
|
-
const leakInfo = detectMemoryLeak(before, after);
|
|
178
|
-
if (
|
|
179
|
-
leakInfo.hasLeak &&
|
|
180
|
-
(typeof process === 'undefined' || process.env?.NODE_ENV === 'development')
|
|
181
|
-
) {
|
|
182
|
-
console.warn(
|
|
183
|
-
`[Memory Monitor] Potential memory leak detected in ${componentName}:`,
|
|
184
|
-
leakInfo
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
return after;
|
|
189
|
-
},
|
|
190
|
-
};
|
|
191
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
// TestTypeCheck Component Settings
|
|
2
|
-
// Generated by Atomix CLI
|
|
3
|
-
// =============================================================================
|
|
4
|
-
|
|
5
|
-
@use 'sass:color';
|
|
6
|
-
@use '../../lib/functions' as *;
|
|
7
|
-
@use '../../lib/mixins' as *;
|
|
8
|
-
|
|
9
|
-
// Component-specific CSS Custom Properties
|
|
10
|
-
// These override or extend global design tokens
|
|
11
|
-
|
|
12
|
-
:root {
|
|
13
|
-
// Brand Colors
|
|
14
|
-
--testtypecheck-primary: var(--atomix-color-primary);
|
|
15
|
-
--testtypecheck-primary-hover: color.adjust(var(--atomix-color-primary), $lightness: -10%);
|
|
16
|
-
--testtypecheck-primary-active: color.adjust(var(--atomix-color-primary), $lightness: -20%);
|
|
17
|
-
|
|
18
|
-
// Spacing
|
|
19
|
-
--testtypecheck-padding-x: var(--atomix-spacing-4);
|
|
20
|
-
--testtypecheck-padding-y: calc(var(--atomix-spacing-4) * 0.5);
|
|
21
|
-
--testtypecheck-gap: var(--atomix-spacing-4);
|
|
22
|
-
|
|
23
|
-
// Border Radius
|
|
24
|
-
--testtypecheck-radius: var(--atomix-radius-md);
|
|
25
|
-
|
|
26
|
-
// Typography
|
|
27
|
-
--testtypecheck-font-size: var(--atomix-font-size-base);
|
|
28
|
-
--testtypecheck-font-weight: var(--atomix-font-weight-medium);
|
|
29
|
-
--testtypecheck-line-height: var(--atomix-line-height-tight);
|
|
30
|
-
|
|
31
|
-
// States
|
|
32
|
-
--testtypecheck-disabled-opacity: 0.5;
|
|
33
|
-
--testtypecheck-focus-ring: 0 0 0 2px var(--atomix-color-primary-200);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Dark mode overrides
|
|
37
|
-
.dark {
|
|
38
|
-
:root {
|
|
39
|
-
--testtypecheck-focus-ring: 0 0 0 2px var(--atomix-color-primary-800);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Component configuration map
|
|
44
|
-
$testtypecheck-config: (
|
|
45
|
-
'primary': var(--testtypecheck-primary),
|
|
46
|
-
'padding-x': var(--testtypecheck-padding-x),
|
|
47
|
-
'padding-y': var(--testtypecheck-padding-y),
|
|
48
|
-
'gap': var(--testtypecheck-gap),
|
|
49
|
-
'radius': var(--testtypecheck-radius),
|
|
50
|
-
'font-size': var(--testtypecheck-font-size),
|
|
51
|
-
'font-weight': var(--testtypecheck-font-weight),
|
|
52
|
-
'line-height': var(--testtypecheck-line-height),
|
|
53
|
-
) !default;
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
// TypedButton Component Settings
|
|
2
|
-
// Generated by Atomix CLI
|
|
3
|
-
// =============================================================================
|
|
4
|
-
|
|
5
|
-
@use 'sass:color';
|
|
6
|
-
@use '../../lib/functions' as *;
|
|
7
|
-
@use '../../lib/mixins' as *;
|
|
8
|
-
|
|
9
|
-
// Component-specific CSS Custom Properties
|
|
10
|
-
// These override or extend global design tokens
|
|
11
|
-
|
|
12
|
-
:root {
|
|
13
|
-
// Brand Colors
|
|
14
|
-
--typedbutton-primary: var(--atomix-color-primary);
|
|
15
|
-
--typedbutton-primary-hover: color.adjust(var(--atomix-color-primary), $lightness: -10%);
|
|
16
|
-
--typedbutton-primary-active: color.adjust(var(--atomix-color-primary), $lightness: -20%);
|
|
17
|
-
|
|
18
|
-
// Spacing
|
|
19
|
-
--typedbutton-padding-x: var(--atomix-spacing-4);
|
|
20
|
-
--typedbutton-padding-y: calc(var(--atomix-spacing-4) * 0.5);
|
|
21
|
-
--typedbutton-gap: var(--atomix-spacing-4);
|
|
22
|
-
|
|
23
|
-
// Border Radius
|
|
24
|
-
--typedbutton-radius: var(--atomix-radius-md);
|
|
25
|
-
|
|
26
|
-
// Typography
|
|
27
|
-
--typedbutton-font-size: var(--atomix-font-size-base);
|
|
28
|
-
--typedbutton-font-weight: var(--atomix-font-weight-medium);
|
|
29
|
-
--typedbutton-line-height: var(--atomix-line-height-tight);
|
|
30
|
-
|
|
31
|
-
// States
|
|
32
|
-
--typedbutton-disabled-opacity: 0.5;
|
|
33
|
-
--typedbutton-focus-ring: 0 0 0 2px var(--atomix-color-primary-200);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Dark mode overrides
|
|
37
|
-
.dark {
|
|
38
|
-
:root {
|
|
39
|
-
--typedbutton-focus-ring: 0 0 0 2px var(--atomix-color-primary-800);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Component configuration map
|
|
44
|
-
$typedbutton-config: (
|
|
45
|
-
'primary': var(--typedbutton-primary),
|
|
46
|
-
'padding-x': var(--typedbutton-padding-x),
|
|
47
|
-
'padding-y': var(--typedbutton-padding-y),
|
|
48
|
-
'gap': var(--typedbutton-gap),
|
|
49
|
-
'radius': var(--typedbutton-radius),
|
|
50
|
-
'font-size': var(--typedbutton-font-size),
|
|
51
|
-
'font-weight': var(--typedbutton-font-weight),
|
|
52
|
-
'line-height': var(--typedbutton-line-height),
|
|
53
|
-
) !default;
|