diff --git a/src/components/Footer/Footer/Footer.stories.tsx b/src/components/Footer/Footer/Footer.stories.tsx
index 9ae97202b6..64dfd01307 100644
--- a/src/components/Footer/Footer/Footer.stories.tsx
+++ b/src/components/Footer/Footer/Footer.stories.tsx
@@ -139,7 +139,7 @@ export const MediumFooter = (): React.ReactElement => (
/>
-
Agency Contact Center
+
Agency Contact Center
(
/>
-
Agency Contact Center
+
Agency Contact Center
{
const link = container.querySelector('.usa-social-link')
expect(link).toBeInTheDocument()
expect(link).toHaveAttribute('title', 'Instagram')
- expect(screen.getByRole('img')).toHaveAttribute('name', 'Instagram')
})
})
diff --git a/src/components/Footer/SocialLinks/SocialLinks.tsx b/src/components/Footer/SocialLinks/SocialLinks.tsx
index 1f70126720..a806da44f9 100644
--- a/src/components/Footer/SocialLinks/SocialLinks.tsx
+++ b/src/components/Footer/SocialLinks/SocialLinks.tsx
@@ -57,7 +57,11 @@ export const SocialLink = ({
return (
{IconComponent && (
-
+
)}
)
diff --git a/src/components/Icon/Icon.stories.tsx b/src/components/Icon/Icon.stories.tsx
index 98329c0b7b..3092f87705 100644
--- a/src/components/Icon/Icon.stories.tsx
+++ b/src/components/Icon/Icon.stories.tsx
@@ -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,
},
}
diff --git a/src/components/Icon/Icon.tsx b/src/components/Icon/Icon.tsx
index 4752f8fd25..976da96efa 100644
--- a/src/components/Icon/Icon.tsx
+++ b/src/components/Icon/Icon.tsx
@@ -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
}
IconFunctionalComponent.displayName = Component.displayName
diff --git a/src/components/Icon/Icons.stories.tsx b/src/components/Icon/Icons.stories.tsx
index ab6a9e6fd4..9393de32e3 100644
--- a/src/components/Icon/Icons.stories.tsx
+++ b/src/components/Icon/Icons.stories.tsx
@@ -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,
},
}
diff --git a/src/components/IconList/IconList.stories.tsx b/src/components/IconList/IconList.stories.tsx
index 7f850b127c..bd7c7f69b5 100644
--- a/src/components/IconList/IconList.stories.tsx
+++ b/src/components/IconList/IconList.stories.tsx
@@ -24,7 +24,7 @@ export const Default = (): ReactElement => (
-
+
Wash your hands for 20 seconds with soap
@@ -32,13 +32,13 @@ export const Default = (): ReactElement => (
-
+
Stay six feet away from others
-
+
Avoid large gatherings
@@ -51,13 +51,13 @@ export const SimpleContent = (): ReactElement => (
-
+
No processing lines
-
+
Access to expedited entry benefits in other countries
@@ -65,13 +65,13 @@ export const SimpleContent = (): ReactElement => (
-
+
Available at major U.S. airports
-
+
Reduced wait times
@@ -83,7 +83,7 @@ export const RichContent = (): ReactElement => (
-
+
Donate cash when possible.
@@ -98,7 +98,7 @@ export const RichContent = (): ReactElement => (
-
+
@@ -113,7 +113,7 @@ export const RichContent = (): ReactElement => (
-
+
@@ -140,7 +140,7 @@ export const CustomSizeWithRichContent = (): ReactElement => (
-
+
Let the sun shine.
@@ -154,7 +154,7 @@ export const CustomSizeWithRichContent = (): ReactElement => (
-
+
Adjust your schedule.
@@ -168,7 +168,7 @@ export const CustomSizeWithRichContent = (): ReactElement => (
-
+
Fill it up.
@@ -188,7 +188,7 @@ export const CustomSize = (): ReactElement => (
-
+
Timing. Is now the right time to
@@ -197,7 +197,7 @@ export const CustomSize = (): ReactElement => (
-
+
Funding. Do I have enough money to
@@ -206,7 +206,7 @@ export const CustomSize = (): ReactElement => (
-
+
Need. Will this business fill a real
diff --git a/src/components/LanguageSelector/LanguageSelectorButton.tsx b/src/components/LanguageSelector/LanguageSelectorButton.tsx
index 23bda36374..3efceca537 100644
--- a/src/components/LanguageSelector/LanguageSelectorButton.tsx
+++ b/src/components/LanguageSelector/LanguageSelectorButton.tsx
@@ -6,6 +6,7 @@ type LanguageSelectorButtonProps = {
labelAttr?: string
isOpen?: boolean
onToggle: () => void
+ controls?: string
}
export const LanguageSelectorButton = ({
@@ -14,6 +15,7 @@ export const LanguageSelectorButton = ({
isOpen,
onToggle,
className,
+ controls,
...buttonProps
}: LanguageSelectorButtonProps &
JSX.IntrinsicElements['button']): React.ReactElement => {
@@ -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}>
diff --git a/src/components/LanguageSelector/LanguageSelectorDropdown.tsx b/src/components/LanguageSelector/LanguageSelectorDropdown.tsx
index 7b22236ca7..1c5589f895 100644
--- a/src/components/LanguageSelector/LanguageSelectorDropdown.tsx
+++ b/src/components/LanguageSelector/LanguageSelectorDropdown.tsx
@@ -54,6 +54,7 @@ const LanguageSelectorDropdown: React.FC = ({
className
)
const displayLabel = langs.find((langDef) => langDef.attr === displayLang)
+ const menuID = 'language-options'
return (
@@ -63,12 +64,13 @@ const LanguageSelectorDropdown: React.FC
= ({
className={classes}
label={displayLabel?.label || label || langs[0].label}
isOpen={isOpen}
+ controls={menuID}
onToggle={() => setIsOpen((prevIsOpen) => !prevIsOpen)}
/>
diff --git a/src/components/Pagination/Pagination.stories.tsx b/src/components/Pagination/Pagination.stories.tsx
index 2c314eb56b..f41cc1ec77 100644
--- a/src/components/Pagination/Pagination.stories.tsx
+++ b/src/components/Pagination/Pagination.stories.tsx
@@ -1,8 +1,8 @@
import React, { useEffect, useState } from 'react'
import { Pagination } from './Pagination'
-import type { Meta, StoryFn } from '@storybook/react'
+import type { Meta, StoryObj } from '@storybook/react'
-export default {
+const meta: Meta = {
title: 'Components/Pagination',
component: Pagination,
argTypes: {
@@ -11,10 +11,12 @@ export default {
pathname: { control: 'string' },
totalPages: { control: 'number' },
},
-} as Meta
+}
+export default meta
+type Story = StoryObj
const pathname = '/test-pathname'
-const Template: StoryFn = (args) => {
+const Template = ({ ...args }) => {
const [current, setCurrentPage] = useState(args.currentPage)
useEffect(() => {
@@ -46,7 +48,7 @@ const Template: StoryFn = (args) => {
totalPages={args.totalPages}
currentPage={current}
maxSlots={args.maxSlots}
- pathname={args.pathname}
+ pathname={pathname}
onClickNext={handleNext}
onClickPrevious={handlePrevious}
onClickPageNumber={handlePageNumber}
@@ -54,68 +56,78 @@ const Template: StoryFn = (args) => {
)
}
-export const Sandbox = {
+export const Sandbox: Story = {
render: Template,
-
args: {
currentPage: 10,
maxSlots: 7,
},
}
-export const Default = (): React.ReactElement => (
-
-)
+export const Basic: Story = {
+ render: Template,
+ args: {
+ currentPage: 10,
+ totalPages: 10,
+ },
+}
-export const Unbounded = (): React.ReactElement => (
-
-)
+export const Unbounded: Story = {
+ render: Template,
+ args: { currentPage: 10 },
+}
-export const ThreePagesFirst = (): React.ReactElement => (
-
-)
+export const ThreePagesFirst: Story = {
+ render: Template,
+ args: { currentPage: 1, totalPages: 3 },
+}
-export const ThreePages = (): React.ReactElement => (
-
-)
+export const ThreePages: Story = {
+ render: Template,
+ args: { currentPage: 2, totalPages: 3 },
+}
-export const ThreePagesLast = (): React.ReactElement => (
-
-)
+export const ThreePagesLast: Story = {
+ render: Template,
+ args: { currentPage: 3, totalPages: 3 },
+}
-export const SevenPages = (): React.ReactElement => (
-
-)
+export const SevenPages: Story = {
+ render: Template,
+ args: { currentPage: 4, totalPages: 7 },
+}
-export const EightPagesFirst = (): React.ReactElement => (
-
-)
+export const EightPagesFirst: Story = {
+ render: Template,
+ args: { currentPage: 1, totalPages: 8 },
+}
-export const EightPagesFour = (): React.ReactElement => (
-
-)
+export const EightPagesFour: Story = {
+ render: Template,
+ args: { currentPage: 4, totalPages: 8 },
+}
-export const EightPagesFive = (): React.ReactElement => (
-
-)
+export const EightPagesFive: Story = {
+ render: Template,
+ args: { currentPage: 5, totalPages: 8 },
+}
-export const EightPagesSix = (): React.ReactElement => (
-
-)
+export const EightPagesSix: Story = {
+ render: Template,
+ args: { currentPage: 6, totalPages: 8 },
+}
-export const EightPagesLast = (): React.ReactElement => (
-
-)
+export const EightPagesLast: Story = {
+ render: Template,
+ args: { currentPage: 8, totalPages: 8 },
+}
-export const NinePagesFive = (): React.ReactElement => (
-
-)
+export const NinePagesFive: Story = {
+ render: Template,
+ args: { currentPage: 5, totalPages: 9 },
+}
-export const TenSlots = (): React.ReactElement => (
-
-)
+export const TenSlots: Story = {
+ render: Template,
+ args: { currentPage: 10, totalPages: 24, maxSlots: 10 },
+}
diff --git a/src/components/Pagination/Pagination.test.tsx b/src/components/Pagination/Pagination.test.tsx
index eaee7ddfb8..29104654e6 100644
--- a/src/components/Pagination/Pagination.test.tsx
+++ b/src/components/Pagination/Pagination.test.tsx
@@ -61,7 +61,7 @@ describe('Pagination component', () => {
pathname={testPathname}
/>
)
- expect(screen.getAllByRole('listitem')).toHaveLength(7) // overflow slots don't count
+ expect(screen.getAllByRole('listitem')).toHaveLength(9) // overflow slots don't count
})
it('renders pagination when the first page is current', () => {
@@ -307,7 +307,7 @@ describe('Pagination component', () => {
maxSlots={10}
/>
)
- expect(screen.getAllByRole('listitem')).toHaveLength(10)
+ expect(screen.getAllByRole('listitem')).toHaveLength(12)
})
})
})
diff --git a/src/components/Pagination/Pagination.tsx b/src/components/Pagination/Pagination.tsx
index 342b9fd28d..696d01d99c 100644
--- a/src/components/Pagination/Pagination.tsx
+++ b/src/components/Pagination/Pagination.tsx
@@ -68,7 +68,7 @@ const PaginationPage = ({
const PaginationOverflow = () => (
+ aria-label="ellipsis indicating non-visible pages">
…
)
@@ -174,7 +174,7 @@ export const Pagination = ({
aria-label="Previous page"
data-testid="pagination-previous"
onClick={onClickPrevious}>
-
+
Previous
) : (
@@ -182,7 +182,7 @@ export const Pagination = ({
href={`${pathname}?page=${prevPage}`}
className="usa-pagination__link usa-pagination__previous-page"
aria-label="Previous page">
-
+
Previous
)}
@@ -214,7 +214,7 @@ export const Pagination = ({
data-testid="pagination-next"
onClick={onClickNext}>
Next
-
+
) : (
Next
-
+
)}
diff --git a/src/components/Search/SearchButton/SearchButton.tsx b/src/components/Search/SearchButton/SearchButton.tsx
index aae112b1e2..9e2be0c0a1 100644
--- a/src/components/Search/SearchButton/SearchButton.tsx
+++ b/src/components/Search/SearchButton/SearchButton.tsx
@@ -43,6 +43,7 @@ export const SearchButton = ({
className="usa-search__submit-icon"
name={buttonText}
size={3}
+ aria-hidden={true}
/>
diff --git a/src/components/Tag/Tag.stories.tsx b/src/components/Tag/Tag.stories.tsx
index d886a0a7dd..768e1096cf 100644
--- a/src/components/Tag/Tag.stories.tsx
+++ b/src/components/Tag/Tag.stories.tsx
@@ -20,9 +20,9 @@ Source: https://designsystem.digital.gov/components/tag/
export const DefaultTag = (): React.ReactElement => My Tag
export const CustomBg = (): React.ReactElement => (
- My Tag
+ My Tag
)
export const CustomClass = (): React.ReactElement => (
- My Tag
+ My Tag
)
diff --git a/src/components/card/CardHeader/CardHeader.tsx b/src/components/card/CardHeader/CardHeader.tsx
index 61268ba0c0..32f4537617 100644
--- a/src/components/card/CardHeader/CardHeader.tsx
+++ b/src/components/card/CardHeader/CardHeader.tsx
@@ -8,7 +8,7 @@ export const CardHeader = ({
...headerProps
}: {
exdent?: boolean
-} & JSX.IntrinsicElements['header']): React.ReactElement => {
+} & JSX.IntrinsicElements['div']): React.ReactElement => {
const classes = classnames(
'usa-card__header',
{
@@ -18,9 +18,9 @@ export const CardHeader = ({
)
return (
-
+
{children}
-
+
)
}
diff --git a/src/components/forms/DatePicker/DatePicker.stories.tsx b/src/components/forms/DatePicker/DatePicker.stories.tsx
index ec774f4854..91e318206b 100644
--- a/src/components/forms/DatePicker/DatePicker.stories.tsx
+++ b/src/components/forms/DatePicker/DatePicker.stories.tsx
@@ -83,19 +83,27 @@ export const CompleteDatePicker = {
),
}
-export const DefaultDatePicker = (): React.ReactElement => (
-
+const Template = ({ ...args }) => (
+ <>
+
+
+ >
)
-export const Disabled = (): React.ReactElement => (
-
-)
+export const Basic = {
+ render: Template,
+}
-export const WithDefaultValue = {
- render: (): React.ReactElement => (
-
- ),
+export const Disabled = {
+ render: Template,
+ args: { disabled: true },
+}
+export const WithDefaultValue = {
+ render: Template,
+ args: { defaultValue: '1988-05-16' },
parameters: {
happo: {
waitForContent: '05/16/1988',
@@ -103,49 +111,32 @@ export const WithDefaultValue = {
},
}
-const withDefaultInvalidValue = (): React.ReactElement => (
-
-)
-export { withDefaultInvalidValue }
-
-export const WithMinMaxInSameMonth = (): React.ReactElement => (
-
-)
+export const WithDefaultInvalidValue = {
+ render: Template,
+ args: { defaultValue: '1988-05-16', minDate: '2020-01-01' },
+}
-export const WithMinMax = (): React.ReactElement => (
-
-)
+export const WithMinMaxInSameMonth = {
+ render: Template,
+ args: { minDate: '2021-01-01', maxDate: '2021-01-20' },
+}
-const withRangeDate = (): React.ReactElement => (
-
-)
-withRangeDate.parameters = {
- happo: {
- waitForContent: '01/20/2021',
+export const WithMinMax = {
+ render: Template,
+ args: { minDate: '2020-01-01', maxDate: '2021-5-31' },
+}
+
+export const WithRangeDate = {
+ render: Template,
+ args: { defaultValue: '2021-01-20', rangeDate: '2021-01-08' },
+ parameters: {
+ happo: {
+ waitForContent: '01/20/2021',
+ },
},
}
-export { withRangeDate }
-export const WithLocalizations = (): React.ReactElement => (
-
-)
+export const WithLocalizations = {
+ render: Template,
+ args: { i18n: sampleLocalization },
+}
diff --git a/src/components/forms/InputPrefix/InputPrefix.stories.tsx b/src/components/forms/InputPrefix/InputPrefix.stories.tsx
index e3b64bd3db..da2189fcc2 100644
--- a/src/components/forms/InputPrefix/InputPrefix.stories.tsx
+++ b/src/components/forms/InputPrefix/InputPrefix.stories.tsx
@@ -4,6 +4,7 @@ import { Icon } from '../../Icon/Icons'
import { TextInput } from '../TextInput/TextInput'
import { InputGroup } from '../InputGroup/InputGroup'
import { FormGroup } from '../FormGroup/FormGroup'
+import { Label } from '../Label/Label'
export default {
title: 'Components/Input prefix or suffix/InputPrefix',
@@ -21,31 +22,22 @@ Source: https://designsystem.digital.gov/components/input-prefix-suffix/
},
}
-export const InputWithTextInputPrefix = (): React.ReactElement => (
+const Template = ({ ...args }) => (
+
- cvc
+ {args.prefix}
)
-export const InputWithTextInputPrefixError = (): React.ReactElement => (
-
-
- cvc
-
-
-
-)
+export const AsText = {
+ render: Template,
+ args: { prefix: 'cvc' },
+}
-export const InputWithIconInputPrefix = (): React.ReactElement => (
-
-
-
-
-
-
-
-
-)
+export const AsIcon = {
+ render: Template,
+ args: { prefix: },
+}
diff --git a/src/components/forms/InputSuffix/InputSuffix.stories.tsx b/src/components/forms/InputSuffix/InputSuffix.stories.tsx
index acb060ab33..e8198f772d 100644
--- a/src/components/forms/InputSuffix/InputSuffix.stories.tsx
+++ b/src/components/forms/InputSuffix/InputSuffix.stories.tsx
@@ -4,6 +4,7 @@ import { InputGroup } from '../InputGroup/InputGroup'
import { FormGroup } from '../FormGroup/FormGroup'
import { TextInput } from '../TextInput/TextInput'
import { Icon } from '../../Icon/Icons'
+import { Label } from '../Label/Label'
export default {
title: 'Components/Input prefix or suffix/InputSuffix',
@@ -21,38 +22,22 @@ Source: https://designsystem.digital.gov/components/input-prefix-suffix/
},
}
-export const InputWithIconInputSuffix = (): React.ReactElement => (
+const Template = ({ ...args }) => (
+
-
-
-
+ {args.suffix}
)
-export const InputWithIconInputSuffixError = (): React.ReactElement => (
-
-
-
-
-
-
-
-
-)
+export const AsText = {
+ render: Template,
+ args: { suffix: 'lbs.' },
+}
-export const InputWithTextInputSuffix = (): React.ReactElement => (
-
-
-
- lbs.
-
-
-)
+export const AsIcon = {
+ render: Template,
+ args: { suffix: },
+}
diff --git a/src/components/forms/RangeInput/RangeInput.stories.tsx b/src/components/forms/RangeInput/RangeInput.stories.tsx
index d833e5d236..ac16fd02c5 100644
--- a/src/components/forms/RangeInput/RangeInput.stories.tsx
+++ b/src/components/forms/RangeInput/RangeInput.stories.tsx
@@ -18,66 +18,61 @@ Source: https://designsystem.digital.gov/components/range-slider
},
}
-const labelChildren = (
+const Template = ({ ...args }) => (
<>
-
- Start: 0
-
-
- End: 100
-
- >
-)
-
-const labelHint = <>(drag to adjust or use arrow keys)>
-
-export const DefaultRange = (): React.ReactElement => (
- <>
-