Skip to content

Commit 0e804f7

Browse files
committed
Refactor useRovingCellRef, fix test warnings
1 parent 625fad5 commit 0e804f7

File tree

2 files changed

+27
-29
lines changed

2 files changed

+27
-29
lines changed

src/hooks/useRovingCellRef.ts

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,30 @@
1-
import { useRef, useState } from 'react';
2-
import { useLayoutEffect } from './useLayoutEffect';
1+
import { useCallback, useState } from 'react';
32

43
// https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_roving_tabindex
54
export function useRovingCellRef(isSelected: boolean) {
6-
const ref = useRef<HTMLDivElement>(null);
75
// https://www.w3.org/TR/wai-aria-practices-1.1/#gridNav_focus
8-
const isChildFocused = useRef(false);
9-
const [, forceRender] = useState<unknown>({});
6+
const [isChildFocused, setIsChildFocused] = useState(false);
107

11-
useLayoutEffect(() => {
12-
if (!isSelected) {
13-
isChildFocused.current = false;
14-
return;
15-
}
8+
if (isChildFocused && !isSelected) {
9+
setIsChildFocused(false);
10+
}
1611

17-
if (isChildFocused.current) {
18-
// When the child is focused, we need to rerender
19-
// the cell again so tabIndex is updated to -1
20-
forceRender({});
21-
return;
22-
}
23-
ref.current?.focus({ preventScroll: true });
24-
}, [isSelected]);
12+
const ref = useCallback(
13+
(cell: HTMLDivElement | null) => {
14+
if (cell === null || !isSelected || cell.contains(document.activeElement)) return;
15+
16+
cell.focus({ preventScroll: true });
17+
},
18+
[isSelected]
19+
);
2520

2621
function onFocus(event: React.FocusEvent<HTMLDivElement>) {
27-
if (event.target !== ref.current) {
28-
isChildFocused.current = true;
22+
if (event.target !== event.currentTarget) {
23+
setIsChildFocused(true);
2924
}
3025
}
3126

32-
const isFocused = isSelected && !isChildFocused.current;
27+
const isFocused = isSelected && !isChildFocused;
3328

3429
return {
3530
ref,

test/components.test.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { StrictMode } from 'react';
1+
import { forwardRef, StrictMode } from 'react';
22
import { render, screen } from '@testing-library/react';
33

44
import DataGrid, { DataGridDefaultComponentsProvider, SelectColumn } from '../src';
5-
import type { Column, DataGridProps } from '../src';
5+
import type { Column, DataGridProps, CheckboxFormatterProps } from '../src';
66
import { getRows, setup } from './utils';
77

88
interface Row {
@@ -25,13 +25,16 @@ function GlobalNoRowsFallback() {
2525
return <div>Global no rows fallback</div>;
2626
}
2727

28-
function Checkbox() {
29-
return <div>Local checkbox</div>;
30-
}
28+
const Checkbox = forwardRef<HTMLDivElement, CheckboxFormatterProps>(function Checkbox(props, ref) {
29+
return <div ref={ref}>Local checkbox</div>;
30+
});
3131

32-
function GlobalCheckbox() {
33-
return <div>Global checkbox</div>;
34-
}
32+
const GlobalCheckbox = forwardRef<HTMLDivElement, CheckboxFormatterProps>(function GlobalCheckbox(
33+
props,
34+
ref
35+
) {
36+
return <div ref={ref}>Global checkbox</div>;
37+
});
3538

3639
function setupProvider<R, SR, K extends React.Key>(props: DataGridProps<R, SR, K>) {
3740
return render(

0 commit comments

Comments
 (0)