diff --git a/components/menu/src/flyout-menu/__tests__/flyout-menu.test.js b/components/menu/src/flyout-menu/__tests__/flyout-menu.test.js
new file mode 100644
index 0000000000..002b51c1a5
--- /dev/null
+++ b/components/menu/src/flyout-menu/__tests__/flyout-menu.test.js
@@ -0,0 +1,48 @@
+import { render, act } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
+import React from 'react'
+import { MenuItem } from '../../menu-item/menu-item.js'
+import { FlyoutMenu } from '../flyout-menu.js'
+
+describe('Flyout Menu Component', () => {
+    it('can handle navigation of submenus', async () => {
+        const { getByText, queryByText, getAllByRole } = render(
+            <FlyoutMenu>
+                <MenuItem label="Item 1" />
+                <MenuItem label="Item 2">
+                    <MenuItem label="Item 2 a" />
+                </MenuItem>
+            </FlyoutMenu>
+        )
+
+        const itemOne = getByText(/Item 1/i)
+        const itemTwo = getByText(/Item 2/i)
+        const submenuChild = queryByText(/Item 2 a/i)
+
+        const menuItems = getAllByRole('menuitem')
+
+        expect(menuItems.length).toBe(2)
+        expect(menuItems[0]).toBe(itemOne.parentNode)
+        expect(menuItems[1]).toBe(itemTwo.parentNode)
+
+        userEvent.tab()
+        expect(menuItems[0].parentNode).toHaveFocus()
+        expect(menuItems[1].parentNode).not.toHaveFocus()
+
+        userEvent.keyboard('{ArrowDown}')
+        expect(menuItems[0].parentNode).not.toHaveFocus()
+        expect(menuItems[1].parentNode).toHaveFocus()
+
+        expect(submenuChild).not.toBeInTheDocument()
+
+        act(() => {
+            userEvent.keyboard('{ArrowRight}')
+        })
+        expect(getByText(/Item 2 a/i)).toBeInTheDocument()
+
+        act(() => {
+            userEvent.keyboard('{ArrowLeft}')
+        })
+        expect(queryByText(/Item 2 a/i)).not.toBeInTheDocument()
+    })
+})
diff --git a/components/menu/src/flyout-menu/flyout-menu.js b/components/menu/src/flyout-menu/flyout-menu.js
index c3b4035635..aa8aec0e90 100644
--- a/components/menu/src/flyout-menu/flyout-menu.js
+++ b/components/menu/src/flyout-menu/flyout-menu.js
@@ -1,6 +1,13 @@
 import { colors, elevations, spacers } from '@dhis2/ui-constants'
 import PropTypes from 'prop-types'
-import React, { Children, cloneElement, isValidElement, useState } from 'react'
+import React, {
+    Children,
+    cloneElement,
+    isValidElement,
+    useEffect,
+    useRef,
+    useState,
+} from 'react'
 import { Menu } from '../index.js'
 
 const FlyoutMenu = ({
@@ -17,8 +24,33 @@ const FlyoutMenu = ({
         setOpenedSubMenu(toggleValue)
     }
 
+    const divRef = useRef(null)
+
+    const handleFocus = (event) => {
+        if (event.target === divRef.current) {
+            divRef.current.children[0].focus()
+        }
+    }
+
+    useEffect(() => {
+        if (!divRef) {
+            return
+        }
+        const div = divRef.current
+        div.addEventListener('focus', handleFocus)
+
+        return () => {
+            div.removeEventListener('focus', handleFocus)
+        }
+    })
+
     return (
-        <div className={className} data-test={dataTest}>
+        <div
+            className={className}
+            data-test={dataTest}
+            tabIndex={0}
+            ref={divRef}
+        >
             <Menu dense={dense}>
                 {Children.map(children, (child, index) =>
                     isValidElement(child)
diff --git a/components/menu/src/menu-item/menu-item.js b/components/menu/src/menu-item/menu-item.js
index edacfac93d..9ce2918528 100644
--- a/components/menu/src/menu-item/menu-item.js
+++ b/components/menu/src/menu-item/menu-item.js
@@ -60,6 +60,7 @@ const MenuItem = ({
                 data-test={dataTest}
                 role="presentation"
                 tabIndex={tabIndex}
+                data-submenu-open={children && showSubMenu}
             >
                 <a
                     target={target}
diff --git a/components/menu/src/menu/use-menu.js b/components/menu/src/menu/use-menu.js
index 07adee4f70..1afeaf0560 100644
--- a/components/menu/src/menu/use-menu.js
+++ b/components/menu/src/menu/use-menu.js
@@ -6,6 +6,7 @@ export const useMenuNavigation = (children) => {
     const menuItemsRef = useRef(null)
     const [focusableItemsIndices, setFocusableItemsIndices] = useState(null)
     const [activeItemIndex, setActiveItemIndex] = useState(-1)
+    const [openSubMenus, setOpenSubMenus] = useState([])
 
     // Focus the first menu item when the menu receives focus
     const handleFocus = useCallback(
@@ -41,6 +42,10 @@ export const useMenuNavigation = (children) => {
     const handleNavigation = useCallback(
         (event) => {
             const totalFocusablePositions = focusableItemsIndices?.length
+            //menu item components
+            const anchorChild = event.target.children[0]
+            const hasSubMenu = anchorChild?.getAttribute('aria-haspopup')
+
             switch (event.key) {
                 case 'ArrowUp':
                     event.preventDefault()
@@ -58,11 +63,24 @@ export const useMenuNavigation = (children) => {
                         setActiveItemIndex(activeItemIndex + 1)
                     }
                     break
+                // for MenuItem components
+                case 'ArrowRight':
+                    event.preventDefault()
+                    if (hasSubMenu) {
+                        anchorChild.click()
+                    }
+                    break
+                case 'ArrowLeft':
+                case 'Escape':
+                    event.preventDefault()
+                    openSubMenus[openSubMenus.length - 1]?.focus()
+                    openSubMenus[openSubMenus.length - 1]?.children[0].click()
+                    break
                 default:
                     break
             }
         },
-        [activeItemIndex, focusableItemsIndices]
+        [activeItemIndex, focusableItemsIndices?.length, openSubMenus]
     )
 
     // Keydown: handleNavigation and handleAction
@@ -77,6 +95,7 @@ export const useMenuNavigation = (children) => {
     )
 
     // Initializes the indices for focusable items
+    // track open submenus
     useEffect(() => {
         if (!menuRef) {
             return
@@ -88,6 +107,8 @@ export const useMenuNavigation = (children) => {
             Array.from(menu.children)
         )
         setFocusableItemsIndices(itemsIndices)
+
+        setOpenSubMenus(document.querySelectorAll('[data-submenu-open=true]'))
     }, [children])
 
     // Focus the active menu child
diff --git a/components/popper/src/popper.js b/components/popper/src/popper.js
index 453e3a067f..1ba1ee86a2 100644
--- a/components/popper/src/popper.js
+++ b/components/popper/src/popper.js
@@ -1,6 +1,6 @@
 import { sharedPropTypes } from '@dhis2/ui-constants'
 import PropTypes from 'prop-types'
-import React, { useState, useMemo } from 'react'
+import React, { useState, useMemo, useEffect } from 'react'
 import { usePopper } from 'react-popper'
 import { getReferenceElement } from './get-reference-element.js'
 import { deduplicateModifiers } from './modifiers.js'
@@ -49,6 +49,12 @@ const Popper = ({
         modifiers: deduplicatedModifiers,
     })
 
+    useEffect(() => {
+        if (popperElement) {
+            popperElement.children?.[0].focus() || popperElement.focus()
+        }
+    }, [popperElement])
+
     return (
         <div
             className={className}