React Accessibility Checker Component
This challenge asks you to build a reusable React component that checks for common accessibility issues within a given React element. Ensuring accessibility is crucial for inclusive web development, and this component will help developers quickly identify and address potential problems in their UI. The component should highlight elements that violate basic accessibility guidelines, providing feedback to improve the user experience for everyone.
Problem Description
You need to create a React component called AccessibilityChecker that takes a React element (rendered JSX) as a prop and analyzes it for common accessibility issues. The component should then visually highlight these issues directly within the rendered element. The highlighting should be subtle but noticeable, allowing developers to easily spot and fix problems.
Key Requirements:
- Input: The component must accept a single prop:
children, which is a React element (JSX). - Accessibility Checks: The component should perform the following checks:
- Missing
altattribute on<img>tags: Highlight<img>tags without analtattribute. - Empty
altattribute on<img>tags: Highlight<img>tags with an emptyaltattribute (""). - Missing
aria-labeloraria-labelledbyon elements without visible text: Highlight elements (e.g., buttons, links) that lack visible text and do not have anaria-labeloraria-labelledbyattribute. - Missing
labelassociated with<input>,<textarea>, or<select>: Highlight input elements without a properly associated<label>. The label should be directly before the input or useforattribute to connect to the input'sid.
- Missing
- Visual Highlighting: When an accessibility issue is detected, the component should wrap the problematic element in a
spanwith a specific class name (e.g., "accessibility-error"). This class should be styled to visually indicate the error (e.g., a red border or background). You can use inline styles for simplicity in this challenge. - Recursive Checking: The component should recursively check the
childrenof the input element to ensure that accessibility issues within nested components are also detected. - Typescript: The entire solution must be written in Typescript.
Expected Behavior:
The AccessibilityChecker component should render the input element, but with any accessibility issues visually highlighted. The highlighting should not interfere with the functionality of the element.
Edge Cases to Consider:
- Null or undefined
children: Handle cases where the inputchildrenprop is null or undefined gracefully. - Complex JSX structures: The component should be able to handle deeply nested JSX structures.
- Elements with dynamic attributes: The component should correctly identify missing attributes even if they are dynamically added or removed.
- SVG elements: While not required for this challenge, consider how the checks might be adapted for SVG elements in the future.
Examples
Example 1:
Input: <img src="image.jpg" />
Output: <span className="accessibility-error"><img src="image.jpg" /></span>
Explanation: The `<img>` tag is missing an `alt` attribute, so it's wrapped in a span with the "accessibility-error" class.
Example 2:
Input: <button>Click Me</button>
Output: <button>Click Me</button>
Explanation: The button has visible text, so no highlighting is applied.
Example 3:
Input: <a href="#"></a>
Output: <span className="accessibility-error"><a href="#"></a></span>
Explanation: The `<a>` tag has no visible text and no `aria-label` or `aria-labelledby`, so it's wrapped in a span with the "accessibility-error" class.
Example 4:
Input: <label htmlFor="name">Name:</label><input type="text" id="name" />
Output: <label htmlFor="name">Name:</label><input type="text" id="name" />
Explanation: The input has a correctly associated label, so no highlighting is applied.
Constraints
- Component Size: The component should be relatively small and focused on the accessibility checks outlined above. Avoid adding unnecessary features.
- Performance: While performance is not a primary concern for this challenge, avoid excessively complex or inefficient algorithms. The component should render reasonably quickly even with moderately complex JSX.
- Styling: Use inline styles for the "accessibility-error" class for simplicity. (e.g.,
style={{ border: '1px solid red' }}) - Typescript: Strict Typescript usage is required.
Notes
- Consider using React's
React.cloneElementto wrap elements with the error highlightingspan. - You can use a recursive function to traverse the JSX tree and perform the accessibility checks.
- Focus on the core accessibility checks listed in the problem description. Don't try to implement a comprehensive accessibility audit.
- Think about how to handle different types of elements and attributes.
- This is a simplified accessibility checker. Real-world accessibility auditing tools are much more sophisticated.