@sc4rfurryx/proteusjs 1.0.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 (82) hide show
  1. package/API.md +438 -0
  2. package/FEATURES.md +286 -0
  3. package/LICENSE +21 -0
  4. package/README.md +645 -0
  5. package/dist/.tsbuildinfo +1 -0
  6. package/dist/proteus.cjs.js +16014 -0
  7. package/dist/proteus.cjs.js.map +1 -0
  8. package/dist/proteus.d.ts +3018 -0
  9. package/dist/proteus.esm.js +16005 -0
  10. package/dist/proteus.esm.js.map +1 -0
  11. package/dist/proteus.esm.min.js +8 -0
  12. package/dist/proteus.esm.min.js.map +1 -0
  13. package/dist/proteus.js +16020 -0
  14. package/dist/proteus.js.map +1 -0
  15. package/dist/proteus.min.js +8 -0
  16. package/dist/proteus.min.js.map +1 -0
  17. package/package.json +98 -0
  18. package/src/__tests__/mvp-integration.test.ts +518 -0
  19. package/src/accessibility/AccessibilityEngine.ts +2106 -0
  20. package/src/accessibility/ScreenReaderSupport.ts +444 -0
  21. package/src/accessibility/__tests__/ScreenReaderSupport.test.ts +435 -0
  22. package/src/animations/FLIPAnimationSystem.ts +491 -0
  23. package/src/compatibility/BrowserCompatibility.ts +1076 -0
  24. package/src/containers/BreakpointSystem.ts +347 -0
  25. package/src/containers/ContainerBreakpoints.ts +726 -0
  26. package/src/containers/ContainerManager.ts +370 -0
  27. package/src/containers/ContainerUnits.ts +336 -0
  28. package/src/containers/ContextIsolation.ts +394 -0
  29. package/src/containers/ElementQueries.ts +411 -0
  30. package/src/containers/SmartContainer.ts +536 -0
  31. package/src/containers/SmartContainers.ts +376 -0
  32. package/src/containers/__tests__/ContainerBreakpoints.test.ts +411 -0
  33. package/src/containers/__tests__/SmartContainers.test.ts +281 -0
  34. package/src/content/ResponsiveImages.ts +570 -0
  35. package/src/core/EventSystem.ts +147 -0
  36. package/src/core/MemoryManager.ts +321 -0
  37. package/src/core/PerformanceMonitor.ts +238 -0
  38. package/src/core/PluginSystem.ts +275 -0
  39. package/src/core/ProteusJS.test.ts +164 -0
  40. package/src/core/ProteusJS.ts +962 -0
  41. package/src/developer/PerformanceProfiler.ts +567 -0
  42. package/src/developer/VisualDebuggingTools.ts +656 -0
  43. package/src/developer/ZeroConfigSystem.ts +593 -0
  44. package/src/index.ts +35 -0
  45. package/src/integration.test.ts +227 -0
  46. package/src/layout/AdaptiveGrid.ts +429 -0
  47. package/src/layout/ContentReordering.ts +532 -0
  48. package/src/layout/FlexboxEnhancer.ts +406 -0
  49. package/src/layout/FlowLayout.ts +545 -0
  50. package/src/layout/SpacingSystem.ts +512 -0
  51. package/src/observers/IntersectionObserverPolyfill.ts +289 -0
  52. package/src/observers/ObserverManager.ts +299 -0
  53. package/src/observers/ResizeObserverPolyfill.ts +179 -0
  54. package/src/performance/BatchDOMOperations.ts +519 -0
  55. package/src/performance/CSSOptimizationEngine.ts +646 -0
  56. package/src/performance/CacheOptimizationSystem.ts +601 -0
  57. package/src/performance/EfficientEventHandler.ts +740 -0
  58. package/src/performance/LazyEvaluationSystem.ts +532 -0
  59. package/src/performance/MemoryManagementSystem.ts +497 -0
  60. package/src/performance/PerformanceMonitor.ts +931 -0
  61. package/src/performance/__tests__/BatchDOMOperations.test.ts +309 -0
  62. package/src/performance/__tests__/EfficientEventHandler.test.ts +268 -0
  63. package/src/performance/__tests__/PerformanceMonitor.test.ts +422 -0
  64. package/src/polyfills/BrowserPolyfills.ts +586 -0
  65. package/src/polyfills/__tests__/BrowserPolyfills.test.ts +328 -0
  66. package/src/test/setup.ts +115 -0
  67. package/src/theming/SmartThemeSystem.ts +591 -0
  68. package/src/types/index.ts +134 -0
  69. package/src/typography/ClampScaling.ts +356 -0
  70. package/src/typography/FluidTypography.ts +759 -0
  71. package/src/typography/LineHeightOptimization.ts +430 -0
  72. package/src/typography/LineHeightOptimizer.ts +326 -0
  73. package/src/typography/TextFitting.ts +355 -0
  74. package/src/typography/TypographicScale.ts +428 -0
  75. package/src/typography/VerticalRhythm.ts +369 -0
  76. package/src/typography/__tests__/FluidTypography.test.ts +432 -0
  77. package/src/typography/__tests__/LineHeightOptimization.test.ts +436 -0
  78. package/src/utils/Logger.ts +173 -0
  79. package/src/utils/debounce.ts +259 -0
  80. package/src/utils/performance.ts +371 -0
  81. package/src/utils/support.ts +106 -0
  82. package/src/utils/version.ts +24 -0
@@ -0,0 +1,356 @@
1
+ /**
2
+ * Clamp-Based Scaling System for ProteusJS
3
+ * Implements intelligent font scaling using CSS clamp() with JavaScript fallbacks
4
+ */
5
+
6
+ export interface ScalingConfig {
7
+ minSize: number;
8
+ maxSize: number;
9
+ minContainer: number;
10
+ maxContainer: number;
11
+ unit: 'px' | 'rem' | 'em';
12
+ containerUnit: 'px' | 'cw' | 'ch' | 'cmin' | 'cmax';
13
+ curve: 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'custom';
14
+ customCurve?: (progress: number) => number;
15
+ }
16
+
17
+ export interface ScalingResult {
18
+ clampValue: string;
19
+ fallbackValue: string;
20
+ currentSize: number;
21
+ progress: number;
22
+ isNative: boolean;
23
+ }
24
+
25
+ export class ClampScaling {
26
+ private supportsClamp: boolean;
27
+ private supportsContainerUnits: boolean;
28
+
29
+ constructor() {
30
+ this.supportsClamp = this.checkClampSupport();
31
+ this.supportsContainerUnits = this.checkContainerUnitSupport();
32
+ }
33
+
34
+ /**
35
+ * Create clamp-based scaling value
36
+ */
37
+ public createScaling(config: ScalingConfig): ScalingResult {
38
+ const {
39
+ minSize,
40
+ maxSize,
41
+ minContainer,
42
+ maxContainer,
43
+ unit,
44
+ containerUnit,
45
+ curve
46
+ } = config;
47
+
48
+ // Validate configuration to prevent NaN
49
+ const containerRange = maxContainer - minContainer;
50
+ const sizeRange = maxSize - minSize;
51
+
52
+ if (containerRange <= 0) {
53
+ console.warn('Invalid container range, using fallback scaling');
54
+ return {
55
+ clampValue: `${minSize}${unit}`,
56
+ fallbackValue: `${minSize}${unit}`,
57
+ currentSize: minSize,
58
+ progress: 0,
59
+ isNative: false
60
+ };
61
+ }
62
+
63
+ // Calculate slope and y-intercept for linear scaling
64
+ const slope = sizeRange / containerRange;
65
+ const yIntercept = minSize - slope * minContainer;
66
+
67
+ let clampValue: string;
68
+ let fallbackValue: string;
69
+
70
+ if (this.supportsClamp && (this.supportsContainerUnits || containerUnit === 'px')) {
71
+ // Use native CSS clamp
72
+ const preferredValue = this.createPreferredValue(
73
+ yIntercept,
74
+ slope,
75
+ unit,
76
+ containerUnit,
77
+ curve,
78
+ config
79
+ );
80
+
81
+ clampValue = `clamp(${minSize}${unit}, ${preferredValue}, ${maxSize}${unit})`;
82
+ fallbackValue = `${minSize}${unit}`;
83
+ } else {
84
+ // Use JavaScript fallback
85
+ clampValue = `var(--proteus-font-size, ${minSize}${unit})`;
86
+ fallbackValue = `${minSize}${unit}`;
87
+ }
88
+
89
+ return {
90
+ clampValue,
91
+ fallbackValue,
92
+ currentSize: minSize,
93
+ progress: 0,
94
+ isNative: this.supportsClamp
95
+ };
96
+ }
97
+
98
+ /**
99
+ * Calculate current font size for given container size
100
+ */
101
+ public calculateSize(
102
+ containerSize: number,
103
+ config: ScalingConfig
104
+ ): number {
105
+ const {
106
+ minSize,
107
+ maxSize,
108
+ minContainer,
109
+ maxContainer,
110
+ curve,
111
+ customCurve
112
+ } = config;
113
+
114
+ // Clamp container size to valid range
115
+ const clampedSize = Math.max(minContainer, Math.min(maxContainer, containerSize));
116
+
117
+ // Calculate progress (0-1)
118
+ const progress = (clampedSize - minContainer) / (maxContainer - minContainer);
119
+
120
+ // Apply easing curve
121
+ const easedProgress = this.applyCurve(progress, curve, customCurve);
122
+
123
+ // Calculate final size
124
+ const size = minSize + (maxSize - minSize) * easedProgress;
125
+
126
+ return Math.max(minSize, Math.min(maxSize, size));
127
+ }
128
+
129
+ /**
130
+ * Apply scaling to element
131
+ */
132
+ public applyScaling(
133
+ element: Element,
134
+ containerSize: number,
135
+ config: ScalingConfig
136
+ ): void {
137
+ const htmlElement = element as HTMLElement;
138
+ const result = this.createScaling(config);
139
+
140
+ if (result.isNative) {
141
+ // Use CSS clamp
142
+ htmlElement.style.fontSize = result.clampValue;
143
+ } else {
144
+ // Use JavaScript calculation
145
+ const calculatedSize = this.calculateSize(containerSize, config);
146
+ htmlElement.style.setProperty('--proteus-font-size', `${calculatedSize}${config.unit}`);
147
+ htmlElement.style.fontSize = result.clampValue;
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Create responsive scaling for multiple breakpoints
153
+ */
154
+ public createMultiBreakpointScaling(
155
+ breakpoints: Array<{
156
+ container: number;
157
+ size: number;
158
+ }>,
159
+ unit: 'px' | 'rem' | 'em' = 'rem',
160
+ containerUnit: 'px' | 'cw' | 'ch' | 'cmin' | 'cmax' = 'cw'
161
+ ): string {
162
+ if (breakpoints.length < 2) {
163
+ throw new Error('At least 2 breakpoints required for multi-breakpoint scaling');
164
+ }
165
+
166
+ // Sort breakpoints by container size
167
+ const sorted = [...breakpoints].sort((a, b) => a.container - b.container);
168
+
169
+ // Create clamp values for each segment
170
+ const clampValues: string[] = [];
171
+
172
+ for (let i = 0; i < sorted.length - 1; i++) {
173
+ const current = sorted[i]!;
174
+ const next = sorted[i + 1]!;
175
+
176
+ const config: ScalingConfig = {
177
+ minSize: current.size,
178
+ maxSize: next.size,
179
+ minContainer: current.container,
180
+ maxContainer: next.container,
181
+ unit,
182
+ containerUnit,
183
+ curve: 'linear'
184
+ };
185
+
186
+ const result = this.createScaling(config);
187
+ clampValues.push(result.clampValue);
188
+ }
189
+
190
+ // Combine with CSS max() for proper breakpoint handling
191
+ return clampValues.length === 1
192
+ ? clampValues[0]!
193
+ : `max(${clampValues.join(', ')})`;
194
+ }
195
+
196
+ /**
197
+ * Generate optimal scaling configuration
198
+ */
199
+ public generateOptimalConfig(
200
+ _element: Element,
201
+ targetSizes: { small: number; large: number },
202
+ containerSizes: { small: number; large: number },
203
+ options: {
204
+ unit?: 'px' | 'rem' | 'em';
205
+ accessibility?: boolean;
206
+ readability?: boolean;
207
+ } = {}
208
+ ): ScalingConfig {
209
+ const { unit = 'rem', accessibility = true, readability = true } = options;
210
+
211
+ let { small: minSize, large: maxSize } = targetSizes;
212
+ const { small: minContainer, large: maxContainer } = containerSizes;
213
+
214
+ // Apply accessibility constraints
215
+ if (accessibility) {
216
+ // Ensure minimum readable size (WCAG guidelines)
217
+ const minReadableSize = unit === 'px' ? 16 : 1; // 16px or 1rem
218
+ minSize = Math.max(minSize, minReadableSize);
219
+
220
+ // Limit maximum size to prevent overwhelming text
221
+ const maxReadableSize = unit === 'px' ? 72 : 4.5; // 72px or 4.5rem
222
+ maxSize = Math.min(maxSize, maxReadableSize);
223
+ }
224
+
225
+ // Apply readability constraints
226
+ if (readability) {
227
+ // Ensure reasonable scaling ratio (not too aggressive)
228
+ const maxRatio = 2.5;
229
+ if (maxSize / minSize > maxRatio) {
230
+ maxSize = minSize * maxRatio;
231
+ }
232
+ }
233
+
234
+ return {
235
+ minSize,
236
+ maxSize,
237
+ minContainer,
238
+ maxContainer,
239
+ unit,
240
+ containerUnit: 'cw',
241
+ curve: 'ease-out' // Slightly slower scaling at larger sizes
242
+ };
243
+ }
244
+
245
+ /**
246
+ * Validate scaling configuration
247
+ */
248
+ public validateConfig(config: ScalingConfig): { valid: boolean; errors: string[] } {
249
+ const errors: string[] = [];
250
+
251
+ if (config.minSize >= config.maxSize) {
252
+ errors.push('minSize must be less than maxSize');
253
+ }
254
+
255
+ if (config.minContainer >= config.maxContainer) {
256
+ errors.push('minContainer must be less than maxContainer');
257
+ }
258
+
259
+ if (config.minSize <= 0) {
260
+ errors.push('minSize must be positive');
261
+ }
262
+
263
+ if (config.minContainer <= 0) {
264
+ errors.push('minContainer must be positive');
265
+ }
266
+
267
+ // Check for reasonable scaling ratios
268
+ const sizeRatio = config.maxSize / config.minSize;
269
+ if (sizeRatio > 5) {
270
+ errors.push('Size ratio is very large (>5x), consider reducing for better readability');
271
+ }
272
+
273
+ return {
274
+ valid: errors.length === 0,
275
+ errors
276
+ };
277
+ }
278
+
279
+ /**
280
+ * Create preferred value for clamp function
281
+ */
282
+ private createPreferredValue(
283
+ yIntercept: number,
284
+ slope: number,
285
+ unit: string,
286
+ containerUnit: string,
287
+ curve: ScalingConfig['curve'],
288
+ _config: ScalingConfig
289
+ ): string {
290
+ // Validate inputs to prevent NaN
291
+ if (!isFinite(yIntercept) || !isFinite(slope)) {
292
+ console.warn('Invalid scaling values detected, using fallback');
293
+ return `1${unit}`; // Fallback value
294
+ }
295
+
296
+ if (curve === 'linear') {
297
+ // Simple linear scaling
298
+ const slopeValue = slope * (containerUnit === 'px' ? 1 : 100);
299
+
300
+ // Format numbers to prevent very long decimals
301
+ const formattedIntercept = Number(yIntercept.toFixed(3));
302
+ const formattedSlope = Number(slopeValue.toFixed(3));
303
+
304
+ return `${formattedIntercept}${unit} + ${formattedSlope}${containerUnit}`;
305
+ } else {
306
+ // For non-linear curves, we need to use CSS calc with custom properties
307
+ // This is a simplified approach - full implementation would need more complex CSS
308
+ const formattedIntercept = Number(yIntercept.toFixed(3));
309
+ const formattedSlope = Number((slope * 100).toFixed(3));
310
+
311
+ return `${formattedIntercept}${unit} + ${formattedSlope}${containerUnit}`;
312
+ }
313
+ }
314
+
315
+ /**
316
+ * Apply easing curve to progress value
317
+ */
318
+ private applyCurve(
319
+ progress: number,
320
+ curve: ScalingConfig['curve'],
321
+ customCurve?: (progress: number) => number
322
+ ): number {
323
+ switch (curve) {
324
+ case 'linear':
325
+ return progress;
326
+ case 'ease-in':
327
+ return progress * progress;
328
+ case 'ease-out':
329
+ return 1 - Math.pow(1 - progress, 2);
330
+ case 'ease-in-out':
331
+ return progress < 0.5
332
+ ? 2 * progress * progress
333
+ : 1 - Math.pow(-2 * progress + 2, 2) / 2;
334
+ case 'custom':
335
+ return customCurve ? customCurve(progress) : progress;
336
+ default:
337
+ return progress;
338
+ }
339
+ }
340
+
341
+ /**
342
+ * Check if CSS clamp() is supported
343
+ */
344
+ private checkClampSupport(): boolean {
345
+ if (typeof CSS === 'undefined' || !CSS.supports) return false;
346
+ return CSS.supports('font-size', 'clamp(1rem, 2vw, 2rem)');
347
+ }
348
+
349
+ /**
350
+ * Check if container units are supported
351
+ */
352
+ private checkContainerUnitSupport(): boolean {
353
+ if (typeof CSS === 'undefined' || !CSS.supports) return false;
354
+ return CSS.supports('font-size', '1cw');
355
+ }
356
+ }