RocketChat / RocketChat/Rocket.Chat
Accessibility: Interactive anchor elements lack keyboard accessibility in multiple modals
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 46.1k
- Forks
- 13.9k
- Avg merge
- 3d 3h
- Merged PRs (30d)
- 130
Description
Accessibility: Interactive anchor elements lack keyboard accessibility in multiple modals
Labels
type: bug, accessibility, contrib: valid
Description
Multiple components throughout the codebase use <Box is='a' onClick={...}> to create interactive elements without proper accessibility attributes. These pseudo-links are not keyboard accessible and violate WCAG 2.1 Level A guidelines (2.1.1 Keyboard, 4.1.2 Name/Role/Value), preventing keyboard-only users and screen reader users from interacting with critical functionality.
Scope: 5 instances identified across 4 files affecting workspace registration, ABAC administration, Matrix federation, and user status management.
Technical Details
Anchor elements (<a>) with onClick handlers but without href attributes are not keyboard-focusable by default and lack proper semantic information for assistive technologies. The current implementation creates links that:
- Cannot be focused using the Tab key
- Cannot be activated with Enter or Space keys
- Are not announced as interactive elements by screen readers
- Have no visible focus indicator for keyboard navigation
- Violate semantic HTML principles
All Affected Files
1. RegisterWorkspaceSetupStepTwoModal.tsx (2 instances) - HIGH PRIORITY
File: apps/meteor/client/views/admin/workspace/VersionCard/modals/RegisterWorkspaceSetupModal/RegisterWorkspaceSetupStepTwoModal.tsx
Lines 109-110: "Resend" link
Lines 113-114: "change email" link
<Trans i18nKey='RegisterWorkspace_Didnt_Receive_Email'>
Didn't receive email?{' '}
<Box is='a' pi={4} onClick={handleResendRegistrationEmail}>
Resend
</Box>{' '}
or{' '}
<Box is='a' pi={4} onClick={handleBackFromConfirmation}>
change email
</Box>
</Trans>
Context: Email verification modal in workspace registration flow
User Impact: HIGH - Blocks admins from completing workspace setup via keyboard
2. WarningModal.tsx (1 instance) - MEDIUM PRIORITY
File: apps/meteor/client/views/admin/ABAC/ABACSettingTab/WarningModal.tsx
Line 38: "ABAC > Rooms" navigation link
<Box is='a' onClick={handleNavigate}>
{' '}
ABAC {'>'} Rooms
</Box>
Context: ABAC warning modal with navigation to Rooms tab
User Impact: MEDIUM - Prevents keyboard users from accessing ABAC room management
3. MatrixFederationSearchModalContent.tsx (1 instance) - MEDIUM PRIORITY
File: apps/meteor/client/sidebar/header/MatrixFederationSearch/MatrixFederationSearchModalContent.tsx
Line 59: "Manage_server_list" link
<Box is='a' display='flex' flexDirection='row' mbe={16} onClick={manageServers}>
{t('Manage_server_list')}
</Box>
Context: Matrix federation server management
User Impact: MEDIUM - Blocks keyboard access to federation server configuration
4. useStatusItems.tsx (1 instance) - LOW-MEDIUM PRIORITY
File: apps/meteor/client/navbar/NavBarSettingsToolbar/UserMenu/hooks/useStatusItems.tsx
Line 79: "Learn_more" link
<Box is='a' color='info' onClick={handleStatusDisabledModal}>
{t('Learn_more')}
</Box>
Context: User status disabled information
User Impact: LOW-MEDIUM - Prevents keyboard users from accessing help information
Steps to Reproduce
- Navigate to Administration → Workspace → Registration Setup
- Proceed to the email confirmation step (Step 2 of registration)
- Try to navigate the modal using only the Tab key (no mouse)
- Observe: The "Resend" and "change email" links cannot be focused
Alternative verification with DevTools:
// Run in browser console
document.querySelectorAll('a:not([href])[onclick], a[onclick]:not([href])').forEach((el, i) => {
console.log(`${i+1}. "${el.textContent.trim()}" - tabIndex: ${el.tabIndex}`);
el.style.outline = '2px solid red';
});
This will highlight all problematic anchor elements on the page.
Test with screen reader:
- Enable NVDA (Windows), VoiceOver (macOS), or ChromeVox
- Navigate through the modal with Tab/Arrow keys
- Observe: Screen reader does not announce "Resend" and "change email" as interactive
Expected Behavior
- All interactive elements should be keyboard accessible
- Tab key should focus the "Resend" and "change email" links
- Enter or Space key should activate the links
- Visual focus indicator should appear when focused
- Screen readers should announce: "Resend, button" or "Resend, link"
- Elements should follow WCAG 2.1 keyboard interaction patterns
Actual Behavior
- Links are not focusable with Tab key
- Keyboard users cannot access this functionality
- Screen readers do not identify these as interactive elements
- No visual focus indicator
- Elements appear as plain text to keyboard users
Impact Assessment
Severity: Medium (High for workspace registration flow)
Affected User Groups:
- Keyboard-only users (motor impairments, power users)
- Screen reader users (blind/low-vision users)
- Voice control users (Dragon NaturallySpeaking, etc.)
- Switch device users (alternative input devices)
Business Impact:
- Workspace registration becomes inaccessible to keyboard users
- Admins cannot resend verification emails without mouse
- Potential ADA/Section 508/WCAG compliance violations
- Blocks accessibility certification
WCAG 2.1 Violations
This issue violates the following WCAG 2.1 Level A Success Criteria:
| Criterion | Level | Description |
|---|---|---|
| 2.1.1 Keyboard | A | All functionality must be operable through keyboard interface |
| 4.1.2 Name, Role, Value | A | User interface components must expose name, role, and value to assistive technologies |
Proposed Solution
Option 1: Use Button Component (Recommended)
import { Button } from '@rocket.chat/fuselage';
<Trans i18nKey='RegisterWorkspace_Didnt_Receive_Email'>
Didn't receive email?{' '}
<Button nude mi={4} onClick={handleResendRegistrationEmail}>
Resend
</Button>{' '}
or{' '}
<Button nude mi={4} onClick={handleBackFromConfirmation}>
change email
</Button>
</Trans>
Pros:
- Semantic HTML (button element)
- Keyboard accessible by default
- Screen reader compatible
- Follows Fuselage design system
- Minimal code changes
Option 2: Use Button Element with Box
<Box
is='button'
type='button'
pi={4}
onClick={handleResendRegistrationEmail}
style={{
background: 'none',
border: 'none',
color: 'inherit',
textDecoration: 'underline',
cursor: 'pointer',
padding: 0,
font: 'inherit'
}}
>
Resend
</Box>
Pros:
- Maintains styling flexibility
- Semantic HTML
- Keyboard accessible
Environment
- Rocket.Chat Version:
developbranch (8.2.0-develop) - Commit: Latest as of February 20, 2026
- Browser: All modern browsers (Chrome, Firefox, Safari, Edge)
- OS: Cross-platform issue (Windows, macOS, Linux)
- Assistive Technology Impact: NVDA, JAWS, VoiceOver, Dragon NaturallySpeaking
References
- WCAG 2.1.1 Keyboard
- WCAG 4.1.2 Name, Role, Value
- MDN: HTML button element
- W3C: Using the button element
- WebAIM: Keyboard Accessibility
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the five affected instances in RegisterWorkspaceSetupStepTwoModal.tsx, WarningModal.tsx, MatrixFederationSearchModalContent.tsx, and useStatusItems.tsx. Verify each control's keyboard and screen-reader behavior in the relevant modal or menu, then confirm all five interactions are focusable, operable by keyboard, and visibly focused.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- accessibility, frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100