Skip to content

Commit 166c30a

Browse files
committed
refactor(ui-radio-input,ui-form-field): adda aria-errormessage, aria-describedby attributes
1 parent 2afd55e commit 166c30a

File tree

4 files changed

+43
-1
lines changed

4 files changed

+43
-1
lines changed

packages/ui-form-field/src/FormFieldGroup/__new-tests__/FormFieldGroup.test.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { runAxeCheck } from '@instructure/ui-axe-check'
2929
import '@testing-library/jest-dom'
3030

3131
import { FormFieldGroup } from '../index'
32+
import { FormMessage } from '../../FormPropTypes'
3233

3334
describe('<FormFieldGroup />', () => {
3435
let consoleWarningMock: ReturnType<typeof vi.spyOn>
@@ -98,6 +99,41 @@ describe('<FormFieldGroup />', () => {
9899
expect(formFieldGroup).toBeInTheDocument()
99100
})
100101

102+
it('links the messages to the fieldset via aria-describedby', () => {
103+
const messages: FormMessage[] = [{ text: 'Invalid name', type: 'error' }]
104+
105+
const { container } = render(
106+
<FormFieldGroup
107+
description="Please enter your full name"
108+
messages={messages}
109+
>
110+
<label>
111+
First: <input />
112+
</label>
113+
<label>
114+
Middle: <input />
115+
</label>
116+
<label>
117+
Last: <input />
118+
</label>
119+
</FormFieldGroup>
120+
)
121+
122+
const formFieldGroup = container.querySelector(
123+
"fieldset[class$='-formFieldLayout']"
124+
)
125+
const message = container.querySelector("span[id^='FormFieldLayout_']")
126+
127+
expect(message).toBeInTheDocument()
128+
expect(formFieldGroup).toBeInTheDocument()
129+
expect(formFieldGroup).toHaveAttribute('aria-describedby')
130+
131+
const messagesId = formFieldGroup!.getAttribute('aria-describedby')
132+
133+
expect(message).toHaveTextContent('Invalid name')
134+
expect(message).toHaveAttribute('id', messagesId)
135+
})
136+
101137
it('displays description message inside the label', () => {
102138
const description = 'Please enter your full name'
103139

packages/ui-form-field/src/FormFieldGroup/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ class FormFieldGroup extends Component<FormFieldGroupProps> {
144144
// This is quite ugly, but according to ARIA spec the `aria-invalid` prop
145145
// can only be used with certain roles see
146146
// https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-invalid#associated_roles
147+
// `aria-invalid` is put on in FormFieldLayout because the error message
148+
// DOM part gets there its ID.
147149
let ariaInvalid: AriaAttributes['aria-invalid'] = undefined
148150
if (
149151
this.props.role &&

packages/ui-form-field/src/FormFieldLayout/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,14 @@ class FormFieldLayout extends Component<FormFieldLayoutProps> {
178178

179179
const hasNewErrorMsgAndIsGroup =
180180
!!messages?.find((m) => m.type === 'newError') && isGroup
181-
// TODO use aria-errormessage here https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-errormessage
182181
return (
183182
<ElementType
184183
{...omitProps(props, [...FormFieldLayout.allowedProps])}
185184
css={styles?.formFieldLayout}
185+
aria-describedby={this.hasMessages ? this._messagesId : undefined}
186+
aria-errormessage={
187+
this.props['aria-invalid'] ? this._messagesId : undefined
188+
}
186189
style={{ width }}
187190
ref={this.handleRef}
188191
>

packages/ui-radio-input/src/RadioInputGroup/__new-tests__/RadioInputGroup.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,5 +248,6 @@ describe('<RadioInputGroup />', () => {
248248
expect(group).toHaveAttribute('role', 'radiogroup')
249249
expect(group).toHaveAttribute('aria-disabled', 'true')
250250
expect(group).toHaveAttribute('aria-invalid', 'true')
251+
expect(group).toHaveAttribute('aria-errormessage', expect.anything())
251252
})
252253
})

0 commit comments

Comments
 (0)