-
Notifications
You must be signed in to change notification settings - Fork 1
KEYBOARD_NAVIGATION
This document describes all keyboard shortcuts and navigation patterns in the nself-admin application to ensure full keyboard accessibility.
- Tab - Move focus to next interactive element
- Shift + Tab - Move focus to previous interactive element
- Enter - Activate focused link or button
- Space - Activate focused button or checkbox
- Escape - Close modals, dialogs, dropdowns
- Tab (from page load) - Focus skip link (visible on focus)
- Enter (on skip link) - Jump directly to main content
Tab Order:
- Username field (if shown)
- Password field
- Show/hide password button
- Confirm password field (setup mode only)
- Show/hide confirm password button (setup mode only)
- Remember me checkbox (login mode only)
- Submit button
Keyboard Actions:
- Enter (in password field) - Submit form
- Space (on show/hide password) - Toggle password visibility
- Space (on remember me checkbox) - Toggle checkbox
ARIA Live Regions:
- Caps Lock warning announced when detected
- Password strength announced as you type (setup mode)
- Error messages announced with role="alert"
- Rate limit warnings announced
Tab Order:
- Skip to main content link
- Search field
- Mobile navigation toggle
- Theme toggle
- Logout button
- Navigation sections (collapsible)
- Service cards
- Action buttons on each card
Navigation Section Interaction:
- Enter/Space - Expand/collapse section
- Tab - Navigate to links within expanded section
- aria-expanded announces state to screen readers
Service Cards:
- Tab - Navigate through service cards
- Enter - Activate focused button (Start, Stop, Restart, View Logs, etc.)
ARIA Live Regions:
- System alerts announced as they appear (role="alert" for critical, role="status" for warnings)
- Activity feed updates announced (aria-live="polite")
Tab Order:
- Skip to main content
- Main navigation
- Service-specific tabs/controls
- Service actions (start, stop, restart)
- Logs viewer
- Configuration forms
Service Actions:
- Enter - Execute action (start, stop, restart)
- Service status announced via sr-only text
Tab Order:
- Skip to main content
- Main navigation
- Environment tabs
- Form fields
- Save/Cancel buttons
Environment Tabs:
- Left Arrow - Previous tab
- Right Arrow - Next tab
- Home - First tab
- End - Last tab
- Tab - Exit tab list to form fields
Form Fields:
- Tab - Next field
- Shift + Tab - Previous field
- Enter - Submit form (on submit button)
- Escape - Cancel/close (if in modal)
Focus Management:
- When modal opens, focus moves to first interactive element
- Focus is trapped within modal (Tab cycles through modal only)
- Escape closes modal
- When modal closes, focus returns to trigger element
Tab Order within Modal:
- Close button
- Modal content interactive elements
- Action buttons (Cancel, Confirm, etc.)
ARIA:
role="dialog"aria-modal="true"-
aria-labelledbypoints to modal title -
aria-describedbypoints to modal description
Interaction:
- Enter/Space on group header - Expand/collapse
- Tab - Navigate to next group or link
- Shift + Tab - Navigate to previous
ARIA:
-
aria-expanded="true|false"announces state -
aria-labeldescribes action (e.g., "Expand Services section")
Focus Order:
- First form field
- Subsequent fields in logical order
- Submit button
- Cancel/Reset button (if present)
Error Handling:
- Errors announced via
role="alert" - Fields with errors have
aria-invalid="true" -
aria-describedbylinks field to error message
Required Fields:
- Visual indicator (red asterisk)
-
aria-label="required"on asterisk -
requiredattribute on input
Interaction:
- Enter/Space - Open dropdown
- Arrow Down - Next option
- Arrow Up - Previous option
- Home - First option
- End - Last option
- Enter - Select focused option
- Escape - Close dropdown without selecting
ARIA:
-
role="combobox"orrole="listbox" -
aria-expandedannounces state -
aria-activedescendantannounces focused option
Navigation:
- Tab - Next interactive element in table
- Shift + Tab - Previous interactive element
Structure:
-
<th scope="col">for column headers -
<th scope="row">for row headers (if applicable) -
<caption>describes table purpose -
aria-labeloraria-labelledbyfor complex tables
ARIA Live Regions:
- Critical errors:
role="alert"+aria-live="assertive"(interrupts screen reader) - Warnings:
role="status"+aria-live="polite"(waits for pause) - Info messages:
aria-live="polite"
Dismissible Alerts:
- Tab to dismiss button
- Enter/Space - Dismiss alert
-
aria-labeldescribes which alert is being dismissed
- Banner - Header with logo and top navigation
- Navigation - Main sidebar navigation (aria-label="Main navigation")
- Main - Main content area (id="main-content")
- Complementary - Sidebar/aside content
- Contentinfo - Footer
-
VoiceOver (macOS):
-
VO + U - Rotor (navigate by headings, landmarks, links)
-
VO + Command + H - Next heading
-
VO + Command + L - Next link
-
VO + Command + J - Next form control
-
NVDA (Windows):
-
H - Next heading
-
K - Next link
-
F - Next form field
-
D - Next landmark
-
T - Next table
-
JAWS (Windows):
-
H - Next heading
-
R - Next region/landmark
-
F - Next form field
-
T - Next table
All interactive elements have visible focus indicators:
- Minimum size: 2px outline
- Contrast ratio: 3:1 against background
- Color: Blue ring (matches theme)
-
Style: Tailwind's
focus-visible:ring-2classes
- Unplug/hide mouse
- Navigate entire application using only keyboard
- Verify all interactive elements are reachable
- Verify focus order is logical
- Verify focus indicators visible at all times
- Test all forms can be completed
- Test all modals can be opened, used, and closed
- Verify Escape key closes dropdowns/modals
- Test collapsible sections work
- Verify no keyboard traps
- Test with VoiceOver (macOS)
- Test with NVDA (Windows)
- Verify all text is readable
- Verify all images have alt text
- Verify headings are announced
- Verify landmarks are announced
- Test form labels announced
- Verify dynamic content announced (alerts, updates)
- Test button labels are descriptive
- Verify status indicators have text alternatives
Solution: Headless UI Dialog component handles this automatically. Focus returns to trigger element.
Solution: Ensure element is not pointer-events-none and has proper tabindex (0 or not set).
Solution: Check for outline: none in styles. Use focus-visible:ring-2 instead.
Solution: Add appropriate aria-live region with correct politeness level.
Solution: Review focus management. Ensure Tab/Shift+Tab cycle correctly and Escape provides exit.
-
Browser Extensions:
-
axe DevTools (Chrome, Firefox)
-
WAVE (Chrome, Firefox)
-
Lighthouse (Chrome DevTools)
-
Screen Readers:
-
VoiceOver (macOS built-in)
-
NVDA (Windows, free)
-
JAWS (Windows, commercial)
-
Automated Testing:
-
pa11y (CLI tool)
-
axe-core (JavaScript library)
-
jest-axe (Jest integration)
For accessibility issues or questions, please:
- Check this document for guidance
- Review WCAG 2.1 AA standards
- Test with keyboard and screen reader
- File an issue on GitHub with "A11y:" prefix
Target: 100% keyboard navigable, WCAG 2.1 AA compliant
Version: 1.0.0 | Updated: 2026-09-16 11:21 UTC | GitHub