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
7 changes: 7 additions & 0 deletions .changeset/khaki-rules-breathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@primer/react": patch
---

Use `aria-required` instead of `required` on required form elements

<!-- Changed components: TextInput, Textarea -->
9 changes: 9 additions & 0 deletions src/TextInput/TextInput.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ export const Large = () => (
</Box>
)

export const Required = () => (
<Box as="form">
<FormControl required>
<FormControl.Label>Default label</FormControl.Label>
<TextInput size="large" />
</FormControl>
</Box>
)

export const WithLeadingVisual = () => (
<Box as="form">
<FormControl>
Expand Down
2 changes: 2 additions & 0 deletions src/TextInput/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ const TextInput = React.forwardRef<HTMLInputElement, TextInputProps>(
variant: variantProp,
// end deprecated props
type = 'text',
required,
...inputProps
},
ref,
Expand Down Expand Up @@ -143,6 +144,7 @@ const TextInput = React.forwardRef<HTMLInputElement, TextInputProps>(
onFocus={handleInputFocus}
onBlur={handleInputBlur}
type={type}
aria-required={required ? 'true' : 'false'}
{...inputProps}
data-component="input"
/>
Expand Down
1 change: 0 additions & 1 deletion src/Textarea/Textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
<StyledTextarea
value={value}
resize={resize}
required={required}
aria-required={required ? 'true' : 'false'}
aria-invalid={validationStatus === 'error' ? 'true' : 'false'}
ref={ref}
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/FormControl.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ describe('FormControl', () => {

const input = getByRole('textbox')

expect(input.getAttribute('required')).not.toBeNull()
expect(input).toHaveAttribute('aria-required', 'true')
})

it('renders with a caption', () => {
Expand Down
7 changes: 7 additions & 0 deletions src/__tests__/__snapshots__/Autocomplete.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ exports[`snapshots renders a custom empty state message 1`] = `
aria-expanded={false}
aria-haspopup="listbox"
aria-owns="autocompleteId-listbox"
aria-required="false"
autoComplete="off"
className="c2"
data-component="input"
Expand Down Expand Up @@ -285,6 +286,7 @@ exports[`snapshots renders a loading state 1`] = `
aria-expanded={false}
aria-haspopup="listbox"
aria-owns="autocompleteId-listbox"
aria-required="false"
autoComplete="off"
className="c2"
data-component="input"
Expand Down Expand Up @@ -503,6 +505,7 @@ exports[`snapshots renders a menu that contains an item to add to the menu 1`] =
aria-expanded={false}
aria-haspopup="listbox"
aria-owns="autocompleteId-listbox"
aria-required="false"
autoComplete="off"
className="c2"
data-component="input"
Expand Down Expand Up @@ -1273,6 +1276,7 @@ exports[`snapshots renders a multiselect input 1`] = `
aria-expanded={false}
aria-haspopup="listbox"
aria-owns="autocompleteId-listbox"
aria-required="false"
autoComplete="off"
className="c2"
data-component="input"
Expand Down Expand Up @@ -1946,6 +1950,7 @@ exports[`snapshots renders a multiselect input with selected menu items 1`] = `
aria-expanded={false}
aria-haspopup="listbox"
aria-owns="autocompleteId-listbox"
aria-required="false"
autoComplete="off"
className="c2"
data-component="input"
Expand Down Expand Up @@ -2751,6 +2756,7 @@ exports[`snapshots renders a single select input 1`] = `
aria-expanded={false}
aria-haspopup="listbox"
aria-owns="autocompleteId-listbox"
aria-required="false"
autoComplete="off"
className="c2"
data-component="input"
Expand Down Expand Up @@ -3775,6 +3781,7 @@ exports[`snapshots renders with an input value 1`] = `
aria-expanded={false}
aria-haspopup="listbox"
aria-owns="autocompleteId-listbox"
aria-required="false"
autoComplete="off"
className="c2"
data-component="input"
Expand Down
33 changes: 33 additions & 0 deletions src/__tests__/__snapshots__/TextInput.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ exports[`TextInput renders 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="zipcode"
Expand Down Expand Up @@ -242,6 +243,7 @@ exports[`TextInput renders block 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="zipcode"
Expand Down Expand Up @@ -364,6 +366,7 @@ exports[`TextInput renders consistently 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -486,6 +489,7 @@ exports[`TextInput renders contrast 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="zipcode"
Expand Down Expand Up @@ -615,6 +619,7 @@ exports[`TextInput renders error 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="zipcode"
Expand Down Expand Up @@ -744,6 +749,7 @@ exports[`TextInput renders large 1`] = `
size="large"
>
<input
aria-required="false"
className="c2"
data-component="input"
name="zipcode"
Expand Down Expand Up @@ -892,6 +898,7 @@ exports[`TextInput renders leadingVisual 1`] = `
</svg>
</span>
<input
aria-required="false"
className="c2"
data-component="input"
name="search"
Expand Down Expand Up @@ -1041,6 +1048,7 @@ exports[`TextInput renders leadingVisual 2`] = `
</svg>
</span>
<input
aria-required="false"
className="c2"
data-component="input"
name="search"
Expand Down Expand Up @@ -1171,6 +1179,7 @@ exports[`TextInput renders leadingVisual 3`] = `
</div>
</span>
<input
aria-required="false"
className="c2"
data-component="input"
name="search"
Expand Down Expand Up @@ -1301,6 +1310,7 @@ exports[`TextInput renders leadingVisual 4`] = `
</div>
</span>
<input
aria-required="false"
className="c2"
data-component="input"
name="search"
Expand Down Expand Up @@ -1425,6 +1435,7 @@ exports[`TextInput renders monospace 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="zipcode"
Expand Down Expand Up @@ -1547,6 +1558,7 @@ exports[`TextInput renders placeholder 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="zipcode"
Expand Down Expand Up @@ -1679,6 +1691,7 @@ exports[`TextInput renders small 1`] = `
size="small"
>
<input
aria-required="false"
className="c2"
data-component="input"
name="zipcode"
Expand Down Expand Up @@ -2295,6 +2308,7 @@ exports[`TextInput renders trailingAction icon button 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="search"
Expand Down Expand Up @@ -2734,6 +2748,7 @@ exports[`TextInput renders trailingAction text button 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="search"
Expand Down Expand Up @@ -3379,6 +3394,7 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="search"
Expand Down Expand Up @@ -3531,6 +3547,7 @@ exports[`TextInput renders trailingVisual 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="search"
Expand Down Expand Up @@ -3680,6 +3697,7 @@ exports[`TextInput renders trailingVisual 2`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="search"
Expand Down Expand Up @@ -3829,6 +3847,7 @@ exports[`TextInput renders trailingVisual 3`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="search"
Expand Down Expand Up @@ -3959,6 +3978,7 @@ exports[`TextInput renders trailingVisual 4`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="search"
Expand Down Expand Up @@ -4112,6 +4132,7 @@ exports[`TextInput renders with a loading indicator 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -4334,6 +4355,7 @@ exports[`TextInput renders with a loading indicator 1`] = `
</div>
</span>
<input
aria-required="false"
className="c4"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -4512,6 +4534,7 @@ exports[`TextInput renders with a loading indicator 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -4774,6 +4797,7 @@ exports[`TextInput renders with a loading indicator 1`] = `
</div>
</span>
<input
aria-required="false"
className="c5"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -5036,6 +5060,7 @@ exports[`TextInput renders with a loading indicator 1`] = `
</div>
</span>
<input
aria-required="false"
className="c5"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -5298,6 +5323,7 @@ exports[`TextInput renders with a loading indicator 1`] = `
</div>
</span>
<input
aria-required="false"
className="c5"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -5485,6 +5511,7 @@ exports[`TextInput renders with a loading indicator 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -5747,6 +5774,7 @@ exports[`TextInput renders with a loading indicator 1`] = `
</div>
</span>
<input
aria-required="false"
className="c4"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -5965,6 +5993,7 @@ exports[`TextInput renders with a loading indicator 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -6276,6 +6305,7 @@ exports[`TextInput renders with a loading indicator 1`] = `
</div>
</span>
<input
aria-required="false"
className="c5"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -6578,6 +6608,7 @@ exports[`TextInput renders with a loading indicator 1`] = `
</div>
</span>
<input
aria-required="false"
className="c5"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -6887,6 +6918,7 @@ exports[`TextInput renders with a loading indicator 1`] = `
</div>
</span>
<input
aria-required="false"
className="c5"
data-component="input"
onBlur={[Function]}
Expand Down Expand Up @@ -7078,6 +7110,7 @@ exports[`TextInput should render a password input 1`] = `
onClick={[Function]}
>
<input
aria-required="false"
className="c2"
data-component="input"
name="password"
Expand Down
4 changes: 2 additions & 2 deletions src/drafts/MarkdownEditor/MarkdownEditor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,12 @@ describe('MarkdownEditor', () => {

it('does not require the textarea by default', async () => {
const {getInput} = await render(<UncontrolledEditor />)
expect(getInput()).not.toHaveAttribute('required')
expect(getInput()).toHaveAttribute('aria-required', 'false')
})

it('requires the textarea when required', async () => {
const {getInput} = await render(<UncontrolledEditor required />)
expect(getInput()).toHaveAttribute('required')
expect(getInput()).toHaveAttribute('aria-required', 'true')
})

it('does not render a placeholder by default', async () => {
Expand Down