@react-aria/test-utils 1.0.0-alpha.6 → 1.0.0-alpha.8

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.
Files changed (61) hide show
  1. package/dist/combobox.main.js +5 -4
  2. package/dist/combobox.main.js.map +1 -1
  3. package/dist/combobox.mjs +5 -4
  4. package/dist/combobox.module.js +5 -4
  5. package/dist/combobox.module.js.map +1 -1
  6. package/dist/events.main.js +31 -1
  7. package/dist/events.main.js.map +1 -1
  8. package/dist/events.mjs +30 -2
  9. package/dist/events.module.js +30 -2
  10. package/dist/events.module.js.map +1 -1
  11. package/dist/gridlist.main.js +23 -9
  12. package/dist/gridlist.main.js.map +1 -1
  13. package/dist/gridlist.mjs +24 -10
  14. package/dist/gridlist.module.js +24 -10
  15. package/dist/gridlist.module.js.map +1 -1
  16. package/dist/listbox.main.js +22 -13
  17. package/dist/listbox.main.js.map +1 -1
  18. package/dist/listbox.mjs +23 -14
  19. package/dist/listbox.module.js +23 -14
  20. package/dist/listbox.module.js.map +1 -1
  21. package/dist/menu.main.js +1 -1
  22. package/dist/menu.main.js.map +1 -1
  23. package/dist/menu.mjs +1 -1
  24. package/dist/menu.module.js +1 -1
  25. package/dist/menu.module.js.map +1 -1
  26. package/dist/select.main.js +7 -4
  27. package/dist/select.main.js.map +1 -1
  28. package/dist/select.mjs +7 -4
  29. package/dist/select.module.js +7 -4
  30. package/dist/select.module.js.map +1 -1
  31. package/dist/table.main.js +90 -9
  32. package/dist/table.main.js.map +1 -1
  33. package/dist/table.mjs +92 -11
  34. package/dist/table.module.js +92 -11
  35. package/dist/table.module.js.map +1 -1
  36. package/dist/tabs.main.js +1 -1
  37. package/dist/tabs.main.js.map +1 -1
  38. package/dist/tabs.mjs +1 -1
  39. package/dist/tabs.module.js +1 -1
  40. package/dist/tabs.module.js.map +1 -1
  41. package/dist/tree.main.js +27 -8
  42. package/dist/tree.main.js.map +1 -1
  43. package/dist/tree.mjs +28 -9
  44. package/dist/tree.module.js +28 -9
  45. package/dist/tree.module.js.map +1 -1
  46. package/dist/types.d.ts +31 -1
  47. package/dist/types.d.ts.map +1 -1
  48. package/dist/userEventMaps.main.js.map +1 -1
  49. package/dist/userEventMaps.module.js.map +1 -1
  50. package/package.json +7 -3
  51. package/src/combobox.ts +10 -7
  52. package/src/events.ts +34 -2
  53. package/src/gridlist.ts +35 -12
  54. package/src/listbox.ts +47 -19
  55. package/src/menu.ts +1 -1
  56. package/src/select.ts +10 -4
  57. package/src/table.ts +163 -10
  58. package/src/tabs.ts +1 -1
  59. package/src/tree.ts +40 -10
  60. package/src/types.ts +11 -1
  61. package/src/userEventMaps.ts +1 -1
package/src/tree.ts CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  import {act, within} from '@testing-library/react';
14
14
  import {BaseGridRowInteractionOpts, GridRowActionOpts, ToggleGridRowOpts, TreeTesterOpts, UserOpts} from './types';
15
- import {pressElement, triggerLongPress} from './events';
15
+ import {getAltKey, getMetaKey, pressElement, triggerLongPress} from './events';
16
16
 
17
17
  interface TreeToggleExpansionOpts extends BaseGridRowInteractionOpts {}
18
18
  interface TreeToggleRowOpts extends ToggleGridRowOpts {}
@@ -64,20 +64,21 @@ export class TreeTester {
64
64
  }
65
65
 
66
66
  // TODO: RTL
67
- private async keyboardNavigateToRow(opts: {row: HTMLElement}) {
68
- let {row} = opts;
67
+ private async keyboardNavigateToRow(opts: {row: HTMLElement, selectionOnNav?: 'default' | 'none'}) {
68
+ let {row, selectionOnNav = 'default'} = opts;
69
+ let altKey = getAltKey();
69
70
  let rows = this.rows;
70
71
  let targetIndex = rows.indexOf(row);
71
72
  if (targetIndex === -1) {
72
73
  throw new Error('Option provided is not in the tree');
73
74
  }
74
75
 
75
- if (document.activeElement !== this._tree || !this._tree.contains(document.activeElement)) {
76
+ if (document.activeElement !== this._tree && !this._tree.contains(document.activeElement)) {
76
77
  act(() => this._tree.focus());
77
78
  }
78
79
 
79
80
  if (document.activeElement === this.tree) {
80
- await this.user.keyboard('[ArrowDown]');
81
+ await this.user.keyboard(`${selectionOnNav === 'none' ? `[${altKey}>]` : ''}[ArrowDown]${selectionOnNav === 'none' ? `[/${altKey}]` : ''}`);
81
82
  } else if (this._tree.contains(document.activeElement) && document.activeElement!.getAttribute('role') !== 'row') {
82
83
  do {
83
84
  await this.user.keyboard('[ArrowLeft]');
@@ -89,22 +90,33 @@ export class TreeTester {
89
90
  }
90
91
  let direction = targetIndex > currIndex ? 'down' : 'up';
91
92
 
93
+ if (selectionOnNav === 'none') {
94
+ await this.user.keyboard(`[${altKey}>]`);
95
+ }
92
96
  for (let i = 0; i < Math.abs(targetIndex - currIndex); i++) {
93
97
  await this.user.keyboard(`[${direction === 'down' ? 'ArrowDown' : 'ArrowUp'}]`);
94
98
  }
99
+ if (selectionOnNav === 'none') {
100
+ await this.user.keyboard(`[/${altKey}]`);
101
+ }
95
102
  };
96
103
 
97
104
  /**
98
105
  * Toggles the selection for the specified tree row. Defaults to using the interaction type set on the tree tester.
106
+ * Note that this will endevor to always add/remove JUST the provided row to the set of selected rows.
99
107
  */
100
108
  async toggleRowSelection(opts: TreeToggleRowOpts): Promise<void> {
101
109
  let {
102
110
  row,
103
111
  needsLongPress,
104
112
  checkboxSelection = true,
105
- interactionType = this._interactionType
113
+ interactionType = this._interactionType,
114
+ selectionBehavior = 'toggle'
106
115
  } = opts;
107
116
 
117
+ let altKey = getAltKey();
118
+ let metaKey = getMetaKey();
119
+
108
120
  if (typeof row === 'string' || typeof row === 'number') {
109
121
  row = this.findRow({rowIndexOrText: row});
110
122
  }
@@ -123,9 +135,15 @@ export class TreeTester {
123
135
 
124
136
  // this would be better than the check to do nothing in events.ts
125
137
  // also, it'd be good to be able to trigger selection on the row instead of having to go to the checkbox directly
126
- if (interactionType === 'keyboard' && !checkboxSelection) {
127
- await this.keyboardNavigateToRow({row});
128
- await this.user.keyboard('{Space}');
138
+ if (interactionType === 'keyboard' && (!checkboxSelection || !rowCheckbox)) {
139
+ await this.keyboardNavigateToRow({row, selectionOnNav: selectionBehavior === 'replace' ? 'none' : 'default'});
140
+ if (selectionBehavior === 'replace') {
141
+ await this.user.keyboard(`[${altKey}>]`);
142
+ }
143
+ await this.user.keyboard('[Space]');
144
+ if (selectionBehavior === 'replace') {
145
+ await this.user.keyboard(`[/${altKey}]`);
146
+ }
129
147
  return;
130
148
  }
131
149
  if (rowCheckbox && checkboxSelection) {
@@ -140,7 +158,14 @@ export class TreeTester {
140
158
  // Note that long press interactions with rows is strictly touch only for grid rows
141
159
  await triggerLongPress({element: cell, advanceTimer: this._advanceTimer, pointerOpts: {pointerType: 'touch'}});
142
160
  } else {
143
- await pressElement(this.user, cell, interactionType);
161
+ // TODO add modifiers here? Maybe move into pressElement if we get more cases for different types of modifier keys
162
+ if (selectionBehavior === 'replace' && interactionType !== 'touch') {
163
+ await this.user.keyboard(`[${metaKey}>]`);
164
+ }
165
+ await pressElement(this.user, row, interactionType);
166
+ if (selectionBehavior === 'replace' && interactionType !== 'touch') {
167
+ await this.user.keyboard(`[/${metaKey}]`);
168
+ }
144
169
  }
145
170
  }
146
171
  };
@@ -177,6 +202,9 @@ export class TreeTester {
177
202
  return;
178
203
  }
179
204
 
205
+ // TODO: We always Use Option/Ctrl when keyboard navigating so selection isn't changed
206
+ // in selectionmode="replace"/highlight selection when navigating to the row that the user wants
207
+ // to expand. Discuss if this is useful or not
180
208
  await this.keyboardNavigateToRow({row});
181
209
  if (row.getAttribute('aria-expanded') === 'true') {
182
210
  await this.user.keyboard('[ArrowLeft]');
@@ -211,6 +239,8 @@ export class TreeTester {
211
239
  return;
212
240
  }
213
241
 
242
+ // TODO: same as above, uses the modifier key to make sure we don't modify selection state on row focus
243
+ // as we keyboard navigate to the row we want activate
214
244
  await this.keyboardNavigateToRow({row});
215
245
  await this.user.keyboard('[Enter]');
216
246
  } else {
package/src/types.ts CHANGED
@@ -126,7 +126,17 @@ export interface ToggleGridRowOpts extends BaseGridRowInteractionOpts {
126
126
  * Whether the checkbox should be used to select the row. If false, will attempt to select the row via press.
127
127
  * @default 'true'
128
128
  */
129
- checkboxSelection?: boolean
129
+ checkboxSelection?: boolean,
130
+ // TODO: this api feels a bit confusing tbh...
131
+ /**
132
+ * Whether the grid has a selectionBehavior of "toggle" or "replace" (aka highlight selection). This affects the user operations
133
+ * required to toggle row selection by adding modifier keys during user actions, useful when performing multi-row selection in a "selectionBehavior: 'replace'" grid.
134
+ * If you would like to still simulate user actions (aka press) without these modifiers keys for a "selectionBehavior: replace" grid, simply omit this option.
135
+ * See the "Selection Behavior" section of the appropriate React Aria Component docs for more information (e.g. https://react-spectrum.adobe.com/react-aria/Tree.html#selection-behavior).
136
+ *
137
+ * @default 'toggle'
138
+ */
139
+ selectionBehavior?: 'toggle' | 'replace'
130
140
  }
131
141
 
132
142
  export interface GridRowActionOpts extends BaseGridRowInteractionOpts {
@@ -1,4 +1,4 @@
1
- import {pointerKey} from '@testing-library/user-event/system/pointer/shared';
1
+ import {pointerKey} from '@testing-library/user-event';
2
2
 
3
3
  export let pointerMap: pointerKey[] = [
4
4
  {name: 'MouseLeft', pointerType: 'mouse', button: 'primary', height: 1, width: 1, pressure: 0.5},