# Defaults: CategoryNav (/themes/sdk/reference/navigation/defaults-4)

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

## `CategoryNav` [#categorynav]

A bar of the top-level categories, each with its subcategories in a dropdown and the current one marked.

```ts
CategoryNav(props: CategoryNavProps): ReactElement | null
```

**Props:** [`CategoryNavProps`](/themes/sdk/reference/navigation/types-2#categorynavprops)

<Tab value='Example'>

```tsx
import { CategoryNav } from '@poltura/theme-sdk/navigation';

export function CategoryBar() {
  return <CategoryNav className='border-t' />;
}
```

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

```tsx title="source/category-nav.tsx"
import type { ReactElement } from 'react';
import { ChevronDown } from 'lucide-react';
import { useTranslations } from '@poltura/theme-sdk/i18n';
import {
  useMegaMenu,
  useNavData,
  type CategoryNavProps,
  type NavCategory,
} from '@poltura/theme-sdk/navigation';
import { Link, usePathname } from '@poltura/theme-sdk/routing';
import { Icon, cn } from '@poltura/theme-sdk/ui';

const PANEL_BOX =
  'absolute left-0 top-full z-50 mt-2 overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-[var(--overlay-shadow)]';

const CATEGORY_LINK =
  'inline-flex items-center gap-1 whitespace-nowrap rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-muted';

function isCurrent(pathname: string, href: string): boolean {
  return pathname === href || pathname.startsWith(`${href}/`);
}

function CategoryNavItem({
  category,
  current,
  openOn,
}: {
  category: NavCategory;
  current: boolean;
  openOn: 'hover' | 'click';
}): ReactElement {
  const menu = useMegaMenu({ openOn });
  const marked = current ? 'page' : undefined;
  if (category.children.length === 0) {
    return (
      <li>
        <Link
          href={category.href}
          aria-current={marked}
          className={cn(CATEGORY_LINK, current && 'bg-muted')}
        >
          {category.name}
        </Link>
      </li>
    );
  }
  return (
    <li {...menu.rootProps} className='relative'>
      <Link
        href={category.href}
        {...menu.triggerProps}
        aria-current={marked}
        className={cn(CATEGORY_LINK, current && 'bg-muted')}
      >
        {category.name}
        <ChevronDown aria-hidden='true' className='size-3.5 opacity-60' />
      </Link>
      <ul {...menu.panelProps} className={cn(PANEL_BOX, 'min-w-48 py-2')}>
        {category.children.map((child) => (
          <li key={child.id}>
            <Link
              href={child.href}
              className='flex items-center gap-2 px-4 py-1.5 text-sm transition-colors hover:bg-muted'
            >
              {child.icon === null ? null : (
                <Icon value={child.icon} className='size-4 text-muted-foreground' />
              )}
              {child.name}
            </Link>
          </li>
        ))}
      </ul>
    </li>
  );
}

export function CategoryNav({
  openOn = 'hover',
  className,
}: CategoryNavProps): ReactElement | null {
  const { categories } = useNavData();
  const pathname = usePathname();
  const t = useTranslations('nav');
  if (categories.length === 0) return null;
  return (
    <nav aria-label={t('categories')} className={cn('min-w-0', className)}>
      <ul className='flex min-w-0 flex-wrap items-center gap-0.5'>
        {categories.map((category) => (
          <CategoryNavItem
            key={category.id}
            category={category}
            current={isCurrent(pathname, category.href)}
            openOn={openOn}
          />
        ))}
      </ul>
    </nav>
  );
}
```

</Tab>


**See also:** [`useNavData`](/themes/sdk/reference/navigation/hooks#usenavdata), [`useMegaMenu`](/themes/sdk/reference/navigation/hooks#usemegamenu)
