Skip to content

Commit 6c7a3f6

Browse files
github-actions[bot]m4rc0zhirsch88
authored
♿ a11y(dropdown): start focus from selected option (#1448)
* Create PR for #1446 * feat(a11y-dropdown): focus selected option when opening dropdown popup to improve a11y with keyboard navigation * feat(a11y-dropdown): move to option list to be consumed by other parts (like combobox) in the future * fix(dropdonw): adjust selection * chore: fix condtion * chore: update ts definitions --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Marco Zirkenbach <marco.zirkenbach@baloise.ch> Co-authored-by: Gery Hirschfeld <gerhard.hirschfeld@baloise.ch>
1 parent e2c48b0 commit 6c7a3f6

5 files changed

Lines changed: 40 additions & 9 deletions

File tree

.changeset/shy-birds-poke.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@baloise/ds-core': minor
3+
---
4+
5+
**dropdown**: focus selected option when navigating with opening dropdown popup

e2e/cypress/e2e/a11y/bal-dropdown.a11y.cy.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
import { selectors } from 'support/utils'
2-
31
describe('bal-dropdown', () => {
42
beforeEach(() => {
53
cy.pageA11y('/components/bal-dropdown/test/bal-dropdown.a11y.html')
64
cy.platform('desktop')
75
cy.waitForDesignSystem()
86
})
97

10-
it('closed state', () => {
8+
it('inital state', () => {
119
cy.get('main').testA11y()
1210
})
1311

14-
it('open state', () => {
12+
it('selected state', () => {
1513
cy.getByLabelText('Year').click()
16-
cy.get('main').testA11y()
1714
cy.getByRole('option', { name: 'v1990' }).click()
1815
cy.get('main').testA11y()
1916
})

packages/core/src/components.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,6 +2277,10 @@ export namespace Components {
22772277
* @returns focusIndex
22782278
*/
22792279
"focusPrevious": () => Promise<number>;
2280+
/**
2281+
* Focus the selected visible option in the list, if no option is selected it selects the first one
2282+
*/
2283+
"focusSelected": () => Promise<number>;
22802284
/**
22812285
* Returns a list of options
22822286
*/

packages/core/src/components/bal-option-list/bal-option-list.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,22 @@ export class OptionList implements ComponentInterface, Loggable {
115115
* ------------------------------------------------------
116116
*/
117117

118+
/**
119+
* Focus the selected visible option in the list, if no option is selected it selects the first one
120+
*/
121+
@Method() async focusSelected(): Promise<number> {
122+
const options = this.options
123+
const indexToFocus = this.getSelectedOptionIndex(options)
124+
125+
if (indexToFocus > 0) {
126+
this.updateFocus(options, indexToFocus)
127+
await waitAfterFramePaint()
128+
return indexToFocus
129+
} else {
130+
return await this.focusFirst()
131+
}
132+
}
133+
118134
/**
119135
* Focus the first visible option in the list
120136
* @returns focusIndex
@@ -430,10 +446,20 @@ export class OptionList implements ComponentInterface, Loggable {
430446
return undefined
431447
}
432448

449+
private getSelectedOptionIndex(options: HTMLBalOptionElement[]): number {
450+
for (let index = 0; index < options.length; index++) {
451+
const option = options[index]
452+
if (option.selected && !option.hidden) {
453+
return index
454+
}
455+
}
456+
return this.focusIndex
457+
}
458+
433459
private getFirstOptionIndex(options: HTMLBalOptionElement[]): number {
434460
for (let index = 0; index < options.length; index++) {
435461
const option = options[index]
436-
if (!option.disabled) {
462+
if (!option.disabled && !option.hidden) {
437463
return index
438464
}
439465
}
@@ -516,7 +542,6 @@ export class OptionList implements ComponentInterface, Loggable {
516542
...block.class(),
517543
}}
518544
id={this.inputId}
519-
tabIndex={-1}
520545
>
521546
<div
522547
role="listbox"

packages/core/src/utils/dropdown/popup.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export class DropdownPopupUtil {
3030
}
3131
}
3232

33-
expandList() {
33+
async expandList() {
3434
if (this.component.panelEl) {
3535
this.component.panelCleanup = autoUpdate(
3636
this.component.el,
@@ -39,7 +39,7 @@ export class DropdownPopupUtil {
3939
)
4040
}
4141
this.component.isExpanded = true
42-
this.component.listEl?.focusFirst()
42+
await this.component.listEl?.focusSelected()
4343
}
4444

4545
collapseList() {

0 commit comments

Comments
 (0)