JavaScript Components

Examples of each component in the /components directory

Accordion

An accessible accordion component that follows WCAG guidelines .

This is the content for section 1. The accordion component allows you to show and hide content in a collapsible panel.

This is the content for section 2. When you click on the header, this content will toggle visibility.

This is the content for section 3. The accordion is fully accessible and can be controlled via keyboard.

HTML Structure

<div class="accordion">
  <h3 class="accordion__heading">
    <button id="accordion-trigger-01" class="accordion__trigger" aria-expanded="false" aria-controls="accordion-section-01">Accordion Section</button>
  </h3>

  <div id="accordion-section-01" class="accordion__content" role="region" aria-labelledby="accordion-trigger-01">
    <p>This is the accordion content.</p>
  </div>
</div>
      

JavaScript Initialization

// Initialize all accordions on the page
document.querySelectorAll('.accordion').forEach(accordion => {
  const accordionComponent = new Accordion(accordion, {options});
  accordionComponent.init();
});
      

Custom Options Example

const accordionComponent = new Accordion(accordionElement, {
  selectors: {
    trigger: '.my-accordion__trigger[aria-controls]',
  },
  classes: {
    expanded: 'is-open',
  },
});

accordionComponent.init();
      

Tab Content

An accessible tabbed content element that follows WCAG guidelines .

Text content goes here - Tab 01

Text content goes here - Tab 02

Text content goes here - Tab 03

HTML Structure

<div class="tab-content">
  <div role="tablist" class="tab-content__navigation"></div>

  <div id="tab-content-01"
       class="tab-content__group is-expanded"
       role="tabpanel"
       aria-labelledby="tab-tab-content-01">
    <button type="button"
            id="tab-tab-content-01"
            class="tab-content__trigger is-expanded"
            role="tab"
            aria-haspopup="true"
            aria-selected="true"
            aria-expanded="true"
            aria-controls="tab-content-01">
      Tab 01
    </button>

    <div class="tab-content__content">
      <p>Text content goes here - Tab 01</p>
    </div>
  </div>

  <div id="tab-content-02"
       class="tab-content__group"
       role="tabpanel"
       aria-labelledby="tab-tab-content-02">
    <button type="button"
            id="tab-tab-content-02"
            class="tab-content__trigger"
            role="tab"
            aria-haspopup="true"
            aria-selected="true"
            aria-expanded="true"
            aria-controls="tab-content-02">
      Tab 02
    </button>

    <div class="tab-content__content">
      <p>Text content goes here - Tab 02</p>
    </div>
  </div>

  <div id="tab-content-03"
       class="tab-content__group is-expanded"
       role="tabpanel"
       aria-labelledby="tab-tab-content-03">
    <button type="button"
            id="tab-tab-content-03"
            class="tab-content__trigger"
            role="tab"
            aria-haspopup="true"
            aria-selected="true"
            aria-expanded="true"
            aria-controls="tab-content-03">
      Tab 03
    </button>

    <div class="tab-content__content">
      <p>Text content goes here - Tab 03</p>
    </div>
  </div>
</div>
      

JavaScript Initialization

// Initialize all Tab Content elements on the page
document.querySelectorAll('.tab-content').forEach((tabContent) => {
  const tabContentComponent = new TabContent(tabContent, {options});
  tabContentComponent.init();
});
      

Custom Options Example

const tabContentComponent = new TabContent(tabContentElement, {
  selectors: {
    navigation: '.my-tabs__navigation',
    group: '.my-tabs__group',
    trigger: '.my-tabs__trigger',
  },
  classes: {
    expanded: 'is-open',
  },
  breakpoint: 1024,
});

tabContentComponent.init();
      

Sticky

A scroll-aware component that keeps an element visible within its parent container as the page scrolls.

Scroll down to see the sidebar element stick to the viewport while remaining within the bounds of this container. The sticky component tracks three states: default (natural position), stuck (viewport-tracking), and bottom (anchored to the parent's bottom edge).

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim.

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt.

Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit.

At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident.

Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.

HTML Structure

<div class="sticky-parent">
  <aside class="sticky-element">
    Sticky content
  </aside>
</div>
      

Required CSS

.sticky-element.is-stuck {
  position: absolute;
}

.sticky-element.is-bottom {
  position: absolute;
  bottom: 0;
}
      

JavaScript Initialization

// Initialize all sticky elements on the page
document.querySelectorAll('.sticky-element').forEach(el => {
  const stickyComponent = new Sticky(el);
  stickyComponent.mount();
});
      

Custom Options Example

const stickyComponent = new Sticky(el, {
  topSpacing: 80,
  classes: {
    stuck: 'is-pinned',
    bottom: 'is-anchored',
  },
});

stickyComponent.mount();