Skip to content
16 changes: 11 additions & 5 deletions src/components/datagrid/utils/focus.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,22 @@ describe('useFocus', () => {
});

describe('focusedCell / setFocusedCell', () => {
const {
return: { focusedCell, setFocusedCell },
getUpdatedState,
} = testCustomHook(() => useFocus(mockArgs));

it('gets and sets the focusedCell state', () => {
const {
return: { focusedCell, setFocusedCell },
getUpdatedState,
} = testCustomHook(() => useFocus(mockArgs));
expect(focusedCell).toEqual(undefined);

act(() => setFocusedCell([2, 2]));
expect(getUpdatedState().focusedCell).toEqual([2, 2]);
});

it('does not update if setFocusedCell is called with the same cell X/Y coordinates', () => {
const focusedCellInMemory = getUpdatedState().focusedCell;
act(() => getUpdatedState().setFocusedCell([2, 2]));
expect(getUpdatedState().focusedCell).toBe(focusedCellInMemory); // Would fail if the exact same array wasn't returned
});
});

describe('focusFirstVisibleInteractiveCell', () => {
Expand Down
20 changes: 16 additions & 4 deletions src/components/datagrid/utils/focus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,22 @@ export const useFocus = ({
EuiDataGridFocusedCell | undefined
>(undefined);

const setFocusedCell = useCallback((focusedCell: EuiDataGridFocusedCell) => {
_setFocusedCell(focusedCell);
setIsFocusedCellInView(true); // scrolling.ts ensures focused cells are fully in view
}, []);
const setFocusedCell = useCallback(
(nextFocusedCell: EuiDataGridFocusedCell) => {
// If the x/y coordinates remained the same, don't update. This keeps the focusedCell
// reference stable, and allows it to be used in places that need reference equality.
if (
nextFocusedCell[0] === focusedCell?.[0] &&
nextFocusedCell[1] === focusedCell?.[1]
) {
return;
}

_setFocusedCell(nextFocusedCell);
setIsFocusedCellInView(true); // scrolling.ts ensures focused cells are fully in view
},
[focusedCell]
);

const previousCell = useRef<EuiDataGridFocusedCell | undefined>(undefined);
useEffect(() => {
Expand Down
4 changes: 4 additions & 0 deletions upcoming_changelogs/6007.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
**Bug fixes**

- Fixed the focus context of `EuiDataGrid` to ensure that focusedCell maintains it's referential integrity. This ensures that React hooks can use this safely as a dependency.