Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@react-aria/grid

Package Overview
Dependencies
Maintainers
2
Versions
743
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@react-aria/grid - npm Package Compare versions

Comparing version 3.0.0-nightly.2585 to 3.0.0-nightly.2655

src/utils.ts

216

dist/main.js

@@ -181,2 +181,4 @@ var {

}
return this.direction === 'rtl' ? this.getFirstKey(key) : this.getLastKey(key);
}

@@ -213,2 +215,4 @@ }

}
return this.direction === 'rtl' ? this.getLastKey(key) : this.getFirstKey(key);
}

@@ -236,5 +240,5 @@ }

key = this.findNextKey(); // If global flag is set, focus the first cell in the first row.
key = this.findNextKey(); // If global flag is set (or if focus mode is cell), focus the first cell in the first row.
if (key != null && item && this.isCell(item) && global) {
if (key != null && item && this.isCell(item) && global || this.focusMode === 'cell') {
let item = this.collection.getItem(key);

@@ -245,5 +249,3 @@ key = [...item.childNodes][0].key;

if (this.focusMode === 'row') {
return key;
}
return key;
}

@@ -271,5 +273,5 @@

key = this.findPreviousKey(); // If global flag is set, focus the last cell in the last row.
key = this.findPreviousKey(); // If global flag is set (or if focus mode is cell), focus the last cell in the last row.
if (key != null && item && this.isCell(item) && global) {
if (key != null && item && this.isCell(item) && global || this.focusMode === 'cell') {
let item = this.collection.getItem(key);

@@ -281,5 +283,3 @@ let children = [...item.childNodes];

if (this.focusMode === 'row') {
return key;
}
return key;
}

@@ -390,2 +390,6 @@

if (this.collator.compare(substring, search) === 0) {
if (this.isRow(item) && this.focusMode === 'cell') {
return [...item.childNodes][0].key;
}
return item.key;

@@ -395,3 +399,3 @@ }

key = this.getKeyBelow(key); // Wrap around when reaching the end of the collection
key = this.findNextKey(key); // Wrap around when reaching the end of the collection

@@ -410,4 +414,17 @@ if (key == null && !hasWrapped) {

exports.GridKeyboardDelegate = GridKeyboardDelegate;
const $df311f3c863e8abccff59a8ae65a46d3$var$gridIds = new WeakMap();
/*
* Copyright 2020 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
// Used to share keyboard delegate between useGrid and useGridCell
const $e6fd609a4e1bd40f6df88a69c08b6746$export$gridKeyboardDelegates = new WeakMap();
function useGrid(props, state) {

@@ -417,3 +434,4 @@ let {

isVirtualized,
keyboardDelegate
keyboardDelegate,
focusMode
} = props;

@@ -439,4 +457,5 @@

direction,
collator
}), [keyboardDelegate, state.collection, state.disabledKeys, ref, direction, collator]);
collator,
focusMode
}), [keyboardDelegate, state.collection, state.disabledKeys, ref, direction, collator, focusMode]);
let {

@@ -450,3 +469,3 @@ collectionProps

let id = useId();
$df311f3c863e8abccff59a8ae65a46d3$var$gridIds.set(state, id);
$e6fd609a4e1bd40f6df88a69c08b6746$export$gridKeyboardDelegates.set(state, delegate);
let domProps = filterDOMProps(props, {

@@ -473,13 +492,2 @@ labelable: true

/*
* Copyright 2020 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
function useGridRowGroup() {

@@ -501,3 +509,4 @@ return {

isSelected,
isDisabled
isDisabled,
shouldSelectOnPressUp
} = props;

@@ -510,3 +519,4 @@ let {

ref,
isVirtualized
isVirtualized,
shouldSelectOnPressUp
}); // TODO: move into useSelectableItem?

@@ -541,4 +551,10 @@

isVirtualized,
isDisabled
} = props; // Handles focusing the cell. If there is a focusable child,
isDisabled,
focusMode = 'child',
shouldSelectOnPressUp
} = props;
let {
direction
} = useLocale();
let keyboardDelegate = $e6fd609a4e1bd40f6df88a69c08b6746$export$gridKeyboardDelegates.get(state); // Handles focusing the cell. If there is a focusable child,
// it is focused, otherwise the cell itself is focused.

@@ -548,7 +564,13 @@

let treeWalker = getFocusableTreeWalker(ref.current);
let focusable = treeWalker.firstChild();
if (focusable) {
focusSafely(focusable);
} else {
if (focusMode === 'child') {
let focusable = state.selectionManager.childFocusStrategy === 'last' ? $f9bcfab6f4b3fd6f2359f40ca9cd9cf4$var$last(treeWalker) : treeWalker.firstChild();
if (focusable) {
focusSafely(focusable);
return;
}
}
if (!ref.current.contains(document.activeElement)) {
focusSafely(ref.current);

@@ -565,3 +587,4 @@ }

isVirtualized,
focus
focus,
shouldSelectOnPressUp
}); // TODO: move into useSelectableItem?

@@ -573,5 +596,106 @@

isDisabled
})); // Grid cells can have focusable elements inside them. In this case, focus should
}));
let onKeyDown = e => {
let walker = getFocusableTreeWalker(ref.current);
walker.currentNode = document.activeElement;
switch (e.key) {
case 'ArrowLeft':
{
// Find the next focusable element within the cell.
let focusable = direction === 'rtl' ? walker.nextNode() : walker.previousNode(); // Don't focus the cell itself if focusMode is "child"
if (focusMode === 'child' && focusable === ref.current) {
focusable = null;
}
if (focusable) {
e.preventDefault();
e.stopPropagation();
focusSafely(focusable);
} else {
// If there is no next focusable child, then move to the next cell to the left of this one.
// This will be handled by useSelectableCollection. However, if there is no cell to the left
// of this one, only one column, and the grid doesn't focus rows, then the next key will be the
// same as this one. In that case we need to handle focusing either the cell or the first/last
// child, depending on the focus mode.
let prev = keyboardDelegate.getKeyLeftOf(node.key);
if (prev !== node.key) {
break;
}
e.preventDefault();
e.stopPropagation();
if (focusMode === 'cell' && direction === 'rtl') {
focusSafely(ref.current);
} else {
walker.currentNode = ref.current;
focusable = direction === 'rtl' ? walker.firstChild() : $f9bcfab6f4b3fd6f2359f40ca9cd9cf4$var$last(walker);
if (focusable) {
focusSafely(focusable);
}
}
}
break;
}
case 'ArrowRight':
{
let focusable = direction === 'rtl' ? walker.previousNode() : walker.nextNode();
if (focusMode === 'child' && focusable === ref.current) {
focusable = null;
}
if (focusable) {
e.preventDefault();
e.stopPropagation();
focusSafely(focusable);
} else {
let next = keyboardDelegate.getKeyRightOf(node.key);
if (next !== node.key) {
break;
}
e.preventDefault();
e.stopPropagation();
if (focusMode === 'cell' && direction === 'ltr') {
focusSafely(ref.current);
} else {
walker.currentNode = ref.current;
focusable = direction === 'rtl' ? $f9bcfab6f4b3fd6f2359f40ca9cd9cf4$var$last(walker) : walker.firstChild();
if (focusable) {
focusSafely(focusable);
}
}
}
break;
}
case 'ArrowUp':
case 'ArrowDown':
// Prevent this event from reaching cell children, e.g. menu buttons. We want arrow keys to navigate
// to the cell above/below instead. We need to re-dispatch the event from a higher parent so it still
// bubbles and gets handled by useSelectableCollection.
if (!e.altKey && ref.current.contains(e.target)) {
e.stopPropagation();
e.preventDefault();
ref.current.parentElement.dispatchEvent(new KeyboardEvent(e.nativeEvent.type, e.nativeEvent));
}
break;
}
}; // Grid cells can have focusable elements inside them. In this case, focus should
// be marshalled to that element rather than focusing the cell itself.
let onFocus = e => {

@@ -595,3 +719,3 @@ if (e.target !== ref.current) {

requestAnimationFrame(() => {
if (document.activeElement === ref.current) {
if (focusMode === 'child' && document.activeElement === ref.current) {
focus();

@@ -604,2 +728,3 @@ }

role: 'gridcell',
onKeyDownCapture: onKeyDown,
onFocus

@@ -618,2 +743,17 @@ });

exports.useGridCell = useGridCell;
function $f9bcfab6f4b3fd6f2359f40ca9cd9cf4$var$last(walker) {
let next;
let last;
do {
last = walker.lastChild();
if (last) {
next = last;
}
} while (last);
return next;
}
//# sourceMappingURL=main.js.map

@@ -149,2 +149,4 @@ import { focusSafely, getFocusableTreeWalker } from "@react-aria/focus";

}
return this.direction === 'rtl' ? this.getFirstKey(key) : this.getLastKey(key);
}

@@ -181,2 +183,4 @@ }

}
return this.direction === 'rtl' ? this.getLastKey(key) : this.getFirstKey(key);
}

@@ -204,5 +208,5 @@ }

key = this.findNextKey(); // If global flag is set, focus the first cell in the first row.
key = this.findNextKey(); // If global flag is set (or if focus mode is cell), focus the first cell in the first row.
if (key != null && item && this.isCell(item) && global) {
if (key != null && item && this.isCell(item) && global || this.focusMode === 'cell') {
let item = this.collection.getItem(key);

@@ -213,5 +217,3 @@ key = [...item.childNodes][0].key;

if (this.focusMode === 'row') {
return key;
}
return key;
}

@@ -239,5 +241,5 @@

key = this.findPreviousKey(); // If global flag is set, focus the last cell in the last row.
key = this.findPreviousKey(); // If global flag is set (or if focus mode is cell), focus the last cell in the last row.
if (key != null && item && this.isCell(item) && global) {
if (key != null && item && this.isCell(item) && global || this.focusMode === 'cell') {
let item = this.collection.getItem(key);

@@ -249,5 +251,3 @@ let children = [...item.childNodes];

if (this.focusMode === 'row') {
return key;
}
return key;
}

@@ -358,2 +358,6 @@

if (this.collator.compare(substring, search) === 0) {
if (this.isRow(item) && this.focusMode === 'cell') {
return [...item.childNodes][0].key;
}
return item.key;

@@ -363,3 +367,3 @@ }

key = this.getKeyBelow(key); // Wrap around when reaching the end of the collection
key = this.findNextKey(key); // Wrap around when reaching the end of the collection

@@ -376,3 +380,16 @@ if (key == null && !hasWrapped) {

}
const $e3c4cce891c32069b0b54eddd405e76$var$gridIds = new WeakMap();
/*
* Copyright 2020 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
// Used to share keyboard delegate between useGrid and useGridCell
const $c7c16c1fc27e25a205a277212c8e7cfd$export$gridKeyboardDelegates = new WeakMap();
export function useGrid(props, state) {

@@ -382,3 +399,4 @@ let {

isVirtualized,
keyboardDelegate
keyboardDelegate,
focusMode
} = props;

@@ -404,4 +422,5 @@

direction,
collator
}), [keyboardDelegate, state.collection, state.disabledKeys, ref, direction, collator]);
collator,
focusMode
}), [keyboardDelegate, state.collection, state.disabledKeys, ref, direction, collator, focusMode]);
let {

@@ -415,3 +434,3 @@ collectionProps

let id = useId();
$e3c4cce891c32069b0b54eddd405e76$var$gridIds.set(state, id);
$c7c16c1fc27e25a205a277212c8e7cfd$export$gridKeyboardDelegates.set(state, delegate);
let domProps = filterDOMProps(props, {

@@ -435,14 +454,2 @@ labelable: true

}
/*
* Copyright 2020 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
export function useGridRowGroup() {

@@ -461,3 +468,4 @@ return {

isSelected,
isDisabled
isDisabled,
shouldSelectOnPressUp
} = props;

@@ -470,3 +478,4 @@ let {

ref,
isVirtualized
isVirtualized,
shouldSelectOnPressUp
}); // TODO: move into useSelectableItem?

@@ -498,4 +507,10 @@

isVirtualized,
isDisabled
} = props; // Handles focusing the cell. If there is a focusable child,
isDisabled,
focusMode = 'child',
shouldSelectOnPressUp
} = props;
let {
direction
} = useLocale();
let keyboardDelegate = $c7c16c1fc27e25a205a277212c8e7cfd$export$gridKeyboardDelegates.get(state); // Handles focusing the cell. If there is a focusable child,
// it is focused, otherwise the cell itself is focused.

@@ -505,7 +520,13 @@

let treeWalker = getFocusableTreeWalker(ref.current);
let focusable = treeWalker.firstChild();
if (focusable) {
focusSafely(focusable);
} else {
if (focusMode === 'child') {
let focusable = state.selectionManager.childFocusStrategy === 'last' ? $c46764dc2253b1b174632a30143c6340$var$last(treeWalker) : treeWalker.firstChild();
if (focusable) {
focusSafely(focusable);
return;
}
}
if (!ref.current.contains(document.activeElement)) {
focusSafely(ref.current);

@@ -522,3 +543,4 @@ }

isVirtualized,
focus
focus,
shouldSelectOnPressUp
}); // TODO: move into useSelectableItem?

@@ -530,5 +552,106 @@

isDisabled
})); // Grid cells can have focusable elements inside them. In this case, focus should
}));
let onKeyDown = e => {
let walker = getFocusableTreeWalker(ref.current);
walker.currentNode = document.activeElement;
switch (e.key) {
case 'ArrowLeft':
{
// Find the next focusable element within the cell.
let focusable = direction === 'rtl' ? walker.nextNode() : walker.previousNode(); // Don't focus the cell itself if focusMode is "child"
if (focusMode === 'child' && focusable === ref.current) {
focusable = null;
}
if (focusable) {
e.preventDefault();
e.stopPropagation();
focusSafely(focusable);
} else {
// If there is no next focusable child, then move to the next cell to the left of this one.
// This will be handled by useSelectableCollection. However, if there is no cell to the left
// of this one, only one column, and the grid doesn't focus rows, then the next key will be the
// same as this one. In that case we need to handle focusing either the cell or the first/last
// child, depending on the focus mode.
let prev = keyboardDelegate.getKeyLeftOf(node.key);
if (prev !== node.key) {
break;
}
e.preventDefault();
e.stopPropagation();
if (focusMode === 'cell' && direction === 'rtl') {
focusSafely(ref.current);
} else {
walker.currentNode = ref.current;
focusable = direction === 'rtl' ? walker.firstChild() : $c46764dc2253b1b174632a30143c6340$var$last(walker);
if (focusable) {
focusSafely(focusable);
}
}
}
break;
}
case 'ArrowRight':
{
let focusable = direction === 'rtl' ? walker.previousNode() : walker.nextNode();
if (focusMode === 'child' && focusable === ref.current) {
focusable = null;
}
if (focusable) {
e.preventDefault();
e.stopPropagation();
focusSafely(focusable);
} else {
let next = keyboardDelegate.getKeyRightOf(node.key);
if (next !== node.key) {
break;
}
e.preventDefault();
e.stopPropagation();
if (focusMode === 'cell' && direction === 'ltr') {
focusSafely(ref.current);
} else {
walker.currentNode = ref.current;
focusable = direction === 'rtl' ? $c46764dc2253b1b174632a30143c6340$var$last(walker) : walker.firstChild();
if (focusable) {
focusSafely(focusable);
}
}
}
break;
}
case 'ArrowUp':
case 'ArrowDown':
// Prevent this event from reaching cell children, e.g. menu buttons. We want arrow keys to navigate
// to the cell above/below instead. We need to re-dispatch the event from a higher parent so it still
// bubbles and gets handled by useSelectableCollection.
if (!e.altKey && ref.current.contains(e.target)) {
e.stopPropagation();
e.preventDefault();
ref.current.parentElement.dispatchEvent(new KeyboardEvent(e.nativeEvent.type, e.nativeEvent));
}
break;
}
}; // Grid cells can have focusable elements inside them. In this case, focus should
// be marshalled to that element rather than focusing the cell itself.
let onFocus = e => {

@@ -552,3 +675,3 @@ if (e.target !== ref.current) {

requestAnimationFrame(() => {
if (document.activeElement === ref.current) {
if (focusMode === 'child' && document.activeElement === ref.current) {
focus();

@@ -561,2 +684,3 @@ }

role: 'gridcell',
onKeyDownCapture: onKeyDown,
onFocus

@@ -573,2 +697,17 @@ });

}
function $c46764dc2253b1b174632a30143c6340$var$last(walker) {
let next;
let last;
do {
last = walker.lastChild();
if (last) {
next = last;
}
} while (last);
return next;
}
//# sourceMappingURL=module.js.map

8

dist/types.d.ts

@@ -38,8 +38,9 @@ import { Direction, KeyboardDelegate, Node, AriaLabelingProps, DOMProps } from "@react-types/shared";

}
interface GridProps extends DOMProps, AriaLabelingProps {
export interface GridProps extends DOMProps, AriaLabelingProps {
ref: RefObject<HTMLElement>;
isVirtualized?: boolean;
keyboardDelegate?: KeyboardDelegate;
focusMode?: 'row' | 'cell';
}
interface GridAria {
export interface GridAria {
gridProps: HTMLAttributes<HTMLElement>;

@@ -58,2 +59,3 @@ }

isDisabled?: boolean;
shouldSelectOnPressUp?: boolean;
}

@@ -69,2 +71,4 @@ export interface GridRowAria {

isDisabled?: boolean;
focusMode?: 'child' | 'cell';
shouldSelectOnPressUp?: boolean;
}

@@ -71,0 +75,0 @@ interface GridCellAria {

{
"name": "@react-aria/grid",
"version": "3.0.0-nightly.2585+e213843e",
"version": "3.0.0-nightly.2655+f0afbae7",
"description": "Spectrum UI components in React",

@@ -21,11 +21,11 @@ "license": "Apache-2.0",

"@babel/runtime": "^7.6.2",
"@react-aria/focus": "3.0.0-nightly.907+e213843e",
"@react-aria/i18n": "3.0.0-nightly.907+e213843e",
"@react-aria/interactions": "3.0.0-nightly.907+e213843e",
"@react-aria/selection": "3.0.0-nightly.907+e213843e",
"@react-aria/utils": "3.0.0-nightly.907+e213843e",
"@react-stately/grid": "3.0.0-nightly.2585+e213843e",
"@react-stately/virtualizer": "3.1.3-nightly.2585+e213843e",
"@react-types/grid": "3.0.0-nightly.2585+e213843e",
"@react-types/shared": "3.0.0-nightly.907+e213843e"
"@react-aria/focus": "3.0.0-nightly.975+f0afbae7",
"@react-aria/i18n": "3.0.0-nightly.975+f0afbae7",
"@react-aria/interactions": "3.0.0-nightly.975+f0afbae7",
"@react-aria/selection": "3.0.0-nightly.975+f0afbae7",
"@react-aria/utils": "3.0.0-nightly.975+f0afbae7",
"@react-stately/grid": "3.0.0-nightly.2655+f0afbae7",
"@react-stately/virtualizer": "3.1.4-nightly.2655+f0afbae7",
"@react-types/grid": "3.0.0-nightly.2655+f0afbae7",
"@react-types/shared": "3.0.0-nightly.975+f0afbae7"
},

@@ -38,3 +38,3 @@ "peerDependencies": {

},
"gitHead": "e213843ee295bda8ba7f80336a1e179f6e287d9e"
"gitHead": "f0afbae764727b3062170852006ea38689a34f97"
}

@@ -170,2 +170,4 @@ /*

}
return this.direction === 'rtl' ? this.getFirstKey(key) : this.getLastKey(key);
}

@@ -205,2 +207,4 @@ }

}
return this.direction === 'rtl' ? this.getLastKey(key) : this.getFirstKey(key);
}

@@ -228,4 +232,4 @@ }

// If global flag is set, focus the first cell in the first row.
if (key != null && item && this.isCell(item) && global) {
// If global flag is set (or if focus mode is cell), focus the first cell in the first row.
if ((key != null && item && this.isCell(item) && global) || this.focusMode === 'cell') {
let item = this.collection.getItem(key);

@@ -236,5 +240,3 @@ key = [...item.childNodes][0].key;

// Otherwise, focus the row itself.
if (this.focusMode === 'row') {
return key;
}
return key;
}

@@ -262,4 +264,4 @@

// If global flag is set, focus the last cell in the last row.
if (key != null && item && this.isCell(item) && global) {
// If global flag is set (or if focus mode is cell), focus the last cell in the last row.
if ((key != null && item && this.isCell(item) && global) || this.focusMode === 'cell') {
let item = this.collection.getItem(key);

@@ -271,5 +273,3 @@ let children = [...item.childNodes];

// Otherwise, focus the row itself.
if (this.focusMode === 'row') {
return key;
}
return key;
}

@@ -370,2 +370,6 @@

if (this.collator.compare(substring, search) === 0) {
if (this.isRow(item) && this.focusMode === 'cell') {
return [...item.childNodes][0].key;
}
return item.key;

@@ -375,3 +379,3 @@ }

key = this.getKeyBelow(key);
key = this.findNextKey(key);

@@ -388,2 +392,2 @@ // Wrap around when reaching the end of the collection

}

@@ -17,2 +17,3 @@ /*

import {GridKeyboardDelegate} from './GridKeyboardDelegate';
import {gridKeyboardDelegates} from './utils';
import {GridState} from '@react-stately/grid';

@@ -23,11 +24,10 @@ import {HTMLAttributes, RefObject, useMemo} from 'react';

const gridIds = new WeakMap<GridState<unknown, GridCollection<unknown>>, string>();
interface GridProps extends DOMProps, AriaLabelingProps {
export interface GridProps extends DOMProps, AriaLabelingProps {
ref: RefObject<HTMLElement>,
isVirtualized?: boolean,
keyboardDelegate?: KeyboardDelegate
keyboardDelegate?: KeyboardDelegate,
focusMode?: 'row' | 'cell'
}
interface GridAria {
export interface GridAria {
gridProps: HTMLAttributes<HTMLElement>

@@ -40,3 +40,4 @@ }

isVirtualized,
keyboardDelegate
keyboardDelegate,
focusMode
} = props;

@@ -57,4 +58,5 @@

direction,
collator
}), [keyboardDelegate, state.collection, state.disabledKeys, ref, direction, collator]);
collator,
focusMode
}), [keyboardDelegate, state.collection, state.disabledKeys, ref, direction, collator, focusMode]);
let {collectionProps} = useSelectableCollection({

@@ -67,3 +69,3 @@ ref,

let id = useId();
gridIds.set(state, id);
gridKeyboardDelegates.set(state, delegate);

@@ -70,0 +72,0 @@ let domProps = filterDOMProps(props, {labelable: true});

@@ -15,14 +15,20 @@ /*

import {GridCollection} from '@react-types/grid';
import {gridKeyboardDelegates} from './utils';
import {GridState} from '@react-stately/grid';
import {HTMLAttributes, RefObject} from 'react';
import {HTMLAttributes, KeyboardEvent as ReactKeyboardEvent, RefObject} from 'react';
import {isFocusVisible, usePress} from '@react-aria/interactions';
import {mergeProps} from '@react-aria/utils';
import {Node} from '@react-types/shared';
import {Node as RSNode} from '@react-types/shared';
import {useLocale} from '@react-aria/i18n';
import {useSelectableItem} from '@react-aria/selection';
interface GridCellProps {
node: Node<unknown>,
node: RSNode<unknown>,
ref: RefObject<HTMLElement>,
isVirtualized?: boolean,
isDisabled?: boolean
isDisabled?: boolean,
/* when a cell is focused, should the cell or it's first focusable item be focused */
focusMode?: 'child' | 'cell',
shouldSelectOnPressUp?: boolean
}

@@ -39,5 +45,10 @@

isVirtualized,
isDisabled
isDisabled,
focusMode = 'child',
shouldSelectOnPressUp
} = props;
let {direction} = useLocale();
let keyboardDelegate = gridKeyboardDelegates.get(state);
// Handles focusing the cell. If there is a focusable child,

@@ -47,6 +58,13 @@ // it is focused, otherwise the cell itself is focused.

let treeWalker = getFocusableTreeWalker(ref.current);
let focusable = treeWalker.firstChild() as HTMLElement;
if (focusable) {
focusSafely(focusable);
} else {
if (focusMode === 'child') {
let focusable = state.selectionManager.childFocusStrategy === 'last'
? last(treeWalker)
: treeWalker.firstChild() as HTMLElement;
if (focusable) {
focusSafely(focusable);
return;
}
}
if (!ref.current.contains(document.activeElement)) {
focusSafely(ref.current);

@@ -61,3 +79,4 @@ }

isVirtualized,
focus
focus,
shouldSelectOnPressUp
});

@@ -68,2 +87,100 @@

let onKeyDown = (e: ReactKeyboardEvent) => {
let walker = getFocusableTreeWalker(ref.current);
walker.currentNode = document.activeElement;
switch (e.key) {
case 'ArrowLeft': {
// Find the next focusable element within the cell.
let focusable = direction === 'rtl'
? walker.nextNode() as HTMLElement
: walker.previousNode() as HTMLElement;
// Don't focus the cell itself if focusMode is "child"
if (focusMode === 'child' && focusable === ref.current) {
focusable = null;
}
if (focusable) {
e.preventDefault();
e.stopPropagation();
focusSafely(focusable);
} else {
// If there is no next focusable child, then move to the next cell to the left of this one.
// This will be handled by useSelectableCollection. However, if there is no cell to the left
// of this one, only one column, and the grid doesn't focus rows, then the next key will be the
// same as this one. In that case we need to handle focusing either the cell or the first/last
// child, depending on the focus mode.
let prev = keyboardDelegate.getKeyLeftOf(node.key);
if (prev !== node.key) {
break;
}
e.preventDefault();
e.stopPropagation();
if (focusMode === 'cell' && direction === 'rtl') {
focusSafely(ref.current);
} else {
walker.currentNode = ref.current;
focusable = direction === 'rtl'
? walker.firstChild() as HTMLElement
: last(walker);
if (focusable) {
focusSafely(focusable);
}
}
}
break;
}
case 'ArrowRight': {
let focusable = direction === 'rtl'
? walker.previousNode() as HTMLElement
: walker.nextNode() as HTMLElement;
if (focusMode === 'child' && focusable === ref.current) {
focusable = null;
}
if (focusable) {
e.preventDefault();
e.stopPropagation();
focusSafely(focusable);
} else {
let next = keyboardDelegate.getKeyRightOf(node.key);
if (next !== node.key) {
break;
}
e.preventDefault();
e.stopPropagation();
if (focusMode === 'cell' && direction === 'ltr') {
focusSafely(ref.current);
} else {
walker.currentNode = ref.current;
focusable = direction === 'rtl'
? last(walker)
: walker.firstChild() as HTMLElement;
if (focusable) {
focusSafely(focusable);
}
}
}
break;
}
case 'ArrowUp':
case 'ArrowDown':
// Prevent this event from reaching cell children, e.g. menu buttons. We want arrow keys to navigate
// to the cell above/below instead. We need to re-dispatch the event from a higher parent so it still
// bubbles and gets handled by useSelectableCollection.
if (!e.altKey && ref.current.contains(e.target as HTMLElement)) {
e.stopPropagation();
e.preventDefault();
ref.current.parentElement.dispatchEvent(
new KeyboardEvent(e.nativeEvent.type, e.nativeEvent)
);
}
break;
}
};
// Grid cells can have focusable elements inside them. In this case, focus should

@@ -88,3 +205,3 @@ // be marshalled to that element rather than focusing the cell itself.

requestAnimationFrame(() => {
if (document.activeElement === ref.current) {
if (focusMode === 'child' && document.activeElement === ref.current) {
focus();

@@ -97,2 +214,3 @@ }

role: 'gridcell',
onKeyDownCapture: onKeyDown,
onFocus

@@ -109,1 +227,13 @@ });

}
function last(walker: TreeWalker) {
let next: HTMLElement;
let last: HTMLElement;
do {
last = walker.lastChild() as HTMLElement;
if (last) {
next = last;
}
} while (last);
return next;
}

@@ -25,3 +25,4 @@ /*

isSelected?: boolean,
isDisabled?: boolean
isDisabled?: boolean,
shouldSelectOnPressUp?: boolean
}

@@ -39,3 +40,4 @@

isSelected,
isDisabled
isDisabled,
shouldSelectOnPressUp
} = props;

@@ -47,3 +49,4 @@

ref,
isVirtualized
isVirtualized,
shouldSelectOnPressUp
});

@@ -50,0 +53,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc