Skip to content

Commit 0a19f0e

Browse files
committed
Refactor RovingFocusGroup with direction and loop props
1 parent 3b54c70 commit 0a19f0e

File tree

3 files changed

+50
-14
lines changed

3 files changed

+50
-14
lines changed

src/core/utils/RovingFocusGroup/fragments/RovingFocusGroup.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import Primitive from '~/core/primitives/Primitive';
33

44
import { RovingFocusGroupContext } from '../context/RovingFocuGroupContext';
55

6-
const RovingFocusGroup = ({ children, ...props }: { children: React.ReactNode }) => {
6+
type RovingFocusGroupProps = {
7+
children: React.ReactNode;
8+
direction?: 'horizontal' | 'vertical';
9+
loop?: boolean;
10+
};
11+
12+
const RovingFocusGroup = ({ children, direction = 'horizontal', loop = true, ...props }: RovingFocusGroupProps) => {
713
const groupRef = useRef<HTMLDivElement>(null);
814
const [focusItems, setFocusItems] = useState<string[]>([]);
915
const [focusedItemId, setFocusedItemId] = useState<string | null>(null);
@@ -25,7 +31,9 @@ const RovingFocusGroup = ({ children, ...props }: { children: React.ReactNode })
2531
focusItems,
2632
setFocusItems,
2733
addFocusItem,
28-
groupRef
34+
groupRef,
35+
direction,
36+
loop
2937
};
3038

3139
return <RovingFocusGroupContext.Provider value={sendValues}>

src/core/utils/RovingFocusGroup/fragments/RovingFocusItem.tsx

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { RovingFocusGroupContext } from '../context/RovingFocuGroupContext';
66

77
const RovingFocusItem = forwardRef<HTMLButtonElement, { children: React.ReactNode }>(({ children, ...props }, ref) => {
88
const id = useId();
9-
const { focusedItemId, setFocusedItemId, addFocusItem, focusItems, groupRef } = useContext(RovingFocusGroupContext);
9+
const { focusedItemId, setFocusedItemId, addFocusItem, focusItems, groupRef, direction, loop } = useContext(RovingFocusGroupContext);
1010

1111
useEffect(() => {
1212
// we check if the item is in the focusItems array, if not we add it
@@ -31,18 +31,46 @@ const RovingFocusItem = forwardRef<HTMLButtonElement, { children: React.ReactNod
3131

3232
const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {
3333
switch (event.key) {
34-
case 'ArrowUp':
35-
case 'ArrowLeft':
36-
// Logic to move focus to the previous item
37-
setFocusedItemId(focusItems[focusItems.indexOf(id) - 1]);
38-
34+
case 'ArrowUp': {
35+
if (direction === 'vertical') {
36+
// Logic to move focus to the previous item
37+
const previousIndex = focusItems.indexOf(id) - 1;
38+
if (previousIndex >= 0) {
39+
setFocusedItemId(focusItems[previousIndex]);
40+
}
41+
}
3942
break;
40-
case 'ArrowDown':
41-
case 'ArrowRight':
42-
// Logic to move focus to the next item
43-
setFocusedItemId(focusItems[focusItems.indexOf(id) + 1]);
44-
43+
}
44+
case 'ArrowLeft': {
45+
if (direction === 'horizontal') {
46+
// Logic to move focus to the previous item
47+
const previousIndex = focusItems.indexOf(id) - 1;
48+
if (previousIndex >= 0) {
49+
setFocusedItemId(focusItems[previousIndex]);
50+
}
51+
}
52+
break;
53+
}
54+
case 'ArrowDown': {
55+
if (direction === 'vertical') {
56+
// Logic to move focus to the next item
57+
const nextIndex = focusItems.indexOf(id) + 1;
58+
if (nextIndex < focusItems.length) {
59+
setFocusedItemId(focusItems[nextIndex]);
60+
}
61+
}
62+
break;
63+
}
64+
case 'ArrowRight': {
65+
if (direction === 'horizontal') {
66+
// Check if it's not the last item before moving focus to the next item
67+
const nextIndex = focusItems.indexOf(id) + 1;
68+
if (nextIndex < focusItems.length) {
69+
setFocusedItemId(focusItems[nextIndex]);
70+
}
71+
}
4572
break;
73+
}
4674
case 'Tab':
4775
// Logic to handle tab key if needed
4876
console.log('Tab');

src/core/utils/RovingFocusGroup/stories/RovingFocusGroup.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export default {
1717
<Button>Button 1 Group 1</Button>
1818
</RovingFocusGroup.Item>
1919
<RovingFocusGroup.Item>
20-
<input type="text" className="border border-green-500" />
20+
<Button>Button 2 Group 1</Button>
2121
</RovingFocusGroup.Item>
2222
<RovingFocusGroup.Item>
2323
<a href="#" className="border border-green-500">Link 1 Group 1</a>

0 commit comments

Comments
 (0)