From 56f37b392f37903d5b20c6663d365b7ca2553b3e Mon Sep 17 00:00:00 2001 From: marcoskolodny Date: Mon, 21 Oct 2024 15:30:07 +0200 Subject: [PATCH 1/2] spinner a11y --- src/__tests__/spinner-test.tsx | 31 +++++++++++++++++++++++++++++++ src/spinner.tsx | 8 ++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/__tests__/spinner-test.tsx diff --git a/src/__tests__/spinner-test.tsx b/src/__tests__/spinner-test.tsx new file mode 100644 index 000000000..1a56036fe --- /dev/null +++ b/src/__tests__/spinner-test.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import {Spinner} from '..'; +import {render, screen} from '@testing-library/react'; +import ThemeContextProvider from '../theme-context-provider'; +import {makeTheme} from './test-utils'; + +test('spinner is accessible', () => { + render( + + + + ); + + const spinner = screen.getByRole('progressbar', {name: 'Cargando'}); + + expect(spinner).toBeInTheDocument(); + expect(spinner).toHaveAttribute('aria-busy'); +}); + +test('spinner with role presentation is accessible', () => { + render( + + + + ); + + const spinner = screen.getByRole('progressbar'); + + expect(spinner).toBeInTheDocument(); + expect(spinner).toHaveAttribute('aria-busy'); +}); diff --git a/src/spinner.tsx b/src/spinner.tsx index d2584f511..9f59661ec 100644 --- a/src/spinner.tsx +++ b/src/spinner.tsx @@ -31,7 +31,9 @@ const Spinner = ({color, delay = '500ms', size = 24, style, rolePresentation}: P className={styles.spinnerIos} height={size} style={{...style}} - role="img" + role="progressbar" + aria-live="polite" + aria-busy viewBox="0 0 30 30" width={size} > @@ -85,7 +87,9 @@ const Spinner = ({color, delay = '500ms', size = 24, style, rolePresentation}: P className={styles.spinnerDefault} height={size} style={{...style}} - role="img" + role="progressbar" + aria-live="polite" + aria-busy viewBox="0 0 66 66" width={size} > From 327311bff99b6d40d8961c0e7ab609616b4b19da Mon Sep 17 00:00:00 2001 From: marcoskolodny Date: Mon, 21 Oct 2024 17:30:39 +0200 Subject: [PATCH 2/2] deprecate rolePresentation and add aria-hidden --- src/__tests__/spinner-test.tsx | 9 ++++----- src/button.tsx | 2 +- src/spinner.tsx | 20 +++++++++++++++----- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/__tests__/spinner-test.tsx b/src/__tests__/spinner-test.tsx index 1a56036fe..1bcd14222 100644 --- a/src/__tests__/spinner-test.tsx +++ b/src/__tests__/spinner-test.tsx @@ -17,15 +17,14 @@ test('spinner is accessible', () => { expect(spinner).toHaveAttribute('aria-busy'); }); -test('spinner with role presentation is accessible', () => { +test('spinner with aria-hidden is not visible', () => { render( - + ); - const spinner = screen.getByRole('progressbar'); + const spinner = screen.queryByRole('progressbar'); - expect(spinner).toBeInTheDocument(); - expect(spinner).toHaveAttribute('aria-busy'); + expect(spinner).not.toBeInTheDocument(); }); diff --git a/src/button.tsx b/src/button.tsx index b3ae0b294..29caf4624 100644 --- a/src/button.tsx +++ b/src/button.tsx @@ -235,7 +235,7 @@ const renderButtonContent = ({ > {shouldRenderSpinner ? ( { +const Spinner = ({ + color, + delay = '500ms', + size = 24, + style, + rolePresentation, + 'aria-hidden': ariaHidden, +}: Props): JSX.Element => { const {texts, platformOverrides, t} = useTheme(); const isInverse = useIsInverseOrMediaVariant(); color = color || (isInverse ? vars.colors.controlActivatedInverse : vars.colors.controlActivated); const spinnerId = React.useId(); - const withTitle = !rolePresentation; const title = texts.loading || t(tokens.loading); const content = getPlatform(platformOverrides) === 'ios' ? ( @@ -34,10 +42,11 @@ const Spinner = ({color, delay = '500ms', size = 24, style, rolePresentation}: P role="progressbar" aria-live="polite" aria-busy + aria-hidden={ariaHidden || rolePresentation} viewBox="0 0 30 30" width={size} > - {withTitle && {title}} + {title} ) : ( - {withTitle && {title}} + {title}