@react-aria/test-utils 1.0.0-beta.1 → 1.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/import.mjs +5 -5
- package/dist/main.js +9 -9
- package/dist/main.js.map +1 -1
- package/dist/module.js +5 -5
- package/dist/module.js.map +1 -1
- package/dist/private/checkboxgroup.cjs +104 -0
- package/dist/private/checkboxgroup.cjs.map +1 -0
- package/dist/private/checkboxgroup.js +99 -0
- package/dist/private/checkboxgroup.js.map +1 -0
- package/dist/{combobox.main.js → private/combobox.cjs} +35 -35
- package/dist/private/combobox.cjs.map +1 -0
- package/dist/{combobox.mjs → private/combobox.js} +35 -35
- package/dist/private/combobox.js.map +1 -0
- package/dist/private/dialog.cjs +105 -0
- package/dist/private/dialog.cjs.map +1 -0
- package/dist/private/dialog.js +100 -0
- package/dist/private/dialog.js.map +1 -0
- package/dist/{events.main.js → private/events.cjs} +32 -34
- package/dist/private/events.cjs.map +1 -0
- package/dist/{events.mjs → private/events.js} +29 -31
- package/dist/private/events.js.map +1 -0
- package/dist/{gridlist.main.js → private/gridlist.cjs} +27 -28
- package/dist/private/gridlist.cjs.map +1 -0
- package/dist/{gridlist.mjs → private/gridlist.js} +27 -28
- package/dist/private/gridlist.js.map +1 -0
- package/dist/{listbox.main.js → private/listbox.cjs} +24 -24
- package/dist/private/listbox.cjs.map +1 -0
- package/dist/{listbox.mjs → private/listbox.js} +24 -24
- package/dist/private/listbox.js.map +1 -0
- package/dist/{menu.main.js → private/menu.cjs} +46 -48
- package/dist/private/menu.cjs.map +1 -0
- package/dist/{menu.mjs → private/menu.js} +46 -48
- package/dist/private/menu.js.map +1 -0
- package/dist/private/radiogroup.cjs +120 -0
- package/dist/private/radiogroup.cjs.map +1 -0
- package/dist/private/radiogroup.js +115 -0
- package/dist/private/radiogroup.js.map +1 -0
- package/dist/{select.main.js → private/select.cjs} +31 -29
- package/dist/private/select.cjs.map +1 -0
- package/dist/{select.mjs → private/select.js} +31 -29
- package/dist/private/select.js.map +1 -0
- package/dist/{table.main.js → private/table.cjs} +82 -57
- package/dist/private/table.cjs.map +1 -0
- package/dist/{table.module.js → private/table.js} +82 -57
- package/dist/private/table.js.map +1 -0
- package/dist/{tabs.main.js → private/tabs.cjs} +24 -26
- package/dist/private/tabs.cjs.map +1 -0
- package/dist/{tabs.mjs → private/tabs.js} +24 -26
- package/dist/private/tabs.js.map +1 -0
- package/dist/private/testSetup.cjs +87 -0
- package/dist/private/testSetup.cjs.map +1 -0
- package/dist/private/testSetup.js +81 -0
- package/dist/private/testSetup.js.map +1 -0
- package/dist/{tree.main.js → private/tree.cjs} +34 -35
- package/dist/private/tree.cjs.map +1 -0
- package/dist/{tree.mjs → private/tree.js} +34 -35
- package/dist/private/tree.js.map +1 -0
- package/dist/private/user.cjs +85 -0
- package/dist/private/user.cjs.map +1 -0
- package/dist/private/user.js +76 -0
- package/dist/private/user.js.map +1 -0
- package/dist/{userEventMaps.main.js → private/userEventMaps.cjs} +3 -3
- package/dist/{userEventMaps.main.js.map → private/userEventMaps.cjs.map} +1 -1
- package/dist/{userEventMaps.mjs → private/userEventMaps.js} +3 -3
- package/dist/{userEventMaps.module.js.map → private/userEventMaps.js.map} +1 -1
- package/dist/types/src/checkboxgroup.d.ts +45 -0
- package/dist/types/src/combobox.d.ts +75 -0
- package/dist/types/src/dialog.d.ts +36 -0
- package/dist/types/src/events.d.ts +25 -0
- package/dist/types/src/gridlist.d.ts +51 -0
- package/dist/types/src/index.d.ts +16 -0
- package/dist/types/src/listbox.d.ts +80 -0
- package/dist/types/src/menu.d.ts +102 -0
- package/dist/types/src/radiogroup.d.ts +46 -0
- package/dist/types/src/select.d.ts +67 -0
- package/dist/types/src/table.d.ts +104 -0
- package/dist/types/src/tabs.d.ts +58 -0
- package/dist/types/src/testSetup.d.ts +6 -0
- package/dist/types/src/tree.d.ts +57 -0
- package/dist/types/src/types.d.ts +136 -0
- package/dist/types/src/user.d.ts +47 -0
- package/dist/types/src/userEventMaps.d.ts +2 -0
- package/package.json +7 -7
- package/src/checkboxgroup.ts +158 -0
- package/src/dialog.ts +143 -0
- package/src/index.ts +11 -0
- package/src/radiogroup.ts +176 -0
- package/src/select.ts +10 -2
- package/src/table.ts +46 -1
- package/src/tabs.ts +7 -2
- package/src/testSetup.ts +30 -28
- package/src/types.ts +21 -0
- package/src/user.ts +25 -7
- package/dist/combobox.main.js.map +0 -1
- package/dist/combobox.module.js +0 -167
- package/dist/combobox.module.js.map +0 -1
- package/dist/events.main.js.map +0 -1
- package/dist/events.module.js +0 -112
- package/dist/events.module.js.map +0 -1
- package/dist/gridlist.main.js.map +0 -1
- package/dist/gridlist.module.js +0 -149
- package/dist/gridlist.module.js.map +0 -1
- package/dist/listbox.main.js.map +0 -1
- package/dist/listbox.module.js +0 -138
- package/dist/listbox.module.js.map +0 -1
- package/dist/menu.main.js.map +0 -1
- package/dist/menu.module.js +0 -269
- package/dist/menu.module.js.map +0 -1
- package/dist/select.main.js.map +0 -1
- package/dist/select.module.js +0 -158
- package/dist/select.module.js.map +0 -1
- package/dist/table.main.js.map +0 -1
- package/dist/table.mjs +0 -290
- package/dist/table.module.js.map +0 -1
- package/dist/tabs.main.js.map +0 -1
- package/dist/tabs.module.js +0 -128
- package/dist/tabs.module.js.map +0 -1
- package/dist/testSetup.main.js +0 -78
- package/dist/testSetup.main.js.map +0 -1
- package/dist/testSetup.mjs +0 -72
- package/dist/testSetup.module.js +0 -72
- package/dist/testSetup.module.js.map +0 -1
- package/dist/tree.main.js.map +0 -1
- package/dist/tree.module.js +0 -179
- package/dist/tree.module.js.map +0 -1
- package/dist/types.d.ts +0 -694
- package/dist/types.d.ts.map +0 -1
- package/dist/user.main.js +0 -76
- package/dist/user.main.js.map +0 -1
- package/dist/user.mjs +0 -67
- package/dist/user.module.js +0 -67
- package/dist/user.module.js.map +0 -1
- package/dist/userEventMaps.module.js +0 -38
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {getAltKey as $
|
|
2
|
-
import {act as $
|
|
1
|
+
import {getAltKey as $22d7d9b763402afa$export$6fc0ccaebd758b9d, getMetaKey as $22d7d9b763402afa$export$7943c508934e27ce, pressElement as $22d7d9b763402afa$export$6ffa3eb717517feb, triggerLongPress as $22d7d9b763402afa$export$3a22a5a9bc0fd3b} from "./events.js";
|
|
2
|
+
import {act as $5mys8$act, within as $5mys8$within, waitFor as $5mys8$waitFor} from "@testing-library/react";
|
|
3
3
|
|
|
4
4
|
/*
|
|
5
5
|
* Copyright 2024 Adobe. All rights reserved.
|
|
@@ -13,7 +13,14 @@ import {act as $2KUjE$act, within as $2KUjE$within, waitFor as $2KUjE$waitFor} f
|
|
|
13
13
|
* governing permissions and limitations under the License.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
class $
|
|
16
|
+
class $196900c7f8f394b6$export$4c6a9d6ae3b0086 {
|
|
17
|
+
constructor(opts){
|
|
18
|
+
let { root: root, user: user, interactionType: interactionType, advanceTimer: advanceTimer } = opts;
|
|
19
|
+
this.user = user;
|
|
20
|
+
this._interactionType = interactionType || 'mouse';
|
|
21
|
+
this._advanceTimer = advanceTimer;
|
|
22
|
+
this._table = root;
|
|
23
|
+
}
|
|
17
24
|
/**
|
|
18
25
|
* Set the interaction type used by the table tester.
|
|
19
26
|
*/ setInteractionType(type) {
|
|
@@ -22,12 +29,12 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
22
29
|
// TODO: RTL
|
|
23
30
|
async keyboardNavigateToRow(opts) {
|
|
24
31
|
let { row: row, selectionOnNav: selectionOnNav = 'default' } = opts;
|
|
25
|
-
let altKey = (0, $
|
|
32
|
+
let altKey = (0, $22d7d9b763402afa$export$6fc0ccaebd758b9d)();
|
|
26
33
|
let rows = this.rows;
|
|
27
34
|
let targetIndex = rows.indexOf(row);
|
|
28
35
|
if (targetIndex === -1) throw new Error('Row provided is not in the table');
|
|
29
36
|
// Move focus into the table
|
|
30
|
-
if (document.activeElement !== this._table && !this._table.contains(document.activeElement)) (0, $
|
|
37
|
+
if (document.activeElement !== this._table && !this._table.contains(document.activeElement)) (0, $5mys8$act)(()=>this._table.focus());
|
|
31
38
|
if (document.activeElement === this._table) await this.user.keyboard('[ArrowDown]');
|
|
32
39
|
// If focus is currently somewhere in the first row group (aka on a column), we want to keyboard navigate downwards till we reach the rows
|
|
33
40
|
if (this.rowGroups[0].contains(document.activeElement)) do await this.user.keyboard('[ArrowDown]');
|
|
@@ -46,13 +53,13 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
46
53
|
* Toggles the selection for the specified table row. Defaults to using the interaction type set on the table tester.
|
|
47
54
|
*/ async toggleRowSelection(opts) {
|
|
48
55
|
let { row: row, needsLongPress: needsLongPress, checkboxSelection: checkboxSelection = true, interactionType: interactionType = this._interactionType, selectionBehavior: selectionBehavior = 'toggle' } = opts;
|
|
49
|
-
let altKey = (0, $
|
|
50
|
-
let metaKey = (0, $
|
|
56
|
+
let altKey = (0, $22d7d9b763402afa$export$7943c508934e27ce)();
|
|
57
|
+
let metaKey = (0, $22d7d9b763402afa$export$7943c508934e27ce)();
|
|
51
58
|
if (typeof row === 'string' || typeof row === 'number') row = this.findRow({
|
|
52
59
|
rowIndexOrText: row
|
|
53
60
|
});
|
|
54
61
|
if (!row) throw new Error('Target row not found in the table.');
|
|
55
|
-
let rowCheckbox = (0, $
|
|
62
|
+
let rowCheckbox = (0, $5mys8$within)(row).queryByRole('checkbox');
|
|
56
63
|
if (interactionType === 'keyboard' && (!checkboxSelection || !rowCheckbox)) {
|
|
57
64
|
await this.keyboardNavigateToRow({
|
|
58
65
|
row: row,
|
|
@@ -63,13 +70,13 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
63
70
|
if (selectionBehavior === 'replace') await this.user.keyboard(`[/${altKey}]`);
|
|
64
71
|
return;
|
|
65
72
|
}
|
|
66
|
-
if (rowCheckbox && checkboxSelection) await (0, $
|
|
73
|
+
if (rowCheckbox && checkboxSelection) await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, rowCheckbox, interactionType);
|
|
67
74
|
else {
|
|
68
|
-
let cell = (0, $
|
|
75
|
+
let cell = (0, $5mys8$within)(row).getAllByRole('gridcell')[0];
|
|
69
76
|
if (needsLongPress && interactionType === 'touch') {
|
|
70
77
|
if (this._advanceTimer == null) throw new Error('No advanceTimers provided for long press.');
|
|
71
78
|
// Note that long press interactions with rows is strictly touch only for grid rows
|
|
72
|
-
await (0, $
|
|
79
|
+
await (0, $22d7d9b763402afa$export$3a22a5a9bc0fd3b)({
|
|
73
80
|
element: cell,
|
|
74
81
|
advanceTimer: this._advanceTimer,
|
|
75
82
|
pointerOpts: {
|
|
@@ -78,44 +85,71 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
78
85
|
});
|
|
79
86
|
} else {
|
|
80
87
|
if (selectionBehavior === 'replace' && interactionType !== 'touch') await this.user.keyboard(`[${metaKey}>]`);
|
|
81
|
-
await (0, $
|
|
88
|
+
await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, cell, interactionType);
|
|
82
89
|
if (selectionBehavior === 'replace' && interactionType !== 'touch') await this.user.keyboard(`[/${metaKey}]`);
|
|
83
90
|
}
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
/**
|
|
94
|
+
* Toggles the expansion for the specified tree row. Defaults to using the interaction type set on the tree tester.
|
|
95
|
+
*/ async toggleRowExpansion(opts) {
|
|
96
|
+
let { row: row, interactionType: interactionType = this._interactionType } = opts;
|
|
97
|
+
if (!this.table.contains(document.activeElement)) await (0, $5mys8$act)(async ()=>{
|
|
98
|
+
this.table.focus();
|
|
99
|
+
});
|
|
100
|
+
if (typeof row === 'string' || typeof row === 'number') row = this.findRow({
|
|
101
|
+
rowIndexOrText: row
|
|
102
|
+
});
|
|
103
|
+
if (!row) throw new Error('Target row not found in the table.');
|
|
104
|
+
else if (row.getAttribute('aria-expanded') == null) throw new Error('Target row is not expandable.');
|
|
105
|
+
if (interactionType === 'mouse' || interactionType === 'touch') {
|
|
106
|
+
let rowExpander = (0, $5mys8$within)(row).getAllByRole('button')[0]; // what happens if the button is not first? how can we differentiate?
|
|
107
|
+
await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, rowExpander, interactionType);
|
|
108
|
+
} else if (interactionType === 'keyboard') {
|
|
109
|
+
if (row?.getAttribute('aria-disabled') === 'true') return;
|
|
110
|
+
// TODO: We always Use Option/Ctrl when keyboard navigating so selection isn't changed
|
|
111
|
+
// in selectionmode="replace"/highlight selection when navigating to the row that the user wants
|
|
112
|
+
// to expand. Discuss if this is useful or not
|
|
113
|
+
await this.keyboardNavigateToRow({
|
|
114
|
+
row: row
|
|
115
|
+
});
|
|
116
|
+
if (row.getAttribute('aria-expanded') === 'true') await this.user.keyboard('[ArrowLeft]');
|
|
117
|
+
else await this.user.keyboard('[ArrowRight]');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
87
121
|
* Toggles the sort order for the specified table column. Defaults to using the interaction type set on the table tester.
|
|
88
122
|
*/ async toggleSort(opts) {
|
|
89
123
|
let { column: column, interactionType: interactionType = this._interactionType } = opts;
|
|
90
124
|
let columnheader;
|
|
91
125
|
if (typeof column === 'number') columnheader = this.columns[column];
|
|
92
126
|
else if (typeof column === 'string') {
|
|
93
|
-
columnheader = (0, $
|
|
127
|
+
columnheader = (0, $5mys8$within)(this.rowGroups[0]).getByText(column);
|
|
94
128
|
while(columnheader && !/columnheader/.test(columnheader.getAttribute('role')))columnheader = columnheader.parentElement;
|
|
95
129
|
} else columnheader = column;
|
|
96
|
-
let menuButton = (0, $
|
|
130
|
+
let menuButton = (0, $5mys8$within)(columnheader).queryByRole('button');
|
|
97
131
|
if (menuButton) {
|
|
98
132
|
let currentSort = columnheader.getAttribute('aria-sort');
|
|
99
133
|
// TODO: Focus management is all kinda of messed up if I just use .focus and Space to open the sort menu. Seems like
|
|
100
134
|
// the focused key doesn't get properly set to the desired column header. Have to do this strange flow where I focus the
|
|
101
135
|
// column header except if the active element is already the menu button within the column header
|
|
102
|
-
if (interactionType === 'keyboard' && document.activeElement !== menuButton) await (0, $
|
|
103
|
-
else await (0, $
|
|
104
|
-
await (0, $
|
|
136
|
+
if (interactionType === 'keyboard' && document.activeElement !== menuButton) await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, columnheader, interactionType);
|
|
137
|
+
else await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, menuButton, interactionType);
|
|
138
|
+
await (0, $5mys8$waitFor)(()=>{
|
|
105
139
|
if (menuButton.getAttribute('aria-controls') == null) throw new Error('No aria-controls found on table column dropdown menu trigger element.');
|
|
106
140
|
else return true;
|
|
107
141
|
});
|
|
108
142
|
let menuId = menuButton.getAttribute('aria-controls');
|
|
109
|
-
await (0, $
|
|
143
|
+
await (0, $5mys8$waitFor)(()=>{
|
|
110
144
|
if (!menuId || document.getElementById(menuId) == null) throw new Error(`Table column header menu with id of ${menuId} not found in document.`);
|
|
111
145
|
else return true;
|
|
112
146
|
});
|
|
113
147
|
if (menuId) {
|
|
114
148
|
let menu = document.getElementById(menuId);
|
|
115
149
|
if (menu) {
|
|
116
|
-
if (currentSort === 'ascending') await (0, $
|
|
117
|
-
else await (0, $
|
|
118
|
-
await (0, $
|
|
150
|
+
if (currentSort === 'ascending') await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, (0, $5mys8$within)(menu).getAllByRole('menuitem')[1], interactionType);
|
|
151
|
+
else await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, (0, $5mys8$within)(menu).getAllByRole('menuitem')[0], interactionType);
|
|
152
|
+
await (0, $5mys8$waitFor)(()=>{
|
|
119
153
|
if (document.contains(menu)) throw new Error('Expected table column menu listbox to not be in the document after selecting an option');
|
|
120
154
|
else return true;
|
|
121
155
|
});
|
|
@@ -123,15 +157,14 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
123
157
|
}
|
|
124
158
|
// Handle cases where the table may transition in response to the row selection/deselection
|
|
125
159
|
if (!this._advanceTimer) throw new Error('No advanceTimers provided for table transition.');
|
|
126
|
-
await (0, $
|
|
127
|
-
|
|
128
|
-
await ((_this__advanceTimer = (_this = this)._advanceTimer) === null || _this__advanceTimer === void 0 ? void 0 : _this__advanceTimer.call(_this, 200));
|
|
160
|
+
await (0, $5mys8$act)(async ()=>{
|
|
161
|
+
await this._advanceTimer?.(200);
|
|
129
162
|
});
|
|
130
|
-
await (0, $
|
|
163
|
+
await (0, $5mys8$waitFor)(()=>{
|
|
131
164
|
if (document.activeElement !== menuButton) throw new Error(`Expected the document.activeElement to be the table column menu button but got ${document.activeElement}`);
|
|
132
165
|
else return true;
|
|
133
166
|
});
|
|
134
|
-
} else await (0, $
|
|
167
|
+
} else await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, columnheader, interactionType);
|
|
135
168
|
}
|
|
136
169
|
/**
|
|
137
170
|
* Triggers an action for the specified table column menu. Defaults to using the interaction type set on the table tester.
|
|
@@ -140,30 +173,30 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
140
173
|
let columnheader;
|
|
141
174
|
if (typeof column === 'number') columnheader = this.columns[column];
|
|
142
175
|
else if (typeof column === 'string') {
|
|
143
|
-
columnheader = (0, $
|
|
176
|
+
columnheader = (0, $5mys8$within)(this.rowGroups[0]).getByText(column);
|
|
144
177
|
while(columnheader && !/columnheader/.test(columnheader.getAttribute('role')))columnheader = columnheader.parentElement;
|
|
145
178
|
} else columnheader = column;
|
|
146
|
-
let menuButton = (0, $
|
|
179
|
+
let menuButton = (0, $5mys8$within)(columnheader).queryByRole('button');
|
|
147
180
|
if (menuButton) {
|
|
148
181
|
// TODO: Focus management is all kinda of messed up if I just use .focus and Space to open the sort menu. Seems like
|
|
149
182
|
// the focused key doesn't get properly set to the desired column header. Have to do this strange flow where I focus the
|
|
150
183
|
// column header except if the active element is already the menu button within the column header
|
|
151
|
-
if (interactionType === 'keyboard' && document.activeElement !== menuButton) await (0, $
|
|
152
|
-
else await (0, $
|
|
153
|
-
await (0, $
|
|
184
|
+
if (interactionType === 'keyboard' && document.activeElement !== menuButton) await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, columnheader, interactionType);
|
|
185
|
+
else await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, menuButton, interactionType);
|
|
186
|
+
await (0, $5mys8$waitFor)(()=>{
|
|
154
187
|
if (menuButton.getAttribute('aria-controls') == null) throw new Error('No aria-controls found on table column dropdown menu trigger element.');
|
|
155
188
|
else return true;
|
|
156
189
|
});
|
|
157
190
|
let menuId = menuButton.getAttribute('aria-controls');
|
|
158
|
-
await (0, $
|
|
191
|
+
await (0, $5mys8$waitFor)(()=>{
|
|
159
192
|
if (!menuId || document.getElementById(menuId) == null) throw new Error(`Table column header menu with id of ${menuId} not found in document.`);
|
|
160
193
|
else return true;
|
|
161
194
|
});
|
|
162
195
|
if (menuId) {
|
|
163
196
|
let menu = document.getElementById(menuId);
|
|
164
197
|
if (menu) {
|
|
165
|
-
await (0, $
|
|
166
|
-
await (0, $
|
|
198
|
+
await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, (0, $5mys8$within)(menu).getAllByRole('menuitem')[action], interactionType);
|
|
199
|
+
await (0, $5mys8$waitFor)(()=>{
|
|
167
200
|
if (document.contains(menu)) throw new Error('Expected table column menu listbox to not be in the document after selecting an option');
|
|
168
201
|
else return true;
|
|
169
202
|
});
|
|
@@ -171,11 +204,10 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
171
204
|
}
|
|
172
205
|
// Handle cases where the table may transition in response to the row selection/deselection
|
|
173
206
|
if (!this._advanceTimer) throw new Error('No advanceTimers provided for table transition.');
|
|
174
|
-
await (0, $
|
|
175
|
-
|
|
176
|
-
await ((_this__advanceTimer = (_this = this)._advanceTimer) === null || _this__advanceTimer === void 0 ? void 0 : _this__advanceTimer.call(_this, 200));
|
|
207
|
+
await (0, $5mys8$act)(async ()=>{
|
|
208
|
+
await this._advanceTimer?.(200);
|
|
177
209
|
});
|
|
178
|
-
await (0, $
|
|
210
|
+
await (0, $5mys8$waitFor)(()=>{
|
|
179
211
|
if (document.activeElement !== menuButton) throw new Error(`Expected the document.activeElement to be the table column menu button but got ${document.activeElement}`);
|
|
180
212
|
else return true;
|
|
181
213
|
});
|
|
@@ -196,7 +228,7 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
196
228
|
selectionOnNav: 'none'
|
|
197
229
|
});
|
|
198
230
|
await this.user.keyboard('[Enter]');
|
|
199
|
-
} else await (0, $
|
|
231
|
+
} else await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, row, interactionType);
|
|
200
232
|
}
|
|
201
233
|
// TODO: should there be utils for drag and drop and column resizing? For column resizing, I'm not entirely convinced that users will be doing that in their tests.
|
|
202
234
|
// For DnD, it might be tricky to do for keyboard DnD since we wouldn't know what valid drop zones there are... Similarly, for simulating mouse drag and drop the coordinates depend
|
|
@@ -207,10 +239,10 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
207
239
|
* Toggle selection for all rows in the table. Defaults to using the interaction type set on the table tester.
|
|
208
240
|
*/ async toggleSelectAll(opts = {}) {
|
|
209
241
|
let { interactionType: interactionType = this._interactionType } = opts;
|
|
210
|
-
let checkbox = (0, $
|
|
242
|
+
let checkbox = (0, $5mys8$within)(this.table).getByLabelText('Select All');
|
|
211
243
|
if (interactionType === 'keyboard') // TODO: using the .focus -> trigger keyboard Enter approach doesn't work for some reason, for now just trigger select all with click.
|
|
212
244
|
await this.user.click(checkbox);
|
|
213
|
-
else await (0, $
|
|
245
|
+
else await (0, $22d7d9b763402afa$export$6ffa3eb717517feb)(this.user, checkbox, interactionType);
|
|
214
246
|
}
|
|
215
247
|
/**
|
|
216
248
|
* Returns a row matching the specified index or text content.
|
|
@@ -221,7 +253,7 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
221
253
|
let bodyRowGroup = this.rowGroups[1];
|
|
222
254
|
if (typeof rowIndexOrText === 'number') row = rows[rowIndexOrText];
|
|
223
255
|
else if (typeof rowIndexOrText === 'string') {
|
|
224
|
-
row = (0, $
|
|
256
|
+
row = (0, $5mys8$within)(bodyRowGroup).getByText(rowIndexOrText);
|
|
225
257
|
while(row && row.getAttribute('role') !== 'row')row = row.parentElement;
|
|
226
258
|
}
|
|
227
259
|
return row;
|
|
@@ -230,7 +262,7 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
230
262
|
* Returns a cell matching the specified text content.
|
|
231
263
|
*/ findCell(opts) {
|
|
232
264
|
let { text: text } = opts;
|
|
233
|
-
let cell = (0, $
|
|
265
|
+
let cell = (0, $5mys8$within)(this.table).getByText(text);
|
|
234
266
|
if (cell) while(cell && !/gridcell|rowheader|columnheader/.test(cell.getAttribute('role') || '')){
|
|
235
267
|
if (cell.parentElement) cell = cell.parentElement;
|
|
236
268
|
else break;
|
|
@@ -246,19 +278,19 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
246
278
|
* Returns the row groups within the table.
|
|
247
279
|
*/ get rowGroups() {
|
|
248
280
|
let table = this._table;
|
|
249
|
-
return table ? (0, $
|
|
281
|
+
return table ? (0, $5mys8$within)(table).queryAllByRole('rowgroup') : [];
|
|
250
282
|
}
|
|
251
283
|
/**
|
|
252
284
|
* Returns the columns within the table.
|
|
253
285
|
*/ get columns() {
|
|
254
286
|
let headerRowGroup = this.rowGroups[0];
|
|
255
|
-
return headerRowGroup ? (0, $
|
|
287
|
+
return headerRowGroup ? (0, $5mys8$within)(headerRowGroup).queryAllByRole('columnheader') : [];
|
|
256
288
|
}
|
|
257
289
|
/**
|
|
258
290
|
* Returns the rows within the table if any.
|
|
259
291
|
*/ get rows() {
|
|
260
292
|
let bodyRowGroup = this.rowGroups[1];
|
|
261
|
-
return bodyRowGroup ? (0, $
|
|
293
|
+
return bodyRowGroup ? (0, $5mys8$within)(bodyRowGroup).queryAllByRole('row') : [];
|
|
262
294
|
}
|
|
263
295
|
/**
|
|
264
296
|
* Returns the currently selected rows within the table if any.
|
|
@@ -268,23 +300,16 @@ class $6d1e4cf220920c37$export$4c6a9d6ae3b0086 {
|
|
|
268
300
|
/**
|
|
269
301
|
* Returns the row headers within the table if any.
|
|
270
302
|
*/ get rowHeaders() {
|
|
271
|
-
return (0, $
|
|
303
|
+
return (0, $5mys8$within)(this.table).queryAllByRole('rowheader');
|
|
272
304
|
}
|
|
273
305
|
/**
|
|
274
306
|
* Returns the cells within the table if any. Can be filtered against a specific row if provided via `element`.
|
|
275
307
|
*/ cells(opts = {}) {
|
|
276
308
|
let { element: element = this.table } = opts;
|
|
277
|
-
return (0, $
|
|
278
|
-
}
|
|
279
|
-
constructor(opts){
|
|
280
|
-
let { root: root, user: user, interactionType: interactionType, advanceTimer: advanceTimer } = opts;
|
|
281
|
-
this.user = user;
|
|
282
|
-
this._interactionType = interactionType || 'mouse';
|
|
283
|
-
this._advanceTimer = advanceTimer;
|
|
284
|
-
this._table = root;
|
|
309
|
+
return (0, $5mys8$within)(element).queryAllByRole('gridcell');
|
|
285
310
|
}
|
|
286
311
|
}
|
|
287
312
|
|
|
288
313
|
|
|
289
|
-
export {$
|
|
290
|
-
//# sourceMappingURL=table.
|
|
314
|
+
export {$196900c7f8f394b6$export$4c6a9d6ae3b0086 as TableTester};
|
|
315
|
+
//# sourceMappingURL=table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["packages/@react-aria/test-utils/src/table.ts"],"sourcesContent":["/*\n * Copyright 2024 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {act, waitFor, within} from '@testing-library/react';\nimport {BaseGridRowInteractionOpts, GridRowActionOpts, TableTesterOpts, ToggleGridRowOpts, UserOpts} from './types';\nimport {getAltKey, getMetaKey, pressElement, triggerLongPress} from './events';\n\ninterface TableToggleRowOpts extends ToggleGridRowOpts {}\ninterface TableToggleExpansionOpts extends BaseGridRowInteractionOpts {}\ninterface TableToggleSortOpts {\n /**\n * The index, text, or node of the column to toggle selection for.\n */\n column: number | string | HTMLElement,\n /**\n * What interaction type to use when sorting the column. Defaults to the interaction type set on the tester.\n */\n interactionType?: UserOpts['interactionType']\n}\ninterface TableColumnHeaderActionOpts extends TableToggleSortOpts {\n /**\n * The index of the column header action to trigger.\n */\n action: number\n}\ninterface TableRowActionOpts extends GridRowActionOpts {}\n\nexport class TableTester {\n private user;\n private _interactionType: UserOpts['interactionType'];\n private _advanceTimer: UserOpts['advanceTimer'];\n private _table: HTMLElement;\n\n constructor(opts: TableTesterOpts) {\n let {root, user, interactionType, advanceTimer} = opts;\n this.user = user;\n this._interactionType = interactionType || 'mouse';\n this._advanceTimer = advanceTimer;\n this._table = root;\n }\n\n /**\n * Set the interaction type used by the table tester.\n */\n setInteractionType(type: UserOpts['interactionType']): void {\n this._interactionType = type;\n }\n\n // TODO: RTL\n private async keyboardNavigateToRow(opts: {row: HTMLElement, selectionOnNav?: 'default' | 'none'}) {\n let {row, selectionOnNav = 'default'} = opts;\n let altKey = getAltKey();\n let rows = this.rows;\n let targetIndex = rows.indexOf(row);\n if (targetIndex === -1) {\n throw new Error('Row provided is not in the table');\n }\n\n // Move focus into the table\n if (document.activeElement !== this._table && !this._table.contains(document.activeElement)) {\n act(() => this._table.focus());\n }\n\n if (document.activeElement === this._table) {\n await this.user.keyboard('[ArrowDown]');\n }\n\n // If focus is currently somewhere in the first row group (aka on a column), we want to keyboard navigate downwards till we reach the rows\n if (this.rowGroups[0].contains(document.activeElement)) {\n do {\n await this.user.keyboard('[ArrowDown]');\n } while (!this.rowGroups[1].contains(document.activeElement));\n }\n\n // Move focus onto the row itself\n if (this.rowGroups[1].contains(document.activeElement) && document.activeElement!.getAttribute('role') !== 'row') {\n do {\n await this.user.keyboard('[ArrowLeft]');\n } while (document.activeElement!.getAttribute('role') !== 'row');\n }\n let currIndex = rows.indexOf(document.activeElement as HTMLElement);\n if (currIndex === -1) {\n throw new Error('Current active element is not on any of the table rows');\n }\n let direction = targetIndex > currIndex ? 'down' : 'up';\n\n if (selectionOnNav === 'none') {\n await this.user.keyboard(`[${altKey}>]`);\n }\n for (let i = 0; i < Math.abs(targetIndex - currIndex); i++) {\n await this.user.keyboard(`[${direction === 'down' ? 'ArrowDown' : 'ArrowUp'}]`);\n }\n if (selectionOnNav === 'none') {\n await this.user.keyboard(`[/${altKey}]`);\n }\n };\n\n /**\n * Toggles the selection for the specified table row. Defaults to using the interaction type set on the table tester.\n */\n async toggleRowSelection(opts: TableToggleRowOpts): Promise<void> {\n let {\n row,\n needsLongPress,\n checkboxSelection = true,\n interactionType = this._interactionType,\n selectionBehavior = 'toggle'\n } = opts;\n\n let altKey = getMetaKey();\n let metaKey = getMetaKey();\n\n if (typeof row === 'string' || typeof row === 'number') {\n row = this.findRow({rowIndexOrText: row});\n }\n\n if (!row) {\n throw new Error('Target row not found in the table.');\n }\n\n let rowCheckbox = within(row).queryByRole('checkbox');\n\n if (interactionType === 'keyboard' && (!checkboxSelection || !rowCheckbox)) {\n await this.keyboardNavigateToRow({row, selectionOnNav: selectionBehavior === 'replace' ? 'none' : 'default'});\n if (selectionBehavior === 'replace') {\n await this.user.keyboard(`[${altKey}>]`);\n }\n await this.user.keyboard('[Space]');\n if (selectionBehavior === 'replace') {\n await this.user.keyboard(`[/${altKey}]`);\n }\n return;\n }\n if (rowCheckbox && checkboxSelection) {\n await pressElement(this.user, rowCheckbox, interactionType);\n } else {\n let cell = within(row).getAllByRole('gridcell')[0];\n if (needsLongPress && interactionType === 'touch') {\n if (this._advanceTimer == null) {\n throw new Error('No advanceTimers provided for long press.');\n }\n\n // Note that long press interactions with rows is strictly touch only for grid rows\n await triggerLongPress({element: cell, advanceTimer: this._advanceTimer, pointerOpts: {pointerType: 'touch'}});\n } else {\n if (selectionBehavior === 'replace' && interactionType !== 'touch') {\n await this.user.keyboard(`[${metaKey}>]`);\n }\n await pressElement(this.user, cell, interactionType);\n if (selectionBehavior === 'replace' && interactionType !== 'touch') {\n await this.user.keyboard(`[/${metaKey}]`);\n }\n }\n }\n };\n\n /**\n * Toggles the expansion for the specified tree row. Defaults to using the interaction type set on the tree tester.\n */\n async toggleRowExpansion(opts: TableToggleExpansionOpts): Promise<void> {\n let {\n row,\n interactionType = this._interactionType\n } = opts;\n if (!this.table.contains(document.activeElement)) {\n await act(async () => {\n this.table.focus();\n });\n }\n\n if (typeof row === 'string' || typeof row === 'number') {\n row = this.findRow({rowIndexOrText: row});\n }\n\n if (!row) {\n throw new Error('Target row not found in the table.');\n } else if (row.getAttribute('aria-expanded') == null) {\n throw new Error('Target row is not expandable.');\n }\n\n if (interactionType === 'mouse' || interactionType === 'touch') {\n let rowExpander = within(row).getAllByRole('button')[0]; // what happens if the button is not first? how can we differentiate?\n await pressElement(this.user, rowExpander, interactionType);\n } else if (interactionType === 'keyboard') {\n if (row?.getAttribute('aria-disabled') === 'true') {\n return;\n }\n\n // TODO: We always Use Option/Ctrl when keyboard navigating so selection isn't changed\n // in selectionmode=\"replace\"/highlight selection when navigating to the row that the user wants\n // to expand. Discuss if this is useful or not\n await this.keyboardNavigateToRow({row});\n if (row.getAttribute('aria-expanded') === 'true') {\n await this.user.keyboard('[ArrowLeft]');\n } else {\n await this.user.keyboard('[ArrowRight]');\n }\n }\n };\n\n /**\n * Toggles the sort order for the specified table column. Defaults to using the interaction type set on the table tester.\n */\n async toggleSort(opts: TableToggleSortOpts): Promise<void> {\n let {\n column,\n interactionType = this._interactionType\n } = opts;\n\n let columnheader;\n if (typeof column === 'number') {\n columnheader = this.columns[column];\n } else if (typeof column === 'string') {\n columnheader = within(this.rowGroups[0]).getByText(column);\n while (columnheader && !/columnheader/.test(columnheader.getAttribute('role'))) {\n columnheader = columnheader.parentElement;\n }\n } else {\n columnheader = column;\n }\n\n let menuButton = within(columnheader).queryByRole('button');\n if (menuButton) {\n let currentSort = columnheader.getAttribute('aria-sort');\n // TODO: Focus management is all kinda of messed up if I just use .focus and Space to open the sort menu. Seems like\n // the focused key doesn't get properly set to the desired column header. Have to do this strange flow where I focus the\n // column header except if the active element is already the menu button within the column header\n if (interactionType === 'keyboard' && document.activeElement !== menuButton) {\n await pressElement(this.user, columnheader, interactionType);\n } else {\n await pressElement(this.user, menuButton, interactionType);\n }\n\n await waitFor(() => {\n if (menuButton.getAttribute('aria-controls') == null) {\n throw new Error('No aria-controls found on table column dropdown menu trigger element.');\n } else {\n return true;\n }\n });\n\n let menuId = menuButton.getAttribute('aria-controls');\n await waitFor(() => {\n if (!menuId || document.getElementById(menuId) == null) {\n throw new Error(`Table column header menu with id of ${menuId} not found in document.`);\n } else {\n return true;\n }\n });\n\n if (menuId) {\n let menu = document.getElementById(menuId);\n if (menu) {\n if (currentSort === 'ascending') {\n await pressElement(this.user, within(menu).getAllByRole('menuitem')[1], interactionType);\n } else {\n await pressElement(this.user, within(menu).getAllByRole('menuitem')[0], interactionType);\n }\n\n await waitFor(() => {\n if (document.contains(menu)) {\n throw new Error('Expected table column menu listbox to not be in the document after selecting an option');\n } else {\n return true;\n }\n });\n }\n }\n\n // Handle cases where the table may transition in response to the row selection/deselection\n if (!this._advanceTimer) {\n throw new Error('No advanceTimers provided for table transition.');\n }\n\n await act(async () => {\n await this._advanceTimer?.(200);\n });\n\n await waitFor(() => {\n if (document.activeElement !== menuButton) {\n throw new Error(`Expected the document.activeElement to be the table column menu button but got ${document.activeElement}`);\n } else {\n return true;\n }\n });\n } else {\n await pressElement(this.user, columnheader, interactionType);\n }\n }\n\n /**\n * Triggers an action for the specified table column menu. Defaults to using the interaction type set on the table tester.\n */\n async triggerColumnHeaderAction(opts: TableColumnHeaderActionOpts): Promise<void> {\n let {\n column,\n interactionType = this._interactionType,\n action\n } = opts;\n\n let columnheader;\n if (typeof column === 'number') {\n columnheader = this.columns[column];\n } else if (typeof column === 'string') {\n columnheader = within(this.rowGroups[0]).getByText(column);\n while (columnheader && !/columnheader/.test(columnheader.getAttribute('role'))) {\n columnheader = columnheader.parentElement;\n }\n } else {\n columnheader = column;\n }\n\n let menuButton = within(columnheader).queryByRole('button');\n if (menuButton) {\n // TODO: Focus management is all kinda of messed up if I just use .focus and Space to open the sort menu. Seems like\n // the focused key doesn't get properly set to the desired column header. Have to do this strange flow where I focus the\n // column header except if the active element is already the menu button within the column header\n if (interactionType === 'keyboard' && document.activeElement !== menuButton) {\n await pressElement(this.user, columnheader, interactionType);\n } else {\n await pressElement(this.user, menuButton, interactionType);\n }\n\n await waitFor(() => {\n if (menuButton.getAttribute('aria-controls') == null) {\n throw new Error('No aria-controls found on table column dropdown menu trigger element.');\n } else {\n return true;\n }\n });\n\n let menuId = menuButton.getAttribute('aria-controls');\n await waitFor(() => {\n if (!menuId || document.getElementById(menuId) == null) {\n throw new Error(`Table column header menu with id of ${menuId} not found in document.`);\n } else {\n return true;\n }\n });\n\n if (menuId) {\n let menu = document.getElementById(menuId);\n if (menu) {\n await pressElement(this.user, within(menu).getAllByRole('menuitem')[action], interactionType);\n\n await waitFor(() => {\n if (document.contains(menu)) {\n throw new Error('Expected table column menu listbox to not be in the document after selecting an option');\n } else {\n return true;\n }\n });\n }\n }\n\n // Handle cases where the table may transition in response to the row selection/deselection\n if (!this._advanceTimer) {\n throw new Error('No advanceTimers provided for table transition.');\n }\n\n await act(async () => {\n await this._advanceTimer?.(200);\n });\n\n await waitFor(() => {\n if (document.activeElement !== menuButton) {\n throw new Error(`Expected the document.activeElement to be the table column menu button but got ${document.activeElement}`);\n } else {\n return true;\n }\n });\n } else {\n throw new Error('No menu button found on table column header.');\n }\n }\n\n /**\n * Triggers the action for the specified table row. Defaults to using the interaction type set on the table tester.\n */\n async triggerRowAction(opts: TableRowActionOpts): Promise<void> {\n let {\n row,\n needsDoubleClick,\n interactionType = this._interactionType\n } = opts;\n\n if (typeof row === 'string' || typeof row === 'number') {\n row = this.findRow({rowIndexOrText: row});\n }\n\n if (!row) {\n throw new Error('Target row not found in the table.');\n }\n\n if (needsDoubleClick) {\n await this.user.dblClick(row);\n } else if (interactionType === 'keyboard') {\n await this.keyboardNavigateToRow({row, selectionOnNav: 'none'});\n await this.user.keyboard('[Enter]');\n } else {\n await pressElement(this.user, row, interactionType);\n }\n }\n\n // TODO: should there be utils for drag and drop and column resizing? For column resizing, I'm not entirely convinced that users will be doing that in their tests.\n // For DnD, it might be tricky to do for keyboard DnD since we wouldn't know what valid drop zones there are... Similarly, for simulating mouse drag and drop the coordinates depend\n // on the mocks the user sets up for their row height/etc.\n // Additionally, should we also support keyboard navigation/typeahead? Those felt like they could be very easily replicated by the user via user.keyboard already and don't really\n // add much value if we provide that to them\n /**\n * Toggle selection for all rows in the table. Defaults to using the interaction type set on the table tester.\n */\n async toggleSelectAll(opts: {interactionType?: UserOpts['interactionType']} = {}): Promise<void> {\n let {\n interactionType = this._interactionType\n } = opts;\n let checkbox = within(this.table).getByLabelText('Select All');\n if (interactionType === 'keyboard') {\n // TODO: using the .focus -> trigger keyboard Enter approach doesn't work for some reason, for now just trigger select all with click.\n await this.user.click(checkbox);\n } else {\n await pressElement(this.user, checkbox, interactionType);\n }\n }\n\n /**\n * Returns a row matching the specified index or text content.\n */\n findRow(opts: {rowIndexOrText: number | string}): HTMLElement {\n let {\n rowIndexOrText\n } = opts;\n\n let row;\n let rows = this.rows;\n let bodyRowGroup = this.rowGroups[1];\n if (typeof rowIndexOrText === 'number') {\n row = rows[rowIndexOrText];\n } else if (typeof rowIndexOrText === 'string') {\n row = within(bodyRowGroup).getByText(rowIndexOrText);\n while (row && row.getAttribute('role') !== 'row') {\n row = row.parentElement;\n }\n }\n\n return row;\n }\n\n /**\n * Returns a cell matching the specified text content.\n */\n findCell(opts: {text: string}): HTMLElement {\n let {\n text\n } = opts;\n\n let cell = within(this.table).getByText(text);\n if (cell) {\n while (cell && !/gridcell|rowheader|columnheader/.test(cell.getAttribute('role') || '')) {\n if (cell.parentElement) {\n cell = cell.parentElement;\n } else {\n break;\n }\n }\n }\n\n return cell;\n }\n\n /**\n * Returns the table.\n */\n get table(): HTMLElement {\n return this._table;\n }\n\n /**\n * Returns the row groups within the table.\n */\n get rowGroups(): HTMLElement[] {\n let table = this._table;\n return table ? within(table).queryAllByRole('rowgroup') : [];\n }\n\n /**\n * Returns the columns within the table.\n */\n get columns(): HTMLElement[] {\n let headerRowGroup = this.rowGroups[0];\n return headerRowGroup ? within(headerRowGroup).queryAllByRole('columnheader') : [];\n }\n\n /**\n * Returns the rows within the table if any.\n */\n get rows(): HTMLElement[] {\n let bodyRowGroup = this.rowGroups[1];\n return bodyRowGroup ? within(bodyRowGroup).queryAllByRole('row') : [];\n }\n\n /**\n * Returns the currently selected rows within the table if any.\n */\n get selectedRows(): HTMLElement[] {\n return this.rows.filter(row => row.getAttribute('aria-selected') === 'true');\n }\n\n /**\n * Returns the row headers within the table if any.\n */\n get rowHeaders(): HTMLElement[] {\n return within(this.table).queryAllByRole('rowheader');\n }\n\n /**\n * Returns the cells within the table if any. Can be filtered against a specific row if provided via `element`.\n */\n cells(opts: {element?: HTMLElement} = {}): HTMLElement[] {\n let {element = this.table} = opts;\n return within(element).queryAllByRole('gridcell');\n }\n}\n"],"names":[],"version":3,"file":"table.js.map"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
var $
|
|
2
|
-
var $
|
|
1
|
+
var $01a4eeee86094c77$exports = require("./events.cjs");
|
|
2
|
+
var $6Eyxy$testinglibraryreact = require("@testing-library/react");
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
function $parcel$export(e, n, v, s) {
|
|
6
6
|
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
$parcel$export(module.exports, "TabsTester", ()
|
|
9
|
+
$parcel$export(module.exports, "TabsTester", function () { return $d225318b7bd4eacf$export$f1539bff3fc7d485; });
|
|
10
10
|
/*
|
|
11
11
|
* Copyright 2024 Adobe. All rights reserved.
|
|
12
12
|
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -19,7 +19,16 @@ $parcel$export(module.exports, "TabsTester", () => $19633c03aff25ae5$export$f153
|
|
|
19
19
|
* governing permissions and limitations under the License.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
class $
|
|
22
|
+
class $d225318b7bd4eacf$export$f1539bff3fc7d485 {
|
|
23
|
+
constructor(opts){
|
|
24
|
+
let { root: root, user: user, interactionType: interactionType, direction: direction } = opts;
|
|
25
|
+
this.user = user;
|
|
26
|
+
this._interactionType = interactionType || 'mouse';
|
|
27
|
+
this._direction = direction || 'ltr';
|
|
28
|
+
this._tablist = root;
|
|
29
|
+
let tablist = (0, $6Eyxy$testinglibraryreact.within)(root).queryAllByRole('tablist');
|
|
30
|
+
if (tablist.length > 0) this._tablist = tablist[0];
|
|
31
|
+
}
|
|
23
32
|
/**
|
|
24
33
|
* Set the interaction type used by the tabs tester.
|
|
25
34
|
*/ setInteractionType(type) {
|
|
@@ -33,24 +42,23 @@ class $19633c03aff25ae5$export$f1539bff3fc7d485 {
|
|
|
33
42
|
let tab;
|
|
34
43
|
let tabs = this.tabs;
|
|
35
44
|
if (typeof tabIndexOrText === 'number') tab = tabs[tabIndexOrText];
|
|
36
|
-
else if (typeof tabIndexOrText === 'string') tab = (0, $
|
|
45
|
+
else if (typeof tabIndexOrText === 'string') tab = (0, $6Eyxy$testinglibraryreact.within)(this._tablist).getByText(tabIndexOrText).closest('[role=tab]');
|
|
37
46
|
return tab;
|
|
38
47
|
}
|
|
39
48
|
// TODO: also quite similar across more utils albeit with orientation, refactor to make generic
|
|
40
49
|
async keyboardNavigateToTab(opts) {
|
|
41
50
|
let { tab: tab, orientation: orientation = 'vertical' } = opts;
|
|
42
51
|
let tabs = this.tabs;
|
|
52
|
+
tabs = tabs.filter((tab)=>!(tab.hasAttribute('disabled') || tab.getAttribute('aria-disabled') === 'true'));
|
|
53
|
+
if (tabs.length === 0) throw new Error('Tablist doesnt have any non-disabled tabs. Please double check your tabs implementation.');
|
|
43
54
|
let targetIndex = tabs.indexOf(tab);
|
|
44
55
|
if (targetIndex === -1) throw new Error('Tab provided is not in the tablist');
|
|
45
56
|
if (!this._tablist.contains(document.activeElement)) {
|
|
46
57
|
let selectedTab = this.selectedTab;
|
|
47
|
-
if (selectedTab != null) (0, $
|
|
48
|
-
else (0, $
|
|
49
|
-
var _tabs_find;
|
|
50
|
-
return (_tabs_find = tabs.find((tab)=>!(tab.hasAttribute('disabled') || tab.getAttribute('aria-disabled') === 'true'))) === null || _tabs_find === void 0 ? void 0 : _tabs_find.focus();
|
|
51
|
-
});
|
|
58
|
+
if (selectedTab != null) (0, $6Eyxy$testinglibraryreact.act)(()=>selectedTab.focus());
|
|
59
|
+
else (0, $6Eyxy$testinglibraryreact.act)(()=>tabs[0]?.focus());
|
|
52
60
|
}
|
|
53
|
-
let currIndex =
|
|
61
|
+
let currIndex = tabs.indexOf(document.activeElement);
|
|
54
62
|
if (currIndex === -1) throw new Error('ActiveElement is not in the tablist');
|
|
55
63
|
let arrowUp = 'ArrowUp';
|
|
56
64
|
let arrowDown = 'ArrowDown';
|
|
@@ -76,14 +84,14 @@ class $19633c03aff25ae5$export$f1539bff3fc7d485 {
|
|
|
76
84
|
if (!tab) throw new Error('Target tab not found in the tablist.');
|
|
77
85
|
else if (tab.hasAttribute('disabled')) throw new Error('Target tab is disabled.');
|
|
78
86
|
if (interactionType === 'keyboard') {
|
|
79
|
-
if (document.activeElement !== this._tablist && !this._tablist.contains(document.activeElement)) (0, $
|
|
87
|
+
if (document.activeElement !== this._tablist && !this._tablist.contains(document.activeElement)) (0, $6Eyxy$testinglibraryreact.act)(()=>this._tablist.focus());
|
|
80
88
|
let tabsOrientation = this._tablist.getAttribute('aria-orientation') || 'horizontal';
|
|
81
89
|
await this.keyboardNavigateToTab({
|
|
82
90
|
tab: tab,
|
|
83
91
|
orientation: tabsOrientation
|
|
84
92
|
});
|
|
85
93
|
if (manualActivation) await this.user.keyboard('[Enter]');
|
|
86
|
-
} else await (0, $
|
|
94
|
+
} else await (0, $01a4eeee86094c77$exports.pressElement)(this.user, tab, interactionType);
|
|
87
95
|
}
|
|
88
96
|
/**
|
|
89
97
|
* Returns the tablist.
|
|
@@ -104,7 +112,7 @@ class $19633c03aff25ae5$export$f1539bff3fc7d485 {
|
|
|
104
112
|
/**
|
|
105
113
|
* Returns the tabs in the tablist.
|
|
106
114
|
*/ get tabs() {
|
|
107
|
-
return (0, $
|
|
115
|
+
return (0, $6Eyxy$testinglibraryreact.within)(this.tablist).queryAllByRole('tab');
|
|
108
116
|
}
|
|
109
117
|
/**
|
|
110
118
|
* Returns the currently selected tab in the tablist if any.
|
|
@@ -114,20 +122,10 @@ class $19633c03aff25ae5$export$f1539bff3fc7d485 {
|
|
|
114
122
|
/**
|
|
115
123
|
* Returns the currently active tabpanel if any.
|
|
116
124
|
*/ get activeTabpanel() {
|
|
117
|
-
|
|
118
|
-
let activeTabpanelId = (_this_selectedTab = this.selectedTab) === null || _this_selectedTab === void 0 ? void 0 : _this_selectedTab.getAttribute('aria-controls');
|
|
125
|
+
let activeTabpanelId = this.selectedTab?.getAttribute('aria-controls');
|
|
119
126
|
return activeTabpanelId ? document.getElementById(activeTabpanelId) : null;
|
|
120
127
|
}
|
|
121
|
-
constructor(opts){
|
|
122
|
-
let { root: root, user: user, interactionType: interactionType, direction: direction } = opts;
|
|
123
|
-
this.user = user;
|
|
124
|
-
this._interactionType = interactionType || 'mouse';
|
|
125
|
-
this._direction = direction || 'ltr';
|
|
126
|
-
this._tablist = root;
|
|
127
|
-
let tablist = (0, $1inx6$testinglibraryreact.within)(root).queryAllByRole('tablist');
|
|
128
|
-
if (tablist.length > 0) this._tablist = tablist[0];
|
|
129
|
-
}
|
|
130
128
|
}
|
|
131
129
|
|
|
132
130
|
|
|
133
|
-
//# sourceMappingURL=tabs.
|
|
131
|
+
//# sourceMappingURL=tabs.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["packages/@react-aria/test-utils/src/tabs.ts"],"sourcesContent":["/*\n * Copyright 2024 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {act, within} from '@testing-library/react';\nimport {Direction, Orientation, TabsTesterOpts, UserOpts} from './types';\nimport {pressElement} from './events';\n\ninterface TriggerTabOptions {\n /**\n * What interaction type to use when triggering a tab. Defaults to the interaction type set on the tester.\n */\n interactionType?: UserOpts['interactionType'],\n /**\n * The index, text, or node of the tab to toggle selection for.\n */\n tab: number | string | HTMLElement,\n /**\n * Whether the tab needs to be activated manually rather than on focus.\n */\n manualActivation?: boolean\n}\n\nexport class TabsTester {\n private user;\n private _interactionType: UserOpts['interactionType'];\n private _tablist: HTMLElement;\n private _direction: Direction;\n\n constructor(opts: TabsTesterOpts) {\n let {root, user, interactionType, direction} = opts;\n this.user = user;\n this._interactionType = interactionType || 'mouse';\n this._direction = direction || 'ltr';\n\n this._tablist = root;\n let tablist = within(root).queryAllByRole('tablist');\n if (tablist.length > 0) {\n this._tablist = tablist[0];\n }\n }\n\n /**\n * Set the interaction type used by the tabs tester.\n */\n setInteractionType(type: UserOpts['interactionType']): void {\n this._interactionType = type;\n }\n\n // TODO: This is pretty similar across most the utils, refactor to make it generic?\n /**\n * Returns a tab matching the specified index or text content.\n */\n findTab(opts: {tabIndexOrText: number | string}): HTMLElement {\n let {\n tabIndexOrText\n } = opts;\n\n let tab;\n let tabs = this.tabs;\n if (typeof tabIndexOrText === 'number') {\n tab = tabs[tabIndexOrText];\n } else if (typeof tabIndexOrText === 'string') {\n tab = (within(this._tablist).getByText(tabIndexOrText).closest('[role=tab]'))! as HTMLElement;\n }\n\n return tab;\n }\n\n // TODO: also quite similar across more utils albeit with orientation, refactor to make generic\n private async keyboardNavigateToTab(opts: {tab: HTMLElement, orientation?: Orientation}) {\n let {tab, orientation = 'vertical'} = opts;\n let tabs = this.tabs;\n tabs = tabs.filter(tab => !(tab.hasAttribute('disabled') || tab.getAttribute('aria-disabled') === 'true'));\n if (tabs.length === 0) {\n throw new Error('Tablist doesnt have any non-disabled tabs. Please double check your tabs implementation.');\n }\n\n let targetIndex = tabs.indexOf(tab);\n if (targetIndex === -1) {\n throw new Error('Tab provided is not in the tablist');\n }\n\n if (!this._tablist.contains(document.activeElement)) {\n let selectedTab = this.selectedTab;\n if (selectedTab != null) {\n act(() => selectedTab.focus());\n } else {\n act(() => tabs[0]?.focus());\n }\n }\n\n let currIndex = tabs.indexOf(document.activeElement as HTMLElement);\n if (currIndex === -1) {\n throw new Error('ActiveElement is not in the tablist');\n }\n\n let arrowUp = 'ArrowUp';\n let arrowDown = 'ArrowDown';\n if (orientation === 'horizontal') {\n if (this._direction === 'ltr') {\n arrowUp = 'ArrowLeft';\n arrowDown = 'ArrowRight';\n } else {\n arrowUp = 'ArrowRight';\n arrowDown = 'ArrowLeft';\n }\n }\n\n let movementDirection = targetIndex > currIndex ? 'down' : 'up';\n for (let i = 0; i < Math.abs(targetIndex - currIndex); i++) {\n await this.user.keyboard(`[${movementDirection === 'down' ? arrowDown : arrowUp}]`);\n }\n };\n\n /**\n * Triggers the specified tab. Defaults to using the interaction type set on the tabs tester.\n */\n async triggerTab(opts: TriggerTabOptions): Promise<void> {\n let {\n tab,\n interactionType = this._interactionType,\n manualActivation\n } = opts;\n\n if (typeof tab === 'string' || typeof tab === 'number') {\n tab = this.findTab({tabIndexOrText: tab});\n }\n\n if (!tab) {\n throw new Error('Target tab not found in the tablist.');\n } else if (tab.hasAttribute('disabled')) {\n throw new Error('Target tab is disabled.');\n }\n\n if (interactionType === 'keyboard') {\n if (document.activeElement !== this._tablist && !this._tablist.contains(document.activeElement)) {\n act(() => this._tablist.focus());\n }\n\n let tabsOrientation = this._tablist.getAttribute('aria-orientation') || 'horizontal';\n await this.keyboardNavigateToTab({tab, orientation: tabsOrientation as Orientation});\n if (manualActivation) {\n await this.user.keyboard('[Enter]');\n }\n } else {\n await pressElement(this.user, tab, interactionType);\n }\n }\n\n /**\n * Returns the tablist.\n */\n get tablist(): HTMLElement {\n return this._tablist;\n }\n\n /**\n * Returns the tabpanels.\n */\n get tabpanels(): HTMLElement[] {\n let tabpanels = [] as HTMLElement[];\n for (let tab of this.tabs) {\n let controlId = tab.getAttribute('aria-controls');\n let panel = controlId != null ? document.getElementById(controlId) : null;\n if (panel != null) {\n tabpanels.push(panel);\n }\n }\n\n return tabpanels;\n }\n\n /**\n * Returns the tabs in the tablist.\n */\n get tabs(): HTMLElement[] {\n return within(this.tablist).queryAllByRole('tab');\n }\n\n /**\n * Returns the currently selected tab in the tablist if any.\n */\n get selectedTab(): HTMLElement | null {\n return this.tabs.find(tab => tab.getAttribute('aria-selected') === 'true') || null;\n }\n\n /**\n * Returns the currently active tabpanel if any.\n */\n get activeTabpanel(): HTMLElement | null {\n let activeTabpanelId = this.selectedTab?.getAttribute('aria-controls');\n return activeTabpanelId ? document.getElementById(activeTabpanelId) : null;\n }\n}\n"],"names":[],"version":3,"file":"tabs.cjs.map"}
|