diff --git a/src/app-nav-bar/__tests__/app-nav-bar.test.tsx b/src/app-nav-bar/__tests__/app-nav-bar.test.tsx
new file mode 100644
index 0000000000..db48d654ff
--- /dev/null
+++ b/src/app-nav-bar/__tests__/app-nav-bar.test.tsx
@@ -0,0 +1,30 @@
+/*
+Copyright (c) Uber Technologies, Inc.
+
+This source code is licensed under the MIT license found in the
+LICENSE file in the root directory of this source tree.
+*/
+import * as React from 'react';
+import { render } from '@testing-library/react';
+
+import { AppNavBar } from '..';
+import type { NavItem } from '../types';
+
+const mainItems: NavItem[] = [
+ {
+ label: 'Primary A',
+ active: true,
+ navPosition: { mobile: 'horizontal', desktop: 'vertical' },
+ children: [{ label: 'Secondary A' }, { label: 'Secondary B' }],
+ },
+];
+
+describe('AppNavBar', () => {
+ it('renders the horizontal mobile sub-nav when the active item requests it', () => {
+ const { queryAllByLabelText } = render();
+
+ // navPosition.mobile is 'horizontal' and navPosition.desktop is 'vertical', so exactly one
+ // "Secondary navigation" nav (the mobile one) should render.
+ expect(queryAllByLabelText('Secondary navigation')).toHaveLength(1);
+ });
+});
diff --git a/src/app-nav-bar/app-nav-bar.tsx b/src/app-nav-bar/app-nav-bar.tsx
index 0627f41933..8eeb904a7b 100644
--- a/src/app-nav-bar/app-nav-bar.tsx
+++ b/src/app-nav-bar/app-nav-bar.tsx
@@ -151,9 +151,15 @@ export default function AppNavBar(props: AppNavBarProps) {
);
const [DesktopMenu, desktopMenuProps] = getOverrides(overrides.DesktopMenu, StyledDesktopMenu);
- let secondaryMenu;
- let desktopSubNavPosition: (typeof POSITION)[keyof typeof POSITION] = POSITION.horizontal;
- let mobileSubNavPosition: (typeof POSITION)[keyof typeof POSITION] = POSITION.vertical;
+ // The active top level menu item determines the secondary navigation and its positioning.
+ const activeItemWithChildren = React.useMemo(
+ () => mainItems.find((item) => item.active && item.children && item.children.length),
+ [mainItems]
+ );
+ const secondaryMenu = activeItemWithChildren?.children;
+ const desktopSubNavPosition =
+ activeItemWithChildren?.navPosition?.desktop || POSITION.horizontal;
+ const mobileSubNavPosition = activeItemWithChildren?.navPosition?.mobile || POSITION.vertical;
return (
@@ -170,16 +176,14 @@ export default function AppNavBar(props: AppNavBarProps) {
{title}
- {secondaryMenu &&
- // @ts-expect-error todo(flow->ts) always false
- mobileSubNavPosition === POSITION.horizontal && (
-
- )}
+ {secondaryMenu && mobileSubNavPosition === POSITION.horizontal && (
+
+ )}
{/* Desktop Nav Experience */}
@@ -200,25 +204,15 @@ export default function AppNavBar(props: AppNavBarProps) {
aria-label="Main navigation"
{...primaryMenuContainerProps}
>
- {mainItems.map((item, index) => {
- // For an active top level menu get the secondary navigation and its positioning
- if (item.active && item.children && item.children.length) {
- secondaryMenu = item.children;
- if (item.navPosition) {
- desktopSubNavPosition = item.navPosition.desktop || desktopSubNavPosition;
- mobileSubNavPosition = item.navPosition.mobile || mobileSubNavPosition;
- }
- }
- return (
-
- );
- })}
+ {mainItems.map((item, index) => (
+
+ ))}
{userItems.length ? (