Skip to content

Commit 494ead6

Browse files
committed
refactor(ui-radio-input,ui-form-field,ui-checkbox): add tests
1 parent e00e3df commit 494ead6

File tree

5 files changed

+80
-10
lines changed

5 files changed

+80
-10
lines changed

packages/ui-checkbox/src/CheckboxGroup/__new-tests__/CheckboxGroup.test.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ describe('<CheckboxGroup />', () => {
8888
const { container } = renderCheckboxGroup({
8989
messages: [{ text: TEST_ERROR_MESSAGE, type: 'error' }]
9090
})
91-
const fieldset = screen.getByRole('group')
92-
const ariaDesc = fieldset.getAttribute('aria-describedby')
91+
const group = screen.getByRole('group')
92+
const ariaDesc = group.getAttribute('aria-describedby')
9393
const messageById = container.querySelector(`[id="${ariaDesc}"]`)
9494

9595
expect(messageById).toBeInTheDocument()
@@ -217,5 +217,20 @@ describe('<CheckboxGroup />', () => {
217217

218218
expect(axeCheck).toBe(true)
219219
})
220+
221+
it('adds the correct ARIA attributes', () => {
222+
const { container } = renderCheckboxGroup({
223+
disabled: true,
224+
messages: [{ type: 'newError', text: 'abc' }],
225+
// @ts-ignore This is a valid attribute
226+
'data-id': 'group'
227+
})
228+
const group = container.querySelector(`[data-id="group"]`)
229+
expect(group).toBeInTheDocument()
230+
expect(group).toHaveAttribute('role', 'group')
231+
expect(group).toHaveAttribute('aria-disabled', 'true')
232+
// ARIA role 'group' cannot have the 'aria-invalid' attribute
233+
expect(group).not.toHaveAttribute('aria-invalid')
234+
})
220235
})
221236
})

packages/ui-checkbox/src/CheckboxGroup/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ class CheckboxGroup extends Component<CheckboxGroupProps, CheckboxGroupState> {
148148
vAlign="top"
149149
messagesId={this._messagesId}
150150
elementRef={this.handleRef}
151-
role="group"
152151
>
153152
{this.renderChildren()}
154153
</FormFieldGroup>

packages/ui-checkbox/src/CheckboxGroup/props.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* SOFTWARE.
2323
*/
2424

25-
import React from 'react'
25+
import React, { type InputHTMLAttributes } from 'react'
2626
import PropTypes from 'prop-types'
2727

2828
import { FormPropTypes } from '@instructure/ui-form-field'
@@ -32,7 +32,10 @@ import {
3232
} from '@instructure/ui-prop-types'
3333

3434
import type { FormMessage } from '@instructure/ui-form-field'
35-
import type { PropValidators } from '@instructure/shared-types'
35+
import type {
36+
OtherHTMLAttributes,
37+
PropValidators
38+
} from '@instructure/shared-types'
3639
import type { WithDeterministicIdProps } from '@instructure/ui-react-utils'
3740

3841
import { Checkbox } from '../Checkbox'
@@ -58,7 +61,12 @@ type PropKeys = keyof CheckboxGroupOwnProps
5861

5962
type AllowedPropKeys = Readonly<Array<PropKeys>>
6063

61-
type CheckboxGroupProps = CheckboxGroupOwnProps & WithDeterministicIdProps
64+
type CheckboxGroupProps = CheckboxGroupOwnProps &
65+
OtherHTMLAttributes<
66+
CheckboxGroupOwnProps,
67+
InputHTMLAttributes<CheckboxGroupOwnProps & Element>
68+
> &
69+
WithDeterministicIdProps
6270

6371
const propTypes: PropValidators<PropKeys> = {
6472
name: PropTypes.string.isRequired,

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

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*/
2424

2525
/** @jsx jsx */
26-
import { Component, Children, ReactElement } from 'react'
26+
import { Component, Children, ReactElement, AriaAttributes } from 'react'
2727

2828
import { Grid } from '@instructure/ui-grid'
2929
import { pickProps, omitProps } from '@instructure/ui-react-utils'
@@ -84,7 +84,7 @@ class FormFieldGroup extends Component<FormFieldGroupProps> {
8484
return (
8585
!!this.props.messages &&
8686
this.props.messages.findIndex((message) => {
87-
return message.type === 'error'
87+
return message.type === 'error' || message.type === 'newError'
8888
}) >= 0
8989
)
9090
}
@@ -134,7 +134,33 @@ class FormFieldGroup extends Component<FormFieldGroupProps> {
134134

135135
render() {
136136
const { styles, makeStyles, isGroup, ...props } = this.props
137-
137+
const role = props.role ? props.role : 'group'
138+
// This is quite ugly, but according to ARIA spec
139+
// the `aria-invalid` prop can only be used with certain roles
140+
// see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-invalid#associated_roles
141+
let ariaInvalid: AriaAttributes['aria-invalid'] = undefined
142+
if (
143+
this.invalid &&
144+
[
145+
'application',
146+
'checkbox',
147+
'combobox',
148+
'gridcell',
149+
'listbox',
150+
'radiogroup',
151+
'slider',
152+
'spinbutton',
153+
'textbox',
154+
'tree',
155+
'columnheader',
156+
'rowheader',
157+
'searchbox',
158+
'switch',
159+
'treegrid'
160+
].includes(role)
161+
) {
162+
ariaInvalid = 'true'
163+
}
138164
return (
139165
<FormFieldLayout
140166
{...omitProps(props, FormFieldGroup.allowedProps)}
@@ -143,7 +169,8 @@ class FormFieldGroup extends Component<FormFieldGroupProps> {
143169
layout={props.layout === 'inline' ? 'inline' : 'stacked'}
144170
label={props.description}
145171
aria-disabled={props.disabled ? 'true' : undefined}
146-
aria-invalid={this.invalid ? 'true' : undefined}
172+
aria-invalid={ariaInvalid}
173+
role={role}
147174
elementRef={this.handleRef}
148175
isGroup={isGroup}
149176
>

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,4 +228,25 @@ describe('<RadioInputGroup />', () => {
228228
expect(axeCheck).toBe(true)
229229
})
230230
})
231+
232+
it('adds the correct ARIA attributes', () => {
233+
const { container } = render(
234+
<RadioInputGroup
235+
name="fruit"
236+
description="Select a fruit"
237+
disabled={true}
238+
data-id="group"
239+
messages={[{ type: 'newError', text: 'abc' }]}
240+
>
241+
<RadioInput label="Apple" value="apple" />
242+
<RadioInput label="Banana" value="banana" />
243+
<RadioInput label="Orange" value="orange" />
244+
</RadioInputGroup>
245+
)
246+
const group = container.querySelector(`[data-id="group"]`)
247+
expect(group).toBeInTheDocument()
248+
expect(group).toHaveAttribute('role', 'radiogroup')
249+
expect(group).toHaveAttribute('aria-disabled', 'true')
250+
expect(group).toHaveAttribute('aria-invalid', 'true')
251+
})
231252
})

0 commit comments

Comments
 (0)