fix: improve accessibility for interactive UI elements - aria-labels,…#1877
fix: improve accessibility for interactive UI elements - aria-labels,…#1877garima-agarwall wants to merge 2 commits into
Conversation
… focus-visible, keyboard navigation
|
@garima-agarwall is attempting to deploy a commit to the recode Team on Vercel. A member of the Team first needs to authorize it. |
|
Thank you for submitting your pull request! 🙌 We'll review it as soon as possible. The estimated time for response is 5–8 hrs. In the meantime, please provide all necessary screenshots and make sure you run - npm build run , command and provide a screenshot, a video recording, or an image of the update you made below, which helps speed up the review and assignment. If you have questions, reach out to LinkedIn. Your contributions are highly appreciated!😊 Note: I maintain the repo issue every day twice at 8:00 AM IST and 9:00 PM IST. If your PR goes stale for more than one day, you can tag and comment on this same issue by tagging @sanjay-kv. We are here to help you on this journey of open source. Consistent 20 contributions are eligible for sponsorship 💰 🎁 check our list of amazing people we sponsored so far: GitHub Sponsorship. ✨ 📚Your perks for contribution to this community 👇🏻
If there are any specific instructions or feedback regarding your PR, we'll provide them here. Thanks again for your contribution! 😊 |
|
✅ Synchronized metadata from Issue #1575:
|
sanjay-kv
left a comment
There was a problem hiding this comment.
could you fix the conflicts
|
✅ Synchronized metadata from Issue #1575:
|
|
hi @sanjay-kv @iitzIrFan @Adez017 |
There was a problem hiding this comment.
Pull request overview
Improves site-wide accessibility for interactive UI elements to better support keyboard navigation and screen readers (Fixes #1575).
Changes:
- Adds accessible names (
aria-label) and keyboard interaction handlers to several clickable, non-semantic elements. - Removes redundant
role="button"from a native<button>and introduces focus-visible styling in global CSS. - Makes several card-like UI elements keyboard-focusable via
tabIndexandrole="button".
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/pages/showcase/_components/ShowcaseCard/index.tsx | Makes the “clickable overlay” keyboard-focusable and adds an accessible name. |
| src/css/custom.css | Introduces global :focus-visible outline styling for keyboard users. |
| src/components/navbar/NavbarIcon.tsx | Adds aria-label and removes redundant ARIA role from a native button. |
| src/components/merch/ProductCard.tsx | Adds keyboard/focus support to the product image click target. |
| src/components/dashboard/LeaderBoard/leaderboard.tsx | Adds keyboard/focus support to the contributor badges click target. |
Comments suppressed due to low confidence (1)
src/components/navbar/NavbarIcon.tsx:49
<button>elements already support Enter/Space activation by default. Keeping a customonKeyDownhere can causeonClickto fire twice (native click + manual call), leading to toggles/navigation triggering twice. Removing the extra keyboard handler (and redundanttabIndex) preserves accessibility and prevents double-invocation.
<button
className={`navbar-icon-item ${active ? "active" : ""}`}
onClick={onClick}
aria-label={text}
tabIndex={0}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
onClick();
}
}}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| > | ||
| <div className="product-card-image-wrapper"> | ||
| <div className="product-card-image" onClick={openViewer} style={{ cursor: 'pointer' }}> | ||
| <div className="product-card-image" onClick={openViewer} role="button" tabIndex={0} aria-label="View product image" onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") openViewer(); }} style={{ cursor: 'pointer' }}> |
| return ( | ||
| <li key={user.title} className={clsx("card shadow--md", styles.card)}> | ||
| <div className={styles.cardLink} onClick={handleCardClick} /> | ||
| <div className={styles.cardLink} onClick={handleCardClick} role="button" tabIndex={0} aria-label={`Visit ${user.title}`} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") handleCardClick(); }} /> |
|
|
||
| return ( | ||
| <div className="contributor-badges" onClick={onClick}> | ||
| <div className="contributor-badges" onClick={onClick} role="button" tabIndex={0} aria-label="View contributor badges" onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") onClick?.(); }}> |
| /* ===== Accessibility: focus-visible indicators ===== */ | ||
| :focus-visible { | ||
| outline: 2px solid var(--ifm-color-primary) !important; | ||
| outline-offset: 2px !important; | ||
| border-radius: 4px !important; | ||
| } | ||
|
|
||
| button:focus-visible, | ||
| a:focus-visible, | ||
| [role="button"]:focus-visible, | ||
| [tabindex]:focus-visible { | ||
| outline: 2px solid var(--ifm-color-primary) !important; | ||
| outline-offset: 2px !important; | ||
| border-radius: 4px !important; | ||
| } |
iitzIrFan
left a comment
There was a problem hiding this comment.
look into the comments and do verify your changes before pushing any code plz!
| badges?: string[]; // Array of badge image paths | ||
| } | ||
|
|
||
| interface Stats { |
There was a problem hiding this comment.
'Stats' is defined but never used
|
|
||
| return ( | ||
| <div className="contributor-badges" onClick={onClick}> | ||
| <div className="contributor-badges" onClick={onClick} role="button" tabIndex={0} aria-label="View contributor badges" onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") onClick?.(); }}> |
| ); | ||
| } | ||
|
|
||
| function TopPerformerCard({ |
There was a problem hiding this comment.
TopPerformerCard' is defined but never used
|
|
||
| const renderPaginationButtons = () => { | ||
| const pages = []; | ||
| const maxVisibleButtons = 5; // Maximum number of page buttons to show directly |
There was a problem hiding this comment.
'maxVisibleButtons' is assigned a value but never used
| }; | ||
|
|
||
| // Helper function for time filter display | ||
| const getTimeFilterLabel = (filter: string) => { |
There was a problem hiding this comment.
'getTimeFilterLabel' is assigned a value but never used
| value={currentTimeFilter} | ||
| onChange={(e) => { | ||
| // Use setTimeFilter from context | ||
| setTimeFilter(e.target.value as any); |
There was a problem hiding this comment.
Unexpected any. Specify a different type
| > | ||
| <div className="product-card-image-wrapper"> | ||
| <div className="product-card-image" onClick={openViewer} style={{ cursor: 'pointer' }}> | ||
| <div className="product-card-image" onClick={openViewer} role="button" tabIndex={0} aria-label="View product image" onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") openViewer(); }} style={{ cursor: 'pointer' }}> |
| /* ===== Accessibility: focus-visible indicators ===== */ | ||
| :focus-visible { | ||
| outline: 2px solid var(--ifm-color-primary) !important; | ||
| outline-offset: 2px !important; | ||
| border-radius: 4px !important; | ||
| } | ||
|
|
||
| button:focus-visible, | ||
| a:focus-visible, | ||
| [role="button"]:focus-visible, | ||
| [tabindex]:focus-visible { | ||
| outline: 2px solid var(--ifm-color-primary) !important; | ||
| outline-offset: 2px !important; | ||
| border-radius: 4px !important; | ||
| } |
| return ( | ||
| <li key={user.title} className={clsx("card shadow--md", styles.card)}> | ||
| <div className={styles.cardLink} onClick={handleCardClick} /> | ||
| <div className={styles.cardLink} onClick={handleCardClick} role="button" tabIndex={0} aria-label={`Visit ${user.title}`} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") handleCardClick(); }} /> |
… focus-visible, keyboard navigation
Description
Fixes #1575
Improved accessibility support for interactive UI elements across the website to ensure usability for screen readers and keyboard navigation users.
Type of Change
Changes Made
NavbarIcon.tsx — removed redundant role="button" from , added aria-label={text} for screen readers
ShowcaseCard/index.tsx — added role="button", tabIndex={0}, aria-label, onKeyDown to clickable
leaderboard.tsx — added role="button", tabIndex={0}, aria-label, onKeyDown to clickable
ProductCard.tsx — added role="button", tabIndex={0}, aria-label, onKeyDown to clickable
custom.css — added global focus-visible outline styles for keyboard navigation across all interactive elements
Dependencies
No new dependencies added.
Checklist
npm run buildand attached screenshot(s) in this PR.