From f26dc593d614b64865640470bba43725eb30f2dd Mon Sep 17 00:00:00 2001 From: Harshit Date: Sun, 30 Nov 2025 20:35:21 +0530 Subject: [PATCH] feat: add ARIA attributes to ProgressBar component Add aria-valuemin, aria-valuemax, and aria-valuenow attributes to the ProgressBar component to improve accessibility for screen reader users. - Add aria-valuemin (0) and aria-valuemax (1) for all progress bars - Add aria-valuenow for controlled progress bars only - Clamp aria-valuenow values between 0 and 1 - Add comprehensive tests for ARIA attributes - Remove TODO comment requesting this feature This addresses the TODO comment on line 115 of ProgressBar.tsx and improves WCAG 2.1 compliance for progress indicators. --- src/components/ProgressBar.cy.tsx | 44 +++++++++++++++++++++++++++++++ src/components/ProgressBar.tsx | 17 +++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/components/ProgressBar.cy.tsx b/src/components/ProgressBar.cy.tsx index 29455601..45cef286 100644 --- a/src/components/ProgressBar.cy.tsx +++ b/src/components/ProgressBar.cy.tsx @@ -90,4 +90,48 @@ describe('ProgressBar', () => { cy.findByRole('progressbar').should('have.attr', 'style').and('include', 'scaleX(0.7)'); }); + + it('has ARIA attributes for accessibility', () => { + cy.mount( + + + + ); + + cy.findByRole('progressbar') + .should('have.attr', 'aria-valuemin', '0') + .should('have.attr', 'aria-valuemax', '1') + .should('not.have.attr', 'aria-valuenow'); + }); + + it('has aria-valuenow for controlled progress bar', () => { + cy.mount( + + + + ); + + cy.findByRole('progressbar') + .should('have.attr', 'aria-valuemin', '0') + .should('have.attr', 'aria-valuemax', '1') + .should('have.attr', 'aria-valuenow', '0.5'); + }); + + it('clamps aria-valuenow between 0 and 1', () => { + cy.mount( + + + + ); + + cy.findByRole('progressbar').should('have.attr', 'aria-valuenow', '1'); + + cy.mount( + + + + ); + + cy.findByRole('progressbar').should('have.attr', 'aria-valuenow', '0'); + }); }); diff --git a/src/components/ProgressBar.tsx b/src/components/ProgressBar.tsx index 6414f4e5..2c741a3c 100644 --- a/src/components/ProgressBar.tsx +++ b/src/components/ProgressBar.tsx @@ -112,7 +112,21 @@ export function ProgressBar({ } }; - // TODO: add aria-valuenow, aria-valuemax, aria-valuemin + // ARIA attributes for progress bar accessibility + // Only provide aria-valuenow for controlled progress bars where we know the exact value + // For animated progress bars, we omit aria-valuenow as the value changes continuously + const ariaProps: { + 'aria-valuemin': number; + 'aria-valuemax': number; + 'aria-valuenow'?: number; + } = { + 'aria-valuemin': 0, + 'aria-valuemax': 1 + }; + + if (controlledProgress && typeof progress === 'number') { + ariaProps['aria-valuenow'] = Math.max(0, Math.min(1, progress)); + } return (
@@ -125,6 +139,7 @@ export function ProgressBar({ aria-label="notification timer" className={classNames} style={style} + {...ariaProps} {...animationEvent} />