(e: ReactKeyboardEvent)
| 131 | }); |
| 132 | |
| 133 | let onKeyDownCapture = (e: ReactKeyboardEvent) => { |
| 134 | let activeElement = getActiveElement(); |
| 135 | if ( |
| 136 | !nodeContains(e.currentTarget, getEventTarget(e) as Element) || |
| 137 | state.isKeyboardNavigationDisabled || |
| 138 | !ref.current || |
| 139 | !activeElement |
| 140 | ) { |
| 141 | return; |
| 142 | } |
| 143 | |
| 144 | let walker = getFocusableTreeWalker(ref.current); |
| 145 | walker.currentNode = activeElement; |
| 146 | |
| 147 | switch (e.key) { |
| 148 | case 'ArrowLeft': { |
| 149 | // Find the next focusable element within the cell. |
| 150 | let focusable: FocusableElement | null = |
| 151 | direction === 'rtl' |
| 152 | ? (walker.nextNode() as FocusableElement) |
| 153 | : (walker.previousNode() as FocusableElement); |
| 154 | |
| 155 | // Don't focus the cell itself if focusMode is "child" |
| 156 | if (focusMode === 'child' && focusable === ref.current) { |
| 157 | focusable = null; |
| 158 | } |
| 159 | |
| 160 | e.preventDefault(); |
| 161 | e.stopPropagation(); |
| 162 | if (focusable) { |
| 163 | focusSafely(focusable); |
| 164 | scrollIntoViewport(focusable, {containingElement: getScrollParent(ref.current)}); |
| 165 | } else { |
| 166 | // If there is no next focusable child, then move to the next cell to the left of this one. |
| 167 | // This will be handled by useSelectableCollection. However, if there is no cell to the left |
| 168 | // of this one, only one column, and the grid doesn't focus rows, then the next key will be the |
| 169 | // same as this one. In that case we need to handle focusing either the cell or the first/last |
| 170 | // child, depending on the focus mode. |
| 171 | let prev = keyboardDelegate.getKeyLeftOf?.(node.key); |
| 172 | if (prev !== node.key) { |
| 173 | // We prevent the capturing event from reaching children of the cell, e.g. pickers. |
| 174 | // We want arrow keys to navigate to the next cell instead. We need to re-dispatch |
| 175 | // the event from a higher parent so it still bubbles and gets handled by useSelectableCollection. |
| 176 | ref.current.parentElement?.dispatchEvent( |
| 177 | new KeyboardEvent(e.nativeEvent.type, e.nativeEvent) |
| 178 | ); |
| 179 | break; |
| 180 | } |
| 181 | |
| 182 | if (focusMode === 'cell' && direction === 'rtl') { |
| 183 | focusSafely(ref.current); |
| 184 | scrollIntoViewport(ref.current, {containingElement: getScrollParent(ref.current)}); |
| 185 | } else { |
| 186 | walker.currentNode = ref.current; |
| 187 | focusable = |
| 188 | direction === 'rtl' ? (walker.firstChild() as FocusableElement) : last(walker); |
| 189 | if (focusable) { |
| 190 | focusSafely(focusable); |
nothing calls this directly
no test coverage detected