diff --git a/components/header-bar/src/command-palette/__tests__/command-palette.test.js b/components/header-bar/src/command-palette/__tests__/command-palette.test.js
index 7a4d318f9..a72385157 100644
--- a/components/header-bar/src/command-palette/__tests__/command-palette.test.js
+++ b/components/header-bar/src/command-palette/__tests__/command-palette.test.js
@@ -1,7 +1,24 @@
-import { render } from '@testing-library/react'
+import { render as originalRender } from '@testing-library/react'
 import userEvent from '@testing-library/user-event'
+import PropTypes from 'prop-types'
 import React from 'react'
 import CommandPalette from '../command-palette.js'
+import { CommandPaletteContextProvider } from '../context/command-palette-context.js'
+
+const CommandPaletteProviderWrapper = ({ children }) => {
+    return (
+        <CommandPaletteContextProvider>
+            {children}
+        </CommandPaletteContextProvider>
+    )
+}
+
+CommandPaletteProviderWrapper.propTypes = {
+    children: PropTypes.node,
+}
+
+const render = (ui, options) =>
+    originalRender(ui, { wrapper: CommandPaletteProviderWrapper, ...options })
 
 describe('Command Palette Component', () => {
     const headerBarIconTest = 'headerbar-apps-icon'
@@ -144,7 +161,6 @@ describe('Command Palette Component', () => {
         expect(searchField).toHaveValue('Command')
 
         expect(queryByTestId('headerbar-top-apps-list')).not.toBeInTheDocument()
-        expect(queryByTestId('headerbar-search-results')).toBeInTheDocument()
         expect(queryByText(/Results for "Command"/i)).toBeInTheDocument()
         expect(queryByText(/Test Command/)).toBeInTheDocument()
         expect(queryByText(/Test App/)).not.toBeInTheDocument()
@@ -153,9 +169,8 @@ describe('Command Palette Component', () => {
         const clearButton = getAllByRole('button')[1]
         userEvent.click(clearButton)
         expect(searchField).toHaveValue('')
-        expect(
-            queryByTestId('headerbar-search-results')
-        ).not.toBeInTheDocument()
+        // back to default view
+        expect(queryByTestId('headerbar-top-apps-list')).toBeInTheDocument()
     })
 
     it('renders Browse Apps View', () => {
diff --git a/components/header-bar/src/command-palette/command-palette.js b/components/header-bar/src/command-palette/command-palette.js
index d71f78578..b07a24238 100755
--- a/components/header-bar/src/command-palette/command-palette.js
+++ b/components/header-bar/src/command-palette/command-palette.js
@@ -3,72 +3,66 @@ import { IconApps24 } from '@dhis2/ui-icons'
 import PropTypes from 'prop-types'
 import React, { useState, useCallback, useRef, useEffect } from 'react'
 import i18n from '../locales/index.js'
-import ActionsMenu from './sections/actions-menu.js'
+import { useCommandPaletteContext } from './context/command-palette-context.js'
+import { useFilter } from './hooks/use-filter.js'
+import { useNavigation } from './hooks/use-navigation.js'
 import BackButton from './sections/back-button.js'
 import ModalContainer from './sections/container.js'
 import Search from './sections/search-field.js'
-import { filterItemsArray } from './utils/filterItemsArray.js'
-import BrowseApps from './views/browse-apps.js'
-import BrowseCommands from './views/browse-commands.js'
-import BrowseShortcuts from './views/browse-shortcuts.js'
 import HomeView from './views/home-view.js'
-
-const MIN_APPS_NUM = 8
+import {
+    BrowseApps,
+    BrowseCommands,
+    BrowseShortcuts,
+} from './views/list-view.js'
 
 const CommandPalette = ({ apps, commands, shortcuts }) => {
     const containerEl = useRef(null)
     const [show, setShow] = useState(false)
-    const [filter, setFilter] = useState('')
-
-    const [currentView, setCurrentView] = useState('home')
-
-    const showActions = filter.length <= 0 && currentView === 'home'
+    const { currentView, filter, setFilter } = useCommandPaletteContext()
 
     const handleVisibilityToggle = useCallback(() => setShow(!show), [show])
-    const handleFilterChange = useCallback(({ value }) => setFilter(value), [])
+    const handleFilterChange = useCallback(
+        ({ value }) => setFilter(value),
+        [setFilter]
+    )
 
-    const goToDefaultView = () => {
-        setFilter('')
-        setCurrentView('home')
-    }
+    const {
+        filteredApps,
+        filteredCommands,
+        filteredShortcuts,
+        currentViewItemsArray,
+    } = useFilter({ apps, commands, shortcuts })
 
-    const filteredApps = filterItemsArray(apps, filter)
-    const filteredCommands = filterItemsArray(commands, filter)
-    const filteredShortcuts = filterItemsArray(shortcuts, filter)
+    const { handleKeyDown, goToDefaultView, modalRef } = useNavigation({
+        setShow,
+        itemsArray: currentViewItemsArray,
+        show,
+    })
 
-    const handleKeyDown = useCallback(
-        (event) => {
-            switch (event.key) {
-                case 'Escape':
-                    event.preventDefault()
-                    if (currentView === 'home') {
-                        setShow(false)
-                    } else {
-                        goToDefaultView()
-                    }
-                    break
-            }
+    useEffect(() => {
+        const activeItem = document.querySelector('.highlighted')
+        if (activeItem && typeof activeItem.scrollIntoView === 'function') {
+            activeItem?.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
+        }
+    })
 
-            if ((event.metaKey || event.ctrlKey) && event.key === '/') {
-                setShow(!show)
-            }
-        },
-        [currentView, show]
-    )
+    useEffect(() => {
+        if (modalRef.current) {
+            modalRef.current?.focus()
+        }
+    })
 
-    const handleFocus = (e) => {
-        // this is about the focus of the element
-        // on launch: focus entire element
-        console.log(e.target, 'e.target')
-        console.log(document.activeElement, 'active element')
+    const handleFocus = (event) => {
+        if (event.target === modalRef?.current) {
+            modalRef.current?.querySelector('input').focus()
+        }
     }
 
     useEffect(() => {
         document.addEventListener('keydown', handleKeyDown)
-        document.addEventListener('focus', handleFocus)
         return () => {
             document.removeEventListener('keydown', handleKeyDown)
-            document.removeEventListener('focus', handleFocus)
         }
     }, [handleKeyDown])
 
@@ -82,20 +76,24 @@ const CommandPalette = ({ apps, commands, shortcuts }) => {
             </button>
             {show ? (
                 <ModalContainer setShow={setShow} show={show}>
-                    <div data-test="headerbar-menu" className="headerbar-menu">
+                    <div
+                        data-test="headerbar-menu"
+                        className="headerbar-menu"
+                        ref={modalRef}
+                        tabIndex={0}
+                        onFocus={handleFocus}
+                    >
                         <Search
                             value={filter}
                             onChange={handleFilterChange}
                             placeholder={
-                                currentView === 'home'
-                                    ? i18n.t('Search apps, shortcuts, commands')
-                                    : currentView === 'apps'
+                                currentView === 'apps'
                                     ? i18n.t('Search apps')
                                     : currentView === 'commands'
                                     ? i18n.t('Search commands')
                                     : currentView === 'shortcuts'
                                     ? i18n.t('Search shortcuts')
-                                    : null
+                                    : i18n.t('Search apps, shortcuts, commands')
                             }
                         />
                         <div className="headerbar-menu-content">
@@ -103,47 +101,28 @@ const CommandPalette = ({ apps, commands, shortcuts }) => {
                                 <BackButton onClickHandler={goToDefaultView} />
                             ) : null}
                             {/* switch views */}
-                            {currentView === 'apps' && (
-                                <BrowseApps
+                            {currentView === 'home' && (
+                                <HomeView
                                     apps={filteredApps}
-                                    filter={filter}
+                                    commands={filteredCommands}
+                                    shortcuts={filteredShortcuts}
                                 />
                             )}
+                            {currentView === 'apps' && (
+                                <BrowseApps apps={filteredApps} />
+                            )}
                             {currentView === 'commands' && (
-                                <BrowseCommands
-                                    commands={filteredCommands}
-                                    filter={filter}
-                                    type={'commands'}
-                                />
+                                <BrowseCommands commands={filteredCommands} />
                             )}
                             {currentView === 'shortcuts' && (
                                 <BrowseShortcuts
                                     shortcuts={filteredShortcuts}
-                                    filter={filter}
-                                />
-                            )}
-                            {currentView === 'home' && (
-                                <HomeView
-                                    apps={filteredApps}
-                                    commands={filteredCommands}
-                                    shortcuts={filteredShortcuts}
-                                    filter={filter}
-                                />
-                            )}
-                            {/* actions sections */}
-                            {showActions && (
-                                <ActionsMenu
-                                    showAppsList={apps?.length > MIN_APPS_NUM}
-                                    showCommandsList={commands?.length > 0}
-                                    showShortcutsList={shortcuts?.length > 0}
-                                    setCurrentView={setCurrentView}
                                 />
                             )}
                         </div>
                     </div>
                 </ModalContainer>
             ) : null}
-
             <style jsx>{`
                 button {
                     display: block;
@@ -173,9 +152,8 @@ const CommandPalette = ({ apps, commands, shortcuts }) => {
                     height: 100%;
                 }
                 .headerbar-menu-content {
-                    display: flex;
-                    flex-direction: column;
                     overflow-y: auto;
+                    max-height: calc(544px - 50px);
                 }
             `}</style>
         </div>
diff --git a/components/header-bar/src/command-palette/context/command-palette-context.js b/components/header-bar/src/command-palette/context/command-palette-context.js
new file mode 100644
index 000000000..a23768037
--- /dev/null
+++ b/components/header-bar/src/command-palette/context/command-palette-context.js
@@ -0,0 +1,34 @@
+import PropTypes from 'prop-types'
+import React, { createContext, useContext, useState } from 'react'
+
+const commandPaletteContext = createContext()
+
+export const CommandPaletteContextProvider = ({ children }) => {
+    const [filter, setFilter] = useState('')
+    const [highlightedIndex, setHighlightedIndex] = useState(0)
+    const [currentView, setCurrentView] = useState('home')
+    // home view sections
+    const [activeSection, setActiveSection] = useState('grid')
+
+    return (
+        <commandPaletteContext.Provider
+            value={{
+                filter,
+                setFilter,
+                highlightedIndex,
+                setHighlightedIndex,
+                currentView,
+                setCurrentView,
+                activeSection,
+                setActiveSection,
+            }}
+        >
+            {children}
+        </commandPaletteContext.Provider>
+    )
+}
+CommandPaletteContextProvider.propTypes = {
+    children: PropTypes.node,
+}
+
+export const useCommandPaletteContext = () => useContext(commandPaletteContext)
diff --git a/components/header-bar/src/command-palette/hooks/use-filter.js b/components/header-bar/src/command-palette/hooks/use-filter.js
new file mode 100644
index 000000000..7f65be78e
--- /dev/null
+++ b/components/header-bar/src/command-palette/hooks/use-filter.js
@@ -0,0 +1,30 @@
+import { useMemo } from 'react'
+import { useCommandPaletteContext } from '../context/command-palette-context.js'
+import { filterItemsArray } from '../utils/filterItemsArray.js'
+
+export const useFilter = ({ apps, commands, shortcuts }) => {
+    const { filter, currentView } = useCommandPaletteContext()
+
+    const filteredApps = filterItemsArray(apps, filter)
+    const filteredCommands = filterItemsArray(commands, filter)
+    const filteredShortcuts = filterItemsArray(shortcuts, filter)
+
+    const currentViewItemsArray = useMemo(() => {
+        if (currentView === 'apps') {
+            return filteredApps
+        } else if (currentView === 'commands') {
+            return filteredCommands
+        } else if (currentView === 'shortcuts') {
+            return filteredShortcuts
+        } else {
+            return filteredApps.concat(filteredCommands, filteredShortcuts)
+        }
+    }, [currentView, filteredApps, filteredCommands, filteredShortcuts])
+
+    return {
+        filteredApps,
+        filteredCommands,
+        filteredShortcuts,
+        currentViewItemsArray,
+    }
+}
diff --git a/components/header-bar/src/command-palette/hooks/use-navigation.js b/components/header-bar/src/command-palette/hooks/use-navigation.js
new file mode 100644
index 000000000..d584dc857
--- /dev/null
+++ b/components/header-bar/src/command-palette/hooks/use-navigation.js
@@ -0,0 +1,219 @@
+import { useCallback, useRef } from 'react'
+import { useCommandPaletteContext } from '../context/command-palette-context.js'
+
+export const GRID_ITEMS_LENGTH = 8
+
+export const useNavigation = ({ setShow, itemsArray, show }) => {
+    const modalRef = useRef(null)
+    const {
+        activeSection,
+        currentView,
+        filter,
+        highlightedIndex,
+        setHighlightedIndex,
+        setFilter,
+        setCurrentView,
+        setActiveSection,
+    } = useCommandPaletteContext()
+
+    const goToDefaultView = useCallback(() => {
+        setFilter('')
+        setCurrentView('home')
+        setActiveSection('grid')
+        setHighlightedIndex(0)
+    }, [setActiveSection, setCurrentView, setFilter, setHighlightedIndex])
+
+    const handleListViewNavigation = useCallback(
+        (event) => {
+            const lastIndex = itemsArray.length - 1
+            switch (event.key) {
+                case 'ArrowDown':
+                    setHighlightedIndex(
+                        highlightedIndex >= lastIndex ? 0 : highlightedIndex + 1
+                    )
+                    break
+                case 'ArrowUp':
+                    setHighlightedIndex(
+                        highlightedIndex > 0 ? highlightedIndex - 1 : lastIndex
+                    )
+                    break
+                case 'Escape':
+                    event.preventDefault()
+                    goToDefaultView()
+                    break
+                default:
+                    break
+            }
+        },
+        [
+            goToDefaultView,
+            highlightedIndex,
+            itemsArray.length,
+            setHighlightedIndex,
+        ]
+    )
+
+    const handleHomeViewNavigation = useCallback(
+        (event) => {
+            // grid
+            const gridRowLength = GRID_ITEMS_LENGTH / 2
+            const topRowLastIndex = gridRowLength - 1
+            const lastRowFirstIndex = gridRowLength
+            const lastRowLastIndex = GRID_ITEMS_LENGTH - 1
+
+            switch (event.key) {
+                case 'ArrowLeft':
+                    if (activeSection === 'grid') {
+                        // row 1
+                        if (highlightedIndex <= topRowLastIndex) {
+                            setHighlightedIndex(
+                                highlightedIndex > 0
+                                    ? highlightedIndex - 1
+                                    : topRowLastIndex
+                            )
+                        }
+                        // row 2
+                        if (highlightedIndex >= lastRowFirstIndex) {
+                            setHighlightedIndex(
+                                highlightedIndex > lastRowFirstIndex
+                                    ? highlightedIndex - 1
+                                    : lastRowLastIndex
+                            )
+                        }
+                    }
+                    break
+                case 'ArrowRight':
+                    if (activeSection === 'grid') {
+                        // row 1
+                        if (highlightedIndex <= topRowLastIndex) {
+                            setHighlightedIndex(
+                                highlightedIndex >= topRowLastIndex
+                                    ? 0
+                                    : highlightedIndex + 1
+                            )
+                        }
+                        // row 2
+                        if (highlightedIndex >= lastRowFirstIndex) {
+                            setHighlightedIndex(
+                                highlightedIndex >= lastRowLastIndex
+                                    ? lastRowFirstIndex
+                                    : highlightedIndex + 1
+                            )
+                        }
+                    }
+                    break
+                case 'ArrowDown':
+                    if (activeSection === 'grid') {
+                        if (highlightedIndex >= lastRowFirstIndex) {
+                            setActiveSection('actions')
+                            setHighlightedIndex(0)
+                        } else {
+                            setHighlightedIndex(
+                                highlightedIndex + gridRowLength
+                            )
+                        }
+                    } else if (activeSection === 'actions') {
+                        if (highlightedIndex >= 3) {
+                            setActiveSection('grid')
+                            setHighlightedIndex(0)
+                        } else {
+                            setHighlightedIndex(highlightedIndex + 1)
+                        }
+                    }
+                    break
+                case 'ArrowUp':
+                    if (activeSection === 'grid') {
+                        if (highlightedIndex < lastRowFirstIndex) {
+                            setActiveSection('actions')
+                            setHighlightedIndex(3)
+                        } else {
+                            setHighlightedIndex(
+                                highlightedIndex - gridRowLength
+                            )
+                        }
+                    } else if (activeSection === 'actions') {
+                        if (highlightedIndex <= 0) {
+                            setActiveSection('grid')
+                            setHighlightedIndex(lastRowFirstIndex)
+                        } else {
+                            setHighlightedIndex(highlightedIndex - 1)
+                        }
+                    }
+                    break
+                case 'Escape':
+                    event.preventDefault()
+                    setShow(false)
+                    setActiveSection('grid')
+                    setHighlightedIndex(0)
+                    break
+                default:
+                    break
+            }
+        },
+        [
+            activeSection,
+            highlightedIndex,
+            setActiveSection,
+            setHighlightedIndex,
+            setShow,
+        ]
+    )
+
+    const handleKeyDown = useCallback(
+        (event) => {
+            const modal = modalRef.current
+
+            if (currentView === 'home') {
+                if (filter.length > 0) {
+                    // search mode
+                    handleListViewNavigation(event)
+                } else {
+                    handleHomeViewNavigation(event)
+                }
+            } else {
+                setActiveSection(null)
+                handleListViewNavigation(event)
+            }
+
+            if ((event.metaKey || event.ctrlKey) && event.key === '/') {
+                setShow(!show)
+                goToDefaultView()
+            }
+
+            if (event.key === 'Enter') {
+                if (activeSection === 'grid') {
+                    window.open(itemsArray[highlightedIndex]?.['defaultAction'])
+                } else if (activeSection === 'actions') {
+                    modal
+                        ?.querySelector('.actions-menu')
+                        ?.childNodes?.[highlightedIndex]?.click()
+                } else {
+                    // open apps, shortcuts link
+                    window.open(itemsArray[highlightedIndex]?.['defaultAction'])
+                    // TODO: execute commands
+                }
+            }
+        },
+        [
+            activeSection,
+            currentView,
+            filter.length,
+            goToDefaultView,
+            handleHomeViewNavigation,
+            handleListViewNavigation,
+            highlightedIndex,
+            itemsArray,
+            setActiveSection,
+            setShow,
+            show,
+        ]
+    )
+
+    return {
+        handleKeyDown,
+        goToDefaultView,
+        modalRef,
+        activeSection,
+        setActiveSection,
+    }
+}
diff --git a/components/header-bar/src/command-palette/sections/actions-menu.js b/components/header-bar/src/command-palette/sections/actions-menu.js
deleted file mode 100644
index a96d3863a..000000000
--- a/components/header-bar/src/command-palette/sections/actions-menu.js
+++ /dev/null
@@ -1,83 +0,0 @@
-import { clearSensitiveCaches, useConfig } from '@dhis2/app-runtime'
-import { colors } from '@dhis2/ui-constants'
-import {
-    IconApps16,
-    IconLogOut16,
-    IconRedo16,
-    IconTerminalWindow16,
-} from '@dhis2/ui-icons'
-import PropTypes from 'prop-types'
-import React from 'react'
-import { joinPath } from '../../join-path.js'
-import i18n from '../../locales/index.js'
-import Heading from './heading.js'
-import ListItem from './list-item.js'
-
-const ActionsMenu = ({
-    showAppsList,
-    showCommandsList,
-    showShortcutsList,
-    setCurrentView,
-}) => {
-    const { baseUrl } = useConfig()
-    return (
-        <div
-            role="menu"
-            className="actions-menu"
-            data-test="headerbar-actions-menu"
-        >
-            <Heading heading={'Actions'} />
-            {showAppsList ? (
-                <ListItem
-                    title={i18n.t('Browse apps')}
-                    icon={<IconApps16 color={colors.grey700} />}
-                    onClickHandler={() => setCurrentView('apps')}
-                    dataTest="headerbar-browse-apps"
-                />
-            ) : null}
-            {showCommandsList ? (
-                <ListItem
-                    title={i18n.t('Browse commands')}
-                    icon={<IconTerminalWindow16 color={colors.grey700} />}
-                    onClickHandler={() => setCurrentView('commands')}
-                    dataTest="headerbar-browse-commands"
-                />
-            ) : null}
-            {showShortcutsList ? (
-                <ListItem
-                    title={i18n.t('Browse shortcuts')}
-                    icon={<IconRedo16 color={colors.grey700} />}
-                    onClickHandler={() => setCurrentView('shortcuts')}
-                    dataTest="headerbar-browse-shortcuts"
-                />
-            ) : null}
-            <ListItem
-                title={i18n.t('Logout')}
-                icon={<IconLogOut16 color={colors.grey700} />}
-                onClickHandler={async () => {
-                    await clearSensitiveCaches()
-                    window.location.assign(
-                        joinPath(
-                            baseUrl,
-                            'dhis-web-commons-security/logout.action'
-                        )
-                    )
-                }}
-                href={joinPath(
-                    baseUrl,
-                    'dhis-web-commons-security/logout.action'
-                )}
-                dataTest="headerbar-logout"
-            />
-        </div>
-    )
-}
-
-ActionsMenu.propTypes = {
-    setCurrentView: PropTypes.func,
-    showAppsList: PropTypes.bool,
-    showCommandsList: PropTypes.bool,
-    showShortcutsList: PropTypes.bool,
-}
-
-export default ActionsMenu
diff --git a/components/header-bar/src/command-palette/sections/app-item.js b/components/header-bar/src/command-palette/sections/app-item.js
index 519ea85c8..a258d346a 100644
--- a/components/header-bar/src/command-palette/sections/app-item.js
+++ b/components/header-bar/src/command-palette/sections/app-item.js
@@ -1,10 +1,16 @@
 import { colors, spacers } from '@dhis2/ui-constants'
+import cx from 'classnames'
 import PropTypes from 'prop-types'
 import React from 'react'
 
-function AppItem({ name, path, img }) {
+function AppItem({ name, path, img, highlighted, handleMouseEnter }) {
     return (
-        <a href={path}>
+        <a
+            href={path}
+            className={cx('item', { highlighted })}
+            onMouseEnter={handleMouseEnter}
+            tabIndex={-1}
+        >
             <img src={img} alt="app" className="app-icon" />
             <span className="app-name">{name}</span>
             <style jsx>{`
@@ -20,7 +26,8 @@ function AppItem({ name, path, img }) {
                     color: ${colors.grey900};
                     transition: all 0.1s ease;
                 }
-                a:hover {
+                a:hover,
+                .highlighted {
                     background: ${colors.grey200};
                     cursor: pointer;
                 }
@@ -28,18 +35,12 @@ function AppItem({ name, path, img }) {
                     background: ${colors.grey300};
                 }
                 a:focus {
-                    background: ${colors.grey200};
                     outline: none;
                 }
-                // .grid-item-highlighted {
-                //     background: var(--colors-grey200);
-                // }
-
                 .app-icon {
                     width: 48px;
                     height: 48px;
                 }
-
                 .app-name {
                     font-size: 13px;
                     text-align: center;
@@ -50,6 +51,8 @@ function AppItem({ name, path, img }) {
 }
 
 AppItem.propTypes = {
+    handleMouseEnter: PropTypes.func,
+    highlighted: PropTypes.bool,
     img: PropTypes.string,
     name: PropTypes.string,
     path: PropTypes.string,
diff --git a/components/header-bar/src/command-palette/sections/back-button.js b/components/header-bar/src/command-palette/sections/back-button.js
index 3dfcfb951..6e0a2dc52 100644
--- a/components/header-bar/src/command-palette/sections/back-button.js
+++ b/components/header-bar/src/command-palette/sections/back-button.js
@@ -12,6 +12,7 @@ function BackButton({ onClickHandler }) {
                 name="Back"
                 value="back"
                 className="back-btn"
+                tabIndex={-1}
             >
                 <IconArrowLeft16 />
             </button>
diff --git a/components/header-bar/src/command-palette/sections/list-item.js b/components/header-bar/src/command-palette/sections/list-item.js
index 1107ce4bb..c3e1c4dad 100644
--- a/components/header-bar/src/command-palette/sections/list-item.js
+++ b/components/header-bar/src/command-palette/sections/list-item.js
@@ -13,6 +13,7 @@ function ListItem({
     onClickHandler,
     highlighted,
     dataTest = 'headerbar-list-item',
+    handleMouseEnter,
 }) {
     const showDescription = type === 'commands'
     return (
@@ -21,6 +22,8 @@ function ListItem({
             onClick={onClickHandler}
             className={cx('item', { highlighted })}
             data-test={dataTest}
+            onMouseEnter={handleMouseEnter}
+            tabIndex={-1}
         >
             <div className="icon">
                 {icon && <span className="icon-content">{icon}</span>}
@@ -74,12 +77,9 @@ function ListItem({
                 }
                 .text-content {
                     display: flex;
-                    width: 100%;
-                    align-items: baseline;
-                    gap: 4px;
-                }
-                .text-content {
                     flex-direction: column;
+                    align-items: baseline;
+                    width: 100%;
                     gap: ${spacers.dp8};
                     padding-top: 2px;
                 }
@@ -100,6 +100,7 @@ function ListItem({
 ListItem.propTypes = {
     dataTest: PropTypes.string,
     description: PropTypes.string,
+    handleMouseEnter: PropTypes.func,
     highlighted: PropTypes.bool,
     icon: PropTypes.node,
     image: PropTypes.string,
diff --git a/components/header-bar/src/command-palette/sections/list.js b/components/header-bar/src/command-palette/sections/list.js
index 96d2cee8c..8a5761180 100644
--- a/components/header-bar/src/command-palette/sections/list.js
+++ b/components/header-bar/src/command-palette/sections/list.js
@@ -1,37 +1,12 @@
 import PropTypes from 'prop-types'
-import React, { useState, useRef, useEffect } from 'react'
+import React from 'react'
+import { useCommandPaletteContext } from '../context/command-palette-context.js'
 import ListItem from './list-item.js'
 
 function List({ filteredItems, type }) {
-    const divRef = useRef(null)
-    const [activeItem, setActiveItem] = useState(-1)
-    const lastIndex = filteredItems.length - 1
-
-    const handleKeyDown = (event) => {
-        switch (event.key) {
-            case 'ArrowDown':
-                setActiveItem(activeItem >= lastIndex ? 0 : activeItem + 1)
-                break
-            case 'ArrowUp':
-                setActiveItem(activeItem > 0 ? activeItem - 1 : lastIndex)
-                break
-            case 'Enter':
-                event.preventDefault()
-                event.target?.click()
-                break
-        }
-    }
-
-    useEffect(() => {
-        if (divRef) {
-            if (filteredItems.length && activeItem > -1) {
-                divRef.current.children[activeItem].focus()
-            }
-        }
-    }, [activeItem, filteredItems])
-
+    const { highlightedIndex, setHighlightedIndex } = useCommandPaletteContext()
     return (
-        <div data-test="headerbar-list" onKeyDown={handleKeyDown} ref={divRef}>
+        <div data-test="headerbar-list">
             {filteredItems.map(
                 (
                     { displayName, name, defaultAction, icon, description },
@@ -41,20 +16,14 @@ function List({ filteredItems, type }) {
                         type={type}
                         key={`app-${name}-${idx}`}
                         title={displayName || name}
-                        href={defaultAction}
+                        path={defaultAction}
                         image={icon}
                         description={description}
-                        highlighted={activeItem === idx}
+                        highlighted={highlightedIndex === idx}
+                        handleMouseEnter={() => setHighlightedIndex(idx)}
                     />
                 )
             )}
-            <style jsx>{`
-                div {
-                    display: flex;
-                    flex-direction: column;
-                    overflow-x: hidden;
-                }
-            `}</style>
         </div>
     )
 }
diff --git a/components/header-bar/src/command-palette/sections/search-field.js b/components/header-bar/src/command-palette/sections/search-field.js
index cd4a511da..6ea20c4cc 100644
--- a/components/header-bar/src/command-palette/sections/search-field.js
+++ b/components/header-bar/src/command-palette/sections/search-field.js
@@ -21,9 +21,7 @@ function Search({ value, onChange, placeholder }) {
             />
             <style>{`
                 .search {
-                    
                     border-bottom: 1px solid ${colors.grey300};
-                    
                 }
                 .search input {
                     font-size: 14px;
diff --git a/components/header-bar/src/command-palette/sections/search-results.js b/components/header-bar/src/command-palette/sections/search-results.js
new file mode 100644
index 000000000..574f51e76
--- /dev/null
+++ b/components/header-bar/src/command-palette/sections/search-results.js
@@ -0,0 +1,31 @@
+import { colors } from '@dhis2/ui-constants'
+import React from 'react'
+import i18n from '../../locales/index.js'
+import { useCommandPaletteContext } from '../context/command-palette-context.js'
+import Heading from './heading.js'
+
+export function EmptySearchResults() {
+    const { filter } = useCommandPaletteContext()
+
+    return (
+        <>
+            <div className="empty-results" data-test="headerbar-empty-search">
+                <Heading heading={i18n.t(`Nothing found for "${filter}"`)} />
+            </div>
+            <style jsx>{`
+                .empty-results {
+                    min-height: 92px;
+                    display: flex;
+                    align-items: center;
+                    justify-content: center;
+                    text-align: center;
+                    font-size: 14px;
+                    line-height: 19px;
+                    color: ${colors.grey700};
+                }
+            `}</style>
+        </>
+    )
+}
+
+export default EmptySearchResults
diff --git a/components/header-bar/src/command-palette/views/browse-apps.js b/components/header-bar/src/command-palette/views/browse-apps.js
deleted file mode 100644
index 4224c849a..000000000
--- a/components/header-bar/src/command-palette/views/browse-apps.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import PropTypes from 'prop-types'
-import React from 'react'
-import i18n from '../../locales/index.js'
-import Heading from '../sections/heading.js'
-import List from '../sections/list.js'
-import SearchResults from './search-results.js'
-
-function BrowseApps({ apps, filter }) {
-    return (
-        <>
-            {filter.length > 0 && (
-                <SearchResults filter={filter} filteredItems={apps} />
-            )}
-            {filter.length < 1 && (
-                <>
-                    <Heading heading={i18n.t('All Apps')} />
-                    <List filteredItems={apps} />
-                </>
-            )}
-        </>
-    )
-}
-
-BrowseApps.propTypes = {
-    apps: PropTypes.array,
-    filter: PropTypes.string,
-}
-
-export default BrowseApps
diff --git a/components/header-bar/src/command-palette/views/browse-commands.js b/components/header-bar/src/command-palette/views/browse-commands.js
deleted file mode 100644
index b24dcfbef..000000000
--- a/components/header-bar/src/command-palette/views/browse-commands.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import PropTypes from 'prop-types'
-import React from 'react'
-import i18n from '../../locales/index.js'
-import Heading from '../sections/heading.js'
-import List from '../sections/list.js'
-import SearchResults from './search-results.js'
-
-function BrowseCommands({ commands, filter, type }) {
-    return (
-        <>
-            {filter.length > 0 && (
-                <SearchResults filter={filter} filteredItems={commands} />
-            )}
-            {filter.length < 1 && (
-                <>
-                    <Heading heading={i18n.t('All Commands')} />
-                    <List filteredItems={commands} type={type} />
-                </>
-            )}
-        </>
-    )
-}
-
-BrowseCommands.propTypes = {
-    commands: PropTypes.array,
-    filter: PropTypes.string,
-    type: PropTypes.string,
-}
-
-export default BrowseCommands
diff --git a/components/header-bar/src/command-palette/views/browse-shortcuts.js b/components/header-bar/src/command-palette/views/browse-shortcuts.js
deleted file mode 100644
index c86761d24..000000000
--- a/components/header-bar/src/command-palette/views/browse-shortcuts.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import PropTypes from 'prop-types'
-import React from 'react'
-import i18n from '../../locales/index.js'
-import Heading from '../sections/heading.js'
-import List from '../sections/list.js'
-import SearchResults from './search-results.js'
-
-function BrowseShortcuts({ shortcuts, filter }) {
-    return (
-        <>
-            {filter.length > 0 && (
-                <SearchResults filter={filter} filteredItems={shortcuts} />
-            )}
-            {filter.length < 1 && (
-                <>
-                    <Heading heading={i18n.t('All Shortcuts')} />
-                    <List filteredItems={shortcuts} />
-                </>
-            )}
-        </>
-    )
-}
-
-BrowseShortcuts.propTypes = {
-    filter: PropTypes.string,
-    shortcuts: PropTypes.array,
-}
-
-export default BrowseShortcuts
diff --git a/components/header-bar/src/command-palette/views/home-view.js b/components/header-bar/src/command-palette/views/home-view.js
index d261884c2..33b03da76 100644
--- a/components/header-bar/src/command-palette/views/home-view.js
+++ b/components/header-bar/src/command-palette/views/home-view.js
@@ -1,116 +1,189 @@
-import { spacers } from '@dhis2/ui-constants'
+import { clearSensitiveCaches, useConfig } from '@dhis2/app-runtime'
+import { spacers, colors } from '@dhis2/ui-constants'
+import {
+    IconApps16,
+    IconLogOut16,
+    IconRedo16,
+    IconTerminalWindow16,
+} from '@dhis2/ui-icons'
 import PropTypes from 'prop-types'
-import React, { useEffect, useRef, useState } from 'react'
+import React from 'react'
+import { joinPath } from '../../join-path.js'
+import i18n from '../../locales/index.js'
+import { useCommandPaletteContext } from '../context/command-palette-context.js'
+import { GRID_ITEMS_LENGTH } from '../hooks/use-navigation.js'
 import AppItem from '../sections/app-item.js'
 import Heading from '../sections/heading.js'
-import SearchResults from './search-results.js'
+import ListItem from '../sections/list-item.js'
+import ListView from './list-view.js'
 
-function HomeView({ apps, commands, shortcuts, filter }) {
-    const divRef = useRef(null)
-    const [activeItem, setActiveItem] = useState(-1)
-    const filteredItems = apps.concat(commands, shortcuts)
-
-    const handleKeyDown = (event) => {
-        switch (event.key) {
-            case 'ArrowLeft':
-                // row 1
-                if (activeItem <= 3) {
-                    setActiveItem(activeItem > 0 ? activeItem - 1 : 3)
-                }
-                // row 2
-                if (activeItem >= 4) {
-                    setActiveItem(activeItem > 4 ? activeItem - 1 : 7)
-                }
-                break
-            case 'ArrowRight':
-                // row 1
-                if (activeItem <= 3) {
-                    setActiveItem(activeItem >= 3 ? 0 : activeItem + 1)
-                }
-                // row 2
-                if (activeItem >= 4) {
-                    setActiveItem(activeItem >= 7 ? 4 : activeItem + 1)
-                }
-                break
-            case 'ArrowDown':
-                setActiveItem(activeItem >= 4 ? activeItem - 4 : activeItem + 4)
-                break
-            case 'ArrowUp':
-                setActiveItem(activeItem <= 3 ? activeItem + 4 : activeItem - 4)
-                break
-            case 'Enter':
-                event.preventDefault()
-                event.target?.click()
-                break
-            case 'Tab':
-                event.preventDefault()
-        }
-    }
-
-    const handleFocus = () => {
-        if (divRef) {
-            if (activeItem <= -1) {
-                setActiveItem(0)
-            }
-        }
-    }
-
-    useEffect(() => {
-        if (divRef) {
-            if (apps.length && activeItem > -1) {
-                divRef.current?.children[activeItem]?.focus()
-            }
-        }
-    }, [activeItem, apps.length])
+const MIN_APPS_NUM = GRID_ITEMS_LENGTH
 
+function HomeView({ apps, commands, shortcuts }) {
+    const { baseUrl } = useConfig()
+    const {
+        filter,
+        setCurrentView,
+        highlightedIndex,
+        setHighlightedIndex,
+        activeSection,
+        setActiveSection,
+    } = useCommandPaletteContext()
+    const filteredItems = apps.concat(commands, shortcuts)
+    const topApps = apps?.slice(0, 8)
     return (
-        <div onKeyDown={handleKeyDown} onFocus={handleFocus}>
-            {filter.length > 0 && (
-                <SearchResults filter={filter} filteredItems={filteredItems} />
-            )}
-            {/* normal view */}
-            {filter.length < 1 && apps.length > 0 && (
+        <>
+            {filter.length > 0 ? (
+                <ListView filteredItems={filteredItems} />
+            ) : (
                 <>
-                    <Heading heading={'Top apps'} />
+                    {apps.length > 0 && (
+                        <>
+                            <Heading heading={i18n.t('Top apps')} />
+                            <div
+                                data-test="headerbar-top-apps-list"
+                                className="headerbar-top-apps"
+                            >
+                                {topApps.map(
+                                    (
+                                        {
+                                            displayName,
+                                            name,
+                                            defaultAction,
+                                            icon,
+                                        },
+                                        idx
+                                    ) => (
+                                        <AppItem
+                                            key={`app-${name}-${idx}`}
+                                            name={displayName || name}
+                                            path={defaultAction}
+                                            img={icon}
+                                            highlighted={
+                                                activeSection === 'grid' &&
+                                                highlightedIndex === idx
+                                            }
+                                            handleMouseEnter={() => {
+                                                setActiveSection('grid')
+                                                setHighlightedIndex(idx)
+                                            }}
+                                        />
+                                    )
+                                )}
+                                <style jsx>{`
+                                    .headerbar-top-apps {
+                                        display: grid;
+                                        grid-template-columns: repeat(4, 1fr);
+                                        padding: 0 ${spacers.dp4};
+                                    }
+                                `}</style>
+                            </div>
+                        </>
+                    )}
+                    {/* actions menu */}
+                    <Heading heading={'Actions'} />
                     <div
-                        data-test="headerbar-top-apps-list"
-                        ref={divRef}
-                        className="headerbar-top-apps"
+                        role="menu"
+                        className="actions-menu"
+                        data-test="headerbar-actions-menu"
                     >
-                        {apps
-                            .slice(0, 8)
-                            .map(
-                                (
-                                    { displayName, name, defaultAction, icon },
-                                    idx
-                                ) => (
-                                    <AppItem
-                                        key={`app-${name}-${idx}`}
-                                        name={displayName || name}
-                                        path={defaultAction}
-                                        img={icon}
+                        {apps?.length > MIN_APPS_NUM ? (
+                            <ListItem
+                                title={i18n.t('Browse apps')}
+                                icon={<IconApps16 color={colors.grey700} />}
+                                onClickHandler={() => {
+                                    setCurrentView('apps')
+                                    setHighlightedIndex(0)
+                                }}
+                                dataTest="headerbar-browse-apps"
+                                highlighted={
+                                    activeSection === 'actions' &&
+                                    highlightedIndex === 0
+                                }
+                                handleMouseEnter={() => {
+                                    setActiveSection('actions')
+                                    setHighlightedIndex(0)
+                                }}
+                            />
+                        ) : null}
+                        {commands?.length > 0 ? (
+                            <ListItem
+                                title={i18n.t('Browse commands')}
+                                icon={
+                                    <IconTerminalWindow16
+                                        color={colors.grey700}
                                     />
+                                }
+                                onClickHandler={() => {
+                                    setCurrentView('commands')
+                                    setHighlightedIndex(0)
+                                }}
+                                dataTest="headerbar-browse-commands"
+                                highlighted={
+                                    activeSection === 'actions' &&
+                                    highlightedIndex === 1
+                                }
+                                handleMouseEnter={() => {
+                                    setActiveSection('actions')
+                                    setHighlightedIndex(1)
+                                }}
+                            />
+                        ) : null}
+                        {shortcuts?.length > 0 ? (
+                            <ListItem
+                                title={i18n.t('Browse shortcuts')}
+                                icon={<IconRedo16 color={colors.grey700} />}
+                                onClickHandler={() => {
+                                    setCurrentView('shortcuts')
+                                    setHighlightedIndex(0)
+                                }}
+                                dataTest="headerbar-browse-shortcuts"
+                                highlighted={
+                                    activeSection === 'actions' &&
+                                    highlightedIndex === 2
+                                }
+                                handleMouseEnter={() => {
+                                    setActiveSection('actions')
+                                    setHighlightedIndex(2)
+                                }}
+                            />
+                        ) : null}
+                        <ListItem
+                            title={i18n.t('Logout')}
+                            icon={<IconLogOut16 color={colors.grey700} />}
+                            onClickHandler={async () => {
+                                await clearSensitiveCaches()
+                                window.location.assign(
+                                    joinPath(
+                                        baseUrl,
+                                        'dhis-web-commons-security/logout.action'
+                                    )
                                 )
+                            }}
+                            href={joinPath(
+                                baseUrl,
+                                'dhis-web-commons-security/logout.action'
                             )}
-
-                        <style jsx>{`
-                            .headerbar-top-apps {
-                                display: grid;
-                                grid-template-columns: repeat(4, 1fr);
-                                padding: 0 ${spacers.dp4};
+                            dataTest="headerbar-logout"
+                            highlighted={
+                                activeSection === 'actions' &&
+                                highlightedIndex === 3
                             }
-                        `}</style>
+                            handleMouseEnter={() => {
+                                setActiveSection('actions')
+                                setHighlightedIndex(3)
+                            }}
+                        />
                     </div>
                 </>
             )}
-        </div>
+        </>
     )
 }
 
 HomeView.propTypes = {
     apps: PropTypes.array,
     commands: PropTypes.array,
-    filter: PropTypes.string,
     shortcuts: PropTypes.array,
 }
 
diff --git a/components/header-bar/src/command-palette/views/list-view.js b/components/header-bar/src/command-palette/views/list-view.js
index 9371761a6..d62882ebb 100644
--- a/components/header-bar/src/command-palette/views/list-view.js
+++ b/components/header-bar/src/command-palette/views/list-view.js
@@ -1,36 +1,64 @@
 import PropTypes from 'prop-types'
 import React from 'react'
+import i18n from '../../locales/index.js'
+import { useCommandPaletteContext } from '../context/command-palette-context.js'
 import Heading from '../sections/heading.js'
 import List from '../sections/list.js'
-import { escapeRegExpCharacters } from '../utils/escapeCharacters.js'
+import { EmptySearchResults } from '../sections/search-results.js'
 
-function ListView({ heading, itemsArray, filter, type }) {
-    const filteredItems = itemsArray.filter(({ displayName, name }) => {
-        const itemName = displayName || name
-        const formattedItemName = itemName.toLowerCase()
-        const formattedFilter = escapeRegExpCharacters(filter).toLowerCase()
+export function BrowseApps({ apps }) {
+    return <ListView heading={i18n.t('All Apps')} filteredItems={apps} />
+}
 
-        return filter.length > 0
-            ? formattedItemName.match(formattedFilter)
-            : true
-    })
+BrowseApps.propTypes = {
+    apps: PropTypes.array,
+}
+export function BrowseCommands({ commands }) {
+    return (
+        <ListView
+            heading={i18n.t('All Commands')}
+            filteredItems={commands}
+            type={'commands'}
+        />
+    )
+}
+
+BrowseCommands.propTypes = {
+    commands: PropTypes.array,
+}
 
+export function BrowseShortcuts({ shortcuts }) {
     return (
-        <div>
+        <ListView heading={i18n.t('All Shortcuts')} filteredItems={shortcuts} />
+    )
+}
+
+BrowseShortcuts.propTypes = {
+    shortcuts: PropTypes.array,
+}
+
+function ListView({ heading, filteredItems, type }) {
+    const { filter } = useCommandPaletteContext()
+
+    return filteredItems.length > 0 ? (
+        <>
             <Heading
-                filter={filter}
-                filteredItems={filteredItems}
-                heading={heading}
+                heading={
+                    filter.length > 0
+                        ? i18n.t(`Results for "${filter}"`)
+                        : heading
+                }
             />
             <List filteredItems={filteredItems} type={type} />
-        </div>
-    )
+        </>
+    ) : filter ? (
+        <EmptySearchResults />
+    ) : null
 }
 
 ListView.propTypes = {
-    filter: PropTypes.string,
+    filteredItems: PropTypes.array,
     heading: PropTypes.string,
-    itemsArray: PropTypes.array,
     type: PropTypes.string,
 }
 
diff --git a/components/header-bar/src/command-palette/views/search-results.js b/components/header-bar/src/command-palette/views/search-results.js
deleted file mode 100644
index 892b79d3a..000000000
--- a/components/header-bar/src/command-palette/views/search-results.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { colors } from '@dhis2/ui-constants'
-import PropTypes from 'prop-types'
-import React from 'react'
-import i18n from '../../locales/index.js'
-import Heading from '../sections/heading.js'
-import List from '../sections/list.js'
-
-function SearchResults({ filter, filteredItems }) {
-    return (
-        <>
-            {filteredItems.length > 0 ? (
-                <div data-test="headerbar-search-results">
-                    <Heading heading={i18n.t(`Results for "${filter}"`)} />
-                    <List filteredItems={filteredItems} />
-                </div>
-            ) : (
-                <div
-                    className="empty-results"
-                    data-test="headerbar-empty-search"
-                >
-                    <Heading
-                        heading={i18n.t(`Nothing found for "${filter}"`)}
-                    />
-                </div>
-            )}
-            <style jsx>{`
-                .empty-results {
-                    min-height: 92px;
-                    display: flex;
-                    align-items: center;
-                    justify-content: center;
-                    text-align: center;
-                    font-size: 14px;
-                    line-height: 19px;
-                    color: ${colors.grey700};
-                }
-            `}</style>
-        </>
-    )
-}
-
-SearchResults.propTypes = {
-    filter: PropTypes.string,
-    filteredItems: PropTypes.array,
-}
-
-export default SearchResults
diff --git a/components/header-bar/src/header-bar.js b/components/header-bar/src/header-bar.js
index 1a2854046..47271f93d 100755
--- a/components/header-bar/src/header-bar.js
+++ b/components/header-bar/src/header-bar.js
@@ -3,6 +3,7 @@ import { colors } from '@dhis2/ui-constants'
 import PropTypes from 'prop-types'
 import React, { useMemo } from 'react'
 import CommandPalette from './command-palette/command-palette.js'
+import { CommandPaletteContextProvider } from './command-palette/context/command-palette-context.js'
 import { HeaderBarContextProvider } from './header-bar-context.js'
 import { joinPath } from './join-path.js'
 import i18n from './locales/index.js'
@@ -128,12 +129,13 @@ export const HeaderBar = ({
                                 }
                                 userAuthorities={data.user.authorities}
                             />
-                            <CommandPalette
-                                apps={apps}
-                                commands={commands}
-                                shortcuts={shortcuts}
-                            />
-
+                            <CommandPaletteContextProvider>
+                                <CommandPalette
+                                    apps={apps}
+                                    commands={commands}
+                                    shortcuts={shortcuts}
+                                />
+                            </CommandPaletteContextProvider>
                             <Profile
                                 name={data.user.name}
                                 email={data.user.email}