Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: a11y omnibus package #2819

Merged
merged 29 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3f87e54
adds a11y testing package, runner, and gh action
werdnanoslen Mar 9, 2024
7b3c752
Require aria-hidden/label on Icons, small fix to story's size control
werdnanoslen Mar 12, 2024
086b47e
applied previous commit changes to Icons.stories as well
werdnanoslen Mar 12, 2024
4e9ead6
Added label to all select stories, other minor fixes and improvements
werdnanoslen Mar 12, 2024
11991a2
change card header from semantic header to div
werdnanoslen Mar 13, 2024
918a01f
change tag story color and className to fix a11y violation
werdnanoslen Mar 13, 2024
055a649
added bg-ink to text styles that didn't pass a11y on white bg
werdnanoslen Mar 13, 2024
8b2ca43
Added labels to all TextInput stories to fix a11y warnings there, and…
werdnanoslen Mar 13, 2024
15ba009
Added label to all RangeInput stories, other minor fixes and improvem…
werdnanoslen Mar 13, 2024
c7cf59a
hide SocialLinks' decorative svgs from SRs
werdnanoslen Mar 14, 2024
944fb58
Added label to all textarea stories, tidied
werdnanoslen Mar 14, 2024
4e117b8
added aria-hidden="true" to all decorative IconListIcon stories
werdnanoslen Mar 14, 2024
2e2e371
Added label to all prefix/suffix stories, tidied
werdnanoslen Mar 14, 2024
f73bbcb
Added label to all DatePicker stories, tidied
werdnanoslen Mar 14, 2024
54addb4
aria-hide decorative icon in search button
werdnanoslen Mar 15, 2024
05c6842
changed Footers' h3 to p elements — class already handles styling
werdnanoslen Mar 15, 2024
2cb2456
removed test that shouldn't exist given a11y context
werdnanoslen Mar 15, 2024
b436f93
aria-hid Pagination Icons, tidied stories
werdnanoslen Mar 15, 2024
aa499a8
replaced presentaiton role with aria-label to fix a11y issue
werdnanoslen Mar 15, 2024
e8fd227
disabled skip-link rule for ExtendedNav, out of context
werdnanoslen Mar 15, 2024
d35dc87
use aria-controls only when appropriate
werdnanoslen Mar 15, 2024
f94b1cb
allow local rules to apply
werdnanoslen Mar 15, 2024
0ae68d9
Merge branch 'an-storybooka11y' into an-storybooka11y-fixes
werdnanoslen Mar 15, 2024
904f711
Merge branch 'main' into an-storybooka11y-fixes
werdnanoslen Mar 15, 2024
12a8688
check a11y after building storybook
werdnanoslen Mar 15, 2024
86f210b
Merge branch 'an-storybooka11y-fixes' of github.com:trussworks/react-…
werdnanoslen Mar 15, 2024
db09b00
removed CI, moving to another branch
werdnanoslen Mar 15, 2024
83fff72
Merge branch 'main' into an-storybooka11y-fixes
werdnanoslen Mar 15, 2024
fe3a3e4
Merge branch 'main' into an-storybooka11y-fixes
werdnanoslen Jun 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/Footer/Footer/Footer.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export const MediumFooter = (): React.ReactElement => (
/>
<div className="usa-footer__contact-links mobile-lg:grid-col-6">
<SocialLinks links={socialLinkItems} />
<h3 className="usa-footer__contact-heading">Agency Contact Center</h3>
<p className="usa-footer__contact-heading">Agency Contact Center</p>
<Address
size="medium"
items={[
Expand Down Expand Up @@ -225,7 +225,7 @@ export const BigFooter = (): React.ReactElement => (
/>
<div className="usa-footer__contact-links mobile-lg:grid-col-6">
<SocialLinks links={socialLinkItems} />
<h3 className="usa-footer__contact-heading">Agency Contact Center</h3>
<p className="usa-footer__contact-heading">Agency Contact Center</p>
<Address
size="big"
items={[
Expand Down
3 changes: 1 addition & 2 deletions src/components/Footer/SocialLinks/SocialLinks.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable jsx-a11y/anchor-is-valid */
import React from 'react'
import { render, screen } from '@testing-library/react'
import { render } from '@testing-library/react'

import { SocialLinks, SocialLink } from './SocialLinks'

Expand Down Expand Up @@ -43,6 +43,5 @@ describe('SocialLink component', () => {
const link = container.querySelector('.usa-social-link')
expect(link).toBeInTheDocument()
expect(link).toHaveAttribute('title', 'Instagram')
expect(screen.getByRole('img')).toHaveAttribute('name', 'Instagram')
})
})
6 changes: 5 additions & 1 deletion src/components/Footer/SocialLinks/SocialLinks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ export const SocialLink = ({
return (
<a className="usa-social-link" {...props} title={name}>
{IconComponent && (
<IconComponent className="usa-social-link__icon" name={name} />
<IconComponent
className="usa-social-link__icon"
name={name}
aria-hidden="true"
/>
)}
</a>
)
Expand Down
14 changes: 12 additions & 2 deletions src/components/Icon/Icon.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,23 @@ Source: https://designsystem.digital.gov/components/icon/
argTypes: {
size: {
control: {
type: 'select',
options: [3, 4, 5, 6, 7, 8, 9],
type: 'number',
min: 3,
max: 9,
step: 1,
},
},
'aria-label': {
name: 'aria-label',
description: 'Add this if and only aria-hidden is false',
control: {
type: 'text',
},
},
},
args: {
size: 4,
'aria-hidden': true,
},
}

Expand Down
10 changes: 10 additions & 0 deletions src/components/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ export const makeUSWDSIcon = (
...iconProps,
}

if (
'img' === role &&
!iconProps['aria-hidden'] &&
!iconProps['aria-label'] &&
!iconProps['aria-labelledby']
) {
console.warn(
`Icon with img role is missing an accessible label. https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Img_role#associated_wai-aria_roles_states_and_properties`
)
}
return <Component {...finalProps} />
}
IconFunctionalComponent.displayName = Component.displayName
Expand Down
7 changes: 5 additions & 2 deletions src/components/Icon/Icons.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ Source: https://designsystem.digital.gov/components/icon/
argTypes: {
size: {
control: {
type: 'select',
options: [3, 4, 5, 6, 7, 8, 9],
type: 'number',
min: 3,
max: 9,
step: 1,
},
},
},
args: {
size: 4,
'aria-hidden': true,
},
}

Expand Down
32 changes: 16 additions & 16 deletions src/components/IconList/IconList.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,21 @@ export const Default = (): ReactElement => (
<IconList>
<IconListItem>
<IconListIcon className="text-green">
<Icon.CheckCircle />
<Icon.CheckCircle aria-hidden="true" />
</IconListIcon>
<IconListContent>
Wash your hands for 20 seconds with soap
</IconListContent>
</IconListItem>
<IconListItem>
<IconListIcon className="text-green">
<Icon.CheckCircle />
<Icon.CheckCircle aria-hidden="true" />
</IconListIcon>
<IconListContent>Stay six feet away from others</IconListContent>
</IconListItem>
<IconListItem>
<IconListIcon className="text-red">
<Icon.Cancel />
<Icon.Cancel aria-hidden="true" />
</IconListIcon>
<IconListContent>Avoid large gatherings</IconListContent>
</IconListItem>
Expand All @@ -51,27 +51,27 @@ export const SimpleContent = (): ReactElement => (
<IconList className="usa-icon-list--primary">
<IconListItem>
<IconListIcon>
<Icon.ThumbUpAlt />
<Icon.ThumbUpAlt aria-hidden="true" />
</IconListIcon>
<IconListContent>No processing lines</IconListContent>
</IconListItem>
<IconListItem>
<IconListIcon>
<Icon.ThumbUpAlt />
<Icon.ThumbUpAlt aria-hidden="true" />
</IconListIcon>
<IconListContent>
Access to expedited entry benefits in other countries
</IconListContent>
</IconListItem>
<IconListItem>
<IconListIcon>
<Icon.ThumbUpAlt />
<Icon.ThumbUpAlt aria-hidden="true" />
</IconListIcon>
<IconListContent>Available at major U.S. airports</IconListContent>
</IconListItem>
<IconListItem>
<IconListIcon>
<Icon.ThumbUpAlt />
<Icon.ThumbUpAlt aria-hidden="true" />
</IconListIcon>
<IconListContent>Reduced wait times</IconListContent>
</IconListItem>
Expand All @@ -83,7 +83,7 @@ export const RichContent = (): ReactElement => (
<IconList>
<IconListItem>
<IconListIcon className="text-ink">
<Icon.CheckCircle />
<Icon.CheckCircle aria-hidden="true" />
</IconListIcon>
<IconListContent>
<IconListTitle type="h3">Donate cash when possible.</IconListTitle>
Expand All @@ -98,7 +98,7 @@ export const RichContent = (): ReactElement => (
</IconListItem>
<IconListItem>
<IconListIcon className="text-ink">
<Icon.CheckCircle />
<Icon.CheckCircle aria-hidden="true" />
</IconListIcon>
<IconListContent>
<IconListTitle type="h3">
Expand All @@ -113,7 +113,7 @@ export const RichContent = (): ReactElement => (
</IconListItem>
<IconListItem>
<IconListIcon className="text-ink">
<Icon.CheckCircle />
<Icon.CheckCircle aria-hidden="true" />
</IconListIcon>
<IconListContent>
<IconListTitle type="h3">
Expand All @@ -140,7 +140,7 @@ export const CustomSizeWithRichContent = (): ReactElement => (
<IconList className="usa-icon-list--size-lg">
<IconListItem>
<IconListIcon className="text-green">
<Icon.AttachMoney />
<Icon.AttachMoney aria-hidden="true" />
</IconListIcon>
<IconListContent>
<IconListTitle type="h3">Let the sun shine.</IconListTitle>
Expand All @@ -154,7 +154,7 @@ export const CustomSizeWithRichContent = (): ReactElement => (
</IconListItem>
<IconListItem>
<IconListIcon className="text-green">
<Icon.AttachMoney />
<Icon.AttachMoney aria-hidden="true" />
</IconListIcon>
<IconListContent>
<IconListTitle type="h3">Adjust your schedule.</IconListTitle>
Expand All @@ -168,7 +168,7 @@ export const CustomSizeWithRichContent = (): ReactElement => (
</IconListItem>
<IconListItem>
<IconListIcon className="text-green">
<Icon.AttachMoney />
<Icon.AttachMoney aria-hidden="true" />
</IconListIcon>
<IconListContent>
<IconListTitle type="h3">Fill it up.</IconListTitle>
Expand All @@ -188,7 +188,7 @@ export const CustomSize = (): ReactElement => (
<IconList className="usa-icon-list--size-lg">
<IconListItem>
<IconListIcon className="text-blue">
<Icon.Help />
<Icon.Help aria-hidden="true" />
</IconListIcon>
<IconListContent>
<span className="text-bold">Timing.</span> Is now the right time to
Expand All @@ -197,7 +197,7 @@ export const CustomSize = (): ReactElement => (
</IconListItem>
<IconListItem>
<IconListIcon className="text-blue">
<Icon.Help />
<Icon.Help aria-hidden="true" />
</IconListIcon>
<IconListContent>
<span className="text-bold">Funding.</span> Do I have enough money to
Expand All @@ -206,7 +206,7 @@ export const CustomSize = (): ReactElement => (
</IconListItem>
<IconListItem>
<IconListIcon className="text-blue">
<Icon.Help />
<Icon.Help aria-hidden="true" />
</IconListIcon>
<IconListContent>
<span className="text-bold">Need.</span> Will this business fill a real
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type LanguageSelectorButtonProps = {
labelAttr?: string
isOpen?: boolean
onToggle: () => void
controls?: string
}

export const LanguageSelectorButton = ({
Expand All @@ -14,6 +15,7 @@ export const LanguageSelectorButton = ({
isOpen,
onToggle,
className,
controls,
...buttonProps
}: LanguageSelectorButtonProps &
JSX.IntrinsicElements['button']): React.ReactElement => {
Expand All @@ -28,7 +30,7 @@ export const LanguageSelectorButton = ({
data-testid="languageSelectorButton"
className={classes}
aria-expanded={isOpen}
aria-controls="language-options"
aria-controls={controls}
onClick={(): void => onToggle()}
type="button"
{...buttonProps}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const LanguageSelectorDropdown: React.FC<LanguageSelectorProps> = ({
className
)
const displayLabel = langs.find((langDef) => langDef.attr === displayLang)
const menuID = 'language-options'

return (
<div className={classes} data-testid="languageSelector" {...divProps}>
Expand All @@ -63,12 +64,13 @@ const LanguageSelectorDropdown: React.FC<LanguageSelectorProps> = ({
className={classes}
label={displayLabel?.label || label || langs[0].label}
isOpen={isOpen}
controls={menuID}
onToggle={() => setIsOpen((prevIsOpen) => !prevIsOpen)}
/>
<Menu
items={generateMenuItems(langs)}
isOpen={isOpen}
id="language-options"
id={menuID}
type="language"
/>
</li>
Expand Down
Loading
Loading