<nav class="panelNav" aria-label="Browse by category">
    <h2 class="panelNav__heading">Category</h2>
    <div class="panelNav__items" role="list">
        <a href="#" class="panelNav__item panelNav__link" role="listitem">Item 1</a>
        <a href="#" class="panelNav__item panelNav__link" role="listitem">Item 2</a>
        <a href="#" class="panelNav__item panelNav__link" role="listitem">Item 3</a>
        <span class="panelNav__item panelNav__item--active" role="listitem">
            <span class="prependedIcon fa-solid fa-angle-right"></span>
            <span class="u-srOnly">Current page:&nbsp;</span>Item 4
        </span>
        <a href="#" class="panelNav__item panelNav__link" role="listitem">Item 5</a>
        <a href="#" class="panelNav__item panelNav__link" role="listitem">Item 6</a>
    </div>
</nav>

<link media="all" rel="stylesheet" href="/panel-nav/panel-nav.css" />
<script src="/panel-nav/panel-nav.js"></script>
<nav class="panelNav" aria-label="Browse by category">
  <h2 class="panelNav__heading">{{ heading }}</h2>
  <div class="panelNav__items" role="list">
    {% for item in items %}
      {% if item.active %}
        <span class="panelNav__item panelNav__item--active" role="listitem">
          <span class="prependedIcon fa-solid fa-angle-right"></span>
          <span class="u-srOnly">Current page:&nbsp;</span>{{ item.title }}
        </span>
      {% else %}
        <a href="#" class="panelNav__item panelNav__link" role="listitem">{{ item.title }}</a>
      {% endif %}
    {% endfor %}
  </div>
</nav>

{% import "_macros.twig" as h %}
{{ h.componentAssets('panel-nav') }}
{
  "heading": "Category",
  "items": [
    {
      "title": "Item 1"
    },
    {
      "title": "Item 2"
    },
    {
      "title": "Item 3"
    },
    {
      "title": "Item 4",
      "active": true
    },
    {
      "title": "Item 5"
    },
    {
      "title": "Item 6"
    }
  ]
}
  • Content:
    @use "../panel/panel";
    @use "../_layout/mixins";
    
    /* @todo rebuild so that <ul> and <li> can be used as children for .panelNav__items to negate need for aria roles */
    
    .panelNav {
      @include panel.panel();
    }
    .panelNav__heading {
      font-size: var(--step-2);
    }
    .panelNav__items {
      display: flex;
      flex-direction: column;
      margin-block: 0 -0.5em;
    }
    .panelNav__items--inline {
      display: block;
    }
    .panelNav__item {
      @include mixins.blockLink($underline: false);
      padding-block: 0.5em;
    
      &:hover,
      &:focus {
        text-decoration: none;
      }
      & + & {
        border-block-start: 1px solid var(--neutral--dark);
      }
    }
    
    .panelNav__item--active {
      --color: var(--type);
    
      &:hover, &:active {
        --color: var(--type);
      }
    }
    
    .panelNav__items--inline {
      margin-block-start: .5em;
      .panelNav__item {
        padding-block: 0;
      }
      .panelNav__item + .panelNav__item {
        border-block-start: 0;
      }
      .panelNav__item:nth-last-child(n+2)::after {
        content: "|";
        margin-inline-start: 0.3em;
        pointer-events: none;
        cursor: default;
        text-decoration: none;
        color: var(--type);
      }
      .panelNav__item--active {
        display: inline-flex;
        align-items: center;
        vertical-align: bottom;
      }
    }
  • URL: /components/raw/panel-nav/panel-nav.scss
  • Filesystem Path: src/components/panel-nav/panel-nav.scss
  • Size: 1.2 KB

Accessibility and Current Page

The containing div.panelNav__items should receive role="list" and its children should receive role="listitem". This allows screen readers to announce how many items are in the navigation list. Eventually this component should be reworked to allow <ul> and <li> to use native lists instead of relying on aria roles.

The current page should be wrapped in a <span> as opposed to an <a> so it is not clickable. Additionally, prepend the text with off-screen text to indicate the current page and a Font Awesome angle-right icon:

<span class="panelNav__item panelNav__item--active" role="listitem">
  <span class="u-srOnly">Current page:&nbsp;</span>
  <span class="prependedIcon fa-solid fa-angle-right"></span>Page title
</span>

Inline Layout

Add .panelNav__items--inline modifier to list nav items inline (not vertically) with a pipe separator.

To denote the current item, use two angle icons surrounding the text:


<nav class="panelNav" aria-labelledby="unique-id">
  <h2 class="panelNav__heading" id="unique-id">Child Navigation</h2>
  <div class="panelNav__items panelNav__items--inline" role="list">
    <a href="#" class="panelNav__item panelNav__link" role="listitem">Page title</a>
    <span class="panelNav__item panelNav__item--active" role="listitem">
      <span class="u-srOnly">Current page:&nbsp;</span>
      <span class="fa-solid fa-angle-left"></span>Page title<span class="fa-solid fa-angle-right"></span>
    </span>
    <a href="#" class="panelNav__item panelNav__link" role="listitem">Page title</a>
  </div>
</nav>