Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

Commit 83bccfb

Browse files
authored
feat(Accessibility): Improvements to Menu accessibility behaviors (#523)
* Improvements to menu behaviors * Update changelog
1 parent bcf62f3 commit 83bccfb

File tree

5 files changed

+80
-28
lines changed

5 files changed

+80
-28
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
2020
### Features
2121
- Add `renderComponent` function in the public API @mnajdova ([#503](https://github.com/stardust-ui/react/pull/503))
2222
- Apply `dir=auto` attribute to string content of `Text` @kuzhelov ([#5](https://github.com/stardust-ui/react/pull/5))
23+
- Improve `Menu` accessibility behaviors @sophieH29 ([#523](https://github.com/stardust-ui/react/pull/523))
2324

2425
### Fixes
2526
- Fix the behaviour of `AutoControlledComponent` when `undefined` is passed as a prop value @layershifter ([#499](https://github.com/stardust-ui/react/pull/499))

src/lib/accessibility/Behaviors/Menu/menuBehavior.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Accessibility, FocusZoneMode } from '../../types'
66
*
77
* @specification
88
* Adds role='menu'.
9-
* Wraps component in FocusZone allowing circular arrow key navigation through the children of the component.
9+
* Embeds FocusZone into component allowing circular arrow key navigation through the children of the component.
1010
*/
1111

1212
const menuBehavior: Accessibility = (props: any) => ({
@@ -16,10 +16,11 @@ const menuBehavior: Accessibility = (props: any) => ({
1616
},
1717
},
1818
focusZone: {
19-
mode: FocusZoneMode.Wrap,
19+
mode: FocusZoneMode.Embed,
2020
props: {
2121
isCircularNavigation: true,
2222
preventDefaultWhenHandled: true,
23+
shouldFocusFirstElementWhenReceivedFocus: true,
2324
},
2425
},
2526
})

src/lib/accessibility/Behaviors/Tab/tabListBehavior.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Accessibility, FocusZoneMode } from '../../types'
33
/**
44
* @specification
55
* Adds role 'tablist' to 'root' component's part.
6-
* Wraps component in FocusZone allowing arrow key navigation through the children of the component.
6+
* Embeds FocusZone into component allowing arrow key navigation through the children of the component.
77
*/
88
const tabListBehavior: Accessibility = (props: any) => ({
99
attributes: {
@@ -12,10 +12,11 @@ const tabListBehavior: Accessibility = (props: any) => ({
1212
},
1313
},
1414
focusZone: {
15-
mode: FocusZoneMode.Wrap,
15+
mode: FocusZoneMode.Embed,
1616
props: {
1717
isCircularNavigation: false,
1818
preventDefaultWhenHandled: true,
19+
shouldFocusFirstElementWhenReceivedFocus: true,
1920
},
2021
},
2122
})

src/lib/accessibility/Behaviors/Toolbar/toolbarBehavior.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Accessibility, FocusZoneMode } from '../../types'
33
/**
44
* @specification
55
* Adds role 'toolbar' to 'root' component's part.
6-
* Wraps component in FocusZone allowing arrow key navigation through the children of the component.
6+
* Embeds FocusZone into component allowing arrow key navigation through the children of the component.
77
*/
88
const toolbarBehavior: Accessibility = (props: any) => ({
99
attributes: {
@@ -12,10 +12,11 @@ const toolbarBehavior: Accessibility = (props: any) => ({
1212
},
1313
},
1414
focusZone: {
15-
mode: FocusZoneMode.Wrap,
15+
mode: FocusZoneMode.Embed,
1616
props: {
1717
isCircularNavigation: false,
1818
preventDefaultWhenHandled: true,
19+
shouldFocusFirstElementWhenReceivedFocus: true,
1920
},
2021
},
2122
})

test/specs/behaviors/testDefinitions.ts

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { TestDefinition, TestMethod, TestHelper } from './testHelper'
2+
import { FocusZoneMode, FocusZoneDefinition } from '../../../src/lib/accessibility/types'
23
import * as keyboardKey from 'keyboard-key'
34

45
const definitions: TestDefinition[] = []
@@ -181,44 +182,91 @@ definitions.push({
181182
},
182183
})
183184

185+
// Embeds FocusZone into component allowing arrow key navigation through the children of the component.
186+
definitions.push({
187+
regexp: /Embeds FocusZone into component allowing arrow key navigation through the children of the component\.+/g,
188+
testMethod: (parameters: TestMethod) => {
189+
const actualFocusZone = parameters.behavior({}).focusZone
190+
191+
const expectedFocusZone: FocusZoneDefinition = {
192+
mode: FocusZoneMode.Embed,
193+
props: {
194+
isCircularNavigation: false,
195+
preventDefaultWhenHandled: true,
196+
},
197+
}
198+
199+
verifyFocusZones(expectedFocusZone, actualFocusZone)
200+
},
201+
})
202+
203+
// [Circular navigation] Embeds FocusZone into component allowing circular arrow key navigation through the children of the component.
204+
definitions.push({
205+
regexp: /Embeds FocusZone into component allowing circular arrow key navigation through the children of the component\.+/g,
206+
testMethod: (parameters: TestMethod) => {
207+
const actualFocusZone = parameters.behavior({}).focusZone
208+
209+
const expectedFocusZone: FocusZoneDefinition = {
210+
mode: FocusZoneMode.Embed,
211+
props: {
212+
isCircularNavigation: true,
213+
preventDefaultWhenHandled: true,
214+
},
215+
}
216+
217+
verifyFocusZones(expectedFocusZone, actualFocusZone)
218+
},
219+
})
220+
184221
// Wraps component in FocusZone allowing arrow key navigation through the children of the component.
185222
definitions.push({
186223
regexp: /Wraps component in FocusZone allowing arrow key navigation through the children of the component\.+/g,
187224
testMethod: (parameters: TestMethod) => {
188-
const property = {
189-
isCircularNavigation: undefined,
190-
preventDefaultWhenHandled: undefined,
225+
const actualFocusZone = parameters.behavior({}).focusZone
226+
227+
const expectedFocusZone: FocusZoneDefinition = {
228+
mode: FocusZoneMode.Wrap,
229+
props: {
230+
isCircularNavigation: false,
231+
preventDefaultWhenHandled: true,
232+
},
191233
}
192-
const expectedMode = parameters.behavior(property).focusZone.mode
193-
const expectedIsCircularNav = parameters.behavior(property).focusZone.props.isCircularNavigation
194-
const expectedPreventDefault = parameters.behavior(property).focusZone.props
195-
.preventDefaultWhenHandled
196-
197-
expect(expectedMode).toBe(1)
198-
expect(expectedIsCircularNav).toBe(false)
199-
expect(expectedPreventDefault).toBe(true)
234+
235+
verifyFocusZones(expectedFocusZone, actualFocusZone)
200236
},
201237
})
202238

203239
// [Circular navigation] Wraps component in FocusZone allowing circular arrow key navigation through the children of the component.
204240
definitions.push({
205241
regexp: /Wraps component in FocusZone allowing circular arrow key navigation through the children of the component\.+/g,
206242
testMethod: (parameters: TestMethod) => {
207-
const property = {
208-
isCircularNavigation: undefined,
209-
preventDefaultWhenHandled: undefined,
243+
const actualFocusZone = parameters.behavior({}).focusZone
244+
245+
const expectedFocusZone: FocusZoneDefinition = {
246+
mode: FocusZoneMode.Wrap,
247+
props: {
248+
isCircularNavigation: true,
249+
preventDefaultWhenHandled: true,
250+
},
210251
}
211-
const expectedMode = parameters.behavior(property).focusZone.mode
212-
const expectedIsCircularNav = parameters.behavior(property).focusZone.props.isCircularNavigation
213-
const expectedPreventDefault = parameters.behavior(property).focusZone.props
214-
.preventDefaultWhenHandled
215-
216-
expect(expectedMode).toBe(1)
217-
expect(expectedIsCircularNav).toBe(true)
218-
expect(expectedPreventDefault).toBe(true)
252+
253+
verifyFocusZones(expectedFocusZone, actualFocusZone)
219254
},
220255
})
221256

257+
function verifyFocusZones(
258+
expectedFocusZone: FocusZoneDefinition,
259+
actualFocusZone: FocusZoneDefinition,
260+
) {
261+
expect(expectedFocusZone.mode).toBe(actualFocusZone.mode)
262+
expect(expectedFocusZone.props.isCircularNavigation).toBe(
263+
actualFocusZone.props.isCircularNavigation,
264+
)
265+
expect(expectedFocusZone.props.preventDefaultWhenHandled).toBe(
266+
actualFocusZone.props.preventDefaultWhenHandled,
267+
)
268+
}
269+
222270
// [FocusTrapZone] Traps focus inside component
223271
definitions.push({
224272
regexp: /Traps focus inside component/,

0 commit comments

Comments
 (0)