SideNavigation is start-aligned and arranged vertically. It is used to navigate between page urls or sections when you have too many menu items to fit in horizontal Tabs.

also known as Legend

Figma:

Web:

iOS:

Android:

A11y:

Props

Component props
Name
Type
Default
accessibilityLabel
Required
string
-

String that clients such as VoiceOver will read to describe the element.

children
Required
React.Node
-

The content shown in SideNavigation. See subcomponents.

dismissButton
{| accessibilityLabel?: string, onDismiss: () => void |}
-

Callback fired when SideNavigation requests to be closed in mobile devices. Must be used to control SideNavigation´s on/off display state. The accessibilityLabel should follow the Accessibility guidelines.

React.Node
-

Content to display at the bottom of SideNavigation. Open slot available to display other functionality required in the page. See the Footer variant to learn more.

header
React.Node
-

Content to display at the top of SideNavigation. Open slot used for controlling the display of navigation items. See the Header variant to learn more.

showBorder
boolean
-

/**
Displays a border in SideNavigation. See the Border variant for more info.

title
string
-

Title for mobile navigation.

Usage guidelines

When to use
  • When Tabs or a top navigation cannot accommodate the number of links or sections you need to navigate through
  • When a deep hierarchy of navigation items is needed
When not to use
  • When you only have two to five items to navigate through. Use Tabs instead
  • When you need to open a menu of external links and actions via a button. Use Dropdown instead

Best practices

Do

Keep item labels brief and clear to keep them memorable and scannable.

Don't

Use long text labels that end up wrapping, especially in certain languages. Don’t shorten labels so much that they are hard to understand.

Do

Group related items and use section headings to help users parse information and help with redundancy.

Don't

Provide an unordered “kitchen sink” of features that is hard to parse and creates redundancy.

Do

Use icons that clearly match their text labels and serve as bullet points for the content.

Don't

Use icons if you’ll be forced to include icons that don’t quite reinforce their text labels.

Do

Place under the PageHeader when SideNav is used to navigate urls that are sub-sections of a main page

Don't

Omit a PageHeader and make it seem like each SideNav item is a primary, independent page.

Accessibility

Active item

SideNavigation.TopItem has an "active" state that visually identifies it. To set SideNavigation.TopItem to "active" set 'active="page"' (page redirect) or 'active="section"'. Use routing hooks from React.Router or other frameworks to identify the current route. For example, if the current pathname matches the SideNavigation.TopItem href, set SideNavigation.TopItem to "page". Use the example below as a reference.

import React from 'react';
import { SideNavigation } from 'gestalt';

export default function Example() {
  const reactRouterPath = '/sidenavigation';

  return (
    <SideNavigation accessibilityLabel="Active item example">
      <SideNavigation.Section label="Navigation">
        <SideNavigation.TopItem href="#" label="PageHeader" />
        <SideNavigation.TopItem href="#" label="Tabs" />
        <SideNavigation.TopItem
          active={reactRouterPath === '/sidenavigation' ? 'page' : undefined}
          href="#"
          label="SideNavigation"
          badge={{ text: 'New', type: 'info' }}
        />
      </SideNavigation.Section>
      <SideNavigation.Section label="Controls">
        <SideNavigation.TopItem
          href="#"
          label="RadioButton"
          badge={{ text: 'Deprecated', type: 'warning' }}
        />
        <SideNavigation.TopItem href="#" label="RadioGroup" />
      </SideNavigation.Section>
    </SideNavigation>
  );
}

Localization

Be sure to localize the accessibilityLabel in SideNavigation and all subcomponents as well. When the text of the SideNav.Item becomes longer than the width of the menu, either intentionally or through localization, will wrap as needed to display the full text. Keep this in mind when selecting wording for your SideNavigation menu items.

import React from 'react';
import { SideNavigation } from 'gestalt';

export default function Example() {
  return (
    <SideNavigation accessibilityLabel="Localization example">
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon="bell"
        label="Benachrichtigungen"
        counter={{
          number: '20',
          accessibilityLabel: 'Sie haben 20 Benachrichtigungen',
        }}
        notificationAccessibilityLabel="Du hast neue Benachrichtigungen"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon="speech"
        label="Mitteilungen"
        counter={{
          number: '10',
          accessibilityLabel: 'Sie haben 10 Nachrichten',
        }}
        notificationAccessibilityLabel="Sie haben neue Nachrichten"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon="cog"
        label="Einstellungen"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon="lock"
        label="Geschäftszugriff"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon="add-layout"
        label="Optimieren Sie Ihren Home-Feed"
        badge={{ text: 'New', type: 'info' }}
      />
    </SideNavigation>
  );
}

Subcomponents

SideNavigation.Section

Use SideNavigation.Section to categorize navigation menu items into groups and also avoid redundant language in labels.

SideNavigation.Section Props

SideNavigation.Section subcomponent props
Name
Type
Default
children
Required
React.Node
-

Any SideNavigation.TopItem to be rendered

label
Required
string
-

Label for the section. See the Sections variant for more info.

SideNavigation.TopItem

Use SideNavigation.TopItem to redirect the user to a different page or section. SideNavigation.TopItem must be used at the top level of SideNavigation. It supports badges, icons, counters, and notifications.

SideNavigation.TopItem Props

SideNavigation.TopItem subcomponent props
Name
Type
Default
href
Required
string
-

Directs users to the url when item is selected.

label
Required
string
-

Label for the item.

active
"page" | "section"
-

When set to 'page' or 'section', it displays the item in "active" state. See the Accessibility guidelines to learn more.

badge
{|
  text: string,
  type?: "info" | "error" | "warning" | "success" | "neutral",
|}
-

When supplied, will display a Badge next to the item's label. See the Badges variant to learn more.

counter
{| number: string, accessibilityLabel: string |}
-

When supplied, will display a counter. See the Counter variant to learn more.

icon
$Keys<typeof icons> | {| __path: string |}
-

When supplied, will display Icon. See the Icon variant to learn more.

notificationAccessibilityLabel
string
-

When supplied, will display a notification dot. See the Notification variant to learn more.

onClick
({|
  event:
    | SyntheticMouseEvent<HTMLDivElement>
    | SyntheticKeyboardEvent<HTMLDivElement>
    | SyntheticMouseEvent<HTMLAnchorElement>
    | SyntheticKeyboardEvent<HTMLAnchorElement>,
  dangerouslyDisableOnNavigation: () => void,
|}) => void
-

Callback when the user selects an item using the mouse or keyboard.

SideNavigation.NestedItem

Use SideNavigation.NestedItem to redirect the user to a different page or section. SideNavigation.NestedItem must be used in second and third nested levels.

SideNavigation.NestedItem Props

SideNavigation.NestedItem subcomponent props
Name
Type
Default
href
Required
string
-

Directs users to the url when item is selected.

label
Required
string
-

Label for the item.

active
"page" | "section"
-

When set to 'page' or 'section', it displays the item in "active" state. See the Accessibility guidelines to learn more.

onClick
({|
  event:
    | SyntheticMouseEvent<HTMLDivElement>
    | SyntheticKeyboardEvent<HTMLDivElement>
    | SyntheticMouseEvent<HTMLAnchorElement>
    | SyntheticKeyboardEvent<HTMLAnchorElement>,
  dangerouslyDisableOnNavigation: () => void,
|}) => void
-

Callback when the user selects an item using the mouse or keyboard.

SideNavigation.Group

Use SideNavigation.Group to hold SideNavigation.NestedItem and SideNavigation.NestedGroup at the top level of SideNavigation. It supports badges, icons, counters, and notifications.

SideNavigation.Group Props

SideNavigation.Group subcomponent props
Name
Type
Default
children
Required
React.Node
-

Content of the group. See nested directory variant for more information.

label
Required
string
-

Label for the group. See nested directory variant for more information.

badge
{|
  text: string,
  type?: "info" | "error" | "warning" | "success" | "neutral",
|}
-

When supplied, will display a Badge next to the item's label. See the Badges variant to learn more.

counter
{| number: string, accessibilityLabel: string |}
-

When supplied, will display a counter. See the Counter variant to learn more.

display
"expandable" | "static"
-

Nested directories can be static or expandable. See nested directory variant for more information.

icon
$Keys<typeof icons> | {| __path: string |}
-

When supplied, will display Icon. See the Icon variant to learn more.

notificationAccessibilityLabel
string
-

When supplied, will display a notification dot. See the Notification variant to learn more.

SideNavigation.NestedGroup

Use SideNavigation.NestedGroup to hold SideNavigation.NestedItem in the second nested level of Pageheader.

SideNavigation.NestedGroup Props

SideNavigation.NestedGroup subcomponent props
Name
Type
Default
children
Required
React.Node
-

Content of the group. See nested directory variant for more information.

label
Required
string
-

Label for the group. See nested directory variant for more information.

display
"expandable" | "static"
-

Nested directories can be static or expandable. See nested directory variant for more information.

Variants

Sections

Sections help with categorizing navigation menu items into groups and also avoid redundant language in labels.

import React from 'react';
import { SideNavigation } from 'gestalt';

export default function Example() {
  return (
    <SideNavigation accessibilityLabel="Sections example">
      <SideNavigation.Section label="Resources">
        <SideNavigation.TopItem href="#" label="ESLint plugin" />
        <SideNavigation.TopItem href="#" label="FAQ" />
        <SideNavigation.TopItem href="#" label="How to hack around Gestalt" />
        <SideNavigation.TopItem href="#" label="Tooling" />
      </SideNavigation.Section>
      <SideNavigation.Section label="Foundations">
        <SideNavigation.TopItem href="#" label="Accessibility" />
        <SideNavigation.TopItem href="#" label="Elevation" />
        <SideNavigation.TopItem href="#" label="Typography" />
        <SideNavigation.TopItem href="#" label="Color palette" />
      </SideNavigation.Section>
    </SideNavigation>
  );
}

Headers allow for sorting filters or another UI control to be included at the top of the navigation.

import React from 'react';
import { SideNavigation, RadioGroup, Flex } from 'gestalt';

export default function Example() {
  const [organisedBy, setOrganisedBy] = React.useState('categorized');

  return (
    <SideNavigation
      accessibilityLabel="Header example"
      header={
        <RadioGroup legend="Sort by?" id="example-header">
          <Flex
            gap={{
              row: 2,
              column: 0,
            }}
          >
            <RadioGroup.RadioButton
              checked={organisedBy === 'categorized'}
              id="category"
              label="Category"
              name="SortCategory"
              onChange={() => setOrganisedBy('categorized')}
              value="categorized"
              size="sm"
            />
            <RadioGroup.RadioButton
              checked={organisedBy === 'alphabetical'}
              id="alphabetical"
              label="Alphabetical"
              name="SortCAlphabetical"
              onChange={() => setOrganisedBy('alphabetical')}
              value="alphabetical"
              size="sm"
            />
          </Flex>
        </RadioGroup>
      }
    >
      {organisedBy === 'categorized' ? (
        <React.Fragment>
          <SideNavigation.Section label="Navigation">
            <SideNavigation.TopItem href="#" label="PageHeader" />
            <SideNavigation.TopItem href="#" label="Tabs" />
            <SideNavigation.TopItem
              href="#"
              label="SideNavigation"
              badge={{ text: 'New', type: 'info' }}
            />
          </SideNavigation.Section>
          <SideNavigation.Section label="Controls">
            <SideNavigation.TopItem
              href="#"
              label="RadioButton"
              badge={{ text: 'Deprecated', type: 'warning' }}
            />
            <SideNavigation.TopItem href="#" label="RadioGroup" />
          </SideNavigation.Section>
        </React.Fragment>
      ) : (
        <React.Fragment>
          <SideNavigation.TopItem href="#" label="PageHeader" />
          <SideNavigation.TopItem
            href="#"
            label="RadioButton"
            badge={{ text: 'Deprecated', type: 'warning' }}
          />
          <SideNavigation.TopItem href="#" label="RadioGroup" />
          <SideNavigation.TopItem
            href="#"
            label="SideNavigation"
            badge={{ text: 'New', type: 'info' }}
          />
          <SideNavigation.TopItem href="/web/tabs" label="Tabs" />
        </React.Fragment>
      )}
    </SideNavigation>
  );
}

Footers allow for filters, additional external links or other UI controls to be included at the bottom of the navigation.

Badge

A badge can be added to a menu label with information that may be useful to a person, such as whether a page is new or is a beta or deprecated feature. Only supported in SideNavigation.TopItem and SideNavigation.Group.

import React from 'react';
import { SideNavigation } from 'gestalt';

export default function Example() {
  return (
    <SideNavigation accessibilityLabel="Badge example">
      <SideNavigation.Section label="Navigation">
        <SideNavigation.TopItem href="#" label="PageHeader" />
        <SideNavigation.TopItem href="#" label="Tabs" />
        <SideNavigation.TopItem
          href="#"
          label="SideNavigation"
          badge={{ text: 'New', type: 'info' }}
        />
      </SideNavigation.Section>
      <SideNavigation.Section label="Controls">
        <SideNavigation.TopItem
          href="#"
          label="RadioButton"
          badge={{ text: 'Deprecated', type: 'warning' }}
        />
        <SideNavigation.TopItem href="#" label="RadioGroup" />
      </SideNavigation.Section>
    </SideNavigation>
  );
}

Border

A border can be added to the end edge of the navigation on dense surfaces with tight spacing where it helps to visually separate the nav from other content.

import React from 'react';
import { SideNavigation } from 'gestalt';

export default function Example() {
  return (
    <SideNavigation accessibilityLabel="Border example" showBorder>
      <SideNavigation.Section label="Navigation">
        <SideNavigation.TopItem href="#" label="PageHeader" />
        <SideNavigation.TopItem href="#" label="Tabs" />
        <SideNavigation.TopItem href="#" label="SideNavigation" />
      </SideNavigation.Section>
      <SideNavigation.Section label="Controls">
        <SideNavigation.TopItem href="#" label="RadioButton" />
        <SideNavigation.TopItem href="#" label="RadioGroup" />
      </SideNavigation.Section>
    </SideNavigation>
  );
}

Icons

Icons are used when simple, clear icons help users with scanning the content of a menu. Only supported in SideNavigation.TopItem and SideNavigation.Group.

import React from 'react';
import { SideNavigation } from 'gestalt';

export default function Example() {
  return (
    <SideNavigation accessibilityLabel="Icons example">
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon="bell"
        label="Notifications"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon="speech"
        label="Messages"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon="cog"
        label="Settings"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon="lock"
        label="Business Access"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon="add-layout"
        label="Tune your home feed"
      />
    </SideNavigation>
  );
}
Gestalt icon
import React from 'react';
import { SideNavigation } from 'gestalt';

export default function Example() {
  return (
    <SideNavigation accessibilityLabel="Custom icons example">
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon={{
          __path:
            'M14 17.5c0 1.378-1.122 2.5-2.5 2.5A2.503 2.503 0 0 1 9 17.5V17h5v.5zm8.947-1.87L18.701 2.712a1.022 1.022 0 0 0-1.566-.521l-15.7 11.24c-.37.264-.525.744-.382 1.179l.551 1.678c.14.425.532.712.974.712H7v.5a4.5 4.5 0 0 0 9 0V17h5.973c.7 0 1.195-.696.974-1.37z',
        }}
        label="Notifications"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon={{
          __path:
            'M0 6a4 4 0 0 1 4-4h16a4 4 0 0 1 4 4v12a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4zm3.52-.88 7.53 6.16a1.5 1.5 0 0 0 1.9 0l7.53-6.16A1 1 0 0 0 20 5H4a1 1 0 0 0-.48.12zM3 8.57V18a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V8.57l-6.15 5.04a4.5 4.5 0 0 1-5.7 0z',
        }}
        label="Messages"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon={{
          __path:
            'm2.337 19.942 5.671-1.977L19.265 6.706c.981-.98.981-2.57 0-3.55l-1.42-1.421a2.51 2.51 0 0 0-3.55 0L3.036 12.992l-1.978 5.671a1.005 1.005 0 0 0 1.279 1.279M23 22c0 .55-.45 1-1 1H2c-.55 0-1-.45-1-1s.45-1 1-1h20c.55 0 1 .45 1 1',
        }}
        label="Settings"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon={{
          __path:
            'M23 5v14a4 4 0 0 1-4 4H5a4 4 0 0 1-4-4v-5.5h10.258l-1.94 1.939a1.5 1.5 0 0 0 2.121 2.122L17 12l-5.561-5.561a1.501 1.501 0 0 0-2.121 2.122l1.94 1.939H1V5a4 4 0 0 1 4-4h14a4 4 0 0 1 4 4',
        }}
        label="Business Access"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        icon={{
          __path:
            'M5 1h5.75v22H5c-2.2 0-4-1.8-4-4V5c0-2.2 1.8-4 4-4zm18 4v5.75h-9.75V1H19c2.2 0 4 1.8 4 4zm-9.75 8.25H23V19c0 2.2-1.8 4-4 4h-5.75z',
        }}
        label="Tune your home feed"
      />
    </SideNavigation>
  );
}
Custom icon

Notification

A red indicator dot can be added to signify new items on a page or things that need your attention. Only supported in SideNavigation.TopItem and SideNavigation.Group.

import React from 'react';
import { SideNavigation } from 'gestalt';

export default function Example() {
  return (
    <SideNavigation accessibilityLabel="Notification example">
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        label="Notifications"
        counter={{
          number: '20',
          accessibilityLabel: 'You have 20 notifications in your inbox',
        }}
        notificationAccessibilityLabel="New notifications"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        label="Messages"
        counter={{
          number: '10',
          accessibilityLabel: 'You have 10 messages in your inbox',
        }}
        notificationAccessibilityLabel="New messages"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        label="Settings"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        label="Business Access"
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        label="Tune your home feed"
      />
    </SideNavigation>
  );
}

Counters

Counters can be included as indicators of the number of items on a page or section. Only include counters if it’s information that’s useful to the user to know before clicking on a menu item. Only supported in SideNavigation.TopItem and SideNavigation.Group.

import React from 'react';
import { SideNavigation } from 'gestalt';

export default function Example() {
  return (
    <SideNavigation accessibilityLabel="Counters example">
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        label="Under review"
        counter={{
          number: '20',
          accessibilityLabel: 'You have 20 Idea Pins under review',
        }}
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        label="Drafts"
        counter={{
          number: '5',
          accessibilityLabel: 'You have 5 Idea Pins drafts',
        }}
      />
      <SideNavigation.TopItem
        href="#"
        onClick={({ event }) => event.preventDefault()}
        label="Published"
        counter={{
          number: '200',
          accessibilityLabel: 'You have published 200 Idea Pins',
        }}
      />
    </SideNavigation>
  );
}

Nested directory

SideNavigation supports three navigation levels. The top level is composed of SideNavigation.TopItem and SideNavigation.Group. The second nested level is composed of SideNavigation.NestedGroup and SideNavigation.Item. The third nested level is composed of SideNavigation.Item

import React from 'react';
import { Box, SideNavigation } from 'gestalt';

export default function Example() {
  return (
    <Box height={362} width={280} overflow="scroll">
      <SideNavigation accessibilityLabel="Nested items example">
        <SideNavigation.TopItem
          href="#"
          onClick={({ event }) => event.preventDefault()}
          label="Reporting"
          icon="ads-stats"
        />
        <SideNavigation.TopItem
          href="#"
          onClick={({ event }) => event.preventDefault()}
          label="Conversions"
          icon="replace"
        />
        <SideNavigation.Section label="Audiences">
          <SideNavigation.TopItem
            href="#"
            onClick={({ event }) => event.preventDefault()}
            label="Thanksgiving"
            icon="people"
          />
          <SideNavigation.Group label="Christmas" icon="people">
            <SideNavigation.NestedItem
              href="#"
              onClick={({ event }) => event.preventDefault()}
              label="Luxury Christmas"
            />
            <SideNavigation.NestedGroup label="Classic Christmas">
              <SideNavigation.NestedItem
                href="#"
                onClick={({ event }) => event.preventDefault()}
                label="West Coast"
              />
              <SideNavigation.NestedItem
                href="#"
                onClick={({ event }) => event.preventDefault()}
                label="East Coast"
              />
            </SideNavigation.NestedGroup>
            <SideNavigation.NestedGroup label="Alternative Christmas">
              <SideNavigation.NestedItem
                href="#"
                onClick={({ event }) => event.preventDefault()}
                label="West Coast"
                active="section"
              />
              <SideNavigation.NestedItem
                href="#"
                onClick={({ event }) => event.preventDefault()}
                label="East Coast"
              />
            </SideNavigation.NestedGroup>
          </SideNavigation.Group>
          <SideNavigation.Group
            label="Halloween"
            icon="people"
            display="static"
          >
            <SideNavigation.NestedItem
              href="#"
              onClick={({ event }) => event.preventDefault()}
              label="East Coast"
            />
            <SideNavigation.NestedItem
              href="#"
              onClick={({ event }) => event.preventDefault()}
              label="West Coast"
            />
          </SideNavigation.Group>
        </SideNavigation.Section>
      </SideNavigation>
    </Box>
  );
}

Subcomponent composability

Under the hood, SideNavigation recognizes subcomponents by display name. SideNavigation requires its own subcomponents as children to build the list of navigation items.

When building SideNavigation, we might want to render different combinations of subcomponents conditionally. SideNavigation supports simple conditional rendering of subcomponents lists wrapped in React.Fragment as well as consecutive arrays of subcomponent arrays. See the example below which illustrates both of these cases. More logic complexity might break the correct SideNavigation behavior.

import React from 'react';
import { SideNavigation } from 'gestalt';

export default function Example() {
  const someCondition = true;

  return (
    <SideNavigation accessibilityLabel="Subcomponent composability example">
      {someCondition && (
        <SideNavigation.TopItem
          href="#"
          onClick={({ event }) => event.preventDefault()}
          label="Trends"
          icon="ads-stats"
        />
      )}

      <SideNavigation.Section label="Analytics">
        {someCondition && (
          <SideNavigation.TopItem
            href="#"
            onClick={({ event }) => event.preventDefault()}
            label="Reporting"
            icon="ads-stats"
          />
        )}
        {someCondition && (
          <SideNavigation.TopItem
            href="#"
            onClick={({ event }) => event.preventDefault()}
            label="Conversions"
            icon="replace"
          />
        )}
      </SideNavigation.Section>

      <SideNavigation.Section label="Audiences">
        <SideNavigation.Group label="Christmas" icon="people">
          <SideNavigation.NestedItem
            href="#"
            onClick={({ event }) => event.preventDefault()}
            label="Luxury Christmas"
          />
          <SideNavigation.NestedGroup label="Classic Christmas">
            <SideNavigation.NestedItem
              href="#"
              onClick={({ event }) => event.preventDefault()}
              label="West Coast"
            />
            <SideNavigation.NestedItem
              href="#"
              onClick={({ event }) => event.preventDefault()}
              label="East Coast"
            />
          </SideNavigation.NestedGroup>

          <SideNavigation.NestedGroup label="Alternative Christmas">
            {['West Coast', 'East Coast'].map((x) => (
              <SideNavigation.NestedItem
                href="#"
                key={`xmas${x}`}
                onClick={({ event }) => event.preventDefault()}
                label={x}
              />
            ))}
            {['Southern', 'NorthEast'].map((x) => (
              <SideNavigation.NestedItem
                href="#"
                key={`xmas${x}`}
                onClick={({ event }) => event.preventDefault()}
                label={x}
              />
            ))}
          </SideNavigation.NestedGroup>
        </SideNavigation.Group>
        <SideNavigation.Group label="Halloween" icon="people">
          {['West Coast', 'East Coast'].map((x) => (
            <SideNavigation.NestedItem
              href="#"
              key={`halloween${x}`}
              onClick={({ event }) => event.preventDefault()}
              label={x}
            />
          ))}
        </SideNavigation.Group>
      </SideNavigation.Section>
    </SideNavigation>
  );
}

Mobile

SideNavigation requires DeviceTypeProvider to enable its mobile user interface. The example below shows the mobile platform UI and its implementation.

For mobile, title and dismissButton become required props.

Notice that the mobile UI requires logic to hide and show SideNavigation full width. If Button or TapArea control the visibility of SideNavigation, use accessibilityControls so that screen reader users can identify the relationship between elements.

import React from 'react';
import { Box, SideNavigation, DeviceTypeProvider, Button } from 'gestalt';

export default function Example() {
  const [showNav, setShowNav] = React.useState(false);

  return showNav ? (
    <DeviceTypeProvider deviceType="mobile">
      <Box position="absolute" top bottom left right id="sidenavigation">
        <SideNavigation
          title="Advertisement"
          accessibilityLabel="Mobile device example"
          dismissButton={{
            onDismiss: () => setShowNav(false),
            accessibilityLabel: 'Close navigation',
          }}
        >
          <SideNavigation.TopItem
            href="#"
            onClick={({ event }) => event.preventDefault()}
            label="Reporting"
            icon="ads-stats"
          />
          <SideNavigation.TopItem
            href="#"
            onClick={({ event }) => event.preventDefault()}
            label="Conversions"
            icon="replace"
          />
          <SideNavigation.Section label="Audiences">
            <SideNavigation.TopItem
              href="#"
              onClick={({ event }) => event.preventDefault()}
              label="Thanksgiving"
              icon="people"
            />
            <SideNavigation.Group label="Christmas" icon="people">
              <SideNavigation.NestedItem
                href="#"
                onClick={({ event }) => event.preventDefault()}
                label="Luxury Christmas"
              />
              <SideNavigation.NestedGroup label="Classic Christmas">
                <SideNavigation.NestedItem
                  href="#"
                  onClick={({ event }) => event.preventDefault()}
                  label="West Coast"
                />
                <SideNavigation.NestedItem
                  href="#"
                  onClick={({ event }) => event.preventDefault()}
                  label="East Coast"
                />
              </SideNavigation.NestedGroup>
              <SideNavigation.NestedGroup label="Alternative Christmas">
                <SideNavigation.NestedItem
                  href="#"
                  onClick={({ event }) => event.preventDefault()}
                  label="West Coast"
                />
                <SideNavigation.NestedItem
                  href="#"
                  onClick={({ event }) => event.preventDefault()}
                  label="East Coast"
                />
              </SideNavigation.NestedGroup>
            </SideNavigation.Group>
            <SideNavigation.Group
              label="Halloween"
              icon="people"
              display="static"
            >
              <SideNavigation.NestedItem
                href="#"
                onClick={({ event }) => event.preventDefault()}
                label="East Coast"
              />
              <SideNavigation.NestedItem
                href="#"
                onClick={({ event }) => event.preventDefault()}
                label="West Coast"
              />
            </SideNavigation.Group>
          </SideNavigation.Section>
        </SideNavigation>
      </Box>
    </DeviceTypeProvider>
  ) : (
    <Box padding={2}>
      <Button
        accessibilityLabel="Show navigation"
        accessibilityControls="sidenavigation"
        color="red"
        text="Show navigation"
        size="lg"
        onClick={() => setShowNav(true)}
      />
    </Box>
  );
}

Writing

Do
  • Keep menu item labels brief, remembering that length is language-dependent
Don't
  • Use complete sentences or lengthy descriptions
  • Be redundant; use a section header if you find yourself repeating the same word over and over again in labels

Component quality checklist

Component quality checklist
Quality item
Status
Status description
Figma Library
Component is not currently available in Figma.
Responsive Web
Ready
Component is available in code for web and mobile web.
iOS
Component is not currently available in code for iOS.
Android
Component is not currently available in code for Android.

Tabs
Used to navigate between urls and placed horizontally. Tabs can be used when there are 2–5 URLs to navigate between and can be used as a sub-navigation after the top nav bar or after a SideNav.

SegmentedControl
SegmentedControl is used to select between different views or arrangements of related content. Like Tabs, this control is horizontal, but unlike tabs, it doesn’t navigated between URLs.

Dropdown
A custom menu to select URLs to navigate to, or actions to take. This is always triggered by a button.

PageHeader
For pages with a main top nav bar, every SideNav should have a PageHeader to announce the main page that the navigation items belong to. Exceptions are internal tools or developer platform interfaces where the SideNav is the main navigation.