@shohojdhara/atomix 0.4.8 → 0.5.0

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 (177) hide show
  1. package/atomix.config.ts +58 -1
  2. package/dist/atomix.css +148 -120
  3. package/dist/atomix.css.map +1 -1
  4. package/dist/atomix.min.css +1 -1
  5. package/dist/atomix.min.css.map +1 -1
  6. package/dist/charts.d.ts +33 -0
  7. package/dist/charts.js +1227 -122
  8. package/dist/charts.js.map +1 -1
  9. package/dist/core.d.ts +33 -10
  10. package/dist/core.js +1052 -41
  11. package/dist/core.js.map +1 -1
  12. package/dist/forms.d.ts +33 -0
  13. package/dist/forms.js +2086 -1035
  14. package/dist/forms.js.map +1 -1
  15. package/dist/heavy.d.ts +42 -1
  16. package/dist/heavy.js +1620 -600
  17. package/dist/heavy.js.map +1 -1
  18. package/dist/index.d.ts +441 -270
  19. package/dist/index.esm.js +1900 -638
  20. package/dist/index.esm.js.map +1 -1
  21. package/dist/index.js +1935 -670
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.min.js +1 -1
  24. package/dist/index.min.js.map +1 -1
  25. package/package.json +6 -3
  26. package/scripts/atomix-cli.js +148 -4
  27. package/scripts/cli/__tests__/basic.test.js +3 -2
  28. package/scripts/cli/__tests__/clean.test.js +278 -0
  29. package/scripts/cli/__tests__/component-validator.test.js +433 -0
  30. package/scripts/cli/__tests__/generator.test.js +613 -0
  31. package/scripts/cli/__tests__/glass-motion.test.js +256 -0
  32. package/scripts/cli/__tests__/integration.test.js +719 -108
  33. package/scripts/cli/__tests__/migrate.test.js +74 -0
  34. package/scripts/cli/__tests__/security.test.js +206 -0
  35. package/scripts/cli/__tests__/test-setup.js +3 -1
  36. package/scripts/cli/__tests__/theme-bridge.test.js +507 -0
  37. package/scripts/cli/__tests__/token-provider.test.js +361 -0
  38. package/scripts/cli/__tests__/utils.test.js +5 -5
  39. package/scripts/cli/commands/benchmark.js +105 -0
  40. package/scripts/cli/commands/build-theme.js +4 -1
  41. package/scripts/cli/commands/clean.js +109 -0
  42. package/scripts/cli/commands/doctor.js +88 -0
  43. package/scripts/cli/commands/generate.js +135 -14
  44. package/scripts/cli/commands/init.js +45 -18
  45. package/scripts/cli/commands/migrate.js +106 -0
  46. package/scripts/cli/commands/sync-tokens.js +206 -0
  47. package/scripts/cli/commands/theme-bridge.js +248 -0
  48. package/scripts/cli/commands/tokens.js +157 -0
  49. package/scripts/cli/commands/validate.js +194 -0
  50. package/scripts/cli/internal/ai-engine.js +156 -0
  51. package/scripts/cli/internal/component-validator.js +443 -0
  52. package/scripts/cli/internal/config-loader.js +162 -0
  53. package/scripts/cli/internal/filesystem.js +102 -2
  54. package/scripts/cli/internal/generator.js +359 -39
  55. package/scripts/cli/internal/glass-generator.js +398 -0
  56. package/scripts/cli/internal/hook-generator.js +369 -0
  57. package/scripts/cli/internal/hooks.js +61 -0
  58. package/scripts/cli/internal/itcss-generator.js +565 -0
  59. package/scripts/cli/internal/motion-generator.js +679 -0
  60. package/scripts/cli/internal/template-engine.js +301 -0
  61. package/scripts/cli/internal/theme-bridge.js +664 -0
  62. package/scripts/cli/internal/tokens/engine.js +122 -0
  63. package/scripts/cli/internal/tokens/provider.js +34 -0
  64. package/scripts/cli/internal/tokens/providers/figma.js +50 -0
  65. package/scripts/cli/internal/tokens/providers/style-dictionary.js +48 -0
  66. package/scripts/cli/internal/tokens/providers/w3c.js +48 -0
  67. package/scripts/cli/internal/tokens/token-provider.js +443 -0
  68. package/scripts/cli/internal/tokens/token-validator.js +513 -0
  69. package/scripts/cli/internal/validator.js +276 -0
  70. package/scripts/cli/internal/wizard.js +60 -6
  71. package/scripts/cli/mappings.js +23 -0
  72. package/scripts/cli/migration-tools.js +164 -94
  73. package/scripts/cli/plugins/style-dictionary.js +46 -0
  74. package/scripts/cli/templates/README.md +525 -95
  75. package/scripts/cli/templates/common-templates.js +40 -14
  76. package/scripts/cli/templates/components/react-component.ts +282 -0
  77. package/scripts/cli/templates/config/project-config.ts +112 -0
  78. package/scripts/cli/templates/hooks/use-component.ts +477 -0
  79. package/scripts/cli/templates/index.js +19 -4
  80. package/scripts/cli/templates/index.ts +171 -0
  81. package/scripts/cli/templates/next-templates.js +72 -0
  82. package/scripts/cli/templates/react-templates.js +70 -126
  83. package/scripts/cli/templates/scss-templates.js +35 -35
  84. package/scripts/cli/templates/stories/storybook-story.ts +241 -0
  85. package/scripts/cli/templates/styles/scss-component.ts +255 -0
  86. package/scripts/cli/templates/tests/vitest-test.ts +229 -0
  87. package/scripts/cli/templates/token-templates.js +337 -1
  88. package/scripts/cli/templates/tokens/token-generators.ts +1088 -0
  89. package/scripts/cli/templates/types/component-types.ts +145 -0
  90. package/scripts/cli/templates/utils/testing-utils.ts +144 -0
  91. package/scripts/cli/templates/vanilla-templates.js +39 -0
  92. package/scripts/cli/token-manager.js +8 -2
  93. package/scripts/cli/utils/cache-manager.js +240 -0
  94. package/scripts/cli/utils/detector.js +46 -0
  95. package/scripts/cli/utils/diagnostics.js +289 -0
  96. package/scripts/cli/utils/error.js +45 -3
  97. package/scripts/cli/utils/helpers.js +24 -0
  98. package/scripts/cli/utils/logger.js +1 -1
  99. package/scripts/cli/utils/security.js +302 -0
  100. package/scripts/cli/utils/telemetry.js +115 -0
  101. package/scripts/cli/utils/validation.js +4 -38
  102. package/scripts/cli/utils.js +46 -0
  103. package/src/components/Accordion/Accordion.stories.tsx +0 -18
  104. package/src/components/Accordion/Accordion.test.tsx +0 -17
  105. package/src/components/Accordion/Accordion.tsx +0 -4
  106. package/src/components/AtomixGlass/AtomixGlass.tsx +102 -2
  107. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +125 -12
  108. package/src/components/AtomixGlass/PerformanceDashboard.tsx +219 -0
  109. package/src/components/AtomixGlass/README.md +25 -10
  110. package/src/components/AtomixGlass/animation-system.ts +578 -0
  111. package/src/components/AtomixGlass/shader-utils.ts +3 -0
  112. package/src/components/AtomixGlass/stories/AnimationFeatures.stories.tsx +653 -0
  113. package/src/components/AtomixGlass/stories/AnimationTests.stories.tsx +95 -0
  114. package/src/components/AtomixGlass/stories/CardExamples.stories.tsx +212 -0
  115. package/src/components/AtomixGlass/stories/DashboardExamples.stories.tsx +348 -0
  116. package/src/components/AtomixGlass/stories/EcommerceExamples.stories.tsx +410 -0
  117. package/src/components/AtomixGlass/stories/FormExamples.stories.tsx +436 -0
  118. package/src/components/AtomixGlass/stories/HeroExamples.stories.tsx +264 -0
  119. package/src/components/AtomixGlass/stories/InteractivePlayground.stories.tsx +247 -0
  120. package/src/components/AtomixGlass/stories/MobileUIExamples.stories.tsx +418 -0
  121. package/src/components/AtomixGlass/stories/ModalExamples.stories.tsx +402 -0
  122. package/src/components/AtomixGlass/stories/Overview.stories.tsx +157 -6
  123. package/src/components/AtomixGlass/stories/Playground.stories.tsx +658 -93
  124. package/src/components/AtomixGlass/stories/PresetGallery.stories.tsx +335 -0
  125. package/src/components/AtomixGlass/stories/WidgetExamples.stories.tsx +441 -0
  126. package/src/components/AtomixGlass/stories/argTypes.ts +384 -0
  127. package/src/components/AtomixGlass/stories/shared-components.tsx +91 -1
  128. package/src/components/AtomixGlass/stories/types.ts +127 -0
  129. package/src/components/Avatar/Avatar.tsx +1 -1
  130. package/src/components/Button/Button.stories.disabled-link.tsx +10 -0
  131. package/src/components/Button/Button.stories.tsx +10 -0
  132. package/src/components/Button/Button.test.tsx +16 -11
  133. package/src/components/Button/Button.tsx +4 -4
  134. package/src/components/Card/Card.tsx +1 -1
  135. package/src/components/Dropdown/Dropdown.tsx +12 -12
  136. package/src/components/Form/Select.tsx +62 -3
  137. package/src/components/Modal/Modal.tsx +14 -3
  138. package/src/components/Navigation/Navbar/Navbar.tsx +44 -0
  139. package/src/components/Slider/Slider.stories.tsx +3 -3
  140. package/src/components/Slider/Slider.tsx +38 -0
  141. package/src/components/Steps/Steps.tsx +3 -3
  142. package/src/components/Tabs/Tabs.tsx +77 -8
  143. package/src/components/Testimonial/Testimonial.tsx +1 -1
  144. package/src/components/TypedButton/TypedButton.stories.tsx +59 -0
  145. package/src/components/TypedButton/TypedButton.tsx +39 -0
  146. package/src/components/TypedButton/index.ts +2 -0
  147. package/src/components/VideoPlayer/VideoPlayer.tsx +11 -4
  148. package/src/lib/composables/index.ts +4 -7
  149. package/src/lib/composables/types.ts +45 -0
  150. package/src/lib/composables/useAccordion.ts +0 -7
  151. package/src/lib/composables/useAtomixGlass.ts +144 -5
  152. package/src/lib/composables/useChartExport.ts +3 -13
  153. package/src/lib/composables/useDropdown.ts +66 -0
  154. package/src/lib/composables/useFocusTrap.ts +80 -0
  155. package/src/lib/composables/usePerformanceMonitor.ts +448 -0
  156. package/src/lib/composables/useResponsiveGlass.presets.ts +192 -0
  157. package/src/lib/composables/useResponsiveGlass.ts +441 -0
  158. package/src/lib/composables/useTooltip.ts +16 -0
  159. package/src/lib/composables/useTypedButton.ts +66 -0
  160. package/src/lib/config/index.ts +62 -5
  161. package/src/lib/constants/components.ts +55 -0
  162. package/src/lib/theme/devtools/__tests__/useHistory.test.tsx +150 -0
  163. package/src/lib/theme/tokens/centralized-tokens.ts +120 -0
  164. package/src/lib/theme/utils/__tests__/domUtils.test.ts +101 -0
  165. package/src/lib/types/components.ts +37 -11
  166. package/src/lib/types/glass.ts +35 -0
  167. package/src/lib/types/index.ts +1 -0
  168. package/src/lib/utils/displacement-generator.ts +1 -1
  169. package/src/styles/01-settings/_settings.testtypecheck.scss +53 -0
  170. package/src/styles/01-settings/_settings.typedbutton.scss +53 -0
  171. package/src/styles/06-components/_components.testbutton.scss +212 -0
  172. package/src/styles/06-components/_components.testtypecheck.scss +212 -0
  173. package/src/styles/06-components/_components.typedbutton.scss +212 -0
  174. package/src/styles/99-utilities/_index.scss +1 -0
  175. package/src/styles/99-utilities/_utilities.text.scss +1 -1
  176. package/src/styles/99-utilities/_utilities.touch-target.scss +36 -0
  177. package/src/styles/06-components/old.chart.styles.scss +0 -2788
@@ -3,6 +3,11 @@ import type { AtomixGlassProps } from '../../lib/types/components';
3
3
  import { ATOMIX_GLASS } from '../../lib/constants/components';
4
4
  import { AtomixGlassContainer } from './AtomixGlassContainer';
5
5
  import { useAtomixGlass } from '../../lib/composables/useAtomixGlass';
6
+ // Phase 3: Optimization & Adaptation
7
+ import { useResponsiveGlass } from '../../lib/composables/useResponsiveGlass';
8
+ import { usePerformanceMonitor } from '../../lib/composables/usePerformanceMonitor';
9
+ import { PerformanceDashboard } from './PerformanceDashboard';
10
+ import { getDevicePreset, MOBILE_OPTIMIZED_BREAKPOINTS } from '../../lib/composables/useResponsiveGlass.presets';
6
11
 
7
12
  /**
8
13
  * AtomixGlass - A high-performance glass morphism component with liquid distortion effects
@@ -18,6 +23,8 @@ import { useAtomixGlass } from '../../lib/composables/useAtomixGlass';
18
23
  * - Focus ring support for keyboard navigation
19
24
  * - Responsive breakpoints for mobile optimization
20
25
  * - Enhanced ARIA attributes for screen readers
26
+ * - Time-based animation system with FBM distortion
27
+ * - Device preset optimization for performance/quality balance
21
28
  *
22
29
  * Design System Compliance:
23
30
  * - Uses design tokens for opacity, spacing, and colors
@@ -74,6 +81,12 @@ import { useAtomixGlass } from '../../lib/composables/useAtomixGlass';
74
81
  * <AtomixGlass overLight="auto" debugOverLight={true}>
75
82
  * <div>Content with debug logging enabled</div>
76
83
  * </AtomixGlass>
84
+ *
85
+ * @example
86
+ * // Performance-optimized for mobile devices
87
+ * <AtomixGlass devicePreset="performance" disableResponsiveBreakpoints={false}>
88
+ * <div>Mobile-optimized glass effect</div>
89
+ * </AtomixGlass>
77
90
  */
78
91
  export function AtomixGlass({
79
92
  children,
@@ -104,10 +117,18 @@ export function AtomixGlass({
104
117
  withBorder = true,
105
118
  withOverLightLayers = ATOMIX_GLASS.DEFAULTS.ENABLE_OVER_LIGHT_LAYERS,
106
119
  debugPerformance = false,
107
- debugBorderRadius = false,
108
120
  debugOverLight = false,
109
121
  height,
110
122
  width,
123
+ withTimeAnimation = false,
124
+ animationSpeed = 1.0,
125
+ withMultiLayerDistortion = false,
126
+ distortionOctaves = 3,
127
+ distortionLacunarity = 2.0,
128
+ distortionGain = 0.5,
129
+ distortionQuality = 'medium',
130
+ devicePreset = 'balanced',
131
+ disableResponsiveBreakpoints = false,
111
132
  ...rest
112
133
  }: AtomixGlassProps) {
113
134
  const glassRef = useRef<HTMLDivElement>(null);
@@ -137,6 +158,8 @@ export function AtomixGlass({
137
158
  globalMousePosition,
138
159
  mouseOffset,
139
160
  transformStyle,
161
+ getShaderTime,
162
+ applyTimeBasedDistortion,
140
163
  handleMouseEnter,
141
164
  handleMouseLeave,
142
165
  handleMouseDown,
@@ -155,7 +178,6 @@ export function AtomixGlass({
155
178
  withoutEffects,
156
179
  elasticity,
157
180
  onClick,
158
- debugBorderRadius,
159
181
  debugOverLight,
160
182
  debugPerformance,
161
183
  children,
@@ -165,8 +187,68 @@ export function AtomixGlass({
165
187
  padding,
166
188
  style,
167
189
  isFixedOrSticky,
190
+ // Phase 1: Animation System props
191
+ withTimeAnimation,
192
+ animationSpeed,
193
+ withMultiLayerDistortion,
194
+ distortionOctaves,
195
+ distortionLacunarity,
196
+ distortionGain,
197
+ distortionQuality,
198
+ });
199
+
200
+ // ============================================================================
201
+ // Phase 3: Optimization & Adaptation Systems
202
+ // ============================================================================
203
+
204
+ // Get device preset parameters - memoized to prevent recalculation
205
+ const devicePresetParams = useMemo(() => {
206
+ return getDevicePreset(devicePreset);
207
+ }, [devicePreset]); // Re-calculate only when devicePreset changes
208
+
209
+ // Responsive breakpoint system - automatically adjusts parameters based on viewport
210
+ const {
211
+ responsiveParams,
212
+ currentBreakpoint,
213
+ performanceTier,
214
+ isActive: isResponsiveActive
215
+ } = useResponsiveGlass({
216
+ baseParams: {
217
+ ...devicePresetParams,
218
+ distortionOctaves: Math.round((displacementScale || ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE) / 25),
219
+ displacementScale: displacementScale || ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE,
220
+ blurAmount: blurAmount || ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT,
221
+ saturation: saturation || ATOMIX_GLASS.DEFAULTS.SATURATION,
222
+ aberrationIntensity: aberrationIntensity || ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY,
223
+ animationSpeed: 1.0,
224
+ chromaticIntensity: aberrationIntensity || ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY,
225
+ },
226
+ breakpoints: MOBILE_OPTIMIZED_BREAKPOINTS,
227
+ enabled: !disableResponsiveBreakpoints && typeof window !== 'undefined', // Enable unless disabled
228
+ debug: false
168
229
  });
169
230
 
231
+ // Performance monitoring - tracks FPS, frame time, memory usage
232
+ const {
233
+ metrics: performanceMetrics,
234
+ recommendedQuality,
235
+ isUnderperforming,
236
+ setQualityLevel,
237
+ toggleMonitoring
238
+ } = usePerformanceMonitor({
239
+ enabled: false, // We'll toggle manually based on prop
240
+ debug: false,
241
+ showOverlay: false
242
+ });
243
+
244
+ // Auto-start performance monitoring if enabled (only in development)
245
+ React.useEffect(() => {
246
+ if (process.env.NODE_ENV === 'development' && (window as any)?.enablePerformanceMonitoring) {
247
+ toggleMonitoring();
248
+ }
249
+ // eslint-disable-next-line react-hooks/exhaustive-deps
250
+ }, []); // Only run once on mount
251
+
170
252
  const isOverLight = useMemo(() => overLightConfig.isOverLight, [overLightConfig.isOverLight]);
171
253
 
172
254
  const shouldRenderOverLightLayers = withOverLightLayers && isOverLight;
@@ -479,6 +561,15 @@ export function AtomixGlass({
479
561
  effectiveReducedMotion={effectiveReducedMotion}
480
562
  shaderVariant={shaderVariant}
481
563
  withLiquidBlur={withLiquidBlur}
564
+ // Phase 1: Animation System props
565
+ shaderTime={getShaderTime()}
566
+ withTimeAnimation={withTimeAnimation}
567
+ animationSpeed={animationSpeed}
568
+ withMultiLayerDistortion={withMultiLayerDistortion}
569
+ distortionOctaves={distortionOctaves}
570
+ distortionLacunarity={distortionLacunarity}
571
+ distortionGain={distortionGain}
572
+ distortionQuality={distortionQuality}
482
573
  >
483
574
  {children}
484
575
  </AtomixGlassContainer>
@@ -512,6 +603,15 @@ export function AtomixGlass({
512
603
  <span className={ATOMIX_GLASS.BORDER_2_CLASS} />
513
604
  </>
514
605
  )}
606
+
607
+ {/* Phase 3: Performance Monitoring Dashboard - Only in development with debugPerformance enabled */}
608
+ {debugPerformance && performanceMetrics && (
609
+ <PerformanceDashboard
610
+ metrics={performanceMetrics}
611
+ isVisible={true}
612
+ onClose={() => {}} // No-op, dashboard always visible when debugPerformance is true
613
+ />
614
+ )}
515
615
  </div>
516
616
  );
517
617
  }
@@ -1,6 +1,6 @@
1
1
  import React, { forwardRef, useRef, useState, useEffect, useMemo } from 'react';
2
2
  import type { CSSProperties } from 'react';
3
- import type { DisplacementMode, MousePosition, GlassSize } from '../../lib/types/components';
3
+ import type { DisplacementMode, MousePosition, GlassSize, AtomixGlassProps } from '../../lib/types/components';
4
4
  import type { FragmentShaderType } from './shader-utils';
5
5
  import { GlassFilter } from './GlassFilter';
6
6
  import { calculateMouseInfluence, clampBlur, validateGlassSize } from './glass-utils';
@@ -59,7 +59,17 @@ const setCachedShader = (key: string, url: string): void => {
59
59
  }
60
60
  };
61
61
 
62
- interface AtomixGlassContainerProps {
62
+ interface AtomixGlassContainerProps
63
+ extends Pick<
64
+ AtomixGlassProps,
65
+ | 'withTimeAnimation'
66
+ | 'animationSpeed'
67
+ | 'withMultiLayerDistortion'
68
+ | 'distortionOctaves'
69
+ | 'distortionLacunarity'
70
+ | 'distortionGain'
71
+ | 'distortionQuality'
72
+ > {
63
73
  className?: string;
64
74
  style?: React.CSSProperties;
65
75
  displacementScale?: number;
@@ -92,6 +102,9 @@ interface AtomixGlassContainerProps {
92
102
  shaderVariant?: FragmentShaderType;
93
103
  withLiquidBlur?: boolean;
94
104
 
105
+ // Phase 1: Animation System props
106
+ shaderTime?: number;
107
+
95
108
  contentRef?: React.RefObject<HTMLDivElement>;
96
109
  children?: React.ReactNode;
97
110
  }
@@ -128,6 +141,16 @@ export const AtomixGlassContainer = forwardRef<HTMLDivElement, AtomixGlassContai
128
141
  shaderVariant = 'liquidGlass',
129
142
  withLiquidBlur = false,
130
143
 
144
+ // Phase 1: Animation System props
145
+ shaderTime,
146
+ withTimeAnimation = false,
147
+ animationSpeed = 1.0,
148
+ withMultiLayerDistortion = false,
149
+ distortionOctaves = 3,
150
+ distortionLacunarity = 2.0,
151
+ distortionGain = 0.5,
152
+ distortionQuality = 'medium',
153
+
131
154
  contentRef,
132
155
  },
133
156
  ref
@@ -147,11 +170,15 @@ export const AtomixGlassContainer = forwardRef<HTMLDivElement, AtomixGlassContai
147
170
 
148
171
  // Use shared module-level cache (no per-instance cache needed)
149
172
  const shaderDebounceTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
173
+ const shaderUpdateTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
174
+
175
+ // Phase 1: Animation frame ref for continuous shader updates
176
+ const animationFrameRef = useRef<number | null>(null);
150
177
 
151
178
  // Lazy load shader utilities only when shader mode is needed
152
179
  useEffect(() => {
153
180
  if (mode === 'shader') {
154
- // Dynamic import shader utilities
181
+ // Dynamic import shader utilities with animation support
155
182
  import('./shader-utils')
156
183
  .then(shaderUtils => {
157
184
  shaderUtilsRef.current = {
@@ -174,12 +201,7 @@ export const AtomixGlassContainer = forwardRef<HTMLDivElement, AtomixGlassContai
174
201
  // Generate shader map with debouncing and caching
175
202
  useEffect(() => {
176
203
  // Enhanced validation for shader mode
177
- if (
178
- mode === 'shader' &&
179
- glassSize &&
180
- validateGlassSize(glassSize) &&
181
- shaderUtilsRef.current
182
- ) {
204
+ if (mode === 'shader' && glassSize && validateGlassSize(glassSize)) {
183
205
  // Create cache key from size and variant
184
206
  const cacheKey = `${glassSize.width}x${glassSize.height}-${shaderVariant}`;
185
207
 
@@ -213,10 +235,11 @@ export const AtomixGlassContainer = forwardRef<HTMLDivElement, AtomixGlassContai
213
235
  fragment: selectedShader,
214
236
  });
215
237
 
216
- // Defer shader generation with longer delay to avoid blocking
217
- setTimeout(() => {
238
+ shaderUpdateTimeoutRef.current = setTimeout(() => {
218
239
  const url = shaderGeneratorRef.current?.updateShader() || '';
219
- setCachedShader(cacheKey, url);
240
+ if (url) {
241
+ setCachedShader(cacheKey, url);
242
+ }
220
243
  setShaderMapUrl(url);
221
244
  }, 100);
222
245
  } catch (error) {
@@ -238,6 +261,10 @@ export const AtomixGlassContainer = forwardRef<HTMLDivElement, AtomixGlassContai
238
261
  clearTimeout(shaderDebounceTimeoutRef.current);
239
262
  shaderDebounceTimeoutRef.current = null;
240
263
  }
264
+ if (shaderUpdateTimeoutRef.current) {
265
+ clearTimeout(shaderUpdateTimeoutRef.current);
266
+ shaderUpdateTimeoutRef.current = null;
267
+ }
241
268
  try {
242
269
  shaderGeneratorRef.current?.destroy();
243
270
  } catch (error) {
@@ -248,6 +275,92 @@ export const AtomixGlassContainer = forwardRef<HTMLDivElement, AtomixGlassContai
248
275
  };
249
276
  }, [mode, glassSize, shaderVariant]);
250
277
 
278
+ // Phase 1: Time-Based Animation Loop - Continuous shader regeneration
279
+ useEffect(() => {
280
+ // Only run animations in shader mode with time animation enabled
281
+ if (
282
+ mode !== 'shader' ||
283
+ !withTimeAnimation ||
284
+ effectiveReducedMotion ||
285
+ effectiveWithoutEffects
286
+ ) {
287
+ // Cancel any existing animation frame
288
+ if (animationFrameRef.current !== null) {
289
+ cancelAnimationFrame(animationFrameRef.current);
290
+ animationFrameRef.current = null;
291
+ }
292
+ return;
293
+ }
294
+
295
+ const baseFps =
296
+ distortionQuality === 'ultra'
297
+ ? 60
298
+ : distortionQuality === 'high'
299
+ ? 30
300
+ : distortionQuality === 'medium'
301
+ ? 24
302
+ : 20;
303
+ const effectiveSpeed = Math.max(0.5, Math.min(2, animationSpeed || 1));
304
+ const complexity =
305
+ withMultiLayerDistortion
306
+ ? Math.max(
307
+ 1,
308
+ (distortionOctaves || 3) / 3 +
309
+ Math.max(0, (distortionLacunarity || 2) - 2) * 0.25 +
310
+ Math.max(0, (distortionGain || 0.5) - 0.5)
311
+ )
312
+ : 1;
313
+ const targetFps = Math.max(12, Math.min(60, Math.round((baseFps * effectiveSpeed) / complexity)));
314
+ const frameInterval = 1000 / targetFps;
315
+ let lastUpdate = 0;
316
+ let isCancelled = false;
317
+
318
+ const animate = (currentTime: number) => {
319
+ if (isCancelled) {
320
+ return;
321
+ }
322
+
323
+ if (currentTime - lastUpdate >= frameInterval && shaderGeneratorRef.current) {
324
+ lastUpdate = currentTime;
325
+ try {
326
+ const animatedShaderUrl = shaderGeneratorRef.current.updateShader();
327
+ if (animatedShaderUrl) {
328
+ setShaderMapUrl(animatedShaderUrl);
329
+ }
330
+ } catch (error) {
331
+ console.warn('AtomixGlassContainer: Error in animation loop', error);
332
+ }
333
+ }
334
+
335
+ animationFrameRef.current = requestAnimationFrame(animate);
336
+ };
337
+
338
+ // Start animation loop
339
+ animationFrameRef.current = requestAnimationFrame(animate);
340
+
341
+ // Cleanup animation on unmount or dependency change
342
+ return () => {
343
+ isCancelled = true;
344
+ if (animationFrameRef.current !== null) {
345
+ cancelAnimationFrame(animationFrameRef.current);
346
+ animationFrameRef.current = null;
347
+ }
348
+ };
349
+ }, [
350
+ mode,
351
+ withTimeAnimation,
352
+ animationSpeed,
353
+ displacementScale,
354
+ withMultiLayerDistortion,
355
+ distortionOctaves,
356
+ distortionLacunarity,
357
+ distortionGain,
358
+ distortionQuality,
359
+ effectiveReducedMotion,
360
+ effectiveWithoutEffects,
361
+ glassSize,
362
+ ]);
363
+
251
364
  // Removed forced reflow to avoid layout thrash and potential feedback sizing loops
252
365
 
253
366
  const [rectCache, setRectCache] = useState<DOMRect | null>(null);
@@ -0,0 +1,219 @@
1
+ import React, { useMemo } from 'react';
2
+ import type { PerformanceMetrics } from '../../lib/composables/usePerformanceMonitor';
3
+
4
+ interface PerformanceDashboardProps {
5
+ metrics: PerformanceMetrics;
6
+ isVisible?: boolean;
7
+ onClose?: () => void;
8
+ }
9
+
10
+ /**
11
+ * PerformanceDashboard - Real-time performance monitoring overlay
12
+ *
13
+ * Displays:
14
+ * - Current FPS with color coding
15
+ * - Frame time statistics
16
+ * - Quality level indicator
17
+ * - GPU memory usage (if available)
18
+ * - Auto-scaling status
19
+ */
20
+ export const PerformanceDashboard: React.FC<PerformanceDashboardProps> = ({
21
+ metrics,
22
+ isVisible = true,
23
+ onClose
24
+ }) => {
25
+ // Get color for FPS display
26
+ const getFpsColor = (fps: number): string => {
27
+ if (fps >= 58) return '#4ade80'; // Green - good
28
+ if (fps >= 45) return '#fbbf24'; // Yellow - warning
29
+ return '#ef4444'; // Red - critical
30
+ };
31
+
32
+ // Get quality level badge color
33
+ const getQualityColor = (quality: string): string => {
34
+ switch (quality) {
35
+ case 'high': return '#4ade80';
36
+ case 'medium': return '#fbbf24';
37
+ case 'low': return '#ef4444';
38
+ default: return '#9ca3af';
39
+ }
40
+ };
41
+
42
+ // Dashboard styles
43
+ const dashboardStyle: React.CSSProperties = useMemo(() => ({
44
+ position: 'fixed',
45
+ top: '16px',
46
+ right: '16px',
47
+ padding: '12px 16px',
48
+ backgroundColor: 'rgba(17, 24, 39, 0.95)',
49
+ borderRadius: '8px',
50
+ boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
51
+ fontFamily: 'monospace',
52
+ fontSize: '12px',
53
+ color: '#fff',
54
+ zIndex: 9999,
55
+ minWidth: '200px',
56
+ backdropFilter: 'blur(8px)',
57
+ border: '1px solid rgba(255, 255, 255, 0.1)',
58
+ transition: 'opacity 0.3s ease',
59
+ opacity: isVisible ? 1 : 0,
60
+ pointerEvents: isVisible ? 'auto' : 'none',
61
+ }), [isVisible]);
62
+
63
+ const headerStyle: React.CSSProperties = useMemo(() => ({
64
+ display: 'flex',
65
+ justifyContent: 'space-between',
66
+ alignItems: 'center',
67
+ marginBottom: '8px',
68
+ paddingBottom: '8px',
69
+ borderBottom: '1px solid rgba(255, 255, 255, 0.1)',
70
+ }), []);
71
+
72
+ const titleStyle: React.CSSProperties = useMemo(() => ({
73
+ fontWeight: 'bold',
74
+ fontSize: '13px',
75
+ color: '#fff',
76
+ }), []);
77
+
78
+ const closeButtonStyle: React.CSSProperties = useMemo(() => ({
79
+ background: 'transparent',
80
+ border: 'none',
81
+ color: '#9ca3af',
82
+ cursor: 'pointer',
83
+ fontSize: '16px',
84
+ padding: '0',
85
+ lineHeight: '1',
86
+ }), []);
87
+
88
+ const metricRowStyle: React.CSSProperties = useMemo(() => ({
89
+ display: 'flex',
90
+ justifyContent: 'space-between',
91
+ alignItems: 'center',
92
+ marginBottom: '6px',
93
+ }), []);
94
+
95
+ const labelStyle: React.CSSProperties = useMemo(() => ({
96
+ color: '#9ca3af',
97
+ marginRight: '12px',
98
+ }), []);
99
+
100
+ const valueStyle: React.CSSProperties = useMemo(() => ({
101
+ fontWeight: 'bold',
102
+ }), []);
103
+
104
+ if (!isVisible) return null;
105
+
106
+ return (
107
+ <div style={dashboardStyle}>
108
+ {/* Header */}
109
+ <div style={headerStyle}>
110
+ <span style={titleStyle}>Performance Monitor</span>
111
+ {onClose && (
112
+ <button
113
+ style={closeButtonStyle}
114
+ onClick={onClose}
115
+ aria-label="Close performance dashboard"
116
+ >
117
+ ×
118
+ </button>
119
+ )}
120
+ </div>
121
+
122
+ {/* FPS Display */}
123
+ <div style={metricRowStyle}>
124
+ <span style={labelStyle}>FPS</span>
125
+ <span
126
+ style={{
127
+ ...valueStyle,
128
+ color: getFpsColor(metrics.fps)
129
+ }}
130
+ >
131
+ {Math.round(metrics.fps)}
132
+ </span>
133
+ </div>
134
+
135
+ {/* Frame Time */}
136
+ <div style={metricRowStyle}>
137
+ <span style={labelStyle}>Frame Time</span>
138
+ <span style={valueStyle}>
139
+ {metrics.frameTime.toFixed(2)}ms
140
+ </span>
141
+ </div>
142
+
143
+ {/* Quality Level */}
144
+ <div style={metricRowStyle}>
145
+ <span style={labelStyle}>Quality</span>
146
+ <span
147
+ style={{
148
+ ...valueStyle,
149
+ color: getQualityColor(metrics.qualityLevel),
150
+ textTransform: 'uppercase',
151
+ fontSize: '11px',
152
+ }}
153
+ >
154
+ {metrics.qualityLevel}
155
+ </span>
156
+ </div>
157
+
158
+ {/* GPU Memory (if available) */}
159
+ {metrics.gpuMemory && (
160
+ <div style={metricRowStyle}>
161
+ <span style={labelStyle}>GPU Memory</span>
162
+ <span style={valueStyle}>
163
+ ~{Math.round(metrics.gpuMemory / 1024)}MB
164
+ </span>
165
+ </div>
166
+ )}
167
+
168
+ {/* Auto-scaling Status */}
169
+ {metrics.isAutoScaling && (
170
+ <div style={{
171
+ marginTop: '8px',
172
+ paddingTop: '8px',
173
+ borderTop: '1px solid rgba(255, 255, 255, 0.1)',
174
+ fontSize: '10px',
175
+ color: '#6b7280',
176
+ textAlign: 'center',
177
+ }}>
178
+ Auto-scaling active
179
+ </div>
180
+ )}
181
+
182
+ {/* Performance Status Indicator */}
183
+ <div style={{
184
+ marginTop: '8px',
185
+ paddingTop: '8px',
186
+ borderTop: '1px solid rgba(255, 255, 255, 0.1)',
187
+ display: 'flex',
188
+ alignItems: 'center',
189
+ gap: '6px',
190
+ }}>
191
+ <div style={{
192
+ width: '8px',
193
+ height: '8px',
194
+ borderRadius: '50%',
195
+ backgroundColor: getFpsColor(metrics.fps),
196
+ animation: metrics.fps < 45 ? 'pulse 1s infinite' : 'none',
197
+ }} />
198
+ <span style={{
199
+ fontSize: '10px',
200
+ color: metrics.fps >= 58 ? '#4ade80' : metrics.fps >= 45 ? '#fbbf24' : '#ef4444',
201
+ }}>
202
+ {metrics.fps >= 58 ? 'Optimal' : metrics.fps >= 45 ? 'Warning' : 'Critical'}
203
+ </span>
204
+ </div>
205
+ </div>
206
+ );
207
+ };
208
+
209
+ // Add pulse animation for critical FPS
210
+ if (typeof document !== 'undefined') {
211
+ const styleSheet = document.createElement('style');
212
+ styleSheet.textContent = `
213
+ @keyframes pulse {
214
+ 0%, 100% { opacity: 1; }
215
+ 50% { opacity: 0.5; }
216
+ }
217
+ `;
218
+ document.head.appendChild(styleSheet);
219
+ }
@@ -40,25 +40,38 @@ function MyComponent() {
40
40
  | Prop | Type | Default | Description |
41
41
  |------|------|---------|-------------|
42
42
  | `children` | ReactNode | - | Content to be rendered inside the glass container |
43
- | `displacementScale` | number | 20 | Controls the intensity of the displacement effect |
44
- | `blurAmount` | number | 10 | Controls the intensity of the blur effect |
45
- | `saturation` | number | 150 | Controls the color saturation (100 is normal) |
46
- | `aberrationIntensity` | number | 1.5 | Controls the chromatic aberration effect intensity |
47
- | `elasticity` | number | 0.5 | Controls how responsive the glass is to mouse movement |
43
+ | `displacementScale` | number | 70 | Controls the intensity of the displacement effect |
44
+ | `blurAmount` | number | 0 | Controls the intensity of the blur effect |
45
+ | `saturation` | number | 140 | Controls the color saturation (100 is normal) |
46
+ | `aberrationIntensity` | number | 2 | Controls the chromatic aberration effect intensity |
47
+ | `elasticity` | number | 0.15 | Controls how responsive the glass is to mouse movement |
48
48
  | `borderRadius` | number | 15 | Border radius of the glass container |
49
49
  | `globalMousePos` | boolean | false | Whether to use global mouse position instead of local |
50
50
  | `mouseOffset` | { x: number, y: number } | { x: 0, y: 0 } | Offset for mouse position calculation |
51
51
  | `mouseContainer` | RefObject<HTMLElement> | null | Container to use for mouse position calculation |
52
- | `padding` | number | 0 | Additional padding around the content |
52
+ | `padding` | string | '0' | Additional padding around the content |
53
+ | `height` | string \| number | undefined | Height of the glass component |
54
+ | `width` | string \| number | undefined | Width of the glass component |
53
55
  | `style` | CSSProperties | {} | Additional CSS styles |
54
56
  | `overLight` | boolean \| 'auto' \| OverLightObjectConfig | 'auto' | OverLight configuration. See [OverLight Configuration](#overlight-configuration) section for details |
55
57
  | `withOverLightLayers` | boolean | true | Whether to render additional overlay layers for overLight mode |
56
58
  | `debugOverLight` | boolean | false | Enable debug logging for overLight detection and configuration |
57
59
  | `mode` | 'standard' \| 'polar' \| 'prominent' \| 'shader' | 'standard' | The glass effect mode |
58
60
  | `onClick` | function | undefined | Click handler |
59
- | `showBorderEffects` | boolean | true | Whether to show border effects |
60
- | `showHoverEffects` | boolean | true | Whether to show hover effects |
61
- | `active` | boolean | false | Whether the glass is in active state |
61
+ | `withBorder` | boolean | true | Whether to show border effects |
62
+ | `withLiquidBlur` | boolean | false | Whether to enable liquid blur effects |
63
+ | `withoutEffects` | boolean | false | Whether to disable all visual effects |
64
+ | `reducedMotion` | boolean | false | Force reduced motion preference |
65
+ | `highContrast` | boolean | false | Force high contrast mode |
66
+ | `withTimeAnimation` | boolean | true | Enable time-based animation (Phase 1) |
67
+ | `animationSpeed` | number | 1.0 | Animation speed multiplier (Phase 1) |
68
+ | `withMultiLayerDistortion` | boolean | false | Enable multi-layer distortion using FBM (Phase 1) |
69
+ | `distortionOctaves` | number | 5 | Number of octaves for FBM (Phase 1) |
70
+ | `distortionLacunarity` | number | 2.0 | Lacunarity for FBM (Phase 1) |
71
+ | `distortionGain` | number | 0.5 | Gain for FBM (Phase 1) |
72
+ | `distortionQuality` | 'low' \| 'medium' \| 'high' \| 'ultra' | 'high' | Quality preset for FBM (Phase 1) |
73
+ | `debugPerformance` | boolean | false | Enable performance monitoring dashboard (development only) |
74
+ | `debugBorderRadius` | boolean | false | Debug mode for corner radius extraction |
62
75
 
63
76
  ## Glass Effect Modes
64
77
 
@@ -80,8 +93,10 @@ The AtomixGlass component uses several advanced CSS features and SVG filters tha
80
93
 
81
94
  1. Use sparingly on pages with many instances
82
95
  2. Consider disabling effects on lower-end devices
83
- 3. Use the `showBorderEffects` and `showHoverEffects` props to disable non-essential effects when needed
96
+ 3. Use the `withoutEffects` prop to disable non-essential effects when needed
84
97
  4. Avoid using very high values for `displacementScale` and `blurAmount`
98
+ 5. Use `reducedMotion` for users with vestibular disorders
99
+ 6. Consider using lower `distortionQuality` presets on mobile devices
85
100
 
86
101
  ## Accessibility
87
102