Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Co-authored-by: DonKoko <7840007+DonKoko@users.noreply.github.com>
|
Great work on this accessibility sprint — the additions of aria-labels, semantic list fixes, and contrast improvements are solid steps toward WCAG AA compliance. A few extra things worth considering in the same spirit before merge: Everything else in this PR looks aligned — once these checks are validated, this will cover most of the high-impact a11y points we had flagged. Great progress. @copilot |
Implemented all 4 accessibility points from PR feedback:
1. Badge Color Contrast (WCAG 2.1 AA):
- Implemented darkenColor() in Badge component to ensure 4.5:1 contrast ratio
- All status badges now meet or exceed WCAG AA standards
* IN_CUSTODY: 6.69:1 (exceeds AA, approaching AAA)
* CHECKED_OUT: 8.59:1 (exceeds AAA)
* AVAILABLE: 6.02:1 (exceeds AA, approaching AAA)
- Added comprehensive color contrast utilities in app/utils/color-contrast.ts
- Created 24 unit tests for color contrast calculations
2. Dynamic Color Contrast for User-Generated Colors:
- Color contrast utilities automatically handle any hex color
- Category colors with custom user selections get proper text contrast
- ColorInput component shows accurate badge preview with correct contrast
- Functions: getContrastRatio(), meetsWCAG_AA(), getAccessibleTextColor(), darkenColor()
3. Modal/Dialog Keyboard Behavior:
- Fixed dialog.tsx to handle Escape key press
- Fixed contextual-modal.tsx to handle Escape key for navigation-based modals
- Added aria-label="Close dialog" to close buttons for screen reader support
- Radix UI modals (AlertDialog, Sheet) already handle Escape key correctly
4. Toast Screen Reader Announcements:
- Verified Radix UI Toast provides automatic aria-live regions
- Added aria-label="Close notification" to toast close button
- Keyboard support built-in (F8 to focus, Tab, Space/Enter/Escape)
5. Additional Fixes:
- Fixed AssetStatusBadge cursor showing pointer when it shouldn't (changed button to span)
- Badge component now uses mix-blend-mode for better color rendering
6. Documentation:
- Created comprehensive accessibility guidelines in docs/accessibility.md
- Added to VitePress documentation sidebar under Development section
- Includes practical examples, testing checklists, and common patterns
- Removed old ACCESSIBILITY_IMPROVEMENTS.md from project root
All changes meet WCAG 2.1 Level AA standards.
…essibility Implemented proper accessible name handling for buttons following HTML standards: 1. Icon-Only Button Detection: - Automatically detects buttons with icon but no text children - Only applies aria-label to icon-only buttons (buttons with text don't need it) - Text content automatically provides accessible name for regular buttons 2. Accessibility Logic: - Respects explicit aria-label prop when provided - Falls back to label prop for icon-only buttons - Tooltip also serves as accessible name for icon-only buttons - Regular buttons with text children don't get unnecessary aria-labels 3. Developer Experience: - Development-only console warning for icon-only buttons without accessible names - Warns if button has icon, no children, and no aria-label/label/tooltip - Added comprehensive JSDoc comments explaining prop usage 4. Implementation: - Added isIconOnly check: icon && !children - Smart aria-label logic: explicitAriaLabel || (isIconOnly ? label : undefined) - Applied to all three render paths (disabled with reason, tooltip, normal) - Development warning helps catch accessibility issues early This follows the HTML accessibility standard where text content automatically provides an accessible name, and aria-label is only needed when there's no visible text (like icon-only buttons).
… compliance Created centralized badge color palette and updated all status badges to use accessible, visually appealing color combinations. ## Changes: ### Badge Color Palette (app/utils/badge-colors.ts): - Created centralized BADGE_COLORS constant with 10 predefined color schemes - All colors meet WCAG 2.1 AA standards (4.5:1 contrast ratio minimum) - Color schemes: gray, orange, red, amber, green, indigo, blue, violet, pink, brown ### Badge Component Improvements (app/components/shared/badge.tsx): - Added optional textColor prop for predefined color combinations - When textColor provided: uses colors as-is without opacity or blend modes - When textColor not provided: auto-darkens for user-generated category colors - Dot color now matches text color for consistency - Removed mixBlendMode for predefined badges (only applies to user categories) ### Status Badge Updates: **Assets & Kits:** - IN_CUSTODY → blue (#01579B on #E1F5FE, 6.59:1 contrast) - CHECKED_OUT → violet (#8E24AA on #F3E5F5, 5.81:1 contrast) - AVAILABLE → green (#2E7D32 on #E8F5E9, 4.56:1 contrast) - PARTIALLY_CHECKED_IN → blue **Bookings:** - DRAFT → gray (#343A40 on #F8F9FA, 10.91:1 contrast) - RESERVED → blue (6.59:1 contrast) - ONGOING → violet (5.81:1 contrast) - OVERDUE → red (#C62828 on #FFEBEE, 4.92:1 contrast) - COMPLETE → green (4.56:1 contrast) - ARCHIVED → gray - CANCELLED → gray **Other:** - Returned badge → gray - Dashboard chart colors → use text color (more visible) ### Tests Updated: - Color contrast tests now reference BADGE_COLORS constant - All 34 tests passing with WCAG AA compliance verified - Blue color adjusted from #0288D1 to #01579B to meet accessibility standards ### Files Modified: - app/utils/badge-colors.ts (new file) - app/components/shared/badge.tsx - app/components/shared/returned-badge.tsx - app/components/assets/asset-status-badge.tsx - app/components/kits/kit-status-badge.tsx - app/components/booking/booking-status-badge.tsx - app/components/calendar/event-card.tsx - app/utils/bookings.ts - app/utils/dashboard.server.ts - app/utils/color-contrast.test.ts
- Add aria-label attributes to icon-only buttons in AssetQuickActions and KitQuickActions for screen reader support
- Update AssetImage alt text across the application from "{title}" to "Image of {title}" to avoid redundancy with adjacent text
- Ensures WCAG 2.1 AA compliance for informative images and interactive elements
- Update Button component to default to type="button" to prevent form submission - Modify form Enter key handling to allow button clicks while preventing input submission - Add arrow key navigation to OperatorSelector with visual highlighting - Add keyboard navigation to EnumField and BooleanField components in ValueField - Support Enter/Space for selection and Escape to close in all popover selectors - Pre-select current values when popovers open for better UX - Auto-scroll selected items into view These changes ensure full keyboard accessibility for advanced filtering, allowing users to navigate and select options using only their keyboard.
- Add aria-labels to SelectTrigger components for better screen reader support - Improve icon-only button accessibility with descriptive aria-labels - Add explanatory comments for decorative images with empty alt attributes - Enhance image alt text with descriptive context (e.g., 'main image') - Add aria-labels to tab triggers in booking manage-assets with dynamic counts - Add activationMode='manual' to Tabs component for better keyboard navigation - Create quick action components for categories and tags with proper ARIA attributes - Improve dialog accessibility in delete confirmations - Add aria-label to code preview copy button - Add aria-label to clear selected items button in list title
There was a problem hiding this comment.
Pull Request Overview
This PR focuses on improving accessibility to meet WCAG 2.2 A standards and enhance AA/AAA compliance. The primary goal is to make the Asset Index and related components more accessible to users with disabilities.
Key changes include:
- Added proper ARIA labels for icon-only buttons to ensure screen reader compatibility
- Fixed semantic HTML structure violations in navigation components
- Improved color contrast ratios across the application by updating text colors and badge color schemes
Reviewed Changes
Copilot reviewed 60 out of 60 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
docs/accessibility.md |
Comprehensive accessibility guidelines documentation with WCAG standards and practical implementation guidance |
app/utils/color-contrast.ts |
New utility functions for calculating WCAG-compliant color contrast ratios |
app/utils/badge-colors.ts |
Centralized accessible color palette for status badges with predefined contrast-safe combinations |
app/components/shared/button.tsx |
Enhanced button component with automatic aria-label detection for icon-only buttons |
app/components/layout/sidebar/sidebar-nav.tsx |
Fixed invalid HTML structure by properly nesting list items within sidebar groups |
app/components/assets/assets-index/view-toggle.tsx |
Added aria-labels and improved color contrast for view toggle buttons |
app/components/assets/assets-index/filters.tsx |
Enhanced contrast for filter text elements |
| Multiple image components | Improved alt text descriptions for better screen reader accessibility |
Simplify quick action components by using the Button component's built-in tooltip prop instead of manually wrapping buttons with Tooltip components. - Remove manual Tooltip/TooltipTrigger/TooltipContent usage - Add tooltip prop directly to Button components - Keep icon components as children (PencilIcon, Trash2Icon, QrCodeIcon, CopyIcon) - Maintain aria-label for accessibility Affected components: - AssetQuickActions - CategoryQuickActions - KitQuickActions - TagQuickActions
**Button Component** - Improve isIconOnly check to handle edge cases - Now detects empty strings and whitespace-only children - Ensures proper aria-label assignment for all icon-only scenarios **Color Contrast Utility** - Document the 0.5 luminance threshold in getAccessibleTextColor() - Explain threshold choice based on WCAG 2.1 standards - Add reference to W3C relative luminance specification - Clarify how it ensures AA compliance (4.5:1 contrast ratio)
aria-labelattributes to buttons without visible text (scroll to top, mode switches, view toggles)SidebarGroupLabelwas incorrectly wrapping<li>elementstext-gray-500totext-gray-600in view toggle buttons and filter elements/75to/90opacitytext-gray-400totext-gray-600in various components for better contrast✅ Completed Accessibility Improvements
WCAG 2.0 A Compliance Fixes
Critical Issue: Buttons must have discernible text (4.1.2)
aria-label="Scroll to top"to icon-only scroll buttonaria-label="Switch to simple mode"andaria-label="Switch to advanced mode"to mode toggle buttonsaria-label="Switch to list view"andaria-label="Switch to availability view"to view toggle buttonsSerious Issue: List structure must be correct (1.3.1)
<li>elements were nested insideSidebarGroupLabel(div), creating invalid<ul><div><li>structure. Now properly structured as<ul><li><SidebarGroupLabel>for valid semantic HTML.WCAG 2.0 AA Compliance Fixes
Serious Issue: Elements must meet minimum color contrast ratio (1.4.3)
text-gray-500totext-gray-600text-sidebar-foreground/75to/90for better contrastWCAG 2.0 AAA Compliance Improvements
Enhanced color contrast ratio thresholds (1.4.6)
text-gray-400totext-gray-600text-gray-400totext-gray-600🔧 Technical Implementation Details
All changes maintain existing functionality while improving accessibility:
✅ Quality Assurance
The Asset Index now meets WCAG 2.2 A requirements and has significantly improved AA/AAA compliance for better accessibility across all user types.
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.