Skip to content

Commit 186d63a

Browse files
committed
refactor: include tfoot in table navigation (refs SFKUI-7709)
1 parent b499f70 commit 186d63a

File tree

3 files changed

+40
-30
lines changed

3 files changed

+40
-30
lines changed

packages/vue-labs/src/components/FTable/FTable.cy.ts

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,8 +1260,9 @@ describe("5 tabstop", () => {
12601260
table.cell({ row: 1, col: 1 }).should("have.attr", "tabindex", "0");
12611261
});
12621262

1263-
it("should set correct tabstop for all types of headers and cells on navigation", () => {
1264-
const { buttonBeforeTable } = mountNavigationTestbed();
1263+
it("should set correct tabstop for all types of headers, cells and footer on navigation", () => {
1264+
const slots = { footer: "footer" };
1265+
const { buttonBeforeTable } = mountNavigationTestbed(slots);
12651266
cy.get(buttonBeforeTable).focus();
12661267
cy.focused().press(Cypress.Keyboard.Keys.TAB);
12671268
// {1, 1}: expand button
@@ -1381,10 +1382,23 @@ describe("5 tabstop", () => {
13811382
.should("have.prop", "tagName", "TD")
13821383
.should("not.have.text")
13831384
.should("have.attr", "tabindex", 0);
1385+
cy.focused().press(Cypress.Keyboard.Keys.DOWN);
1386+
// {3, 1}: expand footer
1387+
cy.focused()
1388+
.should("have.prop", "tagName", "TD")
1389+
.should("have.text", "footer")
1390+
.should("have.attr", "tabindex", 0);
1391+
cy.focused().press(Cypress.Keyboard.Keys.UP);
1392+
// {2, 1}: expand for child (empty)
1393+
cy.focused()
1394+
.should("have.prop", "tagName", "TD")
1395+
.should("not.have.text")
1396+
.should("have.attr", "tabindex", 0);
13841397
});
13851398

1386-
it("should set correct tabstop for all types of headers and cells on click", () => {
1387-
mountNavigationTestbed();
1399+
it("should set correct tabstop for all types of headers, cells and footer on click", () => {
1400+
const slots = { footer: "footer" };
1401+
mountNavigationTestbed(slots);
13881402

13891403
// {1, 1}: expand button
13901404
table.cell({ row: 1, col: 1 }).click();
@@ -1493,6 +1507,12 @@ describe("5 tabstop", () => {
14931507
.should("have.prop", "tagName", "TD")
14941508
.should("not.have.text")
14951509
.should("have.attr", "tabindex", 0);
1510+
// {3, 1}: expand footer
1511+
table.footer().click();
1512+
cy.focused()
1513+
.should("have.prop", "tagName", "TD")
1514+
.should("have.text", "footer")
1515+
.should("have.attr", "tabindex", 0);
14961516
});
14971517

14981518
it("should allow tab navigation in and out of expanded row", () => {
@@ -1526,23 +1546,6 @@ describe("5 tabstop", () => {
15261546
cy.focused().press(Cypress.Keyboard.Keys.TAB);
15271547
table.cell({ row: 2, col: 2 }).should("have.focus");
15281548
});
1529-
1530-
it("should not change footer tabindex", () => {
1531-
const footerButtonSelector = "footerButton";
1532-
const slots = {
1533-
footer: renderButton("Footer button", {
1534-
dataTest: footerButtonSelector,
1535-
}),
1536-
};
1537-
mountNavigationTestbed(slots);
1538-
const footerButton = getTestSelector(footerButtonSelector);
1539-
1540-
table.cell({ row: 1, col: 3 }).click();
1541-
cy.focused().press(Cypress.Keyboard.Keys.TAB);
1542-
cy.get(footerButton).should("have.focus");
1543-
cy.focused().realPress(["Shift", "Tab"]);
1544-
table.cell({ row: 1, col: 3 }).should("have.focus");
1545-
});
15461549
});
15471550

15481551
describe("Radio button single‑select functionality in table", () => {

packages/vue-labs/src/components/FTable/FTable.vue

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ function onClick(e: MouseEvent): void {
171171
function onTableFocusin(e: FocusEvent): void {
172172
assertRef(tableRef);
173173
174-
for (const it of tableRef.value.querySelectorAll(`:not(tfoot)[tabindex="0"]`)) {
174+
for (const it of tableRef.value.querySelectorAll(`[tabindex="0"]`)) {
175175
if (it !== e.target) {
176176
it.setAttribute("tabindex", "-1");
177177
}
@@ -199,8 +199,7 @@ function onTableFocusout(e: FocusEvent): void {
199199
return;
200200
}
201201
202-
const outsideTable =
203-
Boolean(tableRef.value.tFoot?.contains(relatedTarget)) || !tableRef.value.contains(relatedTarget);
202+
const outsideTable = !tableRef.value.contains(relatedTarget);
204203
205204
if (outsideTable) {
206205
const cell = target.closest<HTMLElement>("td, th");
@@ -296,11 +295,20 @@ onMounted(() => {
296295
</script>
297296

298297
<template>
299-
<table ref="table" :role :class="tableClasses" :aria-rowcount>
298+
<table
299+
ref="table"
300+
:role
301+
:class="tableClasses"
302+
:aria-rowcount
303+
@focusin="onTableFocusin"
304+
@focusout="onTableFocusout"
305+
@click="onClick"
306+
@keydown="onKeydown"
307+
>
300308
<caption v-if="hasCaption" data-test="caption">
301309
<slot name="caption"></slot>
302310
</caption>
303-
<thead @focusin="onTableFocusin" @focusout="onTableFocusout" @click="onClick" @keydown="onKeydown">
311+
<thead>
304312
<tr class="table-ng__row" aria-rowindex="1">
305313
<th v-if="isTreegrid" scope="col" tabindex="-1" class="table-ng__column"></th>
306314
<i-table-header-selectable
@@ -323,7 +331,7 @@ onMounted(() => {
323331
</tr>
324332
</thead>
325333

326-
<tbody @focusin="onTableFocusin" @focusout="onTableFocusout" @click="onClick" @keydown="onKeydown">
334+
<tbody>
327335
<template v-if="isEmpty">
328336
<tr class="table-ng__row--empty">
329337
<td :colspan="columnCount" class="table-ng__cell">

packages/vue-labs/src/components/FTable/use-tabstop.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,8 @@ export function useTabstop(
6565

6666
// resolve current tabstop details
6767
assertRef(tableRef);
68-
const oldTabstopElement = tableRef.value.querySelector<HTMLElement>(
69-
`:not(tfoot)[tabindex="0"]`,
70-
);
68+
const oldTabstopElement =
69+
tableRef.value.querySelector<HTMLElement>(`[tabindex="0"]`);
7170
assertSet(oldTabstopElement);
7271
const oldTabstopFocused = oldTabstopElement === document.activeElement;
7372

0 commit comments

Comments
 (0)