react-a11y-inspector
Version:
An advanced React accessibility inspection tool with real-time monitoring, screen reader simulation, and customizable rules.
98 lines (85 loc) • 2.9 kB
JavaScript
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { checkAriaRoles } from './issues/AriaCheck.js';
import { checkContrast } from './issues/ContrastCheck.js';
import { checkFormLabels } from './issues/FormCheck.js';
import { exportPDF } from './utils/ReportGenerator.js';
import SeverityMapper from './utils/SeverityMapper.js';
import { simulateScreenReader } from './utils/SpeechReader.js';
const A11yInspector = ({
enabled,
customRules,
reportSeverity,
enableRealTimeMonitoring,
}) => {
const [issues, setIssues] = useState([]);
const runAccessibilityChecks = () => {
let collectedIssues = [
...checkAriaRoles(),
...checkContrast(),
...checkFormLabels(),
];
if (customRules?.length > 0) {
customRules.forEach((rule) => {
document.querySelectorAll(rule.selector).forEach((el) => {
if (!rule.check(el)) {
collectedIssues.push({
type: rule.name || 'Custom Rule',
message: rule.message || 'Custom rule violated.',
severity: rule.severity || 'Warning',
element: el,
});
}
});
});
}
const filteredIssues = collectedIssues.filter((issue) =>
SeverityMapper(issue.severity, reportSeverity)
);
setIssues(filteredIssues);
};
useEffect(() => {
if (!enabled) return;
runAccessibilityChecks();
if (enableRealTimeMonitoring) {
const observer = new MutationObserver(runAccessibilityChecks);
observer.observe(document.body, { childList: true, subtree: true });
return () => observer.disconnect(); // Cleanup
}
}, [enabled, enableRealTimeMonitoring, customRules]);
return (
<div className="a11y-inspector">
<h2>Accessibility Issues Detected: {issues.length}</h2>
<ul>
{issues.map((issue, index) => (
<li key={index}>
<strong>{issue.type}:</strong> {issue.message}
</li>
))}
</ul>
<button onClick={() => exportPDF(issues)}>Generate Report</button>
<button onClick={() => simulateScreenReader(issues)}>Simulate Screen Reader</button>
</div>
);
};
A11yInspector.propTypes = {
enabled: PropTypes.bool,
customRules: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
selector: PropTypes.string.isRequired,
check: PropTypes.func.isRequired,
message: PropTypes.string,
severity: PropTypes.string,
})
),
reportSeverity: PropTypes.oneOf(['Info', 'Warning', 'Critical']),
enableRealTimeMonitoring: PropTypes.bool,
};
A11yInspector.defaultProps = {
enabled: true,
customRules: [],
reportSeverity: 'Warning',
enableRealTimeMonitoring: false,
};
export default A11yInspector;