22import React , { useState , useRef , createRef , useEffect , useMemo } from 'react' ;
33
44// Create interface for button properties
5- interface ButtonProps
5+ interface ButtonProps < ButtonElement extends HTMLElement >
66 extends Pick <
7- React . DetailedHTMLProps < React . ButtonHTMLAttributes < HTMLButtonElement > , HTMLButtonElement > ,
7+ React . DetailedHTMLProps < React . ButtonHTMLAttributes < ButtonElement > , ButtonElement > ,
88 'onKeyDown' | 'onClick' | 'tabIndex' | 'role' | 'aria-haspopup' | 'aria-expanded'
99 > {
10- ref : React . RefObject < HTMLButtonElement > ;
10+ ref : React . RefObject < ButtonElement > ;
1111}
1212
1313// A custom Hook that abstracts away the listeners/controls for dropdown menus
1414export interface DropdownMenuOptions {
1515 disableFocusFirstItemOnClick ?: boolean ;
1616}
1717
18- interface DropdownMenuResponse {
19- readonly buttonProps : ButtonProps ;
18+ interface DropdownMenuResponse < ButtonElement extends HTMLElement > {
19+ readonly buttonProps : ButtonProps < ButtonElement > ;
2020 readonly itemProps : {
2121 onKeyDown : ( e : React . KeyboardEvent < HTMLAnchorElement > ) => void ;
2222 tabIndex : number ;
@@ -28,15 +28,18 @@ interface DropdownMenuResponse {
2828 readonly moveFocus : ( itemIndex : number ) => void ;
2929}
3030
31- export default function useDropdownMenu ( itemCount : number , options ?: DropdownMenuOptions ) : DropdownMenuResponse {
31+ export default function useDropdownMenu < ButtonElement extends HTMLElement = HTMLButtonElement > (
32+ itemCount : number ,
33+ options ?: DropdownMenuOptions
34+ ) : DropdownMenuResponse < ButtonElement > {
3235 // Use state
3336 const [ isOpen , setIsOpen ] = useState < boolean > ( false ) ;
3437 const currentFocusIndex = useRef < number | null > ( null ) ;
3538 const firstRun = useRef ( true ) ;
3639 const clickedOpen = useRef ( false ) ;
3740
3841 // Create refs
39- const buttonRef = useRef < HTMLButtonElement > ( null ) ;
42+ const buttonRef = useRef < ButtonElement > ( null ) ;
4043 const itemRefs = useMemo < React . RefObject < HTMLAnchorElement > [ ] > (
4144 ( ) => Array . from ( { length : itemCount } , ( ) => createRef < HTMLAnchorElement > ( ) ) ,
4245 [ itemCount ]
@@ -216,7 +219,7 @@ export default function useDropdownMenu(itemCount: number, options?: DropdownMen
216219 } ;
217220
218221 // Define spreadable props for button and items
219- const buttonProps : ButtonProps = {
222+ const buttonProps : ButtonProps < ButtonElement > = {
220223 onKeyDown : buttonListener ,
221224 onClick : buttonListener ,
222225 tabIndex : 0 ,
0 commit comments