@shohojdhara/atomix 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/atomix.config.ts +33 -33
  2. package/dist/config.d.ts +187 -112
  3. package/dist/config.js +7 -49
  4. package/dist/config.js.map +1 -1
  5. package/dist/index.d.ts +1958 -900
  6. package/dist/index.esm.js +2275 -383
  7. package/dist/index.esm.js.map +1 -1
  8. package/dist/index.js +2327 -417
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.min.js +1 -1
  11. package/dist/index.min.js.map +1 -1
  12. package/dist/theme.d.ts +1390 -276
  13. package/dist/theme.js +2129 -621
  14. package/dist/theme.js.map +1 -1
  15. package/package.json +1 -1
  16. package/scripts/cli/internal/config-loader.js +30 -20
  17. package/src/lib/config/index.ts +38 -362
  18. package/src/lib/config/loader.ts +419 -0
  19. package/src/lib/config/public-api.ts +43 -0
  20. package/src/lib/config/types.ts +389 -0
  21. package/src/lib/config/validator.ts +305 -0
  22. package/src/lib/theme/adapters/index.ts +1 -1
  23. package/src/lib/theme/adapters/themeAdapter.ts +358 -229
  24. package/src/lib/theme/components/ThemeToggle.tsx +276 -0
  25. package/src/lib/theme/config/configLoader.ts +351 -0
  26. package/src/lib/theme/config/loader.ts +221 -0
  27. package/src/lib/theme/core/createTheme.ts +126 -50
  28. package/src/lib/theme/core/createThemeObject.ts +7 -4
  29. package/src/lib/theme/hooks/useThemeSwitcher.ts +164 -0
  30. package/src/lib/theme/index.ts +322 -38
  31. package/src/lib/theme/runtime/ThemeProvider.tsx +44 -10
  32. package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +44 -393
  33. package/src/lib/theme/runtime/useTheme.ts +1 -0
  34. package/src/lib/theme/tokens/tokens.ts +101 -1
  35. package/src/lib/theme/types.ts +91 -0
  36. package/src/lib/theme/utils/performanceMonitor.ts +315 -0
  37. package/src/lib/theme/utils/responsive.ts +280 -0
  38. package/src/lib/theme/utils/themeUtils.ts +531 -117
  39. package/src/styles/05-objects/_objects.masonry-grid.scss +3 -3
@@ -378,6 +378,59 @@ export interface DesignTokens {
378
378
  'breakpoint-xl': string;
379
379
  'breakpoint-xxl': string;
380
380
 
381
+ // ============================================================================
382
+ // Advanced Features - Interactive Effects (Phase 2)
383
+ // ============================================================================
384
+ 'interactive-vortex-enabled': string;
385
+ 'interactive-vortex-strength': string;
386
+ 'interactive-vortex-radius': string;
387
+ 'interactive-vortex-decay': string;
388
+ 'interactive-chromatic-enabled': string;
389
+ 'interactive-chromatic-mode': string;
390
+ 'interactive-chromatic-red-shift': string;
391
+ 'interactive-chromatic-green-shift': string;
392
+ 'interactive-chromatic-blue-shift': string;
393
+ 'interactive-chromatic-edge-only': string;
394
+ 'interactive-chromatic-edge-threshold': string;
395
+ 'interactive-mouse-sensitivity': string;
396
+ 'interactive-mouse-trail-effect': string;
397
+ 'interactive-animation-speed-base': string;
398
+ 'interactive-animation-speed-multiplier': string;
399
+
400
+ // ============================================================================
401
+ // Advanced Features - Optimization (Phase 3)
402
+ // ============================================================================
403
+ 'optimization-breakpoint-mobile': string;
404
+ 'optimization-breakpoint-tablet': string;
405
+ 'optimization-breakpoint-desktop': string;
406
+ 'optimization-breakpoint-wide': string;
407
+ 'optimization-device-scaling-mobile': string;
408
+ 'optimization-device-scaling-tablet': string;
409
+ 'optimization-device-scaling-desktop': string;
410
+ 'optimization-performance-fps-target': string;
411
+ 'optimization-auto-scaling-enabled': string;
412
+ 'optimization-auto-scaling-low-end': string;
413
+ 'optimization-auto-scaling-mid-range': string;
414
+ 'optimization-auto-scaling-high-end': string;
415
+
416
+ // ============================================================================
417
+ // Advanced Features - Visual Polish (Phase 4)
418
+ // ============================================================================
419
+ 'visual-polish-border-iridescent-glow': string;
420
+ 'visual-polish-border-shimmer-effect': string;
421
+ 'visual-polish-border-beveled-edges': string;
422
+ 'visual-polish-border-pulsing-glow': string;
423
+ 'visual-polish-content-aware-blur-enabled': string;
424
+ 'visual-polish-content-aware-depth-detection': string;
425
+ 'visual-polish-content-aware-edge-preservation': string;
426
+ 'visual-polish-content-aware-variable-radius': string;
427
+ 'visual-polish-holographic-enabled': string;
428
+ 'visual-polish-holographic-rainbow-diffraction': string;
429
+ 'visual-polish-holographic-scanline-animation': string;
430
+ 'visual-polish-holographic-grid-overlay': string;
431
+ 'visual-polish-holographic-data-stream': string;
432
+ 'visual-polish-holographic-pulse-rings': string;
433
+
381
434
  // ============================================================================
382
435
  // Custom tokens (allow any additional tokens)
383
436
  // ============================================================================
@@ -701,6 +754,53 @@ export const defaultTokens: DesignTokens = {
701
754
  'breakpoint-lg': '992px',
702
755
  'breakpoint-xl': '1200px',
703
756
  'breakpoint-xxl': '1440px',
757
+
758
+ // Advanced Features - Interactive Effects (Phase 2)
759
+ 'interactive-vortex-enabled': 'false',
760
+ 'interactive-vortex-strength': '0.5',
761
+ 'interactive-vortex-radius': '100',
762
+ 'interactive-vortex-decay': '0.8',
763
+ 'interactive-chromatic-enabled': 'false',
764
+ 'interactive-chromatic-mode': 'lateral',
765
+ 'interactive-chromatic-red-shift': '0.02',
766
+ 'interactive-chromatic-green-shift': '0',
767
+ 'interactive-chromatic-blue-shift': '-0.02',
768
+ 'interactive-chromatic-edge-only': 'false',
769
+ 'interactive-chromatic-edge-threshold': '0.5',
770
+ 'interactive-mouse-sensitivity': '1.0',
771
+ 'interactive-mouse-trail-effect': 'false',
772
+ 'interactive-animation-speed-base': '1.0',
773
+ 'interactive-animation-speed-multiplier': '1.0',
774
+
775
+ // Advanced Features - Optimization (Phase 3)
776
+ 'optimization-breakpoint-mobile': '0px',
777
+ 'optimization-breakpoint-tablet': '768px',
778
+ 'optimization-breakpoint-desktop': '1024px',
779
+ 'optimization-breakpoint-wide': '1440px',
780
+ 'optimization-device-scaling-mobile': '0.5',
781
+ 'optimization-device-scaling-tablet': '0.75',
782
+ 'optimization-device-scaling-desktop': '1.0',
783
+ 'optimization-performance-fps-target': '60',
784
+ 'optimization-auto-scaling-enabled': 'false',
785
+ 'optimization-auto-scaling-low-end': '0.5',
786
+ 'optimization-auto-scaling-mid-range': '0.75',
787
+ 'optimization-auto-scaling-high-end': '1.0',
788
+
789
+ // Advanced Features - Visual Polish (Phase 4)
790
+ 'visual-polish-border-iridescent-glow': 'false',
791
+ 'visual-polish-border-shimmer-effect': 'false',
792
+ 'visual-polish-border-beveled-edges': 'false',
793
+ 'visual-polish-border-pulsing-glow': 'false',
794
+ 'visual-polish-content-aware-blur-enabled': 'false',
795
+ 'visual-polish-content-aware-depth-detection': 'false',
796
+ 'visual-polish-content-aware-edge-preservation': 'false',
797
+ 'visual-polish-content-aware-variable-radius': 'false',
798
+ 'visual-polish-holographic-enabled': 'false',
799
+ 'visual-polish-holographic-rainbow-diffraction': 'false',
800
+ 'visual-polish-holographic-scanline-animation': 'false',
801
+ 'visual-polish-holographic-grid-overlay': 'false',
802
+ 'visual-polish-holographic-data-stream': 'false',
803
+ 'visual-polish-holographic-pulse-rings': 'false',
704
804
  };
705
805
 
706
806
  /**
@@ -719,4 +819,4 @@ export const defaultTokens: DesignTokens = {
719
819
  */
720
820
  export function createTokens(overrides?: Partial<DesignTokens>): DesignTokens {
721
821
  return { ...defaultTokens, ...overrides };
722
- }
822
+ }
@@ -141,6 +141,8 @@ export interface UseThemeReturn {
141
141
  theme: string | import('./tokens').DesignTokens | Partial<import('./tokens').DesignTokens>,
142
142
  options?: ThemeLoadOptions
143
143
  ) => Promise<void>;
144
+ /** Update a specific theme section */
145
+ updateTheme: (section: ThemeSection, values: any) => Promise<void>;
144
146
  /** Available themes */
145
147
  availableThemes: ThemeMetadata[];
146
148
  /** Whether a theme is currently loading */
@@ -250,6 +252,16 @@ export interface ThemeProviderProps {
250
252
  onError?: (error: Error, themeName: string) => void;
251
253
  }
252
254
 
255
+ /**
256
+ * Theme configuration (partial tokens)
257
+ */
258
+ export type ThemeConfig = Partial<import('./tokens').DesignTokens>;
259
+
260
+ /**
261
+ * Theme section name
262
+ */
263
+ export type ThemeSection = keyof import('./tokens').DesignTokens;
264
+
253
265
  /**
254
266
  * Theme context value
255
267
  */
@@ -263,6 +275,8 @@ export interface ThemeContextValue {
263
275
  theme: string | import('./tokens').DesignTokens | Partial<import('./tokens').DesignTokens>,
264
276
  options?: ThemeLoadOptions
265
277
  ) => Promise<void>;
278
+ /** Update a specific theme section */
279
+ updateTheme: (section: ThemeSection, values: any) => Promise<void>;
266
280
  /** Available themes */
267
281
  availableThemes: ThemeMetadata[];
268
282
  /** Loading state */
@@ -501,6 +515,83 @@ export interface BorderRadiusOptions {
501
515
  * Users can augment this interface via module augmentation
502
516
  */
503
517
  export interface ThemeCustomProperties {
518
+ // Advanced Features Configuration
519
+ interactiveEffects?: {
520
+ vortex?: {
521
+ enabled?: boolean;
522
+ strength?: number;
523
+ radius?: number;
524
+ decay?: number;
525
+ };
526
+ chromaticAberration?: {
527
+ enabled?: boolean;
528
+ mode?: 'longitudinal' | 'lateral' | 'hybrid';
529
+ redShift?: number;
530
+ greenShift?: number;
531
+ blueShift?: number;
532
+ edgeOnly?: boolean;
533
+ edgeThreshold?: number;
534
+ };
535
+ mouseInteraction?: {
536
+ sensitivity?: number;
537
+ trailEffect?: boolean;
538
+ };
539
+ animationSpeed?: {
540
+ base?: number;
541
+ timeMultiplier?: number;
542
+ };
543
+ };
544
+ optimization?: {
545
+ responsive?: {
546
+ breakpoints?: {
547
+ mobile?: string;
548
+ tablet?: string;
549
+ desktop?: string;
550
+ wide?: string;
551
+ };
552
+ deviceScaling?: {
553
+ mobile?: number;
554
+ tablet?: number;
555
+ desktop?: number;
556
+ };
557
+ };
558
+ performance?: {
559
+ fpsTarget?: number;
560
+ autoScaling?: boolean;
561
+ };
562
+ autoScaling?: {
563
+ enabled?: boolean;
564
+ qualityThresholds?: {
565
+ lowEnd?: number;
566
+ midRange?: number;
567
+ highEnd?: number;
568
+ };
569
+ };
570
+ };
571
+
572
+ visualPolish?: {
573
+ borders?: {
574
+ iridescentGlow?: boolean;
575
+ shimmerEffect?: boolean;
576
+ beveledEdges?: boolean;
577
+ pulsingGlow?: boolean;
578
+ };
579
+ contentAwareBlur?: {
580
+ enabled?: boolean;
581
+ depthDetection?: boolean;
582
+ edgePreservation?: boolean;
583
+ variableRadius?: boolean;
584
+ };
585
+ holographicEffects?: {
586
+ enabled?: boolean;
587
+ rainbowDiffraction?: boolean;
588
+ scanlineAnimation?: boolean;
589
+ gridOverlay?: boolean;
590
+ dataStream?: boolean;
591
+ pulseRings?: boolean;
592
+ };
593
+ };
594
+
504
595
  [key: string]: any;
505
596
  }
506
597
 
@@ -0,0 +1,315 @@
1
+ /**
2
+ * Performance Monitor Utility
3
+ *
4
+ * Provides performance monitoring and metrics collection for the Atomix theme system.
5
+ * Used to measure and optimize performance of advanced visual effects.
6
+ */
7
+
8
+ import React from 'react';
9
+
10
+ /**
11
+ * Performance metrics collected by the monitor
12
+ */
13
+ export interface PerformanceMetrics {
14
+ /** Frames per second */
15
+ fps: number;
16
+ /** Average frame render time in ms */
17
+ frameTime: number;
18
+ /** Peak frame render time in ms */
19
+ peakFrameTime: number;
20
+ /** Memory usage statistics */
21
+ memory?: {
22
+ usedJSHeapSize: number;
23
+ totalJSHeapSize: number;
24
+ jsHeapSizeLimit: number;
25
+ };
26
+ /** Timestamp of measurement */
27
+ timestamp: number;
28
+ /** Whether performance is degrading */
29
+ isDegraded: boolean;
30
+ }
31
+
32
+ /**
33
+ * Performance monitor configuration
34
+ */
35
+ export interface PerformanceMonitorConfig {
36
+ /** Target FPS threshold (default: 60) */
37
+ fpsTarget?: number;
38
+ /** How frequently to sample (default: 500ms) */
39
+ sampleInterval?: number;
40
+ /** Callback for performance updates */
41
+ onUpdate?: (metrics: PerformanceMetrics) => void;
42
+ /** Callback when performance degrades */
43
+ onDegraded?: (metrics: PerformanceMetrics) => void;
44
+ /** Enable/disable memory monitoring */
45
+ enableMemoryMonitoring?: boolean;
46
+ }
47
+
48
+ /**
49
+ * Performance monitor class
50
+ */
51
+ export class PerformanceMonitor {
52
+ public config: Required<PerformanceMonitorConfig>;
53
+ private frameCount: number = 0;
54
+ private lastSampleTime: number = 0;
55
+ private lastFpsUpdate: number = 0;
56
+ private frameTimes: number[] = [];
57
+ private animationFrameId: number | null = null;
58
+ private isActive: boolean = false;
59
+ private startTime: number = 0;
60
+
61
+ /**
62
+ * Create a new performance monitor
63
+ *
64
+ * @param config Configuration options
65
+ */
66
+ constructor(config?: PerformanceMonitorConfig) {
67
+ this.config = {
68
+ fpsTarget: config?.fpsTarget ?? 60,
69
+ sampleInterval: config?.sampleInterval ?? 500,
70
+ onUpdate: config?.onUpdate ?? (() => {}),
71
+ onDegraded: config?.onDegraded ?? (() => {}),
72
+ enableMemoryMonitoring: config?.enableMemoryMonitoring ?? (typeof window !== 'undefined' &&
73
+ (window as any).performance &&
74
+ (window as any).performance.memory),
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Start monitoring performance
80
+ */
81
+ public start(): void {
82
+ if (this.isActive) return;
83
+
84
+ this.isActive = true;
85
+ this.frameCount = 0;
86
+ this.lastSampleTime = performance.now();
87
+ this.lastFpsUpdate = this.lastSampleTime;
88
+ this.frameTimes = [];
89
+ this.startTime = this.lastSampleTime;
90
+
91
+ this.animationFrameId = requestAnimationFrame(this.onFrame.bind(this));
92
+ }
93
+
94
+ /**
95
+ * Stop monitoring performance
96
+ */
97
+ public stop(): void {
98
+ if (this.animationFrameId) {
99
+ cancelAnimationFrame(this.animationFrameId);
100
+ this.animationFrameId = null;
101
+ }
102
+ this.isActive = false;
103
+ }
104
+
105
+ /**
106
+ * Get current performance metrics
107
+ */
108
+ public getMetrics(): PerformanceMetrics {
109
+ const now = performance.now();
110
+ const elapsed = now - this.lastFpsUpdate;
111
+ const fps = elapsed > 0 ? Math.round((this.frameCount / elapsed) * 1000) : 0;
112
+
113
+ // Calculate average frame time
114
+ const avgFrameTime = this.frameTimes.length > 0
115
+ ? this.frameTimes.reduce((a, b) => a + b, 0) / this.frameTimes.length
116
+ : 0;
117
+
118
+ // Peak frame time
119
+ const peakFrameTime = this.frameTimes.length > 0
120
+ ? Math.max(...this.frameTimes)
121
+ : 0;
122
+
123
+ // Get memory stats if available
124
+ let memory = undefined;
125
+ if (this.config.enableMemoryMonitoring) {
126
+ const perf = window.performance as any;
127
+ if (perf && perf.memory) {
128
+ memory = {
129
+ usedJSHeapSize: perf.memory.usedJSHeapSize,
130
+ totalJSHeapSize: perf.memory.totalJSHeapSize,
131
+ jsHeapSizeLimit: perf.memory.jsHeapSizeLimit,
132
+ };
133
+ }
134
+ }
135
+
136
+ return {
137
+ fps,
138
+ frameTime: avgFrameTime,
139
+ peakFrameTime,
140
+ memory,
141
+ timestamp: now,
142
+ isDegraded: fps < (this.config.fpsTarget * 0.7), // Degraded if under 70% of target
143
+ };
144
+ }
145
+
146
+ /**
147
+ * Get the current FPS
148
+ */
149
+ public getFps(): number {
150
+ return this.getMetrics().fps;
151
+ }
152
+
153
+ /**
154
+ * Check if performance is degraded
155
+ */
156
+ public isPerformanceDegraded(): boolean {
157
+ return this.getMetrics().isDegraded;
158
+ }
159
+
160
+ /**
161
+ * Private method called on each animation frame
162
+ */
163
+ private onFrame(timestamp: number): void {
164
+ if (!this.isActive) return;
165
+
166
+ // Calculate frame time
167
+ const frameTime = timestamp - this.lastSampleTime;
168
+ this.frameTimes.push(frameTime);
169
+
170
+ // Keep only the last 60 frame times for averaging
171
+ if (this.frameTimes.length > 60) {
172
+ this.frameTimes.shift();
173
+ }
174
+
175
+ this.frameCount++;
176
+ this.lastSampleTime = timestamp;
177
+
178
+ // Check if we need to update metrics
179
+ if (timestamp - this.lastFpsUpdate >= this.config.sampleInterval) {
180
+ const metrics = this.getMetrics();
181
+
182
+ // Call update callback
183
+ this.config.onUpdate(metrics);
184
+
185
+ // Check for degradation
186
+ if (metrics.isDegraded) {
187
+ this.config.onDegraded(metrics);
188
+ }
189
+
190
+ // Reset counters
191
+ this.frameCount = 0;
192
+ this.lastFpsUpdate = timestamp;
193
+ }
194
+
195
+ this.animationFrameId = requestAnimationFrame(this.onFrame.bind(this));
196
+ }
197
+
198
+ /**
199
+ * Run a performance test for a specific function
200
+ *
201
+ * @param fn Function to test
202
+ * @param iterations Number of iterations (default: 100)
203
+ * @returns Average execution time in ms
204
+ */
205
+ public async testFunctionPerformance(
206
+ fn: () => void,
207
+ iterations: number = 100
208
+ ): Promise<number> {
209
+ const times: number[] = [];
210
+
211
+ for (let i = 0; i < iterations; i++) {
212
+ const start = performance.now();
213
+ fn();
214
+ const end = performance.now();
215
+ times.push(end - start);
216
+ }
217
+
218
+ return times.reduce((a, b) => a + b, 0) / times.length;
219
+ }
220
+ }
221
+
222
+ /**
223
+ * Create a performance monitor instance
224
+ *
225
+ * @param config Configuration options
226
+ * @returns PerformanceMonitor instance
227
+ *
228
+ * @example
229
+ * ```typescript
230
+ * import { createPerformanceMonitor } from '@shohojdhara/atomix/theme';
231
+ *
232
+ * const monitor = createPerformanceMonitor({
233
+ * fpsTarget: 60,
234
+ * onUpdate: (metrics) => console.log('FPS:', metrics.fps),
235
+ * onDegraded: (metrics) => console.warn('Performance degraded!', metrics),
236
+ * });
237
+ *
238
+ * monitor.start();
239
+ *
240
+ * // Later...
241
+ * monitor.stop();
242
+ * ```
243
+ */
244
+ export function createPerformanceMonitor(config?: PerformanceMonitorConfig): PerformanceMonitor {
245
+ return new PerformanceMonitor(config);
246
+ }
247
+
248
+ /**
249
+ * Hook for React components to monitor performance
250
+ *
251
+ * @param config Configuration options
252
+ * @returns Performance metrics and monitor controls
253
+ *
254
+ * @example
255
+ * ```typescript
256
+ * import { usePerformanceMonitor } from '@shohojdhara/atomix/theme';
257
+ *
258
+ * function MyComponent() {
259
+ * const { metrics, start, stop } = usePerformanceMonitor({ fpsTarget: 60 });
260
+ *
261
+ * useEffect(() => {
262
+ * start();
263
+ * return () => stop();
264
+ * }, []);
265
+ *
266
+ * return <div>FPS: {metrics.fps}</div>;
267
+ * }
268
+ * ```
269
+ */
270
+ export function usePerformanceMonitor(config?: PerformanceMonitorConfig) {
271
+ const [monitor] = React.useState(() => createPerformanceMonitor(config));
272
+ const [metrics, setMetrics] = React.useState<PerformanceMetrics>(() =>
273
+ typeof window !== 'undefined' ? monitor.getMetrics() : {
274
+ fps: 0,
275
+ frameTime: 0,
276
+ peakFrameTime: 0,
277
+ timestamp: 0,
278
+ isDegraded: false,
279
+ } as PerformanceMetrics
280
+ );
281
+
282
+ const start = React.useCallback(() => {
283
+ if (typeof window !== 'undefined') {
284
+ monitor.start();
285
+ }
286
+ }, [monitor]);
287
+
288
+ const stop = React.useCallback(() => {
289
+ if (typeof window !== 'undefined') {
290
+ monitor.stop();
291
+ }
292
+ }, [monitor]);
293
+
294
+ React.useEffect(() => {
295
+ if (typeof window === 'undefined') return;
296
+
297
+ // Update metrics when monitor callbacks fire
298
+ const originalOnUpdate = config?.onUpdate;
299
+ monitor.config.onUpdate = (newMetrics: PerformanceMetrics) => {
300
+ setMetrics(newMetrics);
301
+ originalOnUpdate?.(newMetrics);
302
+ };
303
+
304
+ return () => {
305
+ monitor.stop();
306
+ };
307
+ }, [monitor, config?.onUpdate]);
308
+
309
+ return {
310
+ metrics,
311
+ start,
312
+ stop,
313
+ };
314
+ }
315
+