Skip to content

Commit 01b101e

Browse files
fix(tabs): DLT-3251 improve accessibility (#1171)
1 parent 522197f commit 01b101e

4 files changed

Lines changed: 209 additions & 45 deletions

File tree

packages/dialtone-vue/components/tab/tab.test.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const MOCK_DEFAULT_SLOT = 'Message Slot';
88
const MOCK_GROUP_CONTEXT = {
99
disabled: false,
1010
selected: '',
11+
focusedTabId: null,
1112
};
1213

1314
const baseProps = {
@@ -388,5 +389,51 @@ describe('DtTab Tests', () => {
388389
expect(tab.attributes('tabindex')).toBe('-1');
389390
});
390391
});
392+
393+
describe('Roving tabindex', () => {
394+
describe('When focusedTabId matches this tab', () => {
395+
beforeEach(() => {
396+
mockProvide = { groupContext: { ...MOCK_GROUP_CONTEXT, selected: '', focusedTabId: MOCK_ID } };
397+
398+
updateWrapper();
399+
});
400+
401+
it('tabindex should be 0', () => {
402+
expect(tab.attributes('tabindex')).toBe('0');
403+
});
404+
405+
it('aria-selected should still be "false"', () => {
406+
expect(tab.attributes('aria-selected')).toBe('false');
407+
});
408+
});
409+
410+
describe('When focusedTabId is a different tab', () => {
411+
beforeEach(() => {
412+
mockProvide = { groupContext: { ...MOCK_GROUP_CONTEXT, selected: MOCK_PANEL_ID, focusedTabId: 'other-tab' } };
413+
414+
updateWrapper();
415+
});
416+
417+
it('tabindex should be -1 even when selected', () => {
418+
expect(tab.attributes('tabindex')).toBe('-1');
419+
});
420+
421+
it('aria-selected should still be "true"', () => {
422+
expect(tab.attributes('aria-selected')).toBe('true');
423+
});
424+
});
425+
426+
describe('When focusedTabId is null', () => {
427+
beforeEach(() => {
428+
mockProvide = { groupContext: { ...MOCK_GROUP_CONTEXT, selected: MOCK_PANEL_ID, focusedTabId: null } };
429+
430+
updateWrapper();
431+
});
432+
433+
it('tabindex should fall back to selected tab', () => {
434+
expect(tab.attributes('tabindex')).toBe('0');
435+
});
436+
});
437+
});
391438
});
392439
});

packages/dialtone-vue/components/tab/tab.vue

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
:leading-class="leadingClass"
2222
:trailing-class="trailingClass"
2323
data-qa="dt-tab"
24-
:tabindex="isSelected ? '0' : '-1'"
24+
:tabindex="isFocusTarget ? '0' : '-1'"
2525
v-bind="$attrs"
2626
v-on="tabListeners"
2727
>
@@ -211,6 +211,11 @@ export default {
211211
return this.groupContext.selected === this.panelId;
212212
},
213213
214+
isFocusTarget () {
215+
const focusedId = this.groupContext.focusedTabId;
216+
return focusedId ? focusedId === this.id : this.isSelected;
217+
},
218+
214219
buttonKind () {
215220
if (this.groupContext.outlined) {
216221
return this.groupContext.kind === 'muted' ? 'muted' : 'default';
@@ -245,6 +250,12 @@ export default {
245250
}
246251
},
247252
253+
beforeUnmount () {
254+
if (this.groupContext.focusedTabId === this.id) {
255+
this.setFocus(null);
256+
}
257+
},
258+
248259
methods: {
249260
},
250261
};

0 commit comments

Comments
 (0)