chore: remove accessibility utility functions from accessibilityUtils.js as they are no longer needed
This commit is contained in:
@@ -1,221 +0,0 @@
|
|||||||
// Accessibility utility functions for ensuring proper button labels
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if all IconButtons on the page have proper aria-labels
|
|
||||||
* This function can be called in development to identify missing labels
|
|
||||||
*/
|
|
||||||
export const validateIconButtonAccessibility = () => {
|
|
||||||
if (process.env.NODE_ENV !== 'development') return;
|
|
||||||
|
|
||||||
// Find all IconButton elements
|
|
||||||
const iconButtons = document.querySelectorAll('[class*="MuiIconButton"]');
|
|
||||||
const missingLabels = [];
|
|
||||||
|
|
||||||
iconButtons.forEach((button, index) => {
|
|
||||||
const hasAriaLabel = button.hasAttribute('aria-label');
|
|
||||||
const hasAriaLabelledBy = button.hasAttribute('aria-labelledby');
|
|
||||||
const hasTitle = button.hasAttribute('title');
|
|
||||||
const isInTooltip = button.closest('[role="tooltip"]') !== null;
|
|
||||||
|
|
||||||
// Check if button has any form of accessible name
|
|
||||||
if (!hasAriaLabel && !hasAriaLabelledBy && !hasTitle && !isInTooltip) {
|
|
||||||
missingLabels.push({
|
|
||||||
element: button,
|
|
||||||
index,
|
|
||||||
classes: button.className,
|
|
||||||
parentElement: button.parentElement?.tagName,
|
|
||||||
parentClasses: button.parentElement?.className
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (missingLabels.length > 0) {
|
|
||||||
console.warn('IconButtons missing accessibility labels:', missingLabels);
|
|
||||||
return missingLabels;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('✅ All IconButtons have proper accessibility labels');
|
|
||||||
return [];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if all images on the page have proper alt attributes
|
|
||||||
* This function can be called in development to identify missing alt text
|
|
||||||
*/
|
|
||||||
export const validateImageAccessibility = () => {
|
|
||||||
if (process.env.NODE_ENV !== 'development') return;
|
|
||||||
|
|
||||||
// Find all img elements
|
|
||||||
const images = document.querySelectorAll('img');
|
|
||||||
const missingAltText = [];
|
|
||||||
|
|
||||||
images.forEach((img, index) => {
|
|
||||||
const hasAlt = img.hasAttribute('alt');
|
|
||||||
const altValue = img.getAttribute('alt');
|
|
||||||
const isDecorative = altValue === '';
|
|
||||||
const src = img.src;
|
|
||||||
|
|
||||||
// Check if image has alt attribute
|
|
||||||
if (!hasAlt) {
|
|
||||||
missingAltText.push({
|
|
||||||
element: img,
|
|
||||||
index,
|
|
||||||
src: src,
|
|
||||||
classes: img.className,
|
|
||||||
parentElement: img.parentElement?.tagName,
|
|
||||||
parentClasses: img.parentElement?.className,
|
|
||||||
issue: 'Missing alt attribute'
|
|
||||||
});
|
|
||||||
} else if (altValue && altValue.trim() === '' && !isDecorative) {
|
|
||||||
// Empty alt text for non-decorative images
|
|
||||||
missingAltText.push({
|
|
||||||
element: img,
|
|
||||||
index,
|
|
||||||
src: src,
|
|
||||||
classes: img.className,
|
|
||||||
parentElement: img.parentElement?.tagName,
|
|
||||||
parentClasses: img.parentElement?.className,
|
|
||||||
issue: 'Empty alt text for informative image'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (missingAltText.length > 0) {
|
|
||||||
console.warn('Images missing accessibility alt text:', missingAltText);
|
|
||||||
return missingAltText;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('✅ All images have proper alt attributes');
|
|
||||||
return [];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Automatically adds alt attributes to images that are missing them
|
|
||||||
* This is a fallback solution for development
|
|
||||||
*/
|
|
||||||
export const addFallbackAltText = () => {
|
|
||||||
if (process.env.NODE_ENV !== 'development') return;
|
|
||||||
|
|
||||||
const images = document.querySelectorAll('img:not([alt])');
|
|
||||||
|
|
||||||
images.forEach((img) => {
|
|
||||||
const src = img.src || '';
|
|
||||||
let fallbackAlt = 'Bild';
|
|
||||||
|
|
||||||
// Try to determine alt text from src or context
|
|
||||||
if (src.includes('prod')) {
|
|
||||||
fallbackAlt = 'Produktbild';
|
|
||||||
} else if (src.includes('cat')) {
|
|
||||||
fallbackAlt = 'Kategoriebild';
|
|
||||||
} else if (src.includes('logo')) {
|
|
||||||
fallbackAlt = 'Logo';
|
|
||||||
} else if (src.includes('nopicture')) {
|
|
||||||
fallbackAlt = 'Kein Bild verfügbar';
|
|
||||||
} else if (src.includes('404')) {
|
|
||||||
fallbackAlt = '404 - Seite nicht gefunden';
|
|
||||||
} else if (src.includes('seeds')) {
|
|
||||||
fallbackAlt = 'Seeds';
|
|
||||||
} else if (src.includes('cutlings')) {
|
|
||||||
fallbackAlt = 'Stecklinge';
|
|
||||||
} else if (src.includes('filiale')) {
|
|
||||||
fallbackAlt = 'Filiale';
|
|
||||||
} else if (src.includes('presse')) {
|
|
||||||
fallbackAlt = 'Presse';
|
|
||||||
}
|
|
||||||
|
|
||||||
img.setAttribute('alt', fallbackAlt);
|
|
||||||
console.warn(`Added fallback alt text "${fallbackAlt}" to image:`, img);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Automatically adds aria-labels to IconButtons that are missing them
|
|
||||||
* This is a fallback solution for development
|
|
||||||
*/
|
|
||||||
export const addFallbackAriaLabels = () => {
|
|
||||||
if (process.env.NODE_ENV !== 'development') return;
|
|
||||||
|
|
||||||
const iconButtons = document.querySelectorAll('[class*="MuiIconButton"]:not([aria-label]):not([aria-labelledby]):not([title])');
|
|
||||||
|
|
||||||
iconButtons.forEach((button) => {
|
|
||||||
// Try to determine button function from context
|
|
||||||
const icon = button.querySelector('[class*="MuiSvgIcon"]');
|
|
||||||
const iconClass = icon?.className || '';
|
|
||||||
|
|
||||||
let fallbackLabel = 'Button';
|
|
||||||
|
|
||||||
// Determine label based on icon type or context
|
|
||||||
if (iconClass.includes('Close')) {
|
|
||||||
fallbackLabel = 'Schließen';
|
|
||||||
} else if (iconClass.includes('Search')) {
|
|
||||||
fallbackLabel = 'Suchen';
|
|
||||||
} else if (iconClass.includes('Add')) {
|
|
||||||
fallbackLabel = 'Hinzufügen';
|
|
||||||
} else if (iconClass.includes('Remove')) {
|
|
||||||
fallbackLabel = 'Entfernen';
|
|
||||||
} else if (iconClass.includes('Delete')) {
|
|
||||||
fallbackLabel = 'Löschen';
|
|
||||||
} else if (iconClass.includes('Edit')) {
|
|
||||||
fallbackLabel = 'Bearbeiten';
|
|
||||||
} else if (iconClass.includes('Expand')) {
|
|
||||||
fallbackLabel = 'Erweitern';
|
|
||||||
} else if (iconClass.includes('ShoppingCart')) {
|
|
||||||
fallbackLabel = 'Warenkorb';
|
|
||||||
} else if (iconClass.includes('Zoom')) {
|
|
||||||
fallbackLabel = 'Vergrößern';
|
|
||||||
}
|
|
||||||
|
|
||||||
button.setAttribute('aria-label', fallbackLabel);
|
|
||||||
console.warn(`Added fallback aria-label "${fallbackLabel}" to IconButton:`, button);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Comprehensive accessibility validation
|
|
||||||
*/
|
|
||||||
export const validateAllAccessibility = () => {
|
|
||||||
if (process.env.NODE_ENV !== 'development') return;
|
|
||||||
|
|
||||||
console.log('🔍 Running comprehensive accessibility validation...');
|
|
||||||
|
|
||||||
const iconButtonIssues = validateIconButtonAccessibility();
|
|
||||||
const imageIssues = validateImageAccessibility();
|
|
||||||
|
|
||||||
if (iconButtonIssues.length === 0 && imageIssues.length === 0) {
|
|
||||||
console.log('✅ All accessibility checks passed!');
|
|
||||||
} else {
|
|
||||||
console.warn(`❌ Found ${iconButtonIssues.length + imageIssues.length} accessibility issues`);
|
|
||||||
|
|
||||||
// Auto-fix issues in development
|
|
||||||
if (iconButtonIssues.length > 0) {
|
|
||||||
addFallbackAriaLabels();
|
|
||||||
}
|
|
||||||
if (imageIssues.length > 0) {
|
|
||||||
addFallbackAltText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize accessibility checking on page load
|
|
||||||
*/
|
|
||||||
export const initializeAccessibilityChecking = () => {
|
|
||||||
if (process.env.NODE_ENV !== 'development') return;
|
|
||||||
|
|
||||||
// Check after initial render
|
|
||||||
setTimeout(() => {
|
|
||||||
validateAllAccessibility();
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
// Check after dynamic content loads
|
|
||||||
const observer = new MutationObserver(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
validateAllAccessibility();
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
|
|
||||||
observer.observe(document.body, {
|
|
||||||
childList: true,
|
|
||||||
subtree: true
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user