Skip to content

Commit

Permalink
fix(a11y): ensure label is present for buttons in busy state
Browse files Browse the repository at this point in the history
  • Loading branch information
langemike authored and AntonLantukh committed May 28, 2024
1 parent 9271d4e commit a388e48
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 170 deletions.
2 changes: 1 addition & 1 deletion packages/ui-react/src/components/Button/Button.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ $large-button-height: 40px;
}

.hidden {
visibility: hidden;
opacity: 0.001; // ensure the label is still accessible for screen readers
}

.centerAbsolute {
Expand Down
39 changes: 37 additions & 2 deletions packages/ui-react/src/components/Button/Button.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,47 @@
import React from 'react';
import { render } from '@testing-library/react';
import { axe } from 'vitest-axe';
import AccountCircle from '@jwp/ott-theme/assets/icons/account_circle.svg?react';
import 'vitest-axe/extend-expect';

import { renderWithRouter } from '../../../test/utils';
import Icon from '../Icon/Icon';

import Button from './Button';

describe('<Button>', () => {
test('renders and matches snapshot', () => {
const { container } = render(<Button label="aa" active onClick={() => null} />);
const { container } = renderWithRouter(
<>
<Button label="Default button" />
<Button label="Active button" active />
<Button label="Disabled button" disabled />
<Button label="Busy button" busy />
<Button label="Small button" size="small" />
<Button label="Large button" size="large" />
<Button label="Full width button" fullWidth />
<Button label="With start icon" startIcon={<Icon icon={AccountCircle} />} />
<Button label="Button link" to="https://jwplayer.com" />
</>,
);

expect(container).toMatchSnapshot();
});

test('WCAG 2.1 (AA) compliant', async () => {
const { container } = renderWithRouter(
<>
<Button label="Default button" />
<Button label="Active button" active />
<Button label="Disabled button" disabled />
<Button label="Busy button" busy />
<Button label="Small button" size="small" />
<Button label="Large button" size="large" />
<Button label="Full width button" fullWidth />
<Button label="With start icon" startIcon={<Icon icon={AccountCircle} />} />
<Button label="Button link" to="https://jwplayer.com" fullWidth />
</>,
);

expect(await axe(container)).toHaveNoViolations();
});
});
4 changes: 1 addition & 3 deletions packages/ui-react/src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ type Props = {
disabled?: boolean;
busy?: boolean;
id?: string;
as?: 'button' | 'a';
activeClassname?: string;
} & React.AriaAttributes;

Expand All @@ -45,7 +44,6 @@ const Button: React.FC<Props> = ({
busy,
type = 'button',
to,
as = 'button',
onClick,
className,
activeClassname = '',
Expand All @@ -64,7 +62,7 @@ const Button: React.FC<Props> = ({
const content = (
<>
{startIcon && <div className={styles.startIcon}>{startIcon}</div>}
{<span className={classNames(styles.buttonLabel, { [styles.hidden]: busy }) || undefined}>{label}</span>}
{<span className={classNames({ [styles.hidden]: busy }) || undefined}>{label}</span>}
{children}
{busy && <Spinner className={styles.centerAbsolute} size={'small'} />}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,102 @@

exports[`<Button> > renders and matches snapshot 1`] = `
<div>
<button
class="_button_f8f296 _default_f8f296 _outlined_f8f296"
type="button"
>
<span>
Default button
</span>
</button>
<button
class="_button_f8f296 _default_f8f296 _outlined_f8f296 _active_f8f296"
type="button"
>
<span>
aa
Active button
</span>
</button>
<button
aria-disabled="true"
class="_button_f8f296 _default_f8f296 _outlined_f8f296 _disabled_f8f296"
type="button"
>
<span>
Disabled button
</span>
</button>
<button
class="_button_f8f296 _default_f8f296 _outlined_f8f296"
type="button"
>
<span
class="_hidden_f8f296"
>
Busy button
</span>
<div
class="_buffer_d122df _centerAbsolute_f8f296 _small_d122df"
>
<div />
<div />
<div />
<div />
</div>
</button>
<button
class="_button_f8f296 _default_f8f296 _outlined_f8f296 _small_f8f296"
type="button"
>
<span>
Small button
</span>
</button>
<button
class="_button_f8f296 _default_f8f296 _outlined_f8f296 _large_f8f296"
type="button"
>
<span>
Large button
</span>
</button>
<button
class="_button_f8f296 _default_f8f296 _outlined_f8f296 _fullWidth_f8f296"
type="button"
>
<span>
Full width button
</span>
</button>
<button
class="_button_f8f296 _default_f8f296 _outlined_f8f296"
type="button"
>
<div
class="_startIcon_f8f296"
>
<svg
aria-hidden="true"
class="_icon_585b29"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"
/>
</svg>
</div>
<span>
With start icon
</span>
</button>
<a
class="_button_f8f296 _default_f8f296 _outlined_f8f296"
href="https://jwplayer.com"
>
<span>
Button link
</span>
</a>
</div>
`;
Loading

0 comments on commit a388e48

Please sign in to comment.