@abstraks-dev/ui-library 1.0.1
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/LICENSE +21 -0
- package/README.md +708 -0
- package/dist/__tests__/Anchor.test.js +145 -0
- package/dist/__tests__/ArrowRight.test.js +91 -0
- package/dist/__tests__/Avatar.test.js +123 -0
- package/dist/__tests__/Button.test.js +82 -0
- package/dist/__tests__/Card.test.js +198 -0
- package/dist/__tests__/CheckCircle.test.js +98 -0
- package/dist/__tests__/Checkbox.test.js +161 -0
- package/dist/__tests__/ChevronDown.test.js +73 -0
- package/dist/__tests__/Close.test.js +98 -0
- package/dist/__tests__/EditSquare.test.js +99 -0
- package/dist/__tests__/Error.test.js +74 -0
- package/dist/__tests__/Footer.test.js +66 -0
- package/dist/__tests__/Heading.test.js +227 -0
- package/dist/__tests__/Hero.test.js +74 -0
- package/dist/__tests__/Label.test.js +123 -0
- package/dist/__tests__/Loader.test.js +115 -0
- package/dist/__tests__/MenuHover.test.js +137 -0
- package/dist/__tests__/Paragraph.test.js +93 -0
- package/dist/__tests__/PlusCircle.test.js +99 -0
- package/dist/__tests__/Radio.test.js +153 -0
- package/dist/__tests__/Select.test.js +187 -0
- package/dist/__tests__/Tabs.test.js +162 -0
- package/dist/__tests__/TextArea.test.js +127 -0
- package/dist/__tests__/TextInput.test.js +181 -0
- package/dist/__tests__/Toggle.test.js +120 -0
- package/dist/__tests__/TrashX.test.js +99 -0
- package/dist/__tests__/useHeadingAccessibility.test.js +144 -0
- package/dist/components/Anchor.js +131 -0
- package/dist/components/Animation.js +129 -0
- package/dist/components/AnimationGroup.js +207 -0
- package/dist/components/AnimationToggle.js +216 -0
- package/dist/components/Avatar.js +153 -0
- package/dist/components/Button.js +218 -0
- package/dist/components/Card.js +222 -0
- package/dist/components/Checkbox.js +305 -0
- package/dist/components/Crud.js +564 -0
- package/dist/components/DragAndDrop.js +337 -0
- package/dist/components/Error.js +206 -0
- package/dist/components/Footer.js +99 -0
- package/dist/components/Form.js +412 -0
- package/dist/components/Header.js +372 -0
- package/dist/components/Heading.js +134 -0
- package/dist/components/Hero.js +181 -0
- package/dist/components/Label.js +256 -0
- package/dist/components/Loader.js +302 -0
- package/dist/components/MenuHover.js +114 -0
- package/dist/components/Paragraph.js +128 -0
- package/dist/components/Prompt.js +61 -0
- package/dist/components/Radio.js +254 -0
- package/dist/components/Select.js +422 -0
- package/dist/components/SideMenu.js +313 -0
- package/dist/components/Tabs.js +297 -0
- package/dist/components/TextArea.js +370 -0
- package/dist/components/TextInput.js +286 -0
- package/dist/components/Toggle.js +186 -0
- package/dist/components/crudFiles/CrudEditBase.js +150 -0
- package/dist/components/crudFiles/CrudViewBase.js +39 -0
- package/dist/components/crudFiles/crudDevelopment.js +118 -0
- package/dist/components/crudFiles/crudEditHandlers.js +50 -0
- package/dist/constants/animation.js +30 -0
- package/dist/icons/ArrowIcon.js +32 -0
- package/dist/icons/ArrowRight.js +33 -0
- package/dist/icons/CheckCircle.js +33 -0
- package/dist/icons/ChevronDown.js +28 -0
- package/dist/icons/Close.js +33 -0
- package/dist/icons/EditSquare.js +33 -0
- package/dist/icons/Ellipses.js +34 -0
- package/dist/icons/Hamburger.js +39 -0
- package/dist/icons/LoadingSpinner.js +42 -0
- package/dist/icons/PlusCircle.js +33 -0
- package/dist/icons/SaveIcon.js +32 -0
- package/dist/icons/TrashX.js +33 -0
- package/dist/icons/__tests__/CheckCircle.test.js +9 -0
- package/dist/icons/__tests__/ChevronDown.test.js +9 -0
- package/dist/icons/__tests__/Close.test.js +9 -0
- package/dist/icons/__tests__/EditSquare.test.js +9 -0
- package/dist/icons/__tests__/PlusCircle.test.js +9 -0
- package/dist/icons/__tests__/TrashX.test.js +9 -0
- package/dist/icons/index.js +89 -0
- package/dist/index.js +332 -0
- package/dist/setupTests.js +3 -0
- package/dist/styles/_variables.scss +286 -0
- package/dist/styles/anchor.scss +40 -0
- package/dist/styles/animation-accessibility.scss +96 -0
- package/dist/styles/animation-toggle.scss +233 -0
- package/dist/styles/animation.scss +3781 -0
- package/dist/styles/avatar.scss +285 -0
- package/dist/styles/button.scss +430 -0
- package/dist/styles/card.scss +210 -0
- package/dist/styles/checkbox.scss +160 -0
- package/dist/styles/crud.scss +474 -0
- package/dist/styles/dragAndDrop.scss +312 -0
- package/dist/styles/error.scss +232 -0
- package/dist/styles/footer.scss +58 -0
- package/dist/styles/form.scss +420 -0
- package/dist/styles/grid.scss +29 -0
- package/dist/styles/header.scss +276 -0
- package/dist/styles/heading.scss +118 -0
- package/dist/styles/hero.scss +185 -0
- package/dist/styles/htmlElements.scss +20 -0
- package/dist/styles/image.scss +9 -0
- package/dist/styles/label.scss +340 -0
- package/dist/styles/list-item.scss +5 -0
- package/dist/styles/loader.scss +354 -0
- package/dist/styles/logo.scss +19 -0
- package/dist/styles/main.css +9056 -0
- package/dist/styles/main.css.map +1 -0
- package/dist/styles/main.scss +0 -0
- package/dist/styles/menu-hover.scss +30 -0
- package/dist/styles/paragraph.scss +88 -0
- package/dist/styles/prompt.scss +51 -0
- package/dist/styles/radio.scss +202 -0
- package/dist/styles/select.scss +363 -0
- package/dist/styles/side-menu.scss +334 -0
- package/dist/styles/tabs.scss +540 -0
- package/dist/styles/text-area.scss +388 -0
- package/dist/styles/text-input.scss +171 -0
- package/dist/styles/toggle.scss +0 -0
- package/dist/styles/unordered-list.scss +8 -0
- package/dist/utils/ScrollHandler.js +30 -0
- package/dist/utils/accessibility.js +128 -0
- package/dist/utils/heroUtils.js +316 -0
- package/dist/utils/index.js +104 -0
- package/dist/utils/inputValidation.js +29 -0
- package/dist/utils/keyboardNavigation.js +536 -0
- package/dist/utils/labelUtils.js +708 -0
- package/dist/utils/loaderUtils.js +387 -0
- package/dist/utils/menuUtils.js +575 -0
- package/dist/utils/useHeadingAccessibility.js +298 -0
- package/dist/utils/useRadioGroup.js +260 -0
- package/dist/utils/useSelectAccessibility.js +426 -0
- package/dist/utils/useTabsAccessibility.js +278 -0
- package/dist/utils/useTextAreaAccessibility.js +255 -0
- package/dist/utils/useTextInputAccessibility.js +295 -0
- package/dist/utils/useTypographyAccessibility.js +168 -0
- package/dist/utils/useWindowSize.js +32 -0
- package/dist/utils/utils/ScrollHandler.js +26 -0
- package/dist/utils/utils/accessibility.js +133 -0
- package/dist/utils/utils/heroUtils.js +348 -0
- package/dist/utils/utils/index.js +9 -0
- package/dist/utils/utils/inputValidation.js +22 -0
- package/dist/utils/utils/keyboardNavigation.js +664 -0
- package/dist/utils/utils/labelUtils.js +772 -0
- package/dist/utils/utils/loaderUtils.js +436 -0
- package/dist/utils/utils/menuUtils.js +651 -0
- package/dist/utils/utils/useHeadingAccessibility.js +334 -0
- package/dist/utils/utils/useRadioGroup.js +311 -0
- package/dist/utils/utils/useSelectAccessibility.js +498 -0
- package/dist/utils/utils/useTabsAccessibility.js +316 -0
- package/dist/utils/utils/useTextAreaAccessibility.js +303 -0
- package/dist/utils/utils/useTextInputAccessibility.js +338 -0
- package/dist/utils/utils/useTypographyAccessibility.js +180 -0
- package/dist/utils/utils/useWindowSize.js +26 -0
- package/dist/utils/utils/validation.js +131 -0
- package/dist/utils/validation.js +139 -0
- package/package.json +90 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.validateHeroAccessibility = exports.useResponsiveHeight = exports.useMotionPreference = exports.useHighContrast = exports.useBackgroundImage = exports.heroTestingUtils = exports.generateHeroAccessibility = exports.default = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
/**
|
|
9
|
+
* Hero Component Utilities
|
|
10
|
+
* Provides helper functions and hooks for Hero component functionality
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Hook to detect user's motion preference and apply appropriate settings
|
|
15
|
+
* @returns {Object} Motion preference settings
|
|
16
|
+
*/
|
|
17
|
+
const useMotionPreference = () => {
|
|
18
|
+
const [prefersReducedMotion, setPrefersReducedMotion] = (0, _react.useState)(false);
|
|
19
|
+
(0, _react.useEffect)(() => {
|
|
20
|
+
if (typeof window !== 'undefined') {
|
|
21
|
+
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
22
|
+
setPrefersReducedMotion(mediaQuery.matches);
|
|
23
|
+
const handleChange = e => {
|
|
24
|
+
setPrefersReducedMotion(e.matches);
|
|
25
|
+
};
|
|
26
|
+
mediaQuery.addEventListener('change', handleChange);
|
|
27
|
+
return () => mediaQuery.removeEventListener('change', handleChange);
|
|
28
|
+
}
|
|
29
|
+
}, []);
|
|
30
|
+
return {
|
|
31
|
+
prefersReducedMotion,
|
|
32
|
+
backgroundAttachment: prefersReducedMotion ? 'scroll' : 'fixed',
|
|
33
|
+
transitionDuration: prefersReducedMotion ? '0s' : '0.3s'
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Hook to detect high contrast mode preference
|
|
39
|
+
* @returns {boolean} Whether high contrast mode is enabled
|
|
40
|
+
*/
|
|
41
|
+
exports.useMotionPreference = useMotionPreference;
|
|
42
|
+
const useHighContrast = () => {
|
|
43
|
+
const [highContrast, setHighContrast] = (0, _react.useState)(false);
|
|
44
|
+
(0, _react.useEffect)(() => {
|
|
45
|
+
if (typeof window !== 'undefined') {
|
|
46
|
+
const mediaQuery = window.matchMedia('(prefers-contrast: high)');
|
|
47
|
+
setHighContrast(mediaQuery.matches);
|
|
48
|
+
const handleChange = e => {
|
|
49
|
+
setHighContrast(e.matches);
|
|
50
|
+
};
|
|
51
|
+
mediaQuery.addEventListener('change', handleChange);
|
|
52
|
+
return () => mediaQuery.removeEventListener('change', handleChange);
|
|
53
|
+
}
|
|
54
|
+
}, []);
|
|
55
|
+
return highContrast;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Hook for responsive hero height based on viewport
|
|
60
|
+
* @param {Object} options - Configuration options
|
|
61
|
+
* @param {string} options.minHeight - Minimum height (default: '400px')
|
|
62
|
+
* @param {string} options.maxHeight - Maximum height (default: '100vh')
|
|
63
|
+
* @returns {Object} Height settings and viewport info
|
|
64
|
+
*/
|
|
65
|
+
exports.useHighContrast = useHighContrast;
|
|
66
|
+
const useResponsiveHeight = ({
|
|
67
|
+
minHeight = '400px',
|
|
68
|
+
maxHeight = '100vh'
|
|
69
|
+
} = {}) => {
|
|
70
|
+
const [viewportHeight, setViewportHeight] = (0, _react.useState)(typeof window !== 'undefined' ? window.innerHeight : 800);
|
|
71
|
+
const [isMobile, setIsMobile] = (0, _react.useState)(false);
|
|
72
|
+
(0, _react.useEffect)(() => {
|
|
73
|
+
const updateHeight = () => {
|
|
74
|
+
setViewportHeight(window.innerHeight);
|
|
75
|
+
setIsMobile(window.innerWidth < 768);
|
|
76
|
+
};
|
|
77
|
+
updateHeight();
|
|
78
|
+
window.addEventListener('resize', updateHeight);
|
|
79
|
+
return () => window.removeEventListener('resize', updateHeight);
|
|
80
|
+
}, []);
|
|
81
|
+
const calculatedHeight = Math.max(parseInt(minHeight), Math.min(viewportHeight * 0.7, parseInt(maxHeight)));
|
|
82
|
+
return {
|
|
83
|
+
height: `${calculatedHeight}px`,
|
|
84
|
+
viewportHeight,
|
|
85
|
+
isMobile,
|
|
86
|
+
isLandscape: viewportHeight < window.innerWidth
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Hook for managing background image loading and optimization
|
|
92
|
+
* @param {string} imageUrl - URL of the background image
|
|
93
|
+
* @returns {Object} Image loading state and optimized URL
|
|
94
|
+
*/
|
|
95
|
+
exports.useResponsiveHeight = useResponsiveHeight;
|
|
96
|
+
const useBackgroundImage = imageUrl => {
|
|
97
|
+
const [isLoaded, setIsLoaded] = (0, _react.useState)(false);
|
|
98
|
+
const [hasError, setHasError] = (0, _react.useState)(false);
|
|
99
|
+
const [optimizedUrl, setOptimizedUrl] = (0, _react.useState)(imageUrl);
|
|
100
|
+
(0, _react.useEffect)(() => {
|
|
101
|
+
if (!imageUrl) return;
|
|
102
|
+
setIsLoaded(false);
|
|
103
|
+
setHasError(false);
|
|
104
|
+
const img = new Image();
|
|
105
|
+
img.onload = () => setIsLoaded(true);
|
|
106
|
+
img.onerror = () => setHasError(true);
|
|
107
|
+
img.src = imageUrl;
|
|
108
|
+
|
|
109
|
+
// Basic URL optimization for common image services
|
|
110
|
+
if (imageUrl.includes('unsplash.com')) {
|
|
111
|
+
const size = window.innerWidth > 1200 ? '2070' : window.innerWidth > 768 ? '1536' : '1024';
|
|
112
|
+
setOptimizedUrl(`${imageUrl}&w=${size}&auto=format&fit=crop&q=80`);
|
|
113
|
+
} else {
|
|
114
|
+
setOptimizedUrl(imageUrl);
|
|
115
|
+
}
|
|
116
|
+
}, [imageUrl]);
|
|
117
|
+
return {
|
|
118
|
+
isLoaded,
|
|
119
|
+
hasError,
|
|
120
|
+
optimizedUrl
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Generates accessible hero props based on content and configuration
|
|
126
|
+
* @param {Object} config - Configuration object
|
|
127
|
+
* @returns {Object} Accessibility props
|
|
128
|
+
*/
|
|
129
|
+
exports.useBackgroundImage = useBackgroundImage;
|
|
130
|
+
const generateHeroAccessibility = ({
|
|
131
|
+
hasHeading = true,
|
|
132
|
+
hasCallToAction = false,
|
|
133
|
+
isLandingPage = false,
|
|
134
|
+
customRole = null,
|
|
135
|
+
customLabel = null
|
|
136
|
+
}) => {
|
|
137
|
+
const role = customRole || (isLandingPage ? 'banner' : 'region');
|
|
138
|
+
const ariaLabel = customLabel || (hasCallToAction ? 'Hero section with call-to-action' : 'Hero content section');
|
|
139
|
+
const props = {
|
|
140
|
+
role,
|
|
141
|
+
'aria-label': ariaLabel
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// Add landmark navigation hints
|
|
145
|
+
if (hasHeading && !customLabel) {
|
|
146
|
+
delete props['aria-label']; // Let heading provide the label
|
|
147
|
+
}
|
|
148
|
+
return props;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Validates hero content for accessibility compliance
|
|
153
|
+
* @param {Object} content - Content configuration
|
|
154
|
+
* @returns {Array} Array of accessibility warnings
|
|
155
|
+
*/
|
|
156
|
+
exports.generateHeroAccessibility = generateHeroAccessibility;
|
|
157
|
+
const validateHeroAccessibility = ({
|
|
158
|
+
hasBackground = false,
|
|
159
|
+
backgroundAlt = '',
|
|
160
|
+
hasHeading = false,
|
|
161
|
+
headingLevel = null,
|
|
162
|
+
hasCallToAction = false,
|
|
163
|
+
textContrast = 'unknown'
|
|
164
|
+
}) => {
|
|
165
|
+
const warnings = [];
|
|
166
|
+
|
|
167
|
+
// Background image validation
|
|
168
|
+
if (hasBackground && !backgroundAlt) {
|
|
169
|
+
warnings.push({
|
|
170
|
+
type: 'error',
|
|
171
|
+
message: 'Background images must have alt text for accessibility',
|
|
172
|
+
recommendation: 'Add backgroundAlt prop with descriptive text'
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Heading validation
|
|
177
|
+
if (!hasHeading) {
|
|
178
|
+
warnings.push({
|
|
179
|
+
type: 'warning',
|
|
180
|
+
message: 'Hero sections should typically include a heading',
|
|
181
|
+
recommendation: 'Add an h1 or h2 element to provide section context'
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
if (hasHeading && headingLevel && headingLevel > 2) {
|
|
185
|
+
warnings.push({
|
|
186
|
+
type: 'warning',
|
|
187
|
+
message: `Hero heading level h${headingLevel} may be too deep`,
|
|
188
|
+
recommendation: 'Consider using h1 or h2 for hero sections'
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Call-to-action validation
|
|
193
|
+
if (hasCallToAction) {
|
|
194
|
+
warnings.push({
|
|
195
|
+
type: 'info',
|
|
196
|
+
message: 'Ensure CTA buttons have descriptive aria-label attributes',
|
|
197
|
+
recommendation: 'Use aria-label to describe the action, not just "Click here"'
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Contrast validation
|
|
202
|
+
if (hasBackground && textContrast === 'low') {
|
|
203
|
+
warnings.push({
|
|
204
|
+
type: 'error',
|
|
205
|
+
message: 'Text contrast may be insufficient over background image',
|
|
206
|
+
recommendation: 'Add overlay or adjust text colors to meet WCAG contrast requirements'
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return warnings;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Hero testing utilities for automated and manual testing
|
|
214
|
+
*/
|
|
215
|
+
exports.validateHeroAccessibility = validateHeroAccessibility;
|
|
216
|
+
const heroTestingUtils = exports.heroTestingUtils = {
|
|
217
|
+
/**
|
|
218
|
+
* Simulates keyboard navigation through hero content
|
|
219
|
+
*/
|
|
220
|
+
async simulateKeyboardNavigation() {
|
|
221
|
+
const focusableElements = document.querySelectorAll('[role="banner"] a, [role="banner"] button, [role="banner"] input, [role="banner"] [tabindex="0"]');
|
|
222
|
+
const results = [];
|
|
223
|
+
for (let element of focusableElements) {
|
|
224
|
+
element.focus();
|
|
225
|
+
const isVisible = this.isFocusVisible(element);
|
|
226
|
+
const hasAriaLabel = element.getAttribute('aria-label') || element.getAttribute('aria-labelledby');
|
|
227
|
+
results.push({
|
|
228
|
+
element: element.tagName,
|
|
229
|
+
isFocusVisible: isVisible,
|
|
230
|
+
hasAriaLabel: !!hasAriaLabel,
|
|
231
|
+
textContent: element.textContent?.trim().substring(0, 50)
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Small delay to simulate real user interaction
|
|
235
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
236
|
+
}
|
|
237
|
+
return results;
|
|
238
|
+
},
|
|
239
|
+
/**
|
|
240
|
+
* Checks if focus indicators are visible
|
|
241
|
+
*/
|
|
242
|
+
isFocusVisible(element) {
|
|
243
|
+
const styles = window.getComputedStyle(element, ':focus-visible');
|
|
244
|
+
return styles.outlineWidth !== '0px' || styles.boxShadow !== 'none';
|
|
245
|
+
},
|
|
246
|
+
/**
|
|
247
|
+
* Validates screen reader announcements
|
|
248
|
+
*/
|
|
249
|
+
validateScreenReaderContent() {
|
|
250
|
+
const hero = document.querySelector('[role="banner"], [role="region"]');
|
|
251
|
+
if (!hero) return {
|
|
252
|
+
valid: false,
|
|
253
|
+
message: 'No hero section found'
|
|
254
|
+
};
|
|
255
|
+
const hasAriaLabel = hero.getAttribute('aria-label') || hero.getAttribute('aria-labelledby');
|
|
256
|
+
const hasHeading = hero.querySelector('h1, h2, h3, h4, h5, h6');
|
|
257
|
+
const backgroundDescription = hero.querySelector('[id*="bg-description"]');
|
|
258
|
+
return {
|
|
259
|
+
valid: hasAriaLabel || hasHeading,
|
|
260
|
+
hasAriaLabel: !!hasAriaLabel,
|
|
261
|
+
hasHeading: !!hasHeading,
|
|
262
|
+
hasBackgroundDescription: !!backgroundDescription,
|
|
263
|
+
recommendations: [...(!(hasAriaLabel || hasHeading) ? ['Add aria-label or heading for screen readers'] : []), ...(!backgroundDescription && hero.style.backgroundImage ? ['Add background image description'] : [])]
|
|
264
|
+
};
|
|
265
|
+
},
|
|
266
|
+
/**
|
|
267
|
+
* Tests responsive behavior
|
|
268
|
+
*/
|
|
269
|
+
testResponsiveBehavior() {
|
|
270
|
+
const viewports = [{
|
|
271
|
+
width: 320,
|
|
272
|
+
height: 568,
|
|
273
|
+
name: 'Mobile Portrait'
|
|
274
|
+
}, {
|
|
275
|
+
width: 768,
|
|
276
|
+
height: 1024,
|
|
277
|
+
name: 'Tablet'
|
|
278
|
+
}, {
|
|
279
|
+
width: 1200,
|
|
280
|
+
height: 800,
|
|
281
|
+
name: 'Desktop'
|
|
282
|
+
}, {
|
|
283
|
+
width: 1920,
|
|
284
|
+
height: 1080,
|
|
285
|
+
name: 'Large Desktop'
|
|
286
|
+
}];
|
|
287
|
+
const hero = document.querySelector('.hero-wrapper');
|
|
288
|
+
if (!hero) return {
|
|
289
|
+
valid: false,
|
|
290
|
+
message: 'Hero wrapper not found'
|
|
291
|
+
};
|
|
292
|
+
const results = viewports.map(viewport => {
|
|
293
|
+
// Note: In real testing, you'd actually resize the viewport
|
|
294
|
+
// This is a simulation for documentation purposes
|
|
295
|
+
return {
|
|
296
|
+
viewport: viewport.name,
|
|
297
|
+
dimensions: `${viewport.width}x${viewport.height}`,
|
|
298
|
+
minHeight: window.getComputedStyle(hero).minHeight,
|
|
299
|
+
backgroundAttachment: window.getComputedStyle(hero).backgroundAttachment
|
|
300
|
+
};
|
|
301
|
+
});
|
|
302
|
+
return {
|
|
303
|
+
valid: true,
|
|
304
|
+
results
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
var _default = exports.default = {
|
|
309
|
+
useMotionPreference,
|
|
310
|
+
useHighContrast,
|
|
311
|
+
useResponsiveHeight,
|
|
312
|
+
useBackgroundImage,
|
|
313
|
+
generateHeroAccessibility,
|
|
314
|
+
validateHeroAccessibility,
|
|
315
|
+
heroTestingUtils
|
|
316
|
+
};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _ScrollHandler = require("./ScrollHandler");
|
|
7
|
+
Object.keys(_ScrollHandler).forEach(function (key) {
|
|
8
|
+
if (key === "default" || key === "__esModule") return;
|
|
9
|
+
if (key in exports && exports[key] === _ScrollHandler[key]) return;
|
|
10
|
+
Object.defineProperty(exports, key, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () {
|
|
13
|
+
return _ScrollHandler[key];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
var _useWindowSize = require("./useWindowSize");
|
|
18
|
+
Object.keys(_useWindowSize).forEach(function (key) {
|
|
19
|
+
if (key === "default" || key === "__esModule") return;
|
|
20
|
+
if (key in exports && exports[key] === _useWindowSize[key]) return;
|
|
21
|
+
Object.defineProperty(exports, key, {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
get: function () {
|
|
24
|
+
return _useWindowSize[key];
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
var _accessibility = require("./accessibility");
|
|
29
|
+
Object.keys(_accessibility).forEach(function (key) {
|
|
30
|
+
if (key === "default" || key === "__esModule") return;
|
|
31
|
+
if (key in exports && exports[key] === _accessibility[key]) return;
|
|
32
|
+
Object.defineProperty(exports, key, {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
get: function () {
|
|
35
|
+
return _accessibility[key];
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
var _validation = require("./validation");
|
|
40
|
+
Object.keys(_validation).forEach(function (key) {
|
|
41
|
+
if (key === "default" || key === "__esModule") return;
|
|
42
|
+
if (key in exports && exports[key] === _validation[key]) return;
|
|
43
|
+
Object.defineProperty(exports, key, {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
get: function () {
|
|
46
|
+
return _validation[key];
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
var _keyboardNavigation = require("./keyboardNavigation");
|
|
51
|
+
Object.keys(_keyboardNavigation).forEach(function (key) {
|
|
52
|
+
if (key === "default" || key === "__esModule") return;
|
|
53
|
+
if (key in exports && exports[key] === _keyboardNavigation[key]) return;
|
|
54
|
+
Object.defineProperty(exports, key, {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function () {
|
|
57
|
+
return _keyboardNavigation[key];
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
var _useHeadingAccessibility = require("./useHeadingAccessibility");
|
|
62
|
+
Object.keys(_useHeadingAccessibility).forEach(function (key) {
|
|
63
|
+
if (key === "default" || key === "__esModule") return;
|
|
64
|
+
if (key in exports && exports[key] === _useHeadingAccessibility[key]) return;
|
|
65
|
+
Object.defineProperty(exports, key, {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
get: function () {
|
|
68
|
+
return _useHeadingAccessibility[key];
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
var _useTypographyAccessibility = require("./useTypographyAccessibility");
|
|
73
|
+
Object.keys(_useTypographyAccessibility).forEach(function (key) {
|
|
74
|
+
if (key === "default" || key === "__esModule") return;
|
|
75
|
+
if (key in exports && exports[key] === _useTypographyAccessibility[key]) return;
|
|
76
|
+
Object.defineProperty(exports, key, {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
get: function () {
|
|
79
|
+
return _useTypographyAccessibility[key];
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
var _useRadioGroup = require("./useRadioGroup");
|
|
84
|
+
Object.keys(_useRadioGroup).forEach(function (key) {
|
|
85
|
+
if (key === "default" || key === "__esModule") return;
|
|
86
|
+
if (key in exports && exports[key] === _useRadioGroup[key]) return;
|
|
87
|
+
Object.defineProperty(exports, key, {
|
|
88
|
+
enumerable: true,
|
|
89
|
+
get: function () {
|
|
90
|
+
return _useRadioGroup[key];
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
var _useSelectAccessibility = require("./useSelectAccessibility");
|
|
95
|
+
Object.keys(_useSelectAccessibility).forEach(function (key) {
|
|
96
|
+
if (key === "default" || key === "__esModule") return;
|
|
97
|
+
if (key in exports && exports[key] === _useSelectAccessibility[key]) return;
|
|
98
|
+
Object.defineProperty(exports, key, {
|
|
99
|
+
enumerable: true,
|
|
100
|
+
get: function () {
|
|
101
|
+
return _useSelectAccessibility[key];
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.validateEmail = validateEmail;
|
|
7
|
+
exports.validateLength = validateLength;
|
|
8
|
+
exports.validatePhone = validatePhone;
|
|
9
|
+
exports.validateRequired = validateRequired;
|
|
10
|
+
var _isEmail = _interopRequireDefault(require("validator/lib/isEmail"));
|
|
11
|
+
var _libphonenumberJs = require("libphonenumber-js");
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
// inputValidation.js
|
|
14
|
+
// Utility functions for input validation
|
|
15
|
+
|
|
16
|
+
function validateEmail(value) {
|
|
17
|
+
return (0, _isEmail.default)(value);
|
|
18
|
+
}
|
|
19
|
+
function validatePhone(value, country = 'US') {
|
|
20
|
+
return (0, _libphonenumberJs.isValidPhoneNumber)(value, country);
|
|
21
|
+
}
|
|
22
|
+
function validateLength(value, minLength, maxLength) {
|
|
23
|
+
if (minLength && value.length < minLength) return false;
|
|
24
|
+
if (maxLength && value.length > maxLength) return false;
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
function validateRequired(value) {
|
|
28
|
+
return value.trim().length > 0;
|
|
29
|
+
}
|