Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"peerDependencies": {
"@types/react": "^16.x || ^17.x || ^18.x || ^19.x",
"@types/react-dom": "^16.x || ^17.x || ^18.x || ^19.x",
"@uswds/uswds": "^3.8.2",
"@uswds/uswds": "^3.9.0",
"focus-trap-react": "^10.2.3",
"react": "^16.x || ^17.x || ^18.x || ^19.x",
"react-dom": "^16.x || ^17.x || ^18.x || ^19.x"
Expand All @@ -108,7 +108,7 @@
"@types/react-dom": "^19.0.4",
"@typescript-eslint/eslint-plugin": "^8.29.0",
"@typescript-eslint/parser": "^8.29.0",
"@uswds/uswds": "3.8.2",
"@uswds/uswds": "3.9.0",
"@vitejs/plugin-react": "^5.0.0",
"@vitest/coverage-istanbul": "^4.0.8",
"@vitest/eslint-plugin": "^1.1.44",
Expand Down
9 changes: 6 additions & 3 deletions src/components/Pagination/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ const PaginationPage = ({
const buttonClasses = classnames(
linkClasses,
'bg-transparent',
'cursor-pointer'
'cursor-pointer',
'text-underline'
)

return (
Expand Down Expand Up @@ -173,7 +174,8 @@ export const Pagination = ({
'border-0',
'padding-0',
'bg-transparent',
'cursor-pointer'
'cursor-pointer',
'text-underline'
)
const nextLinkClasses = classnames(
'usa-pagination__link',
Expand All @@ -184,7 +186,8 @@ export const Pagination = ({
'border-0',
'padding-0',
'bg-transparent',
'cursor-pointer'
'cursor-pointer',
'text-underline'
)

return (
Expand Down
7 changes: 5 additions & 2 deletions src/components/SiteAlert/SiteAlert.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,10 @@ export const AlertWithStringContent = (): JSX.Element => (
export const AlertWithMultipleChildContent = (): JSX.Element => (
<SiteAlert variant="info">
<p className="usa-alert__text">Alert content</p>
<em>which includes</em> <strong>formatting tags</strong> and{' '}
<Link href="#">links</Link>.
<p className="usa-alert__text">
More content{' '}
<em className="usa-alert__text display-inline">which includes</em>{' '}
<strong>formatting tags</strong> and <Link href="#">links</Link>.
</p>
</SiteAlert>
)
2 changes: 1 addition & 1 deletion src/components/footer/Footer/Footer.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const SignUpForm = (): JSX.Element => {
<h3 className="usa-sign-up__heading">Sign up</h3>
<Form onSubmit={mockSubmit}>
<Label htmlFor="email">Your email address</Label>
<TextInput id="email" name="email" type="email" />
<TextInput id="email" name="email" type="email" autoComplete="email" />
<Button type="submit">Sign up</Button>
</Form>
</div>
Expand Down
2 changes: 2 additions & 0 deletions src/components/forms/CharacterCount/CharacterCount.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -323,13 +323,15 @@ describe('CharacterCount component', () => {
})
fireEvent.blur(input)

expect(input).toHaveClass('usa-input--error')
expect(getByRole('textbox')).toBeInvalid()

fireEvent.change(input, {
target: { value: 'abce' },
})
fireEvent.blur(input)

expect(input).not.toHaveClass('usa-input--error')
expect(input).toBeValid()
})

Expand Down
6 changes: 5 additions & 1 deletion src/components/forms/CharacterCount/CharacterCount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ export const CharacterCount = ({
const [isValid, setIsValid] = useState(initialCount < maxLength)
const srMessageRef = useRef<HTMLDivElement>(null)

const classes = classnames('usa-character-count__field', className)
const classes = classnames(
'usa-character-count__field',
{ 'usa-input--error': !isValid },
className
)
const messageClasses = classnames('usa-hint', 'usa-character-count__status', {
'usa-character-count__status--invalid': !isValid,
})
Expand Down
9 changes: 5 additions & 4 deletions src/components/forms/ComboBox/ComboBox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,7 @@ describe('ComboBox component', () => {
'favorite-fruit--list'
)
expect(comboBoxInput).toHaveAttribute('aria-autocomplete', 'list')
expect(comboBoxInput).toHaveAttribute(
'aria-describedby',
'favorite-fruit--assistiveHint'
)
expect(comboBoxInput).not.toHaveAttribute('aria-describedby')
expect(comboBoxInput).toHaveAttribute('aria-expanded', 'false')
expect(comboBoxInput).toHaveAttribute('autocapitalize', 'off')
expect(comboBoxInput).toHaveAttribute('autocomplete', 'off')
Expand Down Expand Up @@ -1733,6 +1730,10 @@ describe('ComboBox component', () => {
/>
)

expect(getByTestId('combo-box-input')).toHaveAttribute(
'aria-describedby',
'favorite-fruit--assistiveHint'
)
const node = getByTestId('combo-box-assistive-hint')
expect(node).toHaveTextContent('Customized assistive hint')
})
Expand Down
19 changes: 9 additions & 10 deletions src/components/forms/ComboBox/ComboBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ const ComboBoxForwardRef: React.ForwardRefRenderFunction<
})

const listID = `${id}--list`
const assistiveHintID = `${id}--assistiveHint`
const assistiveHintID = assistiveHint && `${id}--assistiveHint`

const focusedItemIndex = state.focusedOption
? state.filteredOptions.findIndex((i) => i === state.focusedOption)
Expand Down Expand Up @@ -499,15 +499,14 @@ const ComboBoxForwardRef: React.ForwardRefRenderFunction<
<div className="usa-combo-box__status usa-sr-only" role="status">
{state.statusText}
</div>
<span
id={assistiveHintID}
className="usa-sr-only"
data-testid="combo-box-assistive-hint">
{assistiveHint ||
`When autocomplete results are available use up and down arrows to review
and enter to select. Touch device users, explore by touch or with swipe
gestures.`}
</span>
{assistiveHint && (
<span
id={assistiveHintID}
className="usa-sr-only"
data-testid="combo-box-assistive-hint">
{assistiveHint}
</span>
)}
</div>
)
}
Expand Down
24 changes: 12 additions & 12 deletions src/components/forms/DateInput/DateInput.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,18 @@ export const DateOfBirthExample = (): JSX.Element => (
name="testDateInput"
aria-describedby="dateOfBirthHint">
<option>- Select -</option>
<option value="1">01 - January</option>
<option value="2">02 - February</option>
<option value="3">03 - March</option>
<option value="4">04 - April</option>
<option value="5">05 - May</option>
<option value="6">06 - June</option>
<option value="7">07 - July</option>
<option value="8">08 - August</option>
<option value="9">09 - September</option>
<option value="10">10 - October</option>
<option value="11">11 - November</option>
<option value="12">12 - December</option>
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</Select>
</FormGroup>
<DateInput
Expand Down
29 changes: 29 additions & 0 deletions src/components/forms/DatePicker/DatePicker.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,35 @@ describe('DatePicker component', () => {
})
})

describe('with the aria-disabled prop', () => {
it('the toggle button and external inputs are aria-disabled, and the internal input is not disabled', () => {
const { getByTestId } = renderDatePicker({ 'aria-disabled': true })
expect(getByTestId('date-picker-button')).toHaveAttribute(
'aria-disabled',
'true'
)
expect(getByTestId('date-picker-external-input')).toHaveAttribute(
'aria-disabled',
'true'
)
expect(getByTestId('date-picker-external-input')).toHaveAttribute(
'readonly'
)
expect(getByTestId('date-picker-internal-input')).not.toHaveAttribute(
'aria-disabled'
)
})

it('does not show the calendar when the toggle button is clicked', async () => {
const { getByTestId } = renderDatePicker({ 'aria-disabled': true })
await userEvent.click(getByTestId('date-picker-button'))
expect(getByTestId('date-picker-calendar')).not.toBeVisible()
expect(getByTestId('date-picker')).not.toHaveClass(
'usa-date-picker--active'
)
})
})

describe('with a default value prop', () => {
it('the internal input value is the date string, and the external input value is the formatted date', () => {
const { getByTestId } = renderDatePicker({ defaultValue: '1988-05-16' })
Expand Down
11 changes: 11 additions & 0 deletions src/components/forms/DatePicker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ export const DatePicker = ({
const datePickerEl = useRef<HTMLDivElement>(null)
const externalInputEl = useRef<HTMLInputElement>(null)

const isAriaDisabled =
inputProps['aria-disabled'] === true ||
inputProps['aria-disabled'] === 'true'

const isError = validationStatus === 'error'
const isSuccess = validationStatus === 'success'

Expand Down Expand Up @@ -185,6 +189,10 @@ export const DatePicker = ({
}, [externalValue, minDate, maxDate])

const handleToggleClick = (): void => {
if (isAriaDisabled) {
return
}

if (showCalendar) {
// calendar is open, hide it
setStatuses([])
Expand Down Expand Up @@ -285,6 +293,7 @@ export const DatePicker = ({
tabIndex={-1}
required={false}
disabled={false}
aria-disabled={undefined}
value={internalValue}
readOnly
/>
Expand All @@ -297,6 +306,7 @@ export const DatePicker = ({
type="text"
disabled={disabled}
required={required}
readOnly={inputProps['readOnly'] ?? isAriaDisabled}
value={externalValue}
ref={externalInputEl}
onInput={handleExternalInput}
Expand All @@ -315,6 +325,7 @@ export const DatePicker = ({
aria-haspopup={true}
aria-label={toggleCalendar}
disabled={disabled}
aria-disabled={inputProps['aria-disabled']}
onClick={handleToggleClick}></button>
{/* Ignoring error: "Non-interactive elements should not be assigned mouse or keyboard event listeners." */}
{/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}
Expand Down
10 changes: 5 additions & 5 deletions src/components/modal/Modal.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export const DefaultModal = (): JSX.Element => {
modalRef={modalRef}
closer
unstyled
className="padding-105 flex-justify-center">
className="padding-105 flex-justify-center width-full">
Go back
</ModalToggleButton>
</ButtonGroup>
Expand Down Expand Up @@ -117,7 +117,7 @@ export const LargeModal = (): JSX.Element => {
modalRef={modalRef}
closer
unstyled
className="padding-105 flex-justify-center">
className="padding-105 flex-justify-center width-full">
Go back
</ModalToggleButton>
</ButtonGroup>
Expand Down Expand Up @@ -160,7 +160,7 @@ export const ForceActionModal = (): JSX.Element => {
modalRef={modalRef}
closer
unstyled
className="padding-105 flex-justify-center">
className="padding-105 flex-justify-center width-full">
Sign out
</ModalToggleButton>
</ButtonGroup>
Expand Down Expand Up @@ -204,7 +204,7 @@ export const CustomFocusElementModal = (): JSX.Element => {
modalRef={modalRef}
closer
unstyled
className="padding-105 flex-justify-center">
className="padding-105 flex-justify-center width-full">
Go back
</ModalToggleButton>
</ButtonGroup>
Expand Down Expand Up @@ -246,7 +246,7 @@ export const InitiallyOpenModal = (): JSX.Element => {
modalRef={modalRef}
closer
unstyled
className="padding-105 flex-justify-center">
className="padding-105 flex-justify-center width-full">
Go back
</ModalToggleButton>
</ButtonGroup>
Expand Down
6 changes: 3 additions & 3 deletions src/components/modal/OpenModal.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const DefaultModal = {
type="button"
onClick={argTypes.handleClose}
unstyled
className="padding-105 flex-justify-center">
className="padding-105 flex-justify-center width-full">
Go back
</Button>
</ButtonGroup>
Expand Down Expand Up @@ -109,7 +109,7 @@ export const LargeModal = {
type="button"
onClick={argTypes.handleClose}
unstyled
className="padding-105 flex-justify-center">
className="padding-105 flex-justify-center width-full">
Go back
</Button>
</ButtonGroup>
Expand Down Expand Up @@ -155,7 +155,7 @@ export const ForceActionModal = {
type="button"
onClick={argTypes.handleClose}
unstyled
className="padding-105 flex-justify-center">
className="padding-105 flex-justify-center width-full">
Sign out
</Button>
</ButtonGroup>
Expand Down
1 change: 1 addition & 0 deletions src/stories/templates/createaccount.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ export const CreateAccount = (): JSX.Element => {
type="email"
autoCapitalize="off"
autoCorrect="off"
autoComplete="email"
required={true}
/>

Expand Down
1 change: 1 addition & 0 deletions src/stories/templates/signin.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ export const SignIn = (): JSX.Element => {
type="email"
autoCorrect="off"
autoCapitalize="off"
autoComplete="email"
required={true}
/>

Expand Down
12 changes: 6 additions & 6 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2141,7 +2141,7 @@ __metadata:
"@types/react-dom": ^19.0.4
"@typescript-eslint/eslint-plugin": ^8.29.0
"@typescript-eslint/parser": ^8.29.0
"@uswds/uswds": 3.8.2
"@uswds/uswds": 3.9.0
"@vitejs/plugin-react": ^5.0.0
"@vitest/coverage-istanbul": ^4.0.8
"@vitest/eslint-plugin": ^1.1.44
Expand Down Expand Up @@ -2185,7 +2185,7 @@ __metadata:
peerDependencies:
"@types/react": ^16.x || ^17.x || ^18.x || ^19.x
"@types/react-dom": ^16.x || ^17.x || ^18.x || ^19.x
"@uswds/uswds": ^3.8.2
"@uswds/uswds": ^3.9.0
focus-trap-react: ^10.2.3
react: ^16.x || ^17.x || ^18.x || ^19.x
react-dom: ^16.x || ^17.x || ^18.x || ^19.x
Expand Down Expand Up @@ -2490,14 +2490,14 @@ __metadata:
languageName: node
linkType: hard

"@uswds/uswds@npm:3.8.2":
version: 3.8.2
resolution: "@uswds/uswds@npm:3.8.2"
"@uswds/uswds@npm:3.9.0":
version: 3.9.0
resolution: "@uswds/uswds@npm:3.9.0"
dependencies:
object-assign: 4.1.1
receptor: 1.0.0
resolve-id-refs: 0.1.0
checksum: 146a264492a69aad917754b9bd99c51810055c740197ba0be6301fb01c84068d257ba0f47752e60996500b150903f593080c5b065327837ef560056a72bdfb26
checksum: 52795a1dd61762a5449406b12d8c44eba66e07f880e87c336f8e451be3d8629c54ee29f093a8141752d08fb03e4a607b00ffaaa760f017d9d5d0920ee39fc078
languageName: node
linkType: hard

Expand Down