@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.1.6 → 0.1.7
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.
- package/CHANGELOG.md +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.esm.js +18 -1
- package/dist/index.js +18 -1
- package/dist/setupTests.d.ts +124 -0
- package/dist/setupTests.esm.js +122 -0
- package/dist/setupTests.js +122 -0
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/index.css +1046 -0
- package/src/index.ts +18 -0
- package/src/plugins/theme-css-generator.ts +354 -0
- package/src/setupTests.ts +124 -0
- package/src/stories/README.md +39 -0
- package/src/stories/components/ThemeDebugger.tsx +143 -0
- package/src/stories/index.ts +29 -0
- package/src/stories/storybook-theme-imports.css +51 -0
- package/src/styles/base/fonts.css +30 -0
- package/src/styles/base/generated-theme-variables.css +573 -0
- package/src/styles/base/index.css +7 -0
- package/src/styles/base/reset.css +48 -0
- package/src/styles/base/theme.css +1068 -0
- package/src/styles/base/typography.css +68 -0
- package/src/styles/base/variables.css +5 -0
- package/src/styles/components/CLAUDE.md +62 -0
- package/src/styles/components/base/badge.css +428 -0
- package/src/styles/components/base/button.css +774 -0
- package/src/styles/components/base/card.css +601 -0
- package/src/styles/components/base/checkbox.css +442 -0
- package/src/styles/components/base/index.css +9 -0
- package/src/styles/components/base/input.css +887 -0
- package/src/styles/components/base/label.css +296 -0
- package/src/styles/components/data-display/chart.css +353 -0
- package/src/styles/components/data-display/data-grid.css +619 -0
- package/src/styles/components/data-display/index.css +9 -0
- package/src/styles/components/data-display/list.css +560 -0
- package/src/styles/components/data-display/table.css +498 -0
- package/src/styles/components/data-display/timeline.css +764 -0
- package/src/styles/components/data-display/tree.css +881 -0
- package/src/styles/components/feedback/alert.css +358 -0
- package/src/styles/components/feedback/index.css +7 -0
- package/src/styles/components/feedback/progress.css +435 -0
- package/src/styles/components/feedback/skeleton.css +337 -0
- package/src/styles/components/feedback/toast.css +564 -0
- package/src/styles/components/index.css +17 -0
- package/src/styles/components/navigation/breadcrumb.css +465 -0
- package/src/styles/components/navigation/index.css +9 -0
- package/src/styles/components/navigation/menu.css +572 -0
- package/src/styles/components/navigation/pagination.css +635 -0
- package/src/styles/components/navigation/sidebar.css +807 -0
- package/src/styles/components/navigation/stepper.css +519 -0
- package/src/styles/components/navigation/tabs.css +404 -0
- package/src/styles/components/overlay/backdrop.css +243 -0
- package/src/styles/components/overlay/index.css +8 -0
- package/src/styles/components/overlay/modal.css +482 -0
- package/src/styles/components/overlay/popover.css +607 -0
- package/src/styles/components/overlay/portal.css +213 -0
- package/src/styles/components/overlay/tooltip.css +488 -0
- package/src/styles/generated-theme-variables.css +573 -0
- package/src/styles/index.css +5 -0
- package/src/styles/layers/index.css +54 -0
- package/src/styles/layers/overrides.css +108 -0
- package/src/styles/layers/validation.css +159 -0
- package/src/styles/layers/validation.js +310 -0
- package/src/styles/themes/default.css +450 -0
- package/src/styles/themes/enterprise.css +370 -0
- package/src/styles/themes/harvey.css +436 -0
- package/src/styles/themes/index.css +4 -0
- package/src/styles/themes/stan-design.css +572 -0
- package/src/styles/utilities/advanced-transition-system.css +467 -0
- package/src/styles/utilities/battery-conscious-animations.css +289 -0
- package/src/styles/utilities/enterprise-mobile-experience.css +817 -0
- package/src/styles/utilities/hardware-acceleration.css +121 -0
- package/src/styles/utilities/index.css +20 -0
- package/src/styles/utilities/mobile-skeleton-loading.css +596 -0
- package/src/styles/utilities/semantic-input-system.css +451 -0
- package/src/styles/utilities/touch-friendly-interface.css +247 -0
- package/src/styles/utilities/touch-optimization.css +165 -0
- package/src/test-utils/index.ts +7 -0
- package/src/test-utils/theme-testing.tsx +219 -0
- package/src/testing/test-automation.ts +627 -0
- package/src/testing/test-utils.tsx +367 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/* CSS Overrides Layer */
|
|
2
|
+
/* This layer provides application-specific overrides with highest priority */
|
|
3
|
+
|
|
4
|
+
@layer overrides {
|
|
5
|
+
/* High-priority overrides for application-specific customizations */
|
|
6
|
+
|
|
7
|
+
/* Accessibility overrides that must take precedence */
|
|
8
|
+
.a11y-override {
|
|
9
|
+
/* Force focus visibility for accessibility */
|
|
10
|
+
outline: 2px solid var(--cs-colors-interactive-focus) !important;
|
|
11
|
+
outline-offset: 2px !important;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* High contrast mode overrides */
|
|
15
|
+
@media (prefers-contrast: high) {
|
|
16
|
+
* {
|
|
17
|
+
border-color: currentColor !important;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.button,
|
|
21
|
+
.input,
|
|
22
|
+
.card {
|
|
23
|
+
border-width: var(--cs-border-width-thick) !important;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Reduced motion overrides */
|
|
28
|
+
@media (prefers-reduced-motion: reduce) {
|
|
29
|
+
*,
|
|
30
|
+
*::before,
|
|
31
|
+
*::after {
|
|
32
|
+
animation-duration: 0.01ms !important;
|
|
33
|
+
animation-iteration-count: 1 !important;
|
|
34
|
+
transition-duration: 0.01ms !important;
|
|
35
|
+
scroll-behavior: auto !important;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* Print overrides */
|
|
40
|
+
@media print {
|
|
41
|
+
/* Hide interactive elements in print */
|
|
42
|
+
.button--ghost,
|
|
43
|
+
.tooltip,
|
|
44
|
+
.popover,
|
|
45
|
+
.modal__overlay,
|
|
46
|
+
.sidebar__mobile-toggle {
|
|
47
|
+
display: none !important;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Ensure readability in print */
|
|
51
|
+
.card,
|
|
52
|
+
.alert,
|
|
53
|
+
.modal__container {
|
|
54
|
+
border: 1px solid #000 !important;
|
|
55
|
+
box-shadow: none !important;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Force link visibility in print */
|
|
59
|
+
a[href]:after {
|
|
60
|
+
content: " (" attr(href) ")" !important;
|
|
61
|
+
font-size: 0.8em !important;
|
|
62
|
+
color: #666 !important;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Emergency overrides for broken states */
|
|
67
|
+
.force-visible {
|
|
68
|
+
display: block !important;
|
|
69
|
+
visibility: visible !important;
|
|
70
|
+
opacity: 1 !important;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.force-hidden {
|
|
74
|
+
display: none !important;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Debug and development overrides */
|
|
78
|
+
.debug-outline * {
|
|
79
|
+
outline: 1px solid red !important;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.debug-spacing * {
|
|
83
|
+
background: rgba(255, 0, 0, 0.1) !important;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Browser-specific overrides */
|
|
87
|
+
|
|
88
|
+
/* Safari-specific fixes */
|
|
89
|
+
@supports (-webkit-appearance: none) {
|
|
90
|
+
.input {
|
|
91
|
+
-webkit-appearance: none !important;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Firefox-specific fixes */
|
|
96
|
+
@-moz-document url-prefix() {
|
|
97
|
+
.button {
|
|
98
|
+
-moz-user-select: none !important;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* IE/Edge legacy support (if needed) */
|
|
103
|
+
@supports (-ms-ime-align: auto) {
|
|
104
|
+
.grid {
|
|
105
|
+
display: -ms-grid !important;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/* CSS Layers Validation and Testing */
|
|
2
|
+
/* This file provides diagnostic tools for validating layer order and specificity */
|
|
3
|
+
|
|
4
|
+
/* Test classes to verify layer cascade order */
|
|
5
|
+
|
|
6
|
+
/* Reset layer test - lowest priority */
|
|
7
|
+
@layer reset {
|
|
8
|
+
.layer-test {
|
|
9
|
+
background-color: red; /* Should be overridden */
|
|
10
|
+
content: "reset";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Base layer test */
|
|
15
|
+
@layer base {
|
|
16
|
+
.layer-test {
|
|
17
|
+
background-color: orange; /* Should be overridden */
|
|
18
|
+
content: "base";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Themes layer test */
|
|
23
|
+
@layer themes {
|
|
24
|
+
.layer-test {
|
|
25
|
+
background-color: yellow; /* Should be overridden */
|
|
26
|
+
content: "themes";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Components layer test */
|
|
31
|
+
@layer components {
|
|
32
|
+
.layer-test {
|
|
33
|
+
background-color: green; /* Should be overridden */
|
|
34
|
+
content: "components";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* Utilities layer test */
|
|
39
|
+
@layer utilities {
|
|
40
|
+
.layer-test {
|
|
41
|
+
background-color: blue; /* Should be overridden by overrides only */
|
|
42
|
+
content: "utilities";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Overrides layer test - highest priority */
|
|
47
|
+
@layer overrides {
|
|
48
|
+
.layer-test {
|
|
49
|
+
background-color: purple; /* Should win */
|
|
50
|
+
content: "overrides";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Specificity test classes */
|
|
55
|
+
@layer components {
|
|
56
|
+
/* Lower specificity - should lose */
|
|
57
|
+
.specificity-test {
|
|
58
|
+
background-color: red;
|
|
59
|
+
border: 2px solid red;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@layer utilities {
|
|
64
|
+
/* Same specificity but higher layer - should win */
|
|
65
|
+
.specificity-test {
|
|
66
|
+
background-color: blue;
|
|
67
|
+
border: 2px solid blue;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* Layer inheritance test */
|
|
72
|
+
@layer components {
|
|
73
|
+
.inheritance-test {
|
|
74
|
+
color: red;
|
|
75
|
+
font-size: 16px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.inheritance-test .child {
|
|
79
|
+
/* Inherits color from parent */
|
|
80
|
+
font-weight: bold;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@layer utilities {
|
|
85
|
+
.inheritance-test {
|
|
86
|
+
color: blue; /* Should override components layer */
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Media query layer test */
|
|
91
|
+
@layer components {
|
|
92
|
+
.responsive-layer-test {
|
|
93
|
+
background-color: red;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@media (max-width: 768px) {
|
|
97
|
+
.responsive-layer-test {
|
|
98
|
+
background-color: orange;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@layer utilities {
|
|
104
|
+
.responsive-layer-test {
|
|
105
|
+
background-color: blue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@media (max-width: 768px) {
|
|
109
|
+
.responsive-layer-test {
|
|
110
|
+
background-color: green; /* Should win in mobile */
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Validation diagnostic styles */
|
|
116
|
+
.layer-diagnostic {
|
|
117
|
+
position: fixed;
|
|
118
|
+
top: 10px;
|
|
119
|
+
right: 10px;
|
|
120
|
+
background: white;
|
|
121
|
+
border: 2px solid #ccc;
|
|
122
|
+
padding: 10px;
|
|
123
|
+
font-family: monospace;
|
|
124
|
+
font-size: 12px;
|
|
125
|
+
z-index: 9999;
|
|
126
|
+
border-radius: 4px;
|
|
127
|
+
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
128
|
+
max-width: 300px;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.layer-diagnostic h3 {
|
|
132
|
+
margin: 0 0 10px 0;
|
|
133
|
+
font-size: 14px;
|
|
134
|
+
color: #333;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.layer-diagnostic .test-result {
|
|
138
|
+
margin: 5px 0;
|
|
139
|
+
padding: 3px;
|
|
140
|
+
border-radius: 2px;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.layer-diagnostic .test-result.pass {
|
|
144
|
+
background-color: #d4edda;
|
|
145
|
+
color: #155724;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.layer-diagnostic .test-result.fail {
|
|
149
|
+
background-color: #f8d7da;
|
|
150
|
+
color: #721c24;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* Hidden test elements */
|
|
154
|
+
.layer-test,
|
|
155
|
+
.specificity-test,
|
|
156
|
+
.inheritance-test,
|
|
157
|
+
.responsive-layer-test {
|
|
158
|
+
display: none !important;
|
|
159
|
+
}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS Layers Validation Tool
|
|
3
|
+
* Tests cascade order and specificity control in CSS layers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Test if CSS layers are working correctly
|
|
8
|
+
* @returns {Object} Test results
|
|
9
|
+
*/
|
|
10
|
+
export function validateCSSLayers() {
|
|
11
|
+
const results = {
|
|
12
|
+
layerOrder: testLayerOrder(),
|
|
13
|
+
specificity: testSpecificity(),
|
|
14
|
+
inheritance: testInheritance(),
|
|
15
|
+
responsive: testResponsiveOrder(),
|
|
16
|
+
summary: null
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Calculate summary
|
|
20
|
+
const totalTests = Object.values(results).reduce((acc, testGroup) => {
|
|
21
|
+
if (testGroup && typeof testGroup === 'object' && testGroup.tests) {
|
|
22
|
+
return acc + testGroup.tests.length;
|
|
23
|
+
}
|
|
24
|
+
return acc;
|
|
25
|
+
}, 0);
|
|
26
|
+
|
|
27
|
+
const passedTests = Object.values(results).reduce((acc, testGroup) => {
|
|
28
|
+
if (testGroup && typeof testGroup === 'object' && testGroup.tests) {
|
|
29
|
+
return acc + testGroup.tests.filter(test => test.passed).length;
|
|
30
|
+
}
|
|
31
|
+
return acc;
|
|
32
|
+
}, 0);
|
|
33
|
+
|
|
34
|
+
results.summary = {
|
|
35
|
+
total: totalTests,
|
|
36
|
+
passed: passedTests,
|
|
37
|
+
failed: totalTests - passedTests,
|
|
38
|
+
percentage: totalTests > 0 ? Math.round((passedTests / totalTests) * 100) : 0
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return results;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Test layer cascade order
|
|
46
|
+
*/
|
|
47
|
+
function testLayerOrder() {
|
|
48
|
+
const tests = [];
|
|
49
|
+
|
|
50
|
+
// Create test element
|
|
51
|
+
const testElement = document.createElement('div');
|
|
52
|
+
testElement.className = 'layer-test';
|
|
53
|
+
testElement.style.position = 'absolute';
|
|
54
|
+
testElement.style.visibility = 'hidden';
|
|
55
|
+
document.body.appendChild(testElement);
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const computedStyle = window.getComputedStyle(testElement);
|
|
59
|
+
const backgroundColor = computedStyle.backgroundColor;
|
|
60
|
+
const content = computedStyle.content;
|
|
61
|
+
|
|
62
|
+
// Test that overrides layer wins (purple background)
|
|
63
|
+
tests.push({
|
|
64
|
+
name: 'Layer order - overrides wins',
|
|
65
|
+
passed: backgroundColor === 'rgb(128, 0, 128)' || backgroundColor === 'purple',
|
|
66
|
+
expected: 'purple background from overrides layer',
|
|
67
|
+
actual: backgroundColor
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
tests.push({
|
|
71
|
+
name: 'Layer content property',
|
|
72
|
+
passed: content === '"overrides"',
|
|
73
|
+
expected: '"overrides"',
|
|
74
|
+
actual: content
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
} catch (error) {
|
|
78
|
+
tests.push({
|
|
79
|
+
name: 'Layer order test',
|
|
80
|
+
passed: false,
|
|
81
|
+
expected: 'No errors',
|
|
82
|
+
actual: error.message
|
|
83
|
+
});
|
|
84
|
+
} finally {
|
|
85
|
+
document.body.removeChild(testElement);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
category: 'Layer Order',
|
|
90
|
+
tests
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Test specificity within layers
|
|
96
|
+
*/
|
|
97
|
+
function testSpecificity() {
|
|
98
|
+
const tests = [];
|
|
99
|
+
|
|
100
|
+
const testElement = document.createElement('div');
|
|
101
|
+
testElement.className = 'specificity-test';
|
|
102
|
+
testElement.style.position = 'absolute';
|
|
103
|
+
testElement.style.visibility = 'hidden';
|
|
104
|
+
document.body.appendChild(testElement);
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const computedStyle = window.getComputedStyle(testElement);
|
|
108
|
+
const backgroundColor = computedStyle.backgroundColor;
|
|
109
|
+
|
|
110
|
+
// Test that utilities layer wins over components layer
|
|
111
|
+
tests.push({
|
|
112
|
+
name: 'Specificity - utilities over components',
|
|
113
|
+
passed: backgroundColor === 'rgb(0, 0, 255)' || backgroundColor === 'blue',
|
|
114
|
+
expected: 'blue background from utilities layer',
|
|
115
|
+
actual: backgroundColor
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
} catch (error) {
|
|
119
|
+
tests.push({
|
|
120
|
+
name: 'Specificity test',
|
|
121
|
+
passed: false,
|
|
122
|
+
expected: 'No errors',
|
|
123
|
+
actual: error.message
|
|
124
|
+
});
|
|
125
|
+
} finally {
|
|
126
|
+
document.body.removeChild(testElement);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
category: 'Specificity',
|
|
131
|
+
tests
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Test inheritance within layers
|
|
137
|
+
*/
|
|
138
|
+
function testInheritance() {
|
|
139
|
+
const tests = [];
|
|
140
|
+
|
|
141
|
+
const parentElement = document.createElement('div');
|
|
142
|
+
parentElement.className = 'inheritance-test';
|
|
143
|
+
const childElement = document.createElement('div');
|
|
144
|
+
childElement.className = 'child';
|
|
145
|
+
parentElement.appendChild(childElement);
|
|
146
|
+
|
|
147
|
+
parentElement.style.position = 'absolute';
|
|
148
|
+
parentElement.style.visibility = 'hidden';
|
|
149
|
+
document.body.appendChild(parentElement);
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
const parentStyle = window.getComputedStyle(parentElement);
|
|
153
|
+
const childStyle = window.getComputedStyle(childElement);
|
|
154
|
+
|
|
155
|
+
// Test that utilities layer color overrides components layer
|
|
156
|
+
tests.push({
|
|
157
|
+
name: 'Layer inheritance - parent color',
|
|
158
|
+
passed: parentStyle.color === 'rgb(0, 0, 255)' || parentStyle.color === 'blue',
|
|
159
|
+
expected: 'blue color from utilities layer',
|
|
160
|
+
actual: parentStyle.color
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Test that child inherits the overridden color
|
|
164
|
+
tests.push({
|
|
165
|
+
name: 'Layer inheritance - child inherits',
|
|
166
|
+
passed: childStyle.color === 'rgb(0, 0, 255)' || childStyle.color === 'blue',
|
|
167
|
+
expected: 'inherited blue color',
|
|
168
|
+
actual: childStyle.color
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
} catch (error) {
|
|
172
|
+
tests.push({
|
|
173
|
+
name: 'Inheritance test',
|
|
174
|
+
passed: false,
|
|
175
|
+
expected: 'No errors',
|
|
176
|
+
actual: error.message
|
|
177
|
+
});
|
|
178
|
+
} finally {
|
|
179
|
+
document.body.removeChild(parentElement);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
category: 'Inheritance',
|
|
184
|
+
tests
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Test responsive behavior within layers
|
|
190
|
+
*/
|
|
191
|
+
function testResponsiveOrder() {
|
|
192
|
+
const tests = [];
|
|
193
|
+
|
|
194
|
+
const testElement = document.createElement('div');
|
|
195
|
+
testElement.className = 'responsive-layer-test';
|
|
196
|
+
testElement.style.position = 'absolute';
|
|
197
|
+
testElement.style.visibility = 'hidden';
|
|
198
|
+
document.body.appendChild(testElement);
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
const computedStyle = window.getComputedStyle(testElement);
|
|
202
|
+
const backgroundColor = computedStyle.backgroundColor;
|
|
203
|
+
|
|
204
|
+
// Test that utilities layer wins in responsive context
|
|
205
|
+
if (window.innerWidth <= 768) {
|
|
206
|
+
tests.push({
|
|
207
|
+
name: 'Responsive layers - mobile utilities win',
|
|
208
|
+
passed: backgroundColor === 'rgb(0, 128, 0)' || backgroundColor === 'green',
|
|
209
|
+
expected: 'green background from utilities layer',
|
|
210
|
+
actual: backgroundColor
|
|
211
|
+
});
|
|
212
|
+
} else {
|
|
213
|
+
tests.push({
|
|
214
|
+
name: 'Responsive layers - desktop utilities win',
|
|
215
|
+
passed: backgroundColor === 'rgb(0, 0, 255)' || backgroundColor === 'blue',
|
|
216
|
+
expected: 'blue background from utilities layer',
|
|
217
|
+
actual: backgroundColor
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
} catch (error) {
|
|
222
|
+
tests.push({
|
|
223
|
+
name: 'Responsive layer test',
|
|
224
|
+
passed: false,
|
|
225
|
+
expected: 'No errors',
|
|
226
|
+
actual: error.message
|
|
227
|
+
});
|
|
228
|
+
} finally {
|
|
229
|
+
document.body.removeChild(testElement);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return {
|
|
233
|
+
category: 'Responsive',
|
|
234
|
+
tests
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Generate a visual report of layer validation
|
|
240
|
+
* @param {Object} results - Validation results
|
|
241
|
+
* @returns {HTMLElement} Report element
|
|
242
|
+
*/
|
|
243
|
+
export function generateLayerReport(results) {
|
|
244
|
+
const reportElement = document.createElement('div');
|
|
245
|
+
reportElement.className = 'layer-diagnostic';
|
|
246
|
+
|
|
247
|
+
const title = document.createElement('h3');
|
|
248
|
+
title.textContent = `CSS Layers Validation (${results.summary.passed}/${results.summary.total} passed)`;
|
|
249
|
+
reportElement.appendChild(title);
|
|
250
|
+
|
|
251
|
+
// Add overall status
|
|
252
|
+
const overallStatus = document.createElement('div');
|
|
253
|
+
overallStatus.className = `test-result ${results.summary.percentage >= 80 ? 'pass' : 'fail'}`;
|
|
254
|
+
overallStatus.textContent = `Overall: ${results.summary.percentage}% passed`;
|
|
255
|
+
reportElement.appendChild(overallStatus);
|
|
256
|
+
|
|
257
|
+
// Add category results
|
|
258
|
+
Object.values(results).forEach(category => {
|
|
259
|
+
if (category && category.category && category.tests) {
|
|
260
|
+
const categoryDiv = document.createElement('div');
|
|
261
|
+
categoryDiv.style.marginTop = '10px';
|
|
262
|
+
categoryDiv.innerHTML = `<strong>${category.category}:</strong>`;
|
|
263
|
+
reportElement.appendChild(categoryDiv);
|
|
264
|
+
|
|
265
|
+
category.tests.forEach(test => {
|
|
266
|
+
const testDiv = document.createElement('div');
|
|
267
|
+
testDiv.className = `test-result ${test.passed ? 'pass' : 'fail'}`;
|
|
268
|
+
testDiv.textContent = `${test.passed ? '✓' : '✗'} ${test.name}`;
|
|
269
|
+
if (!test.passed) {
|
|
270
|
+
testDiv.title = `Expected: ${test.expected}, Got: ${test.actual}`;
|
|
271
|
+
}
|
|
272
|
+
reportElement.appendChild(testDiv);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
return reportElement;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Run validation and display results
|
|
282
|
+
*/
|
|
283
|
+
export function runLayerValidation() {
|
|
284
|
+
const results = validateCSSLayers();
|
|
285
|
+
const report = generateLayerReport(results);
|
|
286
|
+
|
|
287
|
+
// Remove existing report
|
|
288
|
+
const existingReport = document.querySelector('.layer-diagnostic');
|
|
289
|
+
if (existingReport) {
|
|
290
|
+
existingReport.remove();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Add new report
|
|
294
|
+
document.body.appendChild(report);
|
|
295
|
+
|
|
296
|
+
// Auto-remove after 10 seconds
|
|
297
|
+
setTimeout(() => {
|
|
298
|
+
if (report.parentNode) {
|
|
299
|
+
report.parentNode.removeChild(report);
|
|
300
|
+
}
|
|
301
|
+
}, 10000);
|
|
302
|
+
|
|
303
|
+
return results;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Auto-run validation if in development mode
|
|
307
|
+
if (process.env.NODE_ENV === 'development') {
|
|
308
|
+
// Run validation after a short delay to ensure CSS is loaded
|
|
309
|
+
setTimeout(runLayerValidation, 1000);
|
|
310
|
+
}
|