refactor: menu keyboard navigation

This commit is contained in:
Aman Harwara
2023-08-14 13:49:32 +05:30
parent cd0111d6b1
commit e1c5d52dbe

View File

@@ -69,8 +69,6 @@ export const useListKeyboardNavigation = (
return return
} }
listItems.current = Array.from(container.current?.querySelectorAll('button') as NodeListOf<HTMLButtonElement>)
if (e.key === KeyboardKey.Up) { if (e.key === KeyboardKey.Up) {
const previousIndex = getPreviousFocusableIndex(focusedItemIndex.current, listItems.current) const previousIndex = getPreviousFocusableIndex(focusedItemIndex.current, listItems.current)
focusItemWithIndex(previousIndex) focusItemWithIndex(previousIndex)
@@ -81,14 +79,13 @@ export const useListKeyboardNavigation = (
focusItemWithIndex(nextIndex) focusItemWithIndex(nextIndex)
} }
}, },
[container, focusItemWithIndex, getNextFocusableIndex, getPreviousFocusableIndex], [focusItemWithIndex, getNextFocusableIndex, getPreviousFocusableIndex],
) )
const FIRST_ITEM_FOCUS_TIMEOUT = 20 const FIRST_ITEM_FOCUS_TIMEOUT = 20
const setInitialFocus = useCallback(() => { const setInitialFocus = useCallback(() => {
const items = Array.from(container.current?.querySelectorAll('button') as NodeListOf<HTMLButtonElement>) const items = listItems.current
listItems.current = items
if (items.length < 1) { if (items.length < 1) {
return return
@@ -99,7 +96,7 @@ export const useListKeyboardNavigation = (
indexToFocus = getNextFocusableIndex(indexToFocus - 1, items) indexToFocus = getNextFocusableIndex(indexToFocus - 1, items)
focusItemWithIndex(indexToFocus, items) focusItemWithIndex(indexToFocus, items)
}, [container, focusItemWithIndex, getNextFocusableIndex, initialFocus]) }, [focusItemWithIndex, getNextFocusableIndex, initialFocus])
useEffect(() => { useEffect(() => {
if (shouldAutoFocus) { if (shouldAutoFocus) {
@@ -117,10 +114,25 @@ export const useListKeyboardNavigation = (
useEffect(() => { useEffect(() => {
const containerElement = container.current const containerElement = container.current
containerElement?.addEventListener('keydown', keyDownHandler)
if (!containerElement) {
return
}
containerElement.addEventListener('keydown', keyDownHandler)
const containerMutationObserver = new MutationObserver(() => {
listItems.current = Array.from(containerElement.querySelectorAll('button'))
})
containerMutationObserver.observe(containerElement, {
childList: true,
subtree: true,
})
return () => { return () => {
containerElement?.removeEventListener('keydown', keyDownHandler) containerElement?.removeEventListener('keydown', keyDownHandler)
containerMutationObserver.disconnect()
} }
}, [container, setInitialFocus, keyDownHandler]) }, [container, setInitialFocus, keyDownHandler])