Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5eaf493

Browse files
committedOct 17, 2024
Allow to use any HTML Element as menu item
The code works with any HTML element, there's nothing that requires specifically `HTMLAnchorElement` (`<a>`) except `e.currentTarget.href` which is already conditional. Thus the current limitation is only a typing issue introduced by unnecessarily specific `ref` type. We can make it a generic parameter, but it wouldn't bring any real benefit, just increase complexity and decrease flexibility. Resolves #174
1 parent 040caac commit 5eaf493

File tree

2 files changed

+10
-9
lines changed

2 files changed

+10
-9
lines changed
 

‎src/use-dropdown-menu.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ export interface ButtonProps<ButtonElement extends HTMLElement>
1212

1313
// Create interface for item properties
1414
export interface ItemProps {
15-
onKeyDown: (e: React.KeyboardEvent<HTMLAnchorElement>) => void;
15+
onKeyDown: (e: React.KeyboardEvent<HTMLElement>) => void;
1616
tabIndex: number;
1717
role: string;
18-
ref: React.RefObject<HTMLAnchorElement>;
18+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
19+
ref: React.RefObject<any>;
1920
}
2021

2122
// A custom Hook that abstracts away the listeners/controls for dropdown menus
@@ -43,8 +44,8 @@ export default function useDropdownMenu<ButtonElement extends HTMLElement = HTML
4344

4445
// Create refs
4546
const buttonRef = useRef<ButtonElement>(null);
46-
const itemRefs = useMemo<React.RefObject<HTMLAnchorElement>[]>(
47-
() => Array.from({ length: itemCount }, () => createRef<HTMLAnchorElement>()),
47+
const itemRefs = useMemo<React.RefObject<HTMLElement>[]>(
48+
() => Array.from({ length: itemCount }, () => createRef<HTMLElement>()),
4849
[itemCount]
4950
);
5051

@@ -171,7 +172,7 @@ export default function useDropdownMenu<ButtonElement extends HTMLElement = HTML
171172
};
172173

173174
// Create a function that handles menu logic based on keyboard events that occur on menu items
174-
const itemListener = (e: React.KeyboardEvent<HTMLAnchorElement>): void => {
175+
const itemListener = (e: React.KeyboardEvent<HTMLElement | HTMLAnchorElement>): void => {
175176
// Destructure the key property from the event object
176177
const { key } = e;
177178

@@ -189,7 +190,7 @@ export default function useDropdownMenu<ButtonElement extends HTMLElement = HTML
189190
setIsOpen(false);
190191
return;
191192
} else if (key === 'Enter' || key === ' ') {
192-
if (!e.currentTarget.href) {
193+
if (!('href' in e.currentTarget && e.currentTarget.href)) {
193194
e.currentTarget.click();
194195
}
195196

‎website/docs/design/return-object.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ This Hook returns an object of the following shape:
1717
};
1818
itemProps: [
1919
{
20-
onKeyDown: (e: React.KeyboardEvent<HTMLAnchorElement>) => void;
20+
onKeyDown: (e: React.KeyboardEvent<HTMLElement>) => void;
2121
tabIndex: -1;
2222
role: 'menuitem';
23-
ref: React.RefObject<HTMLAnchorElement>;
23+
ref: React.RefObject<any>;
2424
};
2525
...
2626
];
@@ -45,4 +45,4 @@ This Hook returns an object of the following shape:
4545
- **ref:** A React ref applied to each menu item, used to manage focus.
4646
- **isOpen:** A boolean value indicating if the menu is open or closed. The developer should use this value to make the menu visible or not.
4747
- **setIsOpen:** A function useful for allowing the developer to programmatically open/close the menu.
48-
- **moveFocus:** A function that moves the browser’s focus to the specified item index.
48+
- **moveFocus:** A function that moves the browser’s focus to the specified item index.

0 commit comments

Comments
 (0)
Please sign in to comment.