Navigation

Build app navigation with groups and collapsible submenus.

Live preview
Interact with the component to see results here.
View code
HTML
<sy-nav>
  <sy-nav-group title="Workspace">
    <sy-nav-item value="overview">Overview</sy-nav-item>
    <sy-nav-item value="members">Members</sy-nav-item>
    <sy-nav-item value="settings" disabled>Settings</sy-nav-item>
  </sy-nav-group>
  <sy-nav-sub title="Project" open>
    <sy-nav-item value="website">Homepage</sy-nav-item>
    <sy-nav-sub title="Component">
      <sy-nav-item value="core">Design System</sy-nav-item>
      <sy-nav-item value="charts">Charts</sy-nav-item>
    </sy-nav-sub>
  </sy-nav-sub>
</sy-nav>

Usage guide

#

A persistent navigation menu between the app's main views. Use Menu or Dropdown for temporary command lists.

Always-visible groups

Use nav-group to create menu groups with headings.

Collapsible submenus

Use nav-sub to expand and collapse child items.

Examples

#

Single menu

Highlight the selected item and emit its unique value in the event.

View code
HTML
<sy-nav>
  <sy-nav-item value="overview">Overview</sy-nav-item>
  <sy-nav-item value="members">Members</sy-nav-item>
  <sy-nav-item value="settings" disabled>Settings</sy-nav-item>
</sy-nav>

Groups and submenus

Separate workspace and project navigation and create nested submenus.

View code
HTML
<sy-nav>
  <sy-nav-group title="Workspace">
    <sy-nav-item value="overview">Overview</sy-nav-item>
    <sy-nav-item value="members">Members</sy-nav-item>
    <sy-nav-item value="settings" disabled>Settings</sy-nav-item>
  </sy-nav-group>
  <sy-nav-sub title="Project" open>
    <sy-nav-item value="website">Homepage</sy-nav-item>
    <sy-nav-sub title="Component">
      <sy-nav-item value="core">Design System</sy-nav-item>
      <sy-nav-item value="charts">Charts</sy-nav-item>
    </sy-nav-sub>
  </sy-nav-sub>
</sy-nav>

Disable all

Disabling the menu also restricts child selection and expansion.

View code
HTML
<sy-nav disabled>
  <sy-nav-group title="Workspace">
    <sy-nav-item value="overview">Overview</sy-nav-item>
    <sy-nav-item value="members">Members</sy-nav-item>
    <sy-nav-item value="settings" disabled>Settings</sy-nav-item>
  </sy-nav-group>
  <sy-nav-sub title="Project" open>
    <sy-nav-item value="website">Homepage</sy-nav-item>
    <sy-nav-sub title="Component">
      <sy-nav-item value="core">Design System</sy-nav-item>
      <sy-nav-item value="charts">Charts</sy-nav-item>
    </sy-nav-sub>
  </sy-nav-sub>
</sy-nav>

Control submenus externally

Use setOpen, setClose, and setTrigger to control submenu expansion.

View code
HTML
<sy-nav>
  <sy-nav-sub title="Project" id="sample">
    <sy-nav-item value="overview">Overview</sy-nav-item>
    <sy-nav-item value="members">Members</sy-nav-item>
    <sy-nav-item value="settings" disabled>Settings</sy-nav-item>
  </sy-nav-sub>
</sy-nav>
<div class="demo-actions"
  style="display:flex;flex-wrap:wrap;gap:8px;margin-top:16px"
>
  <sy-button id="action-0" size="small">Expand</sy-button>
  <sy-button id="action-1" size="small">Collapse</sy-button>
  <sy-button id="action-2" size="small">Toggle</sy-button>
</div>
<output id="demo-result" aria-live="polite"></output>

<script type="module">
  const describeResult = value => JSON.stringify(value, (_key, item) => {
    if (item instanceof File) return {
      name: item.name,
      size: item.size,
      type: item.type
    };
    if (item instanceof Element) return `<${item.localName}>`;
    return item;
  }) ?? 'Done';
  const actionTarget0 = document.querySelector("#sample");
  document.querySelector('#action-0').addEventListener('click', async () => {
    const result = await actionTarget0.setOpen();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget1 = document.querySelector("#sample");
  document.querySelector('#action-1').addEventListener('click', async () => {
    const result = await actionTarget1.setClose();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget2 = document.querySelector("#sample");
  document.querySelector('#action-2').addEventListener('click', async () => {
    const result = await actionTarget2.setTrigger();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
</script>

Events and payloads

Interact with the component and inspect the latest event name and detail. The code includes subscriptions to events emitted by this component and its children.

View code
HTML
<sy-nav>
  <sy-nav-group title="Workspace">
    <sy-nav-item value="overview">Overview</sy-nav-item>
    <sy-nav-item value="members">Members</sy-nav-item>
    <sy-nav-item value="settings" disabled>Settings</sy-nav-item>
  </sy-nav-group>
  <sy-nav-sub title="Project" open>
    <sy-nav-item value="website">Homepage</sy-nav-item>
    <sy-nav-sub title="Component">
      <sy-nav-item value="core">Design System</sy-nav-item>
      <sy-nav-item value="charts">Charts</sy-nav-item>
    </sy-nav-sub>
  </sy-nav-sub>
</sy-nav>
<output id="demo-events" aria-live="polite">Interact with the component to see
  its latest event and payload.</output>

<script type="module">
  const describeResult = value => JSON.stringify(value, (_key, item) => {
    if (item instanceof File) return {
      name: item.name,
      size: item.size,
      type: item.type
    };
    if (item instanceof Element) return `<${item.localName}>`;
    return item;
  }) ?? 'Done';
  for (const name of ["selected"]) {
    document.addEventListener(name, event => {
      document.querySelector('#demo-events').textContent =
        `${event.target.localName} · ${name}: ${describeResult(event.detail)}`;
    });
  }
</script>

Initially collapsed groups

Expand a collapsed navigation group to reveal its child pages.

View code
HTML
<sy-nav id="supplement-1">
  <sy-nav-group title="Workspace">
    <sy-nav-item value="overview">Overview</sy-nav-item>
    <sy-nav-item value="members">Members</sy-nav-item>
    <sy-nav-item value="settings" disabled>Settings</sy-nav-item>
  </sy-nav-group>
  <sy-nav-sub title="Project">
    <sy-nav-item value="website">Homepage</sy-nav-item>
    <sy-nav-sub title="Component">
      <sy-nav-item value="core">Design System</sy-nav-item>
      <sy-nav-item value="charts">Charts</sy-nav-item>
    </sy-nav-sub>
  </sy-nav-sub>
</sy-nav>

<script type="module">
  const component1 = document.querySelector("#supplement-1");
  Object.assign(component1, {});
</script>

API reference

#

Hover over a name or focus it with the keyboard to see the code. On touch screens, tap the name.

<sy-nav>

Properties

Attribute / PropertyTypeDefaultDescription
booleanfalseBlock user interaction and keyboard focus.

Slots

SlotDescription
Component body or child items.

<sy-nav-item>

Properties

Attribute / PropertyTypeDefaultDescription
string''Current value or item identifier.
booleanfalseBlock user interaction and keyboard focus.
number0Menu indentation level, calculated by the parent menu.

Events

EventDetailDescription
CustomEvent<string>Value of the activated navigation item. The application owns routing.

Methods

MethodReturnsDescription
Promise<void>Pass down the parent menu's disabled state. Normally managed by the parent.
Promise<void>Set item styling within a menu group. Managed by the parent.
Promise<void>Change the menu item's selection indicator.

Slots

SlotDescription
Component body or child items.

<sy-nav-sub>

Properties

Attribute / PropertyTypeDefaultDescription
string''Title of the collapsible submenu. The HTML attribute is title.
string''Current value or item identifier.
booleanfalseWhether the submenu is expanded.
booleanfalseBlock user interaction and keyboard focus.
number0Menu indentation level, calculated by the parent menu.

Events

EventDetailDescription
CustomEvent<string>Submenu value, emitted when its expanded state changes.

Methods

MethodReturnsDescription
Promise<void>Pass down the parent menu's disabled state. Normally managed by the parent.
Promise<void>Set item styling within a menu group. Managed by the parent.
Promise<void>Expand or collapse the submenu.
Promise<void>Expand the submenu.
Promise<void>Close the item.

Slots

SlotDescription
Component body or child items.

<sy-nav-group>

Properties

Attribute / PropertyTypeDefaultDescription
string''Menu group title. The HTML attribute is title.
number0Menu indentation level, calculated by the parent menu.

Slots

SlotDescription
Component body or child items.