UNPKG

@grafana/ui

Version:
1 lines 5.82 kB
{"version":3,"file":"hooks.mjs","sources":["../../../../src/components/Menu/hooks.ts"],"sourcesContent":["import { RefObject, useEffect, useState } from 'react';\nimport { useEffectOnce } from 'react-use';\n\nconst modulo = (a: number, n: number) => ((a % n) + n) % n;\nconst UNFOCUSED = -1;\n\n/** @internal */\nexport interface UseMenuFocusProps {\n localRef: RefObject<HTMLDivElement>;\n isMenuOpen?: boolean;\n close?: () => void;\n onOpen?: (focusOnItem: (itemId: number) => void) => void;\n onClose?: () => void;\n onKeyDown?: React.KeyboardEventHandler;\n}\n\n/** @internal */\nexport type UseMenuFocusReturn = [(event: React.KeyboardEvent) => void];\n\n/** @internal */\nexport const useMenuFocus = ({\n localRef,\n isMenuOpen,\n close,\n onOpen,\n onClose,\n onKeyDown,\n}: UseMenuFocusProps): UseMenuFocusReturn => {\n const [focusedItem, setFocusedItem] = useState(UNFOCUSED);\n\n useEffect(() => {\n if (isMenuOpen) {\n setFocusedItem(0);\n }\n }, [isMenuOpen]);\n\n useEffect(() => {\n const menuItems = localRef?.current?.querySelectorAll<HTMLElement | HTMLButtonElement | HTMLAnchorElement>(\n '[data-role=\"menuitem\"]:not([data-disabled])'\n );\n menuItems?.[focusedItem]?.focus();\n menuItems?.forEach((menuItem, i) => {\n menuItem.tabIndex = i === focusedItem ? 0 : -1;\n });\n }, [localRef, focusedItem]);\n\n useEffectOnce(() => {\n onOpen?.(setFocusedItem);\n });\n\n const handleKeys = (event: React.KeyboardEvent) => {\n const menuItems = localRef?.current?.querySelectorAll<HTMLElement | HTMLButtonElement | HTMLAnchorElement>(\n '[data-role=\"menuitem\"]:not([data-disabled])'\n );\n const menuItemsCount = menuItems?.length ?? 0;\n\n switch (event.key) {\n case 'ArrowUp':\n event.preventDefault();\n event.stopPropagation();\n setFocusedItem(modulo(focusedItem - 1, menuItemsCount));\n break;\n case 'ArrowDown':\n event.preventDefault();\n event.stopPropagation();\n setFocusedItem(modulo(focusedItem + 1, menuItemsCount));\n break;\n case 'ArrowLeft':\n event.preventDefault();\n event.stopPropagation();\n setFocusedItem(UNFOCUSED);\n close?.();\n break;\n case 'Home':\n event.preventDefault();\n event.stopPropagation();\n setFocusedItem(0);\n break;\n case 'End':\n event.preventDefault();\n event.stopPropagation();\n setFocusedItem(menuItemsCount - 1);\n break;\n case 'Enter':\n event.preventDefault();\n event.stopPropagation();\n menuItems?.[focusedItem]?.click();\n break;\n case 'Escape':\n onClose?.();\n break;\n case 'Tab':\n event.preventDefault();\n onClose?.();\n break;\n default:\n break;\n }\n\n // Forward event to parent\n onKeyDown?.(event);\n };\n\n return [handleKeys];\n};\n"],"names":[],"mappings":"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"}