# SideNavigation

Import: `import { SideNavigation } from '@neo4j-ndl/react'`

## Props

### SideNavigation

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `ariaLabel` | `string` | ✅ |  | Aria label for the side navigation. Needed for menubar accessibility. |
| `children` | `ReactNode` |  |  | Content displayed inside the side navigation |
| `expandedWidth` | `Width<string \| number>` |  |  | Width used when expanded. Accepts any valid CSS width value or a number |
| `isExpanded` | `boolean` |  | `false` | Whether the side navigation is expanded |
| `onPinButtonClick` | `(() => void)` |  |  | Callback function triggered when the pin button is clicked |
| `ref` | `Ref<HTMLDivElement>` |  |  | A ref to apply to the root element. |
| `shouldOverlayOnInteraction` | `boolean` |  | `true` | Whether the side navigation expands on hover/focus when not pinned or compact |

### SideNavigation.CategoryHeader

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `children` | `ReactNode` |  |  | Content displayed inside the side navigation category header |
| `ref` | `Ref<HTMLLIElement>` |  |  | A ref to apply to the root element. |

### SideNavigation.CategoryItem

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `badge` | `ItemBadgeProps` |  |  | Badge displayed inside the side navigation item. Represented by an object with a number and a type (e.g., 'info', 'warning', 'danger'). |
| `children` | `ReactNode` |  |  | Content displayed inside the submenu popover. Typically a list of `SideNavigation.NavItem`. |
| `icon` | `ReactNode` |  |  | Icon displayed inside the side navigation item |
| `isActive` | `boolean` |  |  | Whether the side navigation item is selected |
| `isMenuOpen` | `boolean` |  | `false` | If true, the menu will be open. Otherwise, the menu will open and close based on the user hovering the item. |
| `label` | `string` |  |  | Text label of the side navigation item |
| `ref` | `Ref<HTMLButtonElement>` |  |  | A ref to apply to the root element. |

### SideNavigation.Divider

_No props documented._
### SideNavigation.ItemBadge

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `number` | `number` | ✅ |  | Number displayed inside the side navigation item badge |
| `ref` | `Ref<HTMLSpanElement>` |  |  | A ref to apply to the root element. |
| `type` | `'danger' \| 'info' \| 'warning'` | ✅ |  | Type of the side navigation item badge |

### SideNavigation.ListItem

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `children` | `ReactNode` |  |  | Content displayed inside the side navigation list item |
| `ref` | `Ref<HTMLLIElement>` |  |  | A ref to apply to the root element. |

### SideNavigation.NavItem

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `as` | `("button" & ElementType<any, keyof IntrinsicElements>) \| ("symbol" & ElementType<any, keyof IntrinsicElements>) \| ... 177 more ... \| (FunctionComponent<...> & ElementType<...>)` |  |  | An override of the default HTML tag of the root of the component. Can also be another React component. What HTML element to render the root element as. |
| `badge` | `ItemBadgeProps` |  |  | Badge displayed inside the side navigation item. Represented by an object with a number and a type (e.g., 'info', 'warning', 'danger'). |
| `href` | `string` |  |  | The href of the link. Only applicable if `as` is `'a'`. |
| `icon` | `ReactNode` |  |  | Icon displayed inside the side navigation item |
| `isActive` | `boolean` |  |  | Whether the side navigation item is selected |
| `label` | `string` |  |  | Text label of the side navigation item |
| `onClick` | `MouseEventHandler<HTMLButtonElement>` |  |  | Event handler for when the button is clicked. Only applicable if `as` is `'button'`. |
| `ref` | `any` |  |  | A ref to apply to the root element. |
| `target` | `HTMLAttributeAnchorTarget` |  |  | The target of the link. Only applicable if `as` is `'a'`. |
| `trailingElement` | `ReactNode` |  |  | Element displayed on the leading side of the side navigation item (e.g., counter) |

## Examples

### Side Nav Badges

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { SideNavigation, Typography } from '@neo4j-ndl/react';
import {
  CodeBracketIconOutline,
  HomeIconOutline,
  MagnifyingGlassIconOutline,
  ServerIconOutline,
  WrenchScrewdriverIconOutline,
} from '@neo4j-ndl/react/icons';
import { useState } from 'react';

const Component = () => {
  const [active, setActive] = useState<string | null>(null);
  const [isExpanded, setIsExpanded] = useState(false);

  return (
    <div className="n-h-[calc(40vh-32px)] n-min-h-[700px] n-flex n-bg-neutral-bg-default">
      <SideNavigation
        ariaLabel="Main side navigation"
        isExpanded={isExpanded}
        shouldOverlayOnInteraction={true}
        onPinButtonClick={() => setIsExpanded(!isExpanded)}
      >
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<HomeIconOutline />}
            label="Info Badge"
            isActive={active === 'nav-item-1'}
            onClick={() => setActive('nav-item-1')}
            badge={{
              number: 1,
              type: 'info',
            }}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<CodeBracketIconOutline />}
            label="Warning Badge"
            isActive={active === 'nav-item-2'}
            onClick={() => setActive('nav-item-2')}
            badge={{
              number: 1,
              type: 'warning',
            }}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<ServerIconOutline />}
            label="Critical Badge"
            isActive={active === 'nav-item-3'}
            onClick={() => setActive('nav-item-3')}
            badge={{
              number: 1,
              type: 'danger',
            }}
          />
        </SideNavigation.ListItem>
        <SideNavigation.Divider />
        <SideNavigation.ListItem>
          <SideNavigation.CategoryItem
            icon={<WrenchScrewdriverIconOutline />}
            label="Category Item"
            isActive={['nav-item-4', 'nav-item-5', 'nav-item-6'].includes(
              active ?? '',
            )}
            badge={{
              number: 3,
              type: 'danger',
            }}
          >
            <SideNavigation.ListItem>
              <SideNavigation.NavItem
                icon={<MagnifyingGlassIconOutline />}
                label="Info Badge"
                isActive={active === 'nav-item-4'}
                onClick={() => setActive('nav-item-4')}
                badge={{
                  number: 1,
                  type: 'info',
                }}
              />
            </SideNavigation.ListItem>
            <SideNavigation.ListItem>
              <SideNavigation.NavItem
                icon={<MagnifyingGlassIconOutline />}
                label="Warning Badge"
                isActive={active === 'nav-item-5'}
                onClick={() => setActive('nav-item-5')}
                badge={{
                  number: 1,
                  type: 'warning',
                }}
              />
            </SideNavigation.ListItem>
            <SideNavigation.ListItem>
              <SideNavigation.NavItem
                icon={<MagnifyingGlassIconOutline />}
                label="Critical Badge"
                isActive={active === 'nav-item-6'}
                onClick={() => setActive('nav-item-6')}
                badge={{
                  number: 1,
                  type: 'danger',
                }}
              />
            </SideNavigation.ListItem>
          </SideNavigation.CategoryItem>
        </SideNavigation.ListItem>
      </SideNavigation>
      <div className="n-h-full n-w-full">
        <div className="n-flex n-flex-col n-p-8 n-w-full n-max-w-[1024px] n-mx-auto">
          <div className="n-flex n-flex-col n-gap-token-8 n-bg-neutral-bg-weak n-p-token-32 n-rounded-lg n-items-center n-justify-center">
            <Typography variant="title-4">Side Nav with Badges</Typography>
            <Typography variant="body-medium">
              Badges can be used to indicate that there are actions that need
              attention from the user on the specific page. The badge can have
              three different types of severity:
              <b className="n-text-primary-text"> info</b>,
              <b className="n-text-warning-text"> warning</b> and
              <b className="n-text-danger-text"> danger</b>.
              <br />
              <br />
              The badge on a <b>CategoryItem</b> should be the type of the
              highest priority badge of the items in the category. The number
              should be the total number of badges in the category.
            </Typography>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Component;
```

### Side Nav Compact

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { SideNavigation, Typography } from '@neo4j-ndl/react';
import {
  AcademicCapIconOutline,
  ChartBarIconOutline,
  CodeBracketIconOutline,
  Cog6ToothIconOutline,
  HomeIconOutline,
  MagnifyingGlassIconOutline,
  ServerIconOutline,
  WrenchScrewdriverIconOutline,
} from '@neo4j-ndl/react/icons';
import { useState } from 'react';

const Component = () => {
  const [active, setActive] = useState<string | null>(null);

  return (
    <div className="n-h-[calc(40vh-32px)] n-min-h-[700px] n-flex n-bg-neutral-bg-default">
      <SideNavigation
        isExpanded={false}
        shouldOverlayOnInteraction={false}
        ariaLabel="Main side navigation"
      >
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<HomeIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-1'}
            onClick={() => setActive('nav-item-1')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<CodeBracketIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-2'}
            onClick={() => setActive('nav-item-2')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.Divider />
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<ServerIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-3'}
            onClick={() => setActive('nav-item-3')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.CategoryItem
            icon={<WrenchScrewdriverIconOutline />}
            label="Category Item"
            isActive={['nav-item-4', 'nav-item-5'].includes(active ?? '')}
          >
            <SideNavigation.ListItem>
              <SideNavigation.NavItem
                icon={<MagnifyingGlassIconOutline />}
                label="Nested Nav Item"
                isActive={active === 'nav-item-4'}
                onClick={() => setActive('nav-item-4')}
              />
            </SideNavigation.ListItem>
            <SideNavigation.ListItem>
              <SideNavigation.NavItem
                icon={<MagnifyingGlassIconOutline />}
                label="Nested Nav Item"
                isActive={active === 'nav-item-5'}
                onClick={() => setActive('nav-item-5')}
              />
            </SideNavigation.ListItem>
          </SideNavigation.CategoryItem>
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<ChartBarIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-6'}
            onClick={() => setActive('nav-item-6')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<Cog6ToothIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-7'}
            onClick={() => setActive('nav-item-7')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.Divider />
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<AcademicCapIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-8'}
            onClick={() => setActive('nav-item-8')}
          />
        </SideNavigation.ListItem>
      </SideNavigation>
      <div className="n-h-full n-w-full">
        <div className="n-flex n-flex-col n-p-8 n-w-full n-max-w-[1024px] n-mx-auto">
          <div className="n-flex n-flex-col n-gap-token-8 n-bg-neutral-bg-weak n-p-token-32 n-rounded-lg n-items-center n-justify-center">
            <Typography variant="title-4">Compact Side Nav</Typography>
            <Typography variant="body-medium">
              When using a compact side nav you must make sure to set a
              <b> label</b> on the NavItems, as the label will be used for the
              built in tooltip. It is also needed for screen readers to behave
              as correctly.
            </Typography>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Component;
```

### Side Nav Default

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { SideNavigation, Typography } from '@neo4j-ndl/react';
import {
  AcademicCapIconOutline,
  ChartBarIconOutline,
  CodeBracketIconOutline,
  Cog6ToothIconOutline,
  HomeIconOutline,
  MagnifyingGlassIconOutline,
  ServerIconOutline,
  WrenchScrewdriverIconOutline,
} from '@neo4j-ndl/react/icons';
import { useState } from 'react';

const Component = () => {
  const [active, setActive] = useState<string | null>(null);
  const [isExpanded, setIsExpanded] = useState(false);

  return (
    <div className="n-h-[calc(40vh-32px)] n-min-h-[700px] n-flex n-bg-neutral-bg-default">
      <SideNavigation
        isExpanded={isExpanded}
        shouldOverlayOnInteraction={true}
        onPinButtonClick={() => setIsExpanded(!isExpanded)}
        ariaLabel="Main side navigation"
      >
        <SideNavigation.CategoryHeader>
          Example Category Header
        </SideNavigation.CategoryHeader>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<HomeIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-1'}
            onClick={() => setActive('nav-item-1')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<CodeBracketIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-2'}
            onClick={() => setActive('nav-item-2')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.Divider />
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<ServerIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-3'}
            onClick={() => setActive('nav-item-3')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.CategoryItem
            icon={<WrenchScrewdriverIconOutline />}
            label="Category Item"
            isActive={['nav-item-4', 'nav-item-5'].includes(active ?? '')}
          >
            <SideNavigation.ListItem>
              <SideNavigation.NavItem
                icon={<MagnifyingGlassIconOutline />}
                label="Nested Nav Item"
                isActive={active === 'nav-item-4'}
                onClick={() => setActive('nav-item-4')}
              />
            </SideNavigation.ListItem>
            <SideNavigation.ListItem>
              <SideNavigation.NavItem
                icon={<MagnifyingGlassIconOutline />}
                label="Nested Nav Item"
                isActive={active === 'nav-item-5'}
                onClick={() => setActive('nav-item-5')}
              />
            </SideNavigation.ListItem>
          </SideNavigation.CategoryItem>
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<ChartBarIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-6'}
            onClick={() => setActive('nav-item-6')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<Cog6ToothIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-7'}
            onClick={() => setActive('nav-item-7')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.Divider />
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<AcademicCapIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-8'}
            onClick={() => setActive('nav-item-8')}
          />
        </SideNavigation.ListItem>
      </SideNavigation>

      <div className="n-h-full n-w-full">
        <div className="n-flex n-flex-col n-p-8 n-w-full n-max-w-[1024px] n-mx-auto">
          <div className="n-flex n-flex-col n-gap-token-8 n-bg-neutral-bg-weak n-p-token-32 n-rounded-lg n-items-center n-justify-center">
            <Typography variant="title-4">Default Side Nav</Typography>
            <Typography variant="body-medium">
              This is the default behavior for a side nav. It expands on hover,
              and can be pinned to stay expanded.
            </Typography>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Component;
```

### Side Nav Secondary

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { SideNavigation, Typography } from '@neo4j-ndl/react';
import {
  AcademicCapIconOutline,
  ChartBarIconOutline,
  CodeBracketIconOutline,
  Cog6ToothIconOutline,
  HomeIconOutline,
  MagnifyingGlassIconOutline,
  ServerIconOutline,
  WrenchScrewdriverIconOutline,
} from '@neo4j-ndl/react/icons';
import { useState } from 'react';

const Component = () => {
  const [active, setActive] = useState<string>('nav-item-8');
  const [secondaryActive, setSecondaryActive] = useState<string>('beginner');
  const [isExpanded, setIsExpanded] = useState(false);

  return (
    <div className="n-h-[calc(40vh-32px)] n-min-h-[700px] n-flex n-bg-neutral-bg-default n-overflow-hidden">
      <SideNavigation
        isExpanded={isExpanded}
        shouldOverlayOnInteraction={true}
        onPinButtonClick={() => setIsExpanded(!isExpanded)}
        ariaLabel="Main side navigation"
      >
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<HomeIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-1'}
            onClick={() => setActive('nav-item-1')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<CodeBracketIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-2'}
            onClick={() => setActive('nav-item-2')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.Divider />
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<ServerIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-3'}
            onClick={() => setActive('nav-item-3')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.CategoryItem
            icon={<WrenchScrewdriverIconOutline />}
            label="Category Item"
            isActive={['nav-item-4', 'nav-item-5'].includes(active)}
          >
            <SideNavigation.ListItem>
              <SideNavigation.NavItem
                icon={<MagnifyingGlassIconOutline />}
                label="Nested Nav Item"
                isActive={active === 'nav-item-4'}
                onClick={() => setActive('nav-item-4')}
              />
            </SideNavigation.ListItem>
            <SideNavigation.ListItem>
              <SideNavigation.NavItem
                icon={<MagnifyingGlassIconOutline />}
                label="Nested Nav Item"
                isActive={active === 'nav-item-5'}
                onClick={() => setActive('nav-item-5')}
              />
            </SideNavigation.ListItem>
          </SideNavigation.CategoryItem>
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<ChartBarIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-6'}
            onClick={() => setActive('nav-item-6')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<Cog6ToothIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-7'}
            onClick={() => setActive('nav-item-7')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.Divider />
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            icon={<AcademicCapIconOutline />}
            label="Nav Item"
            isActive={active === 'nav-item-8'}
            onClick={() => setActive('nav-item-8')}
          />
        </SideNavigation.ListItem>
      </SideNavigation>
      <SideNavigation
        isExpanded={true}
        shouldOverlayOnInteraction={false}
        expandedWidth={220}
        ariaLabel="Secondary side navigation"
      >
        <SideNavigation.CategoryHeader>
          Category Header
        </SideNavigation.CategoryHeader>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            label="Secondary Nav Item"
            isActive={secondaryActive === 'secondary-nav-item-1'}
            onClick={() => setSecondaryActive('secondary-nav-item-1')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            label="Secondary Nav Item"
            isActive={secondaryActive === 'secondary-nav-item-2'}
            onClick={() => setSecondaryActive('secondary-nav-item-2')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            label="Secondary Nav Item"
            isActive={secondaryActive === 'secondary-nav-item-3'}
            onClick={() => setSecondaryActive('secondary-nav-item-3')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            label="Secondary Nav Item"
            isActive={secondaryActive === 'secondary-nav-item-4'}
            onClick={() => setSecondaryActive('secondary-nav-item-4')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            label="Secondary Nav Item"
            isActive={secondaryActive === 'secondary-nav-item-5'}
            onClick={() => setSecondaryActive('secondary-nav-item-5')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.CategoryHeader>
          Category Header
        </SideNavigation.CategoryHeader>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            label="Secondary Nav Item"
            icon={<MagnifyingGlassIconOutline />}
            isActive={secondaryActive === 'secondary-nav-item-6'}
            onClick={() => setSecondaryActive('secondary-nav-item-6')}
          />
        </SideNavigation.ListItem>
        <SideNavigation.ListItem>
          <SideNavigation.NavItem
            label="Secondary Nav Item"
            icon={<MagnifyingGlassIconOutline />}
            isActive={secondaryActive === 'secondary-nav-item-7'}
            onClick={() => setSecondaryActive('secondary-nav-item-7')}
          />
        </SideNavigation.ListItem>
      </SideNavigation>
      <div className="n-h-full n-w-full">
        <div className="n-flex n-flex-col n-p-8 n-w-full n-max-w-[1024px] n-mx-auto">
          <div className="n-flex n-flex-col n-gap-token-8 n-bg-neutral-bg-weak n-p-token-32 n-rounded-lg n-items-center n-justify-center">
            <Typography variant="title-4">Secondary Side Nav</Typography>
            <Typography variant="body-medium">
              If a page requires its own navigation, you can use a secondary
              side nav. The secondary side nav is always expanded and does not
              have a pin button.
            </Typography>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Component;
```
