Skip to content

Commit

Permalink
Allow to use any HTML Element as menu item
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jirutka committed Oct 12, 2024
1 parent 040caac commit e4ae95f
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions src/use-dropdown-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ export interface ButtonProps<ButtonElement extends HTMLElement>

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

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

// Create refs
const buttonRef = useRef<ButtonElement>(null);
const itemRefs = useMemo<React.RefObject<HTMLAnchorElement>[]>(
() => Array.from({ length: itemCount }, () => createRef<HTMLAnchorElement>()),
const itemRefs = useMemo<React.RefObject<HTMLElement>[]>(
() => Array.from({ length: itemCount }, () => createRef<HTMLElement>()),
[itemCount]
);

Expand Down Expand Up @@ -171,7 +172,7 @@ export default function useDropdownMenu<ButtonElement extends HTMLElement = HTML
};

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

Expand All @@ -189,7 +190,7 @@ export default function useDropdownMenu<ButtonElement extends HTMLElement = HTML
setIsOpen(false);
return;
} else if (key === 'Enter' || key === ' ') {
if (!e.currentTarget.href) {
if (!('href' in e.currentTarget && e.currentTarget.href)) {
e.currentTarget.click();
}

Expand Down

0 comments on commit e4ae95f

Please sign in to comment.