@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,347 @@
1
+ /**
2
+ * Breakpoint System for ProteusJS
3
+ * Manages responsive breakpoint definitions and calculations
4
+ */
5
+
6
+ import type { BreakpointConfig } from '../types';
7
+
8
+ export interface BreakpointDefinition {
9
+ name: string;
10
+ value: number; // in pixels
11
+ unit: string;
12
+ originalValue: string | number;
13
+ active: boolean;
14
+ }
15
+
16
+ export interface BreakpointMatch {
17
+ name: string;
18
+ matches: boolean;
19
+ value: number;
20
+ dimension: number;
21
+ }
22
+
23
+ export class BreakpointSystem {
24
+ private breakpoints: Map<string, BreakpointDefinition> = new Map();
25
+ private sortedBreakpoints: BreakpointDefinition[] = [];
26
+
27
+ constructor(breakpoints: BreakpointConfig = {}) {
28
+ this.setBreakpoints(breakpoints);
29
+ }
30
+
31
+ /**
32
+ * Set breakpoints configuration
33
+ */
34
+ public setBreakpoints(breakpoints: BreakpointConfig): void {
35
+ this.breakpoints.clear();
36
+
37
+ Object.entries(breakpoints).forEach(([name, value]) => {
38
+ const definition = this.parseBreakpoint(name, value);
39
+ this.breakpoints.set(name, definition);
40
+ });
41
+
42
+ this.updateSortedBreakpoints();
43
+ }
44
+
45
+ /**
46
+ * Add or update a single breakpoint
47
+ */
48
+ public setBreakpoint(name: string, value: string | number): void {
49
+ const definition = this.parseBreakpoint(name, value);
50
+ this.breakpoints.set(name, definition);
51
+ this.updateSortedBreakpoints();
52
+ }
53
+
54
+ /**
55
+ * Remove a breakpoint
56
+ */
57
+ public removeBreakpoint(name: string): boolean {
58
+ const removed = this.breakpoints.delete(name);
59
+ if (removed) {
60
+ this.updateSortedBreakpoints();
61
+ }
62
+ return removed;
63
+ }
64
+
65
+ /**
66
+ * Get breakpoint definition
67
+ */
68
+ public getBreakpoint(name: string): BreakpointDefinition | undefined {
69
+ return this.breakpoints.get(name);
70
+ }
71
+
72
+ /**
73
+ * Get all breakpoints
74
+ */
75
+ public getAllBreakpoints(): BreakpointDefinition[] {
76
+ return Array.from(this.breakpoints.values());
77
+ }
78
+
79
+ /**
80
+ * Get sorted breakpoints (smallest to largest)
81
+ */
82
+ public getSortedBreakpoints(): BreakpointDefinition[] {
83
+ return [...this.sortedBreakpoints];
84
+ }
85
+
86
+ /**
87
+ * Calculate active breakpoints for given dimensions
88
+ */
89
+ public calculateActiveBreakpoints(
90
+ width: number,
91
+ height: number,
92
+ containerType: 'inline-size' | 'size' | 'block-size' = 'inline-size'
93
+ ): string[] {
94
+ const dimension = this.getRelevantDimension(width, height, containerType);
95
+ const active: string[] = [];
96
+
97
+ this.sortedBreakpoints.forEach(bp => {
98
+ if (dimension >= bp.value) {
99
+ active.push(bp.name);
100
+ }
101
+ });
102
+
103
+ return active;
104
+ }
105
+
106
+ /**
107
+ * Get breakpoint matches for given dimensions
108
+ */
109
+ public getBreakpointMatches(
110
+ width: number,
111
+ height: number,
112
+ containerType: 'inline-size' | 'size' | 'block-size' = 'inline-size'
113
+ ): BreakpointMatch[] {
114
+ const dimension = this.getRelevantDimension(width, height, containerType);
115
+
116
+ return this.sortedBreakpoints.map(bp => ({
117
+ name: bp.name,
118
+ matches: dimension >= bp.value,
119
+ value: bp.value,
120
+ dimension
121
+ }));
122
+ }
123
+
124
+ /**
125
+ * Get the current active breakpoint (largest matching)
126
+ */
127
+ public getCurrentBreakpoint(
128
+ width: number,
129
+ height: number,
130
+ containerType: 'inline-size' | 'size' | 'block-size' = 'inline-size'
131
+ ): string | null {
132
+ const active = this.calculateActiveBreakpoints(width, height, containerType);
133
+ return active.length > 0 ? active[active.length - 1]! : null;
134
+ }
135
+
136
+ /**
137
+ * Check if a specific breakpoint is active
138
+ */
139
+ public isBreakpointActive(
140
+ name: string,
141
+ width: number,
142
+ height: number,
143
+ containerType: 'inline-size' | 'size' | 'block-size' = 'inline-size'
144
+ ): boolean {
145
+ const bp = this.breakpoints.get(name);
146
+ if (!bp) return false;
147
+
148
+ const dimension = this.getRelevantDimension(width, height, containerType);
149
+ return dimension >= bp.value;
150
+ }
151
+
152
+ /**
153
+ * Get breakpoint range (min-max values)
154
+ */
155
+ public getBreakpointRange(name: string): { min: number; max: number | null } | null {
156
+ const bp = this.breakpoints.get(name);
157
+ if (!bp) return null;
158
+
159
+ const index = this.sortedBreakpoints.findIndex(b => b.name === name);
160
+ if (index === -1) return null;
161
+
162
+ const min = bp.value;
163
+ const max = index < this.sortedBreakpoints.length - 1
164
+ ? this.sortedBreakpoints[index + 1]!.value - 1
165
+ : null;
166
+
167
+ return { min, max };
168
+ }
169
+
170
+ /**
171
+ * Generate CSS media queries for breakpoints
172
+ */
173
+ public generateMediaQueries(): Record<string, string> {
174
+ const queries: Record<string, string> = {};
175
+
176
+ this.sortedBreakpoints.forEach((bp) => {
177
+ const range = this.getBreakpointRange(bp.name);
178
+ if (!range) return;
179
+
180
+ let query = `(min-width: ${range.min}px)`;
181
+ if (range.max !== null) {
182
+ query += ` and (max-width: ${range.max}px)`;
183
+ }
184
+
185
+ queries[bp.name] = query;
186
+ });
187
+
188
+ return queries;
189
+ }
190
+
191
+ /**
192
+ * Generate CSS container queries
193
+ */
194
+ public generateContainerQueries(containerName?: string): Record<string, string> {
195
+ const queries: Record<string, string> = {};
196
+ const container = containerName ? `${containerName} ` : '';
197
+
198
+ this.sortedBreakpoints.forEach((bp) => {
199
+ const range = this.getBreakpointRange(bp.name);
200
+ if (!range) return;
201
+
202
+ let query = `@container ${container}(min-width: ${range.min}px)`;
203
+ if (range.max !== null) {
204
+ query += ` and (max-width: ${range.max}px)`;
205
+ }
206
+
207
+ queries[bp.name] = query;
208
+ });
209
+
210
+ return queries;
211
+ }
212
+
213
+ /**
214
+ * Validate breakpoint configuration
215
+ */
216
+ public validateBreakpoints(): { valid: boolean; errors: string[] } {
217
+ const errors: string[] = [];
218
+
219
+ // Check for duplicate values
220
+ const values = new Map<number, string[]>();
221
+ this.breakpoints.forEach((bp, name) => {
222
+ if (!values.has(bp.value)) {
223
+ values.set(bp.value, []);
224
+ }
225
+ values.get(bp.value)!.push(name);
226
+ });
227
+
228
+ values.forEach((names, value) => {
229
+ if (names.length > 1) {
230
+ errors.push(`Duplicate breakpoint value ${value}px for: ${names.join(', ')}`);
231
+ }
232
+ });
233
+
234
+ // Check for invalid values
235
+ this.breakpoints.forEach((bp, name) => {
236
+ if (bp.value < 0) {
237
+ errors.push(`Invalid negative value for breakpoint "${name}": ${bp.value}px`);
238
+ }
239
+ if (!isFinite(bp.value)) {
240
+ errors.push(`Invalid value for breakpoint "${name}": ${bp.originalValue}`);
241
+ }
242
+ });
243
+
244
+ return {
245
+ valid: errors.length === 0,
246
+ errors
247
+ };
248
+ }
249
+
250
+ /**
251
+ * Get breakpoint statistics
252
+ */
253
+ public getStats(): object {
254
+ const values = this.sortedBreakpoints.map(bp => bp.value);
255
+ return {
256
+ count: this.breakpoints.size,
257
+ smallest: values[0] || 0,
258
+ largest: values[values.length - 1] || 0,
259
+ average: values.length > 0 ? values.reduce((a, b) => a + b, 0) / values.length : 0,
260
+ units: Array.from(new Set(this.sortedBreakpoints.map(bp => bp.unit))),
261
+ names: this.sortedBreakpoints.map(bp => bp.name)
262
+ };
263
+ }
264
+
265
+ /**
266
+ * Parse breakpoint value into definition
267
+ */
268
+ private parseBreakpoint(name: string, value: string | number): BreakpointDefinition {
269
+ let pixelValue: number;
270
+ let unit: string;
271
+ const originalValue = value;
272
+
273
+ if (typeof value === 'number') {
274
+ pixelValue = value;
275
+ unit = 'px';
276
+ } else {
277
+ const match = value.match(/^(\d*\.?\d+)(px|em|rem|%|vw|vh)?$/);
278
+ if (!match) {
279
+ console.warn(`ProteusJS: Invalid breakpoint value "${value}" for "${name}". Using 0px.`);
280
+ pixelValue = 0;
281
+ unit = 'px';
282
+ } else {
283
+ const numValue = parseFloat(match[1]!);
284
+ unit = match[2] || 'px';
285
+
286
+ // Convert to pixels
287
+ switch (unit) {
288
+ case 'px':
289
+ pixelValue = numValue;
290
+ break;
291
+ case 'em':
292
+ case 'rem':
293
+ pixelValue = numValue * 16; // Assume 16px base
294
+ break;
295
+ case '%':
296
+ pixelValue = (numValue / 100) * window.innerWidth;
297
+ break;
298
+ case 'vw':
299
+ pixelValue = (numValue / 100) * window.innerWidth;
300
+ break;
301
+ case 'vh':
302
+ pixelValue = (numValue / 100) * window.innerHeight;
303
+ break;
304
+ default:
305
+ pixelValue = numValue;
306
+ unit = 'px';
307
+ }
308
+ }
309
+ }
310
+
311
+ return {
312
+ name,
313
+ value: pixelValue,
314
+ unit,
315
+ originalValue,
316
+ active: false
317
+ };
318
+ }
319
+
320
+ /**
321
+ * Update sorted breakpoints array
322
+ */
323
+ private updateSortedBreakpoints(): void {
324
+ this.sortedBreakpoints = Array.from(this.breakpoints.values())
325
+ .sort((a, b) => a.value - b.value);
326
+ }
327
+
328
+ /**
329
+ * Get relevant dimension based on container type
330
+ */
331
+ private getRelevantDimension(
332
+ width: number,
333
+ height: number,
334
+ containerType: 'inline-size' | 'size' | 'block-size'
335
+ ): number {
336
+ switch (containerType) {
337
+ case 'inline-size':
338
+ return width;
339
+ case 'block-size':
340
+ return height;
341
+ case 'size':
342
+ return Math.min(width, height);
343
+ default:
344
+ return width;
345
+ }
346
+ }
347
+ }