@shohojdhara/atomix 0.3.0 → 0.3.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.
Files changed (144) hide show
  1. package/CHANGELOG.md +0 -1
  2. package/README.md +3 -5
  3. package/dist/atomix.css +753 -643
  4. package/dist/atomix.min.css +3 -5
  5. package/dist/index.d.ts +3075 -247
  6. package/dist/index.esm.js +20412 -16601
  7. package/dist/index.esm.js.map +1 -1
  8. package/dist/index.js +20379 -16605
  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/package.json +1 -11
  13. package/src/components/AtomixGlass/AtomixGlass.test.tsx +21 -32
  14. package/src/components/AtomixGlass/AtomixGlass.tsx +55 -42
  15. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +205 -57
  16. package/src/components/AtomixGlass/GlassFilter.tsx +22 -8
  17. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +221 -0
  18. package/src/components/AtomixGlass/atomixGLass.old.tsx +0 -3
  19. package/src/components/AtomixGlass/shader-utils.ts +8 -0
  20. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +319 -100
  21. package/src/components/AtomixGlass/stories/Examples.stories.tsx +601 -105
  22. package/src/components/AtomixGlass/stories/Modes.stories.tsx +30 -12
  23. package/src/components/AtomixGlass/stories/Playground.stories.tsx +173 -38
  24. package/src/components/AtomixGlass/stories/ShaderVariants.stories.tsx +18 -18
  25. package/src/components/AtomixGlass/stories/shared-components.tsx +27 -5
  26. package/src/components/Button/Button.tsx +62 -17
  27. package/src/components/Callout/Callout.test.tsx +8 -14
  28. package/src/components/Card/Card.tsx +103 -1
  29. package/src/components/Card/index.ts +3 -2
  30. package/src/components/Icon/index.ts +1 -1
  31. package/src/components/Modal/Modal.stories.tsx +29 -38
  32. package/src/components/Modal/Modal.tsx +4 -4
  33. package/src/components/Navigation/SideMenu/SideMenu.tsx +49 -41
  34. package/src/components/Navigation/SideMenu/SideMenuItem.tsx +63 -24
  35. package/src/components/Popover/Popover.tsx +1 -1
  36. package/src/components/VideoPlayer/VideoPlayer.stories.tsx +977 -400
  37. package/src/components/VideoPlayer/VideoPlayer.tsx +1 -6
  38. package/src/lib/composables/shared-mouse-tracker.ts +133 -0
  39. package/src/lib/composables/useAtomixGlass.ts +333 -145
  40. package/src/lib/index.ts +1 -4
  41. package/src/lib/theme/composeTheme.ts +375 -0
  42. package/src/lib/theme/config/index.ts +21 -0
  43. package/src/lib/theme/config/loader.ts +276 -0
  44. package/src/lib/theme/config/types.ts +98 -0
  45. package/src/lib/theme/config/validator.ts +326 -0
  46. package/src/lib/theme/constants.ts +183 -0
  47. package/src/lib/theme/core/ThemeCache.ts +283 -0
  48. package/src/lib/theme/core/ThemeEngine.test.ts +146 -0
  49. package/src/lib/theme/core/ThemeEngine.ts +657 -0
  50. package/src/lib/theme/core/ThemeRegistry.ts +284 -0
  51. package/src/lib/theme/core/ThemeValidator.ts +530 -0
  52. package/src/lib/theme/core/index.ts +24 -0
  53. package/src/lib/theme/createTheme.ts +521 -0
  54. package/src/lib/theme/devtools/CLI.ts +279 -0
  55. package/src/lib/theme/devtools/Inspector.tsx +594 -0
  56. package/src/lib/theme/devtools/Preview.tsx +392 -0
  57. package/src/lib/theme/devtools/index.ts +21 -0
  58. package/src/lib/theme/errors.test.ts +207 -0
  59. package/src/lib/theme/errors.ts +233 -0
  60. package/src/lib/theme/generateCSSVariables.ts +797 -0
  61. package/src/lib/theme/generators/CSSGenerator.ts +311 -0
  62. package/src/lib/theme/generators/ConfigGenerator.ts +287 -0
  63. package/src/lib/theme/generators/TypeGenerator.ts +228 -0
  64. package/src/lib/theme/generators/index.ts +21 -0
  65. package/src/lib/theme/i18n/index.ts +9 -0
  66. package/src/lib/theme/i18n/rtl.ts +325 -0
  67. package/src/lib/theme/index.ts +221 -10
  68. package/src/lib/theme/monitoring/ThemeAnalytics.ts +409 -0
  69. package/src/lib/theme/monitoring/index.ts +17 -0
  70. package/src/lib/theme/overrides/ComponentOverrides.ts +243 -0
  71. package/src/lib/theme/overrides/index.ts +15 -0
  72. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +233 -0
  73. package/src/lib/theme/runtime/ThemeManager.test.ts +176 -0
  74. package/src/lib/theme/runtime/ThemeManager.ts +442 -0
  75. package/src/lib/theme/runtime/ThemeProvider.tsx +318 -0
  76. package/src/lib/theme/runtime/index.ts +17 -0
  77. package/src/lib/theme/runtime/useTheme.ts +52 -0
  78. package/src/lib/theme/studio/ThemeStudio.tsx +312 -0
  79. package/src/lib/theme/studio/index.ts +8 -0
  80. package/src/lib/theme/themeUtils.ts +333 -0
  81. package/src/lib/theme/types.ts +340 -9
  82. package/src/lib/theme/utils.ts +23 -22
  83. package/src/lib/theme/whitelabel/WhiteLabelManager.ts +364 -0
  84. package/src/lib/theme/whitelabel/index.ts +13 -0
  85. package/src/lib/types/components.ts +148 -59
  86. package/src/styles/01-settings/_index.scss +2 -2
  87. package/src/styles/01-settings/_settings.badge.scss +3 -3
  88. package/src/styles/01-settings/_settings.border-radius.scss +1 -1
  89. package/src/styles/01-settings/_settings.callout.scss +1 -1
  90. package/src/styles/01-settings/_settings.card.scss +1 -1
  91. package/src/styles/01-settings/{_settings.maps.scss → _settings.design-tokens.scss} +163 -49
  92. package/src/styles/01-settings/_settings.input.scss +1 -1
  93. package/src/styles/01-settings/_settings.modal.scss +1 -1
  94. package/src/styles/01-settings/_settings.navbar.scss +1 -1
  95. package/src/styles/01-settings/_settings.spacing.scss +14 -13
  96. package/src/styles/01-settings/_settings.upload.scss +1 -1
  97. package/src/styles/03-generic/_generic.root.scss +131 -50
  98. package/src/styles/05-objects/_objects.block.scss +1 -1
  99. package/src/styles/06-components/_components.atomix-glass.scss +20 -22
  100. package/src/styles/06-components/_components.badge.scss +2 -2
  101. package/src/styles/06-components/_components.button.scss +1 -1
  102. package/src/styles/06-components/_components.callout.scss +1 -1
  103. package/src/styles/06-components/_components.card.scss +74 -2
  104. package/src/styles/06-components/_components.chart.scss +3 -3
  105. package/src/styles/06-components/_components.dropdown.scss +6 -0
  106. package/src/styles/06-components/_components.footer.scss +1 -1
  107. package/src/styles/06-components/_components.list-group.scss +1 -1
  108. package/src/styles/06-components/_components.list.scss +1 -1
  109. package/src/styles/06-components/_components.menu.scss +1 -1
  110. package/src/styles/06-components/_components.messages.scss +1 -1
  111. package/src/styles/06-components/_components.modal.scss +7 -2
  112. package/src/styles/06-components/_components.navbar.scss +1 -1
  113. package/src/styles/06-components/_components.popover.scss +10 -0
  114. package/src/styles/06-components/_components.product-review.scss +1 -1
  115. package/src/styles/06-components/_components.progress.scss +1 -1
  116. package/src/styles/06-components/_components.rating.scss +1 -1
  117. package/src/styles/06-components/_components.spinner.scss +1 -1
  118. package/src/styles/99-utilities/_utilities.background.scss +1 -1
  119. package/src/styles/99-utilities/_utilities.border.scss +28 -59
  120. package/src/styles/99-utilities/_utilities.gradient.scss +12 -0
  121. package/src/styles/99-utilities/_utilities.link.scss +1 -1
  122. package/src/styles/99-utilities/_utilities.position.scss +8 -15
  123. package/src/styles/99-utilities/_utilities.scss +2 -0
  124. package/src/styles/99-utilities/_utilities.spacing.scss +76 -121
  125. package/src/styles/99-utilities/_utilities.text.scss +31 -50
  126. package/dist/themes/applemix.css +0 -15411
  127. package/dist/themes/applemix.min.css +0 -72
  128. package/dist/themes/boomdevs.css +0 -15001
  129. package/dist/themes/boomdevs.min.css +0 -405
  130. package/dist/themes/esrar.css +0 -17195
  131. package/dist/themes/esrar.min.css +0 -189
  132. package/dist/themes/flashtrade.css +0 -16408
  133. package/dist/themes/flashtrade.min.css +0 -192
  134. package/dist/themes/mashroom.css +0 -29900
  135. package/dist/themes/mashroom.min.css +0 -403
  136. package/dist/themes/shaj-default.css +0 -16024
  137. package/dist/themes/shaj-default.min.css +0 -500
  138. package/src/lib/theme/ThemeManager.stories.tsx +0 -472
  139. package/src/lib/theme/ThemeManager.test.ts +0 -186
  140. package/src/lib/theme/ThemeManager.ts +0 -501
  141. package/src/lib/theme/ThemeProvider.tsx +0 -227
  142. package/src/lib/theme/useTheme.test.tsx +0 -66
  143. package/src/lib/theme/useTheme.ts +0 -80
  144. package/src/lib/theme/utils.test.ts +0 -140
@@ -4,17 +4,64 @@
4
4
  * Exports all theme management utilities for the Atomix Design System
5
5
  */
6
6
 
7
- // Core theme manager
8
- export { ThemeManager } from './ThemeManager';
9
- export { default as ThemeManagerDefault } from './ThemeManager';
10
-
11
- // React integration
12
- export { ThemeProvider } from './ThemeProvider';
13
- export { default as ThemeProviderDefault } from './ThemeProvider';
14
- export { useTheme } from './useTheme';
15
- export { default as useThemeDefault } from './useTheme';
7
+ // Runtime system
8
+ export { ThemeManager } from './runtime/ThemeManager';
9
+ export { ThemeProvider } from './runtime/ThemeProvider';
10
+ export { ThemeErrorBoundary } from './runtime/ThemeErrorBoundary';
11
+ export { useTheme } from './runtime/useTheme';
16
12
  export { ThemeContext } from './ThemeContext';
17
- export { default as ThemeContextDefault } from './ThemeContext';
13
+ export type { ThemeErrorBoundaryProps } from './runtime/ThemeErrorBoundary';
14
+
15
+ // createTheme System
16
+ export { createTheme } from './createTheme';
17
+
18
+ // CSS Variable Generation
19
+ export {
20
+ generateCSSVariables,
21
+ injectCSS,
22
+ removeInjectedCSS,
23
+ generateSectionVariables,
24
+ } from './generateCSSVariables';
25
+ export type { GenerateCSSVariablesOptions } from './generateCSSVariables';
26
+
27
+ // Theme Composition
28
+ export {
29
+ deepMerge,
30
+ mergeTheme,
31
+ extendTheme,
32
+ createThemeVariants,
33
+ overrideTheme,
34
+ composeThemes,
35
+ createThemePreset,
36
+ } from './composeTheme';
37
+
38
+ // Theme Utilities
39
+ export {
40
+ hexToRgb,
41
+ rgbToHex,
42
+ getLuminance,
43
+ getContrastRatio,
44
+ getContrastText,
45
+ lighten,
46
+ darken,
47
+ alpha,
48
+ emphasize,
49
+ createSpacing,
50
+ spacing,
51
+ getThemeValue,
52
+ isJSTheme,
53
+ breakpointUp,
54
+ breakpointDown,
55
+ breakpointBetween,
56
+ getTypography,
57
+ remToPx,
58
+ pxToRem,
59
+ getShadow,
60
+ createTransition,
61
+ getTransitionDuration,
62
+ getTransitionEasing,
63
+ getZIndex,
64
+ } from './themeUtils';
18
65
 
19
66
  // Types
20
67
  export type {
@@ -33,8 +80,121 @@ export type {
33
80
  ThemeProviderProps,
34
81
  ThemeContextValue,
35
82
  StorageAdapter,
83
+ // createTheme System Types
84
+ PaletteColor,
85
+ PaletteOptions,
86
+ TypographyOptions,
87
+ SpacingOptions,
88
+ SpacingFunction,
89
+ BreakpointValues,
90
+ BreakpointsOptions,
91
+ ShadowOptions,
92
+ TransitionOptions,
93
+ ZIndexOptions,
94
+ ThemeCustomProperties,
95
+ ThemeOptions,
96
+ Theme,
36
97
  } from './types';
37
98
 
99
+ // Configuration system
100
+ export {
101
+ loadThemeConfig,
102
+ clearConfigCache,
103
+ getCachedConfig,
104
+ reloadThemeConfig,
105
+ validateConfig,
106
+ } from './config';
107
+ export type {
108
+ ConfigLoaderOptions,
109
+ LoadedThemeConfig,
110
+ ConfigValidationResult,
111
+ ThemeMetadata as ConfigThemeMetadata,
112
+ } from './config/types';
113
+
114
+ // Core engine
115
+ export {
116
+ ThemeEngine,
117
+ ThemeRegistry,
118
+ ThemeCache,
119
+ ThemeValidator,
120
+ } from './core';
121
+ export type {
122
+ ThemeChangeListener,
123
+ ThemeLoadListener,
124
+ ThemeErrorListener,
125
+ ThemeEngineConfig,
126
+ ValidationResult,
127
+ A11yIssue,
128
+ } from './core';
129
+
130
+ // Generators
131
+ export {
132
+ CSSGenerator,
133
+ generateCSS,
134
+ TypeGenerator,
135
+ generateTypes,
136
+ ConfigGenerator,
137
+ generateConfigTemplate,
138
+ } from './generators';
139
+ export type {
140
+ CSSGeneratorOptions,
141
+ TypeGeneratorOptions,
142
+ ConfigGeneratorOptions,
143
+ } from './generators';
144
+
145
+ // Developer tools
146
+ export {
147
+ ThemeCLI,
148
+ createCLI,
149
+ runCLI,
150
+ ThemePreview,
151
+ ThemeInspector,
152
+ } from './devtools';
153
+ export type {
154
+ CLICommand,
155
+ ThemePreviewProps,
156
+ ThemeInspectorProps,
157
+ } from './devtools';
158
+
159
+
160
+ // Error handling
161
+ export {
162
+ ThemeError,
163
+ ThemeErrorCode,
164
+ ThemeLogger,
165
+ LogLevel,
166
+ getLogger,
167
+ setLogger,
168
+ createLogger,
169
+ } from './errors';
170
+ export type {
171
+ LoggerConfig,
172
+ } from './errors';
173
+
174
+ // Constants
175
+ export {
176
+ DEFAULT_STORAGE_KEY,
177
+ DEFAULT_DATA_ATTRIBUTE,
178
+ DEFAULT_BASE_PATH,
179
+ DEFAULT_STYLE_ID,
180
+ DEFAULT_CACHE_CONFIG,
181
+ DEFAULT_ENGINE_CACHE_CONFIG,
182
+ THEME_LINK_ID_PREFIX,
183
+ CSS_EXTENSIONS,
184
+ DEFAULT_CONFIG_PATH,
185
+ VALIDATION_THRESHOLDS,
186
+ DEFAULT_THEME_METADATA,
187
+ RTL_LOCALES,
188
+ DEFAULT_RTL_CONFIG,
189
+ DEFAULT_ANALYTICS_CONFIG,
190
+ DEFAULT_LOGGER_CONFIG,
191
+ ENV_DEFAULTS,
192
+ DEFAULT_INTEGRATION_CLASS_NAMES,
193
+ DEFAULT_INTEGRATION_CSS_VARIABLES,
194
+ DEFAULT_BUILD_OUTPUT_DIR,
195
+ DEFAULT_SASS_CONFIG,
196
+ } from './constants';
197
+
38
198
  // Utilities
39
199
  export {
40
200
  isBrowser,
@@ -54,3 +214,54 @@ export {
54
214
  createLocalStorageAdapter,
55
215
  debounce,
56
216
  } from './utils';
217
+
218
+ // Internationalization (i18n)
219
+ export {
220
+ RTLManager,
221
+ createRTLManager,
222
+ isRTLLocale,
223
+ getDirectionFromLocale,
224
+ rtlCSS,
225
+ } from './i18n';
226
+ export type { RTLConfig } from './i18n';
227
+
228
+ // Theme Studio
229
+ export { ThemeStudio } from './studio';
230
+ export type { ThemeStudioProps } from './studio';
231
+
232
+ // Monitoring and Analytics
233
+ export {
234
+ ThemeAnalytics,
235
+ createThemeAnalytics,
236
+ getGlobalAnalytics,
237
+ setGlobalAnalytics,
238
+ } from './monitoring';
239
+ export type {
240
+ ThemeAnalyticsEvent,
241
+ ThemeAnalyticsEventData,
242
+ PerformanceMetric,
243
+ AnalyticsConfig,
244
+ } from './monitoring';
245
+
246
+ // Component Overrides
247
+ export {
248
+ ComponentOverrideManager,
249
+ createComponentOverrideManager,
250
+ createComponentOverride,
251
+ } from './overrides';
252
+ export type {
253
+ ComponentOverride,
254
+ ComponentOverrides,
255
+ OverrideOptions,
256
+ } from './overrides';
257
+
258
+ // White Label
259
+ export {
260
+ WhiteLabelManager,
261
+ createWhiteLabelManager,
262
+ } from './whitelabel';
263
+ export type {
264
+ BrandConfig,
265
+ WhiteLabelConfig,
266
+ } from './whitelabel';
267
+
@@ -0,0 +1,409 @@
1
+ /**
2
+ * Theme Analytics and Performance Monitoring
3
+ *
4
+ * Tracks theme usage, performance metrics, and provides analytics
5
+ */
6
+
7
+ import { getLogger } from '../errors';
8
+
9
+ /**
10
+ * Theme analytics event types
11
+ */
12
+ export type ThemeAnalyticsEvent =
13
+ | 'theme_load'
14
+ | 'theme_switch'
15
+ | 'theme_error'
16
+ | 'theme_revert'
17
+ | 'css_load'
18
+ | 'performance_metric';
19
+
20
+ /**
21
+ * Theme analytics event
22
+ */
23
+ export interface ThemeAnalyticsEventData {
24
+ /** Event type */
25
+ type: ThemeAnalyticsEvent;
26
+ /** Event timestamp */
27
+ timestamp: number;
28
+ /** Theme name */
29
+ themeName?: string;
30
+ /** Additional event data */
31
+ data?: Record<string, any>;
32
+ }
33
+
34
+ /**
35
+ * Performance metric
36
+ */
37
+ export interface PerformanceMetric {
38
+ /** Metric name */
39
+ name: string;
40
+ /** Metric value */
41
+ value: number;
42
+ /** Unit */
43
+ unit: 'ms' | 'bytes' | 'count';
44
+ /** Timestamp */
45
+ timestamp: number;
46
+ }
47
+
48
+ /**
49
+ * Analytics configuration
50
+ */
51
+ export interface AnalyticsConfig {
52
+ /** Enable analytics */
53
+ enabled?: boolean;
54
+ /** Enable performance tracking */
55
+ trackPerformance?: boolean;
56
+ /** Enable error tracking */
57
+ trackErrors?: boolean;
58
+ /** Custom event handler */
59
+ onEvent?: (event: ThemeAnalyticsEventData) => void;
60
+ /** Custom performance handler */
61
+ onPerformance?: (metric: PerformanceMetric) => void;
62
+ /** Buffer size for events */
63
+ bufferSize?: number;
64
+ /** Flush interval (ms) */
65
+ flushInterval?: number;
66
+ }
67
+
68
+ /**
69
+ * Default analytics configuration
70
+ */
71
+ const DEFAULT_CONFIG: Required<Omit<AnalyticsConfig, 'onEvent' | 'onPerformance'>> = {
72
+ enabled: true,
73
+ trackPerformance: true,
74
+ trackErrors: true,
75
+ bufferSize: 100,
76
+ flushInterval: 5000,
77
+ };
78
+
79
+ /**
80
+ * Theme Analytics Manager
81
+ *
82
+ * Tracks theme usage, performance, and errors
83
+ */
84
+ export class ThemeAnalytics {
85
+ private config: Required<Omit<AnalyticsConfig, 'onEvent' | 'onPerformance'>> & {
86
+ onEvent?: AnalyticsConfig['onEvent'];
87
+ onPerformance?: AnalyticsConfig['onPerformance'];
88
+ };
89
+ private events: ThemeAnalyticsEventData[] = [];
90
+ private metrics: PerformanceMetric[] = [];
91
+ private flushTimer: ReturnType<typeof setInterval> | null = null;
92
+ private logger = getLogger();
93
+
94
+ constructor(config: AnalyticsConfig = {}) {
95
+ this.config = {
96
+ ...DEFAULT_CONFIG,
97
+ ...config,
98
+ };
99
+
100
+ if (this.config.enabled) {
101
+ this.startFlushTimer();
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Track theme load event
107
+ */
108
+ trackThemeLoad(themeName: string, loadTime?: number): void {
109
+ if (!this.config.enabled) {
110
+ return;
111
+ }
112
+
113
+ const event: ThemeAnalyticsEventData = {
114
+ type: 'theme_load',
115
+ timestamp: Date.now(),
116
+ themeName,
117
+ data: loadTime ? { loadTime } : undefined,
118
+ };
119
+
120
+ this.addEvent(event);
121
+
122
+ if (loadTime !== undefined) {
123
+ this.trackPerformance('theme_load_time', loadTime, 'ms');
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Track theme switch event
129
+ */
130
+ trackThemeSwitch(fromTheme: string, toTheme: string, switchTime?: number): void {
131
+ if (!this.config.enabled) {
132
+ return;
133
+ }
134
+
135
+ const event: ThemeAnalyticsEventData = {
136
+ type: 'theme_switch',
137
+ timestamp: Date.now(),
138
+ themeName: toTheme,
139
+ data: {
140
+ fromTheme,
141
+ toTheme,
142
+ ...(switchTime ? { switchTime } : {}),
143
+ },
144
+ };
145
+
146
+ this.addEvent(event);
147
+
148
+ if (switchTime !== undefined) {
149
+ this.trackPerformance('theme_switch_time', switchTime, 'ms');
150
+ }
151
+ }
152
+
153
+ /**
154
+ * Track theme error
155
+ */
156
+ trackError(themeName: string, error: Error | string): void {
157
+ if (!this.config.enabled || !this.config.trackErrors) {
158
+ return;
159
+ }
160
+
161
+ const event: ThemeAnalyticsEventData = {
162
+ type: 'theme_error',
163
+ timestamp: Date.now(),
164
+ themeName,
165
+ data: {
166
+ error: error instanceof Error ? error.message : error,
167
+ stack: error instanceof Error ? error.stack : undefined,
168
+ },
169
+ };
170
+
171
+ this.addEvent(event);
172
+ }
173
+
174
+ /**
175
+ * Track theme revert
176
+ */
177
+ trackThemeRevert(attemptedTheme: string, revertedToTheme: string | null, error: Error): void {
178
+ if (!this.config.enabled || !this.config.trackErrors) {
179
+ return;
180
+ }
181
+
182
+ const event: ThemeAnalyticsEventData = {
183
+ type: 'theme_revert',
184
+ timestamp: Date.now(),
185
+ themeName: attemptedTheme,
186
+ data: {
187
+ attemptedTheme,
188
+ revertedToTheme,
189
+ error: error.message,
190
+ stack: error.stack,
191
+ },
192
+ };
193
+
194
+ this.addEvent(event);
195
+ }
196
+
197
+ /**
198
+ * Track CSS load
199
+ */
200
+ trackCSSLoad(themeName: string, loadTime: number, size?: number): void {
201
+ if (!this.config.enabled) {
202
+ return;
203
+ }
204
+
205
+ const event: ThemeAnalyticsEventData = {
206
+ type: 'css_load',
207
+ timestamp: Date.now(),
208
+ themeName,
209
+ data: {
210
+ loadTime,
211
+ ...(size ? { size } : {}),
212
+ },
213
+ };
214
+
215
+ this.addEvent(event);
216
+
217
+ this.trackPerformance('css_load_time', loadTime, 'ms');
218
+ if (size !== undefined) {
219
+ this.trackPerformance('css_size', size, 'bytes');
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Track performance metric
225
+ */
226
+ trackPerformance(name: string, value: number, unit: PerformanceMetric['unit'] = 'ms'): void {
227
+ if (!this.config.enabled || !this.config.trackPerformance) {
228
+ return;
229
+ }
230
+
231
+ const metric: PerformanceMetric = {
232
+ name,
233
+ value,
234
+ unit,
235
+ timestamp: Date.now(),
236
+ };
237
+
238
+ this.metrics.push(metric);
239
+
240
+ // Keep only last N metrics
241
+ if (this.metrics.length > this.config.bufferSize) {
242
+ this.metrics.shift();
243
+ }
244
+
245
+ // Notify handler
246
+ if (this.config.onPerformance) {
247
+ try {
248
+ this.config.onPerformance(metric);
249
+ } catch (error) {
250
+ this.logger.error(
251
+ 'Error in performance handler',
252
+ error instanceof Error ? error : new Error(String(error)),
253
+ { metric }
254
+ );
255
+ }
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Add event to buffer
261
+ */
262
+ private addEvent(event: ThemeAnalyticsEventData): void {
263
+ this.events.push(event);
264
+
265
+ // Keep only last N events
266
+ if (this.events.length > this.config.bufferSize) {
267
+ this.events.shift();
268
+ }
269
+
270
+ // Notify handler immediately
271
+ if (this.config.onEvent) {
272
+ try {
273
+ this.config.onEvent(event);
274
+ } catch (error) {
275
+ this.logger.error(
276
+ 'Error in event handler',
277
+ error instanceof Error ? error : new Error(String(error)),
278
+ { event }
279
+ );
280
+ }
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Get all events
286
+ */
287
+ getEvents(): ThemeAnalyticsEventData[] {
288
+ return [...this.events];
289
+ }
290
+
291
+ /**
292
+ * Get all metrics
293
+ */
294
+ getMetrics(): PerformanceMetric[] {
295
+ return [...this.metrics];
296
+ }
297
+
298
+ /**
299
+ * Get events by type
300
+ */
301
+ getEventsByType(type: ThemeAnalyticsEvent): ThemeAnalyticsEventData[] {
302
+ return this.events.filter(event => event.type === type);
303
+ }
304
+
305
+ /**
306
+ * Get metrics by name
307
+ */
308
+ getMetricsByName(name: string): PerformanceMetric[] {
309
+ return this.metrics.filter(metric => metric.name === name);
310
+ }
311
+
312
+ /**
313
+ * Get average performance metric
314
+ */
315
+ getAverageMetric(name: string): number | null {
316
+ const metrics = this.getMetricsByName(name);
317
+ if (metrics.length === 0) {
318
+ return null;
319
+ }
320
+
321
+ const sum = metrics.reduce((acc, metric) => acc + metric.value, 0);
322
+ return sum / metrics.length;
323
+ }
324
+
325
+ /**
326
+ * Clear all events and metrics
327
+ */
328
+ clear(): void {
329
+ this.events = [];
330
+ this.metrics = [];
331
+ }
332
+
333
+ /**
334
+ * Start flush timer
335
+ */
336
+ private startFlushTimer(): void {
337
+ if (this.flushTimer) {
338
+ return;
339
+ }
340
+
341
+ this.flushTimer = setInterval(() => {
342
+ // Auto-flush can be implemented here if needed
343
+ // For now, events are sent immediately via onEvent callback
344
+ }, this.config.flushInterval);
345
+ }
346
+
347
+ /**
348
+ * Stop flush timer
349
+ */
350
+ private stopFlushTimer(): void {
351
+ if (this.flushTimer) {
352
+ clearInterval(this.flushTimer);
353
+ this.flushTimer = null;
354
+ }
355
+ }
356
+
357
+ /**
358
+ * Enable analytics
359
+ */
360
+ enable(): void {
361
+ this.config.enabled = true;
362
+ this.startFlushTimer();
363
+ }
364
+
365
+ /**
366
+ * Disable analytics
367
+ */
368
+ disable(): void {
369
+ this.config.enabled = false;
370
+ this.stopFlushTimer();
371
+ }
372
+
373
+ /**
374
+ * Destroy analytics instance
375
+ */
376
+ destroy(): void {
377
+ this.stopFlushTimer();
378
+ this.clear();
379
+ }
380
+ }
381
+
382
+ /**
383
+ * Create theme analytics instance
384
+ */
385
+ export function createThemeAnalytics(config?: AnalyticsConfig): ThemeAnalytics {
386
+ return new ThemeAnalytics(config);
387
+ }
388
+
389
+ /**
390
+ * Global analytics instance (optional)
391
+ */
392
+ let globalAnalytics: ThemeAnalytics | null = null;
393
+
394
+ /**
395
+ * Get or create global analytics instance
396
+ */
397
+ export function getGlobalAnalytics(): ThemeAnalytics {
398
+ if (!globalAnalytics) {
399
+ globalAnalytics = createThemeAnalytics();
400
+ }
401
+ return globalAnalytics;
402
+ }
403
+
404
+ /**
405
+ * Set global analytics instance
406
+ */
407
+ export function setGlobalAnalytics(analytics: ThemeAnalytics): void {
408
+ globalAnalytics = analytics;
409
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Theme Monitoring and Analytics Module
3
+ */
4
+
5
+ export * from './ThemeAnalytics';
6
+ export {
7
+ ThemeAnalytics,
8
+ createThemeAnalytics,
9
+ getGlobalAnalytics,
10
+ setGlobalAnalytics,
11
+ } from './ThemeAnalytics';
12
+ export type {
13
+ ThemeAnalyticsEvent,
14
+ ThemeAnalyticsEventData,
15
+ PerformanceMetric,
16
+ AnalyticsConfig,
17
+ } from './ThemeAnalytics';