# VerticalMenu Component

A vertical navigation menu component that renders a hierarchical list of links with support for nested submenus, customizable depth, and flexible styling options.

## Import path
```tsx
import VerticalMenu from '@hubspot/cms-component-library/VerticalMenu';
```

## Purpose

The VerticalMenu component provides a consistent way to render vertical navigation menus in HubSpot CMS projects. It automatically integrates with HubSpot's site menu system, supporting multi-level navigation with configurable maximum depth, customizable colors for links and backgrounds, and adjustable indentation for submenu items.

## Component Structure

```
VerticalMenu/
├── index.tsx                      # Main component wrapper (Island integration)
├── types.ts                       # TypeScript type definitions
├── ContentFields.tsx              # HubSpot field definitions for menu selection
├── islands/
│   ├── verticalMenuIsland.tsx    # Island component with rendering logic
│   └── index.module.scss         # CSS module with design tokens
└── stories/
    ├── VerticalMenu.stories.tsx  # Storybook examples
    └── VerticalMenuDecorator.tsx # Storybook decorator
```

## Components

### VerticalMenu (Main Component)

**Purpose:** Renders a vertical navigation menu from HubSpot site menu data with support for nested submenus.

**Props:**
```tsx
{
  menuData: SiteMenu;                    // Menu data from useMenu hook (required)
  maxDepth?: number;                     // Maximum nesting depth (default: unlimited)
  indentation?: string;                  // Submenu indentation (default: '0px')
  linkColor?: string;                    // Top-level link text color
  linkColorHover?: string;               // Top-level link hover text color
  backgroundColor?: string;              // Top-level link background color
  backgroundColorHover?: string;         // Top-level link hover background color
  submenuLinkColor?: string;             // Submenu link text color
  submenuLinkColorHover?: string;        // Submenu link hover text color
  submenuBackgroundColor?: string;       // Submenu link background color
  submenuBackgroundColorHover?: string;  // Submenu link hover background color
  className?: string;                    // Additional CSS classes
  style?: React.CSSProperties;           // Inline styles with CSS variables
}
```

## Consuming the Component with useMenu Hook

The VerticalMenu component requires menu data from HubSpot's `useMenu` hook. This hook fetches the site menu structure based on a menu ID defined in your module fields.

### Basic Module Implementation

```tsx
import { ModuleMeta } from '../types/modules.js';
import VerticalMenu from '@hubspot/cms-component-library/VerticalMenu';
import { useMenu, fieldPath } from '@hubspot/cms-components';

export const Component = () => {
  // Fetch menu data using the useMenu hook
  // fieldPath('menu') references the menu field defined in fields.tsx
  const menuData = useMenu(fieldPath('menu'));

  return (
    <VerticalMenu
      menuData={menuData}
      maxDepth={2}
      indentation="20px"
    />
  );
};

export { fields } from './fields.js';

export const meta: ModuleMeta = {
  label: 'Vertical Navigation Menu',
  content_types: [],
  icon: '',
  categories: ['navigation'],
};
```

### Module Fields Definition

```tsx
import { ModuleFields } from '@hubspot/cms-components/fields';
import VerticalMenu from '@hubspot/cms-component-library/VerticalMenu';

export const fields = (
  <ModuleFields>
    <VerticalMenu.ContentFields />
  </ModuleFields>
);
```

**What this does:**
1. `VerticalMenu.ContentFields` creates a HubSpot MenuField in your module
2. This field allows content editors to select which site menu to display
3. The `useMenu(fieldPath('menu'))` hook fetches the selected menu's data
4. The menu data is passed to the VerticalMenu component via the `menuData` prop

## HubSpot CMS Integration

### Field Definitions

The VerticalMenu component provides field definitions for menu selection in HubSpot CMS modules.

#### ContentFields

Configurable props for customizing field labels, names, and defaults:

```tsx
<VerticalMenu.ContentFields
  menuLabel="Menu"
  menuName="menu"
  menuDefault="default"
/>
```

**Fields:**
- `menu`: MenuField for selecting which site menu to display (default: 'default')

## Styling

Colors and hover states are applied via `--hs-verticalMenu-*` CSS variables, set internally by the component from the color props (`linkColor`, `linkColorHover`, `backgroundColor`, `backgroundColorHover`, `submenuLinkColor`, `submenuLinkColorHover`, `submenuBackgroundColor`, `submenuBackgroundColorHover`). Layout values like width (`100%`), gap (`0`), padding-inline (`10px`), and padding-block (`8px`) are hardcoded in the CSS module. The `indentation` prop is applied via the `--hs-verticalMenu-paddingInlineStart` CSS variable.

**CSS Variables (set from props):**
- `--hs-verticalMenu-color`: Link text color (default: currentColor)
- `--hs-verticalMenu-backgroundColor`: Link background color (default: transparent)
- `--hs-verticalMenu-color-hover`: Link hover text color
- `--hs-verticalMenu-backgroundColor-hover`: Link hover background color
- `--hs-verticalMenu-paddingInlineStart`: Indentation for submenu items (default: 0px)
- `--hs-verticalMenu-submenu-color`: Submenu link text color
- `--hs-verticalMenu-submenu-backgroundColor`: Submenu link background color
- `--hs-verticalMenu-submenu-color-hover`: Submenu link hover text color
- `--hs-verticalMenu-submenu-backgroundColor-hover`: Submenu link hover background color


## Accessibility

The VerticalMenu component follows accessibility best practices:

- **Semantic HTML**: Renders as a `<nav>` element with nested unordered lists (`<ul>`)
- **ARIA Roles**: List items have `role="menuitem"` for proper screen reader support
- **Keyboard Navigation**: Full keyboard support provided by the MenuItem component
- **Link Semantics**: Uses proper `<a>` elements for links with `href` attributes
- **External Links**: Automatically adds `target="_blank"` and `rel="noopener noreferrer"` for external links
- **Focus Management**: Native focus styles preserved for keyboard users

## Best Practices

- **Always use useMenu hook**: The VerticalMenu component requires menu data from the `useMenu` hook—never pass hardcoded menu structures
- **Control depth wisely**: Use `maxDepth` to limit nesting levels for better UX (1-3 levels recommended)
- **Consistent indentation**: Use consistent indentation values across your site (typically 16px, 20px, or 24px)
- **Color contrast**: Ensure sufficient contrast between link colors and backgrounds (WCAG AA minimum)
- **Hover states**: Always define hover colors for better visual feedback
- **Submenu styling**: Use distinct colors for submenu items to create visual hierarchy


## Related Components

- **NavigationMenu**: Horizontal navigation menu component for top-level navigation bars
- **MenuItem**: Used internally to render individual menu items with support for nested children
