import { useCallback, useContext } from 'react' import { handleFocusByKeyBoard } from './handleFocusByKeyBoard' import { MenuListContext } from '../../MenuList/MenuListContext' /** * MenuListContextに含まれるvalue間で上下キーでfocusを移動できる * EnterキーでMenuListContextに値を設定する * 上記2つの処理を含む処理(handleKeyDown)と、Enterキーを押下した処理(setContextValue)を配列で返す * @param value * @returns */ export function useMenuItemHandleKeyDown( value?: string, ): [(e: React.KeyboardEvent) => void, () => void] { const { setValue, root, propsArray } = useContext(MenuListContext) const setContextValue = useCallback(() => { if (value !== undefined) setValue(value) }, [value, setValue]) const handleKeyDown = useCallback( (e: React.KeyboardEvent) => { if (e.key === 'Enter') { setContextValue() } else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { const isForward = e.key === 'ArrowDown' // prevent scroll e.preventDefault() if (!propsArray || value === undefined) return const values = propsArray .map((props) => props.value) .filter((v) => v) as string[] let index = values.indexOf(value) if (index === -1) return for (let n = 0; n < values.length; n++) { const focusValue = isForward ? // prev or last index + 1 >= values.length ? values[0] : values[index + 1] : // next or first index - 1 < 0 ? values[values.length - 1] : values[index - 1] const next = root?.current?.querySelector( `[data-key='${focusValue}']`, ) if (next instanceof HTMLElement) { if (next.ariaDisabled === 'true') { index += isForward ? 1 : -1 continue } next.focus({ preventScroll: true }) if (root?.current?.parentElement) { handleFocusByKeyBoard(next, root.current.parentElement) } break } } } }, [setContextValue, propsArray, value, root], ) return [handleKeyDown, setContextValue] }