Skip to content

Commit 504fb74

Browse files
committed
Add RovingFocusGroup and RovingFocusRoot contexts
1 parent 0821d28 commit 504fb74

File tree

6 files changed

+56
-18
lines changed

6 files changed

+56
-18
lines changed

src/core/utils/RovingFocusGroup/context/RovingFocuGroupContext.tsx

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { createContext, RefObject } from 'react';
2+
3+
// Define the type for the context
4+
export type RovingFocusGroupContextTypes = {
5+
focusedItemId: string | null;
6+
setFocusedItemId: (id: string | null) => void;
7+
focusItems: string[];
8+
setFocusItems: React.Dispatch<React.SetStateAction<string[]>>;
9+
addFocusItem: (id: string) => void;
10+
groupRef: RefObject<HTMLDivElement> | null;
11+
}
12+
13+
// Create context with proper type and default values
14+
export const RovingFocusGroupContext = createContext<RovingFocusGroupContextTypes>({
15+
focusedItemId: null,
16+
setFocusedItemId: () => {},
17+
focusItems: [],
18+
setFocusItems: () => {},
19+
addFocusItem: () => {},
20+
groupRef: null
21+
});
Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
import { createContext } from 'react';
22

3-
export const RovingFocusRootContext = createContext({});
3+
// Define the type for the context
4+
export type RovingFocusRootContextTypes = {
5+
direction: 'horizontal' | 'vertical';
6+
loop: boolean;
7+
}
8+
9+
// Create context with proper type and default values
10+
export const RovingFocusRootContext = createContext<RovingFocusRootContextTypes>({
11+
direction: 'horizontal',
12+
loop: true
13+
});

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import React, { useEffect, useState, useId, useRef } from 'react';
22
import Primitive from '~/core/primitives/Primitive';
33

4-
import { RovingFocusGroupContext } from '../context/RovingFocuGroupContext';
4+
import { RovingFocusGroupContext, RovingFocusGroupContextTypes } from '../context/RovingFocusGroupContext';
55

66
type RovingFocusGroupProps = {
77
children: React.ReactNode;
8-
};
8+
} & React.HTMLAttributes<HTMLDivElement>;
99

1010
const RovingFocusGroup = ({ children, ...props }: RovingFocusGroupProps) => {
1111
const groupRef = useRef<HTMLDivElement>(null);
@@ -23,7 +23,7 @@ const RovingFocusGroup = ({ children, ...props }: RovingFocusGroupProps) => {
2323
}
2424
}, [focusItems, focusedItemId]);
2525

26-
const sendValues = {
26+
const sendValues: RovingFocusGroupContextTypes = {
2727
focusedItemId,
2828
setFocusedItemId,
2929
focusItems,

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ import React, { forwardRef, useContext, useEffect, useId, useRef } from 'react';
22

33
import Primitive from '~/core/primitives/Primitive';
44

5-
import { RovingFocusGroupContext } from '../context/RovingFocuGroupContext';
6-
import { RovingFocusRootContext } from '../context/RovingFocusRootContext';
5+
import { RovingFocusGroupContext, RovingFocusGroupContextTypes } from '../context/RovingFocusGroupContext';
6+
import { RovingFocusRootContext, RovingFocusRootContextTypes } from '../context/RovingFocusRootContext';
77

8-
const RovingFocusItem = forwardRef<HTMLButtonElement, { children: React.ReactNode }>(({ children, ...props }, ref) => {
8+
type RovingFocusItemProps = {
9+
children: React.ReactNode;
10+
} & React.ButtonHTMLAttributes<HTMLButtonElement>;
11+
12+
const RovingFocusItem = forwardRef<HTMLButtonElement, RovingFocusItemProps>(({ children, ...props }, ref) => {
913
const id = useId();
10-
const { focusedItemId, setFocusedItemId, addFocusItem, focusItems, groupRef } = useContext(RovingFocusGroupContext);
11-
const { direction, loop } = useContext(RovingFocusRootContext);
14+
const { focusedItemId, setFocusedItemId, addFocusItem, focusItems, groupRef } = useContext<RovingFocusGroupContextTypes>(RovingFocusGroupContext);
15+
const { direction, loop } = useContext<RovingFocusRootContextTypes>(RovingFocusRootContext);
1216

1317
useEffect(() => {
1418
// we check if the item is in the focusItems array, if not we add it
@@ -22,13 +26,13 @@ const RovingFocusItem = forwardRef<HTMLButtonElement, { children: React.ReactNod
2226
}, [focusItems, focusedItemId]);
2327

2428
const focusItemWithId = (id: string) => {
25-
if (groupRef.current) {
29+
if (groupRef && groupRef.current) {
2630
setFocusedItemId(id);
2731
// Sanitize the id to ensure it's a valid CSS selector
2832
const sanitizedId = CSS.escape(id);
29-
const item = groupRef?.current?.querySelector(`#${sanitizedId}`);
33+
const item = groupRef.current.querySelector(`#${sanitizedId}`);
3034
if (item) {
31-
item.focus();
35+
(item as HTMLElement).focus();
3236
}
3337
}
3438
};

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@ import React from 'react';
22

33
import Primitive from '~/core/primitives/Primitive';
44

5-
import { RovingFocusRootContext } from '../context/RovingFocusRootContext';
5+
import { RovingFocusRootContext, RovingFocusRootContextTypes } from '../context/RovingFocusRootContext';
66

7-
const RovingFocusRoot = ({ children, direction = 'horizontal', loop = true, ...props }: { children: React.ReactNode, direction?: 'horizontal' | 'vertical', loop?: boolean }) => {
8-
const sendValues = {
7+
type RovingFocusRootProps = {
8+
children: React.ReactNode;
9+
direction?: 'horizontal' | 'vertical';
10+
loop?: boolean;
11+
} & React.HTMLAttributes<HTMLDivElement>;
12+
13+
const RovingFocusRoot = ({ children, direction = 'horizontal', loop = true, ...props }: RovingFocusRootProps) => {
14+
const sendValues: RovingFocusRootContextTypes = {
915
direction,
1016
loop
1117
};

0 commit comments

Comments
 (0)