diff --git a/src/components/GridKeyboardNavigationContext/__stories__/useGridKeyboardNavigationContext.stories.js b/src/components/GridKeyboardNavigationContext/__stories__/useGridKeyboardNavigationContext.stories.js
index 2bbaf9a5ee..3711f469b5 100644
--- a/src/components/GridKeyboardNavigationContext/__stories__/useGridKeyboardNavigationContext.stories.js
+++ b/src/components/GridKeyboardNavigationContext/__stories__/useGridKeyboardNavigationContext.stories.js
@@ -12,40 +12,43 @@ const PADDING_PX = 24;
const ON_CLICK = action("Selected");
-export const DummyNavigableGrid = forwardRef(({ itemsCount, numberOfItemsInLine, itemPrefix, disabled }, ref) => {
- const width = useMemo(() => numberOfItemsInLine * ELEMENT_WIDTH_PX + 2 * PADDING_PX, [numberOfItemsInLine]);
- const items = useMemo(() => range(itemsCount).map(num => `${itemPrefix} ${num}`), [itemPrefix, itemsCount]);
- const getItemByIndex = useCallback(index => items[index], [items]);
- const { activeIndex, onSelectionAction } = useGridKeyboardNavigation({
- ref,
- numberOfItemsInLine,
- itemsCount,
- getItemByIndex,
- onItemClicked: ON_CLICK
- });
- const onClickByIndex = useCallback(index => () => onSelectionAction(index), [onSelectionAction]);
- return (
-
- {items.map((item, index) => (
-
- ))}
-
- );
-});
+export const DummyNavigableGrid = forwardRef(
+ ({ itemsCount, numberOfItemsInLine, itemPrefix = "", disabled, disabledIndexes, withoutBorder = false }, ref) => {
+ const width = useMemo(() => numberOfItemsInLine * ELEMENT_WIDTH_PX + 2 * PADDING_PX, [numberOfItemsInLine]);
+ const items = useMemo(() => range(itemsCount).map(num => `${itemPrefix} ${num}`), [itemPrefix, itemsCount]);
+ const getItemByIndex = useCallback(index => items[index], [items]);
+ const { activeIndex, onSelectionAction } = useGridKeyboardNavigation({
+ ref,
+ numberOfItemsInLine,
+ itemsCount,
+ getItemByIndex,
+ onItemClicked: ON_CLICK,
+ disabledIndexes
+ });
+ const onClickByIndex = useCallback(index => () => onSelectionAction(index), [onSelectionAction]);
+ return (
+
+ {items.map((item, index) => (
+
+ ))}
+
+ );
+ }
+);
export const LayoutWithInnerKeyboardNavigation = forwardRef((_ignored, ref) => {
const leftElRef = useRef(null);
diff --git a/src/components/GridKeyboardNavigationContext/__stories__/useGridKeyboardNavigationContext.stories.scss b/src/components/GridKeyboardNavigationContext/__stories__/useGridKeyboardNavigationContext.stories.scss
index 93f8a8cee7..265a6a1854 100644
--- a/src/components/GridKeyboardNavigationContext/__stories__/useGridKeyboardNavigationContext.stories.scss
+++ b/src/components/GridKeyboardNavigationContext/__stories__/useGridKeyboardNavigationContext.stories.scss
@@ -9,6 +9,10 @@
outline: none;
text-align: center;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1), 0 0 0 1px var(--primary-hover-color) inset;
+
+ &.without-border {
+ box-shadow: none;
+ }
}
.use-grid-keyboard-dummy-grid-item {
diff --git a/src/components/Menu/Menu/Menu.jsx b/src/components/Menu/Menu/Menu.jsx
index 9bc3d05139..5018488fd3 100644
--- a/src/components/Menu/Menu/Menu.jsx
+++ b/src/components/Menu/Menu/Menu.jsx
@@ -12,6 +12,7 @@ import useCloseMenuOnKeyEvent from "./hooks/useCloseMenuOnKeyEvent";
import useMenuKeyboardNavigation from "./hooks/useMenuKeyboardNavigation";
import useMouseLeave from "./hooks/useMouseLeave";
import "./Menu.scss";
+import { useAdjacentSelectableMenuIndex } from "./hooks/useAdjacentSelectableMenuIndex";
const Menu = forwardRef(
(
@@ -76,9 +77,12 @@ const Menu = forwardRef(
useClickOutside({ ref, callback: onCloseMenu });
useCloseMenuOnKeyEvent(hasOpenSubMenu, onCloseMenu, ref, onClose, isSubMenu, useDocumentEventListeners);
+
+ const { getNextSelectableIndex, getPreviousSelectableIndex } = useAdjacentSelectableMenuIndex({ children });
useMenuKeyboardNavigation(
hasOpenSubMenu,
- children,
+ getNextSelectableIndex,
+ getPreviousSelectableIndex,
activeItemIndex,
onSetActiveItemIndexCallback,
isVisible,
@@ -91,12 +95,10 @@ const Menu = forwardRef(
setIsInitialSelectedState(true);
}, [setIsInitialSelectedState]);
- useLayoutEffect(() => {
+ useEffect(() => {
if (hasOpenSubMenu || useDocumentEventListeners) return;
if (activeItemIndex > -1) {
- requestAnimationFrame(() => {
- ref && ref.current && ref.current.focus();
- });
+ ref?.current?.focus();
}
}, [activeItemIndex, hasOpenSubMenu, useDocumentEventListeners]);
@@ -147,7 +149,10 @@ const Menu = forwardRef(
menuId: id,
useDocumentEventListeners,
isInitialSelectedState,
- shouldScrollMenu
+ shouldScrollMenu,
+ getNextSelectableIndex,
+ getPreviousSelectableIndex,
+ isUnderSubMenu: isSubMenu
})
: null;
})}
diff --git a/src/components/Menu/Menu/__stories__/Menu.stories.mdx b/src/components/Menu/Menu/__stories__/Menu.stories.mdx
index 32204e4335..5fd4157d35 100644
--- a/src/components/Menu/Menu/__stories__/Menu.stories.mdx
+++ b/src/components/Menu/Menu/__stories__/Menu.stories.mdx
@@ -7,13 +7,17 @@ import {
menuWithIconsTemplate,
ComponentRuleSimpleActions,
ComponentRuleWithSearch,
- ComponentRuleDefaultWidth, ComponentRuleLargeWidth, menuSizesTemplate
+ ComponentRuleDefaultWidth,
+ ComponentRuleLargeWidth,
+ menuSizesTemplate,
+ menuWithGridItems
} from "./menu.stories";
import {
COMBOBOX,
DROPDOWN,
SPLIT_BUTTON
} from "../../../../storybook/components/related-components/component-description-map";
+import classes from "./Menu.stories.module.scss";
+### Menu with grid items and sub menu
+Grid menu items are navigable with a keyboard as well
+
+
+
## Related components
\ No newline at end of file
diff --git a/src/components/Menu/Menu/__stories__/Menu.stories.module.scss b/src/components/Menu/Menu/__stories__/Menu.stories.module.scss
index 187e94393f..8e519da37c 100644
--- a/src/components/Menu/Menu/__stories__/Menu.stories.module.scss
+++ b/src/components/Menu/Menu/__stories__/Menu.stories.module.scss
@@ -9,4 +9,8 @@
&-large-menu {
width: 328px;
}
-}
\ No newline at end of file
+}
+
+.menu-long-story-wrapper {
+ height: 500px;
+}
diff --git a/src/components/Menu/Menu/__stories__/menu.stories.js b/src/components/Menu/Menu/__stories__/menu.stories.js
index 793c6b89f3..579ad60efc 100644
--- a/src/components/Menu/Menu/__stories__/menu.stories.js
+++ b/src/components/Menu/Menu/__stories__/menu.stories.js
@@ -22,6 +22,8 @@ import Search from "components/Search/Search";
import MenuTitle from "components/Menu/MenuTitle/MenuTitle";
import MenuDivider from "components/Menu/MenuDivider/MenuDivider";
import classes from "./Menu.stories.module.scss";
+import { DummyNavigableGrid } from "../../../GridKeyboardNavigationContext/__stories__/useGridKeyboardNavigationContext.stories";
+import MenuGridItem from "components/Menu/MenuGridItem/MenuGridItem";
export const menuTemplate = args => (