# Defaults: MobileNav (/themes/sdk/reference/navigation/defaults-2)

```ts
import { … } from '@poltura/theme-sdk/navigation';
```

## `MobileNav` [#mobilenav]

The main menu as a stacked list whose items fold open to their children, for a mobile drawer.

```ts
MobileNav(props: MobileNavProps): ReactElement | null
```

**Props:** [`MobileNavProps`](/themes/sdk/reference/navigation/types-1#mobilenavprops)

<Tab value='Example'>

```tsx
import { MobileMenu } from '@poltura/theme-sdk/chrome';
import { MobileNav } from '@poltura/theme-sdk/navigation';

export function Drawer() {
  return (
    <MobileMenu title='Menu'>
      <MobileNav />
    </MobileMenu>
  );
}
```

</Tab>
<Tab value='Source'>

```tsx title="source/mobile-nav.tsx"
import { useState, type ReactElement } from 'react';
import { ChevronRight } from 'lucide-react';
import { useThemeText } from '@poltura/theme-sdk/i18n';
import { useMenu, type MenuLink, type MobileNavProps } from '@poltura/theme-sdk/navigation';
import { Link } from '@poltura/theme-sdk/routing';
import { Icon, cn } from '@poltura/theme-sdk/ui';

const VIEW_ALL_KEY = 'nav.viewAll';

const ROW_CLASS =
  'flex min-h-12 w-full items-center justify-between gap-3 border-b border-border py-3 text-left text-[1.0625em] transition-opacity hover:opacity-70';
const CHILD_LINK_CLASS = 'block py-2 opacity-80 transition-opacity hover:opacity-100';

function linkKey(link: MenuLink): string {
  return `${link.href}:${link.label}`;
}

function ItemLabel({ label, icon }: { label: string; icon: string | null }): ReactElement {
  if (icon === null) return <>{label}</>;
  return (
    <span className='flex min-w-0 items-center gap-2'>
      <Icon value={icon} className='size-4 text-muted-foreground' />
      <span className='min-w-0 truncate'>{label}</span>
    </span>
  );
}

function ViewAllLabel(): ReactElement {
  const label = useThemeText()(VIEW_ALL_KEY);
  // A text no language has reads as its key; a translate session leaves its marker after it.
  const rest = label.startsWith(VIEW_ALL_KEY) ? label.slice(VIEW_ALL_KEY.length) : null;
  return <>{rest === null ? label : `View all${rest}`}</>;
}

function MobileNavItems({
  links,
  depth,
}: {
  links: readonly MenuLink[];
  depth: 0 | 1;
}): ReactElement {
  const [openKey, setOpenKey] = useState<string | null>(null);
  return (
    <>
      {links.map((link) => {
        const key = linkKey(link);
        if (link.children.length === 0) {
          return (
            <li key={key}>
              <Link href={link.href} className={depth === 0 ? ROW_CLASS : CHILD_LINK_CLASS}>
                <ItemLabel label={link.label} icon={link.icon ?? null} />
              </Link>
            </li>
          );
        }
        const expanded = openKey === key;
        return (
          <li key={key}>
            <button
              type='button'
              className={
                depth === 0
                  ? ROW_CLASS
                  : cn(CHILD_LINK_CLASS, 'flex w-full items-center justify-between gap-3 text-left')
              }
              aria-expanded={expanded}
              onClick={() => setOpenKey(expanded ? null : key)}
            >
              <ItemLabel label={link.label} icon={link.icon ?? null} />
              <ChevronRight
                aria-hidden='true'
                className={cn(
                  'size-4 shrink-0 opacity-60 transition-transform',
                  expanded && 'rotate-90',
                )}
              />
            </button>
            {expanded ? (
              <ul className='flex flex-col border-b border-border py-2 pl-4'>
                <li>
                  <Link href={link.href} className={CHILD_LINK_CLASS}>
                    <ViewAllLabel />
                  </Link>
                </li>
                {depth === 0 ? (
                  <MobileNavItems links={link.children} depth={1} />
                ) : (
                  link.children.map((child) => (
                    <li key={linkKey(child)}>
                      <Link href={child.href} className={CHILD_LINK_CLASS}>
                        <ItemLabel label={child.label} icon={child.icon ?? null} />
                      </Link>
                    </li>
                  ))
                )}
              </ul>
            ) : null}
          </li>
        );
      })}
    </>
  );
}

export function MobileNav({ links, className }: MobileNavProps): ReactElement | null {
  const primary = useMenu('primary');
  const shown = links ?? primary;
  if (shown.length === 0) return null;
  return (
    <nav className={className} aria-label='Primary'>
      <ul className='flex flex-col'>
        <MobileNavItems links={shown} depth={0} />
      </ul>
    </nav>
  );
}
```

</Tab>


**See also:** [`MainNav`](/themes/sdk/reference/navigation/defaults-1#mainnav)
