@react-aria/grid 3.8.9-nightly.4518 → 3.8.9-nightly.4528

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.
@@ -10,7 +10,7 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import {Direction, Key, KeyboardDelegate, Node} from '@react-types/shared';
13
+ import {Direction, DisabledBehavior, Key, KeyboardDelegate, Node} from '@react-types/shared';
14
14
  import {getChildNodes, getFirstItem, getLastItem, getNthItem} from '@react-stately/collections';
15
15
  import {GridCollection} from '@react-types/grid';
16
16
  import {Layout, Rect} from '@react-stately/virtualizer';
@@ -19,6 +19,7 @@ import {RefObject} from 'react';
19
19
  export interface GridKeyboardDelegateOptions<T, C> {
20
20
  collection: C,
21
21
  disabledKeys: Set<Key>,
22
+ disabledBehavior?: DisabledBehavior,
22
23
  ref?: RefObject<HTMLElement>,
23
24
  direction: Direction,
24
25
  collator?: Intl.Collator,
@@ -29,6 +30,7 @@ export interface GridKeyboardDelegateOptions<T, C> {
29
30
  export class GridKeyboardDelegate<T, C extends GridCollection<T>> implements KeyboardDelegate {
30
31
  collection: C;
31
32
  protected disabledKeys: Set<Key>;
33
+ protected disabledBehavior: DisabledBehavior;
32
34
  protected ref: RefObject<HTMLElement>;
33
35
  protected direction: Direction;
34
36
  protected collator: Intl.Collator;
@@ -38,6 +40,7 @@ export class GridKeyboardDelegate<T, C extends GridCollection<T>> implements Key
38
40
  constructor(options: GridKeyboardDelegateOptions<T, C>) {
39
41
  this.collection = options.collection;
40
42
  this.disabledKeys = options.disabledKeys;
43
+ this.disabledBehavior = options.disabledBehavior || 'all';
41
44
  this.ref = options.ref;
42
45
  this.direction = options.direction;
43
46
  this.collator = options.collator;
@@ -53,6 +56,10 @@ export class GridKeyboardDelegate<T, C extends GridCollection<T>> implements Key
53
56
  return node.type === 'row' || node.type === 'item';
54
57
  }
55
58
 
59
+ private isDisabled(item: Node<unknown>) {
60
+ return this.disabledBehavior === 'all' && (item.props?.isDisabled || this.disabledKeys.has(item.key));
61
+ }
62
+
56
63
  protected findPreviousKey(fromKey?: Key, pred?: (item: Node<T>) => boolean) {
57
64
  let key = fromKey != null
58
65
  ? this.collection.getKeyBefore(fromKey)
@@ -60,7 +67,7 @@ export class GridKeyboardDelegate<T, C extends GridCollection<T>> implements Key
60
67
 
61
68
  while (key != null) {
62
69
  let item = this.collection.getItem(key);
63
- if (!this.disabledKeys.has(key) && (!pred || pred(item))) {
70
+ if (!this.isDisabled(item) && (!pred || pred(item))) {
64
71
  return key;
65
72
  }
66
73
 
@@ -75,7 +82,7 @@ export class GridKeyboardDelegate<T, C extends GridCollection<T>> implements Key
75
82
 
76
83
  while (key != null) {
77
84
  let item = this.collection.getItem(key);
78
- if (!this.disabledKeys.has(key) && (!pred || pred(item))) {
85
+ if (!this.isDisabled(item) && (!pred || pred(item))) {
79
86
  return key;
80
87
  }
81
88
 
package/src/useGrid.ts CHANGED
@@ -86,7 +86,8 @@ export function useGrid<T>(props: GridProps, state: GridState<T, GridCollection<
86
86
  let disabledBehavior = state.selectionManager.disabledBehavior;
87
87
  let delegate = useMemo(() => keyboardDelegate || new GridKeyboardDelegate({
88
88
  collection: state.collection,
89
- disabledKeys: disabledBehavior === 'selection' ? new Set() : state.disabledKeys,
89
+ disabledKeys: state.disabledKeys,
90
+ disabledBehavior,
90
91
  ref,
91
92
  direction,
92
93
  collator,
@@ -124,9 +124,9 @@ export function useGridCell<T, C extends GridCollection<T>>(props: GridCellProps
124
124
  focusable = null;
125
125
  }
126
126
 
127
+ e.preventDefault();
128
+ e.stopPropagation();
127
129
  if (focusable) {
128
- e.preventDefault();
129
- e.stopPropagation();
130
130
  focusSafely(focusable);
131
131
  scrollIntoViewport(focusable, {containingElement: getScrollParent(ref.current)});
132
132
  } else {
@@ -137,11 +137,15 @@ export function useGridCell<T, C extends GridCollection<T>>(props: GridCellProps
137
137
  // child, depending on the focus mode.
138
138
  let prev = keyboardDelegate.getKeyLeftOf(node.key);
139
139
  if (prev !== node.key) {
140
+ // We prevent the capturing event from reaching children of the cell, e.g. pickers.
141
+ // We want arrow keys to navigate to the next cell instead. We need to re-dispatch
142
+ // the event from a higher parent so it still bubbles and gets handled by useSelectableCollection.
143
+ ref.current.parentElement.dispatchEvent(
144
+ new KeyboardEvent(e.nativeEvent.type, e.nativeEvent)
145
+ );
140
146
  break;
141
147
  }
142
148
 
143
- e.preventDefault();
144
- e.stopPropagation();
145
149
  if (focusMode === 'cell' && direction === 'rtl') {
146
150
  focusSafely(ref.current);
147
151
  scrollIntoViewport(ref.current, {containingElement: getScrollParent(ref.current)});
@@ -167,19 +171,23 @@ export function useGridCell<T, C extends GridCollection<T>>(props: GridCellProps
167
171
  focusable = null;
168
172
  }
169
173
 
174
+ e.preventDefault();
175
+ e.stopPropagation();
170
176
  if (focusable) {
171
- e.preventDefault();
172
- e.stopPropagation();
173
177
  focusSafely(focusable);
174
178
  scrollIntoViewport(focusable, {containingElement: getScrollParent(ref.current)});
175
179
  } else {
176
180
  let next = keyboardDelegate.getKeyRightOf(node.key);
177
181
  if (next !== node.key) {
182
+ // We prevent the capturing event from reaching children of the cell, e.g. pickers.
183
+ // We want arrow keys to navigate to the next cell instead. We need to re-dispatch
184
+ // the event from a higher parent so it still bubbles and gets handled by useSelectableCollection.
185
+ ref.current.parentElement.dispatchEvent(
186
+ new KeyboardEvent(e.nativeEvent.type, e.nativeEvent)
187
+ );
178
188
  break;
179
189
  }
180
190
 
181
- e.preventDefault();
182
- e.stopPropagation();
183
191
  if (focusMode === 'cell' && direction === 'ltr') {
184
192
  focusSafely(ref.current);
185
193
  scrollIntoViewport(ref.current, {containingElement: getScrollParent(ref.current)});
package/src/useGridRow.ts CHANGED
@@ -10,6 +10,7 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
+ import {chain} from '@react-aria/utils';
13
14
  import {DOMAttributes, FocusableElement} from '@react-types/shared';
14
15
  import {GridCollection, GridNode} from '@react-types/grid';
15
16
  import {gridMap} from './utils';
@@ -52,14 +53,15 @@ export function useGridRow<T, C extends GridCollection<T>, S extends GridState<T
52
53
  onAction
53
54
  } = props;
54
55
 
55
- let {actions: {onRowAction}} = gridMap.get(state);
56
+ let {actions} = gridMap.get(state);
57
+ let onRowAction = actions.onRowAction ? () => actions.onRowAction(node.key) : onAction;
56
58
  let {itemProps, ...states} = useSelectableItem({
57
59
  selectionManager: state.selectionManager,
58
60
  key: node.key,
59
61
  ref,
60
62
  isVirtualized,
61
63
  shouldSelectOnPressUp,
62
- onAction: onRowAction ? () => onRowAction(node.key) : onAction,
64
+ onAction: onRowAction || node?.props?.onAction ? chain(node?.props?.onAction, onRowAction) : undefined,
63
65
  isDisabled: state.collection.size === 0
64
66
  });
65
67