Unverified Commit 9f948584 authored by Kyle Keating's avatar Kyle Keating Committed by GitHub

Improve typecheck for MenuKeyboardNavigationProps (#2345)

parent 0b01c170
...@@ -8,12 +8,22 @@ function isElementVisible(element) { ...@@ -8,12 +8,22 @@ function isElementVisible(element) {
return element.offsetParent !== null; return element.offsetParent !== null;
} }
/**
* @typedef MenuKeyboardNavigationProps
* @prop {string} [className]
* @prop {(e: KeyboardEvent) => any} [closeMenu] - Callback when the menu is closed via keyboard input
* @prop {boolean} [visible] - When true`, sets focus on the first item in the list
* @prop {Object} children - Array of nodes which may contain <MenuItems> or any nodes
*/
/** /**
* Helper component used by Menu and MenuItem to facilitate keyboard navigation of a * Helper component used by Menu and MenuItem to facilitate keyboard navigation of a
* list of <MenuItem> components. This component should not be used directly. * list of <MenuItem> components. This component should not be used directly.
* *
* Note that `ArrowRight` shall be handled by the parent <MenuItem> directly and * Note that `ArrowRight` shall be handled by the parent <MenuItem> directly and
* all other focus() related navigation is handled here. * all other focus() related navigation is handled here.
*
* @param {MenuKeyboardNavigationProps} props
*/ */
export default function MenuKeyboardNavigation({ export default function MenuKeyboardNavigation({
className, className,
...@@ -21,7 +31,7 @@ export default function MenuKeyboardNavigation({ ...@@ -21,7 +31,7 @@ export default function MenuKeyboardNavigation({
children, children,
visible, visible,
}) { }) {
const menuRef = useRef(null); const menuRef = useRef(/** @type {HTMLDivElement|null} */ (null));
useEffect(() => { useEffect(() => {
let focusTimer = null; let focusTimer = null;
...@@ -30,7 +40,7 @@ export default function MenuKeyboardNavigation({ ...@@ -30,7 +40,7 @@ export default function MenuKeyboardNavigation({
// The focus won't work without delaying rendering. // The focus won't work without delaying rendering.
const firstItem = menuRef.current.querySelector('[role^="menuitem"]'); const firstItem = menuRef.current.querySelector('[role^="menuitem"]');
if (firstItem) { if (firstItem) {
firstItem.focus(); /** @type {HTMLElement} */ (firstItem).focus();
} }
}); });
} }
...@@ -42,7 +52,8 @@ export default function MenuKeyboardNavigation({ ...@@ -42,7 +52,8 @@ export default function MenuKeyboardNavigation({
const onKeyDown = event => { const onKeyDown = event => {
const menuItems = Array.from( const menuItems = Array.from(
menuRef.current.querySelectorAll('[role^="menuitem"]') /** @type {NodeListOf<HTMLElement>} */
(menuRef.current.querySelectorAll('[role^="menuitem"]'))
).filter(isElementVisible); ).filter(isElementVisible);
let focusedIndex = menuItems.findIndex(el => let focusedIndex = menuItems.findIndex(el =>
......
...@@ -57,7 +57,6 @@ ...@@ -57,7 +57,6 @@
"sidebar/components/login-prompt-panel.js", "sidebar/components/login-prompt-panel.js",
"sidebar/components/markdown-editor.js", "sidebar/components/markdown-editor.js",
"sidebar/components/menu-item.js", "sidebar/components/menu-item.js",
"sidebar/components/menu-keyboard-navigation.js",
"sidebar/components/menu.js", "sidebar/components/menu.js",
"sidebar/components/moderation-banner.js", "sidebar/components/moderation-banner.js",
"sidebar/components/new-note-btn.js", "sidebar/components/new-note-btn.js",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment