<section class="accordion" data-module="accordion" aria-labelledby="accordionTitle">
    <header class="accordion__header">
        <h2 class="accordion__title" id="accordionTitle">Accordion Heading</h2>
        <p class="accordion__description">Praesent dui elit, porttitor sed vulputate id, mollis sed nibh. Morbi molestie scelerisque diam, at efficitur erat auctor vitae. Proin vehicula volutpat consequat. Donec sit amet magna sed urna egestas feugiat in et nisi. Suspendisse risus dolor, maximus sit amet pharetra sed, convallis sed orci. Nulla sit amet nisi cursus, blandit ipsum vel, feugiat nisl.</p>
    </header>
    <div class="accordion__items">
        <div class="accordion__item">
            <h3 class="accordion__item-title">
                <button class="accordion__item-trigger" aria-expanded="true">
                    Accordion Tab Title
                    <span class="accordion__item-icon">
                        <svg viewBox="0 0 14 2" class="accordion__item-icon-minus">
                            <use xlink:href="#minus" />
                        </svg>
                        <svg viewBox="0 0 14 14" class="accordion__item-icon-plus">
                            <use xlink:href="#plus" />
                        </svg>
                    </span>
                </button>
            </h3>
            <div role="region" class="accordion__item-panel">
                <div class="accordion__item-content">
                    <div class="rtf accordion__item-description">
                        <h4>Putting you at the center of it all</h4>
                        <p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>
                    </div>
                </div>
            </div>
        </div>
        <div class="accordion__item">
            <h3 class="accordion__item-title">
                <button class="accordion__item-trigger" aria-expanded="false">
                    Accordion Tab With Image
                    <span class="accordion__item-icon">
                        <svg viewBox="0 0 14 2" class="accordion__item-icon-minus">
                            <use xlink:href="#minus" />
                        </svg>
                        <svg viewBox="0 0 14 14" class="accordion__item-icon-plus">
                            <use xlink:href="#plus" />
                        </svg>
                    </span>
                </button>
            </h3>
            <div role="region" class="accordion__item-panel">
                <div class="accordion__item-content">
                    <div class="rtf accordion__item-description">
                        <p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p><img src="https://verndale-image-tools.herokuapp.com/id/EFvP9cHipMQ?w=900&h=450" alt="Image Description">
                    </div>
                </div>
            </div>
        </div>
        <div class="accordion__item">
            <h3 class="accordion__item-title">
                <button class="accordion__item-trigger" aria-expanded="false">
                    Accordion Tab With Video
                    <span class="accordion__item-icon">
                        <svg viewBox="0 0 14 2" class="accordion__item-icon-minus">
                            <use xlink:href="#minus" />
                        </svg>
                        <svg viewBox="0 0 14 14" class="accordion__item-icon-plus">
                            <use xlink:href="#plus" />
                        </svg>
                    </span>
                </button>
            </h3>
            <div role="region" class="accordion__item-panel">
                <div class="accordion__item-content">
                    <div class="rtf accordion__item-description">
                        <p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>
                    </div>
                    <div class="accordion__video">
                        <section class="testimonials container scEnabledChrome" data-module="testimonials" sc-part-of="placeholder rendering">
                            <header>
                                <h2 class="testimonials__heading">
                                    <span class="scChromeData"></span><span id="fld_77D47B44369D4ACE84D66C17A275811D_1D631840345E4DDEB0539099EA076EEE_en_1_e6929504dae7493c83cb7b24225421d3_292_edit" sc_parameters="prevent-line-break=true" contenteditable="true" class="scWebEditInput scEnabledChrome" scfieldtype="single-line text" scdefaulttext="[No text in field]" sc-part-of="field">Testimonial Carousel</span>
                                </h2>
                            </header>
                            <div class="testimonials__slider">
                                <div class="swiper-container swiper-container-initialized swiper-container-horizontal swiper-container-pointer-events">
                                    <div class="swiper-wrapper">
                                        <span type="text/sitecore" sc-part-of="placeholder rendering" style="display: none;" class="scEnabledChrome"></span>
                                        <div class="scEnabledChrome scEmptyPlaceholder" sc-placeholder-id="_Rows_TestimonialCarouselCards__C42E4A27_B288_4A35_82D6_BDF2B96BB2CA__0" sc-part-of="placeholder"></div><code type="text/sitecore" id="scEnclosingTag_" chrometype="placeholder" kind="close" hintname="TestimonialCarouselCards" class="scpm">
                                    </div>
                                </div>
                            </div>
                        </section>
                    </div>
                </div>
            </div>
        </div>
        <div class="accordion__item">
            <h3 class="accordion__item-title">
                <button class="accordion__item-trigger" aria-expanded="false">
                    Accordion Tab With Buttons
                    <span class="accordion__item-icon">
                        <svg viewBox="0 0 14 2" class="accordion__item-icon-minus">
                            <use xlink:href="#minus" />
                        </svg>
                        <svg viewBox="0 0 14 14" class="accordion__item-icon-plus">
                            <use xlink:href="#plus" />
                        </svg>
                    </span>
                </button>
            </h3>
            <div role="region" class="accordion__item-panel">
                <div class="accordion__item-content">
                    <div class="rtf accordion__item-description">
                        <p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>
                    </div>
                    <aside class="buttons-row">
                        <a href="#" class="btn btn--primary">Document Name</a><a href="#" class="btn btn--primary">Document Name</a>
                    </aside>
                </div>
            </div>
        </div>
        <div class="accordion__item">
            <h3 class="accordion__item-title">
                <button class="accordion__item-trigger" aria-expanded="false">
                    Accordion Tab With Image and Paragraph
                    <span class="accordion__item-icon">
                        <svg viewBox="0 0 14 2" class="accordion__item-icon-minus">
                            <use xlink:href="#minus" />
                        </svg>
                        <svg viewBox="0 0 14 14" class="accordion__item-icon-plus">
                            <use xlink:href="#plus" />
                        </svg>
                    </span>
                </button>
            </h3>
            <div role="region" class="accordion__item-panel">
                <div class="accordion__item-content">
                    <div class="rtf accordion__item-description">
                        <p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p><img src="https://verndale-image-tools.herokuapp.com/id/EFvP9cHipMQ?w=900&h=450" alt="Image Description">
                        <p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>
                    </div>
                    <aside class="buttons-row">
                        <a href="#" class="btn btn--primary">Document Name</a><a href="#" class="btn btn--primary">Document Name</a>
                    </aside>
                </div>
            </div>
        </div>
        <div class="accordion__item">
            <h3 class="accordion__item-title">
                <button class="accordion__item-trigger" aria-expanded="false">
                    Accordion Tab With Video, Paragraph and buttons
                    <span class="accordion__item-icon">
                        <svg viewBox="0 0 14 2" class="accordion__item-icon-minus">
                            <use xlink:href="#minus" />
                        </svg>
                        <svg viewBox="0 0 14 14" class="accordion__item-icon-plus">
                            <use xlink:href="#plus" />
                        </svg>
                    </span>
                </button>
            </h3>
            <div role="region" class="accordion__item-panel">
                <div class="accordion__item-content">
                    <div class="rtf accordion__item-description">
                        <p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p><img src="https://verndale-image-tools.herokuapp.com/id/EFvP9cHipMQ?w=900&h=450" alt="Image Description">
                        <p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>
                    </div>
                    <div class="accordion__video">
                        <section class="testimonials container scEnabledChrome" data-module="testimonials" sc-part-of="placeholder rendering">
                            <header>
                                <h2 class="testimonials__heading">
                                    <span class="scChromeData"></span><span id="fld_77D47B44369D4ACE84D66C17A275811D_1D631840345E4DDEB0539099EA076EEE_en_1_e6929504dae7493c83cb7b24225421d3_292_edit" sc_parameters="prevent-line-break=true" contenteditable="true" class="scWebEditInput scEnabledChrome" scfieldtype="single-line text" scdefaulttext="[No text in field]" sc-part-of="field">Testimonial Carousel</span>
                                </h2>
                            </header>
                            <div class="testimonials__slider">
                                <div class="swiper-container swiper-container-initialized swiper-container-horizontal swiper-container-pointer-events">
                                    <div class="swiper-wrapper">
                                        <span type="text/sitecore" sc-part-of="placeholder rendering" style="display: none;" class="scEnabledChrome"></span>
                                        <div class="scEnabledChrome scEmptyPlaceholder" sc-placeholder-id="_Rows_TestimonialCarouselCards__C42E4A27_B288_4A35_82D6_BDF2B96BB2CA__0" sc-part-of="placeholder"></div><code type="text/sitecore" id="scEnclosingTag_" chrometype="placeholder" kind="close" hintname="TestimonialCarouselCards" class="scpm">
                                    </div>
                                </div>
                            </div>
                        </section>
                    </div>
                    <aside class="buttons-row">
                        <a href="#" class="btn btn--primary">Document Name</a><a href="#" class="btn btn--primary">Document Name</a>
                    </aside>
                </div>
            </div>
        </div>
    </div>
</section>
{{#*inline "accordion-tab"}}
  <div class="accordion__item">
    <h3 class="accordion__item-title">
    <button class="accordion__item-trigger" aria-expanded="{{#if expanded}}true{{else}}false{{/if}}">
      {{title}}
      <span class="accordion__item-icon">
        {{>svg name="minus" viewBox="0 0 14 2" className="accordion__item-icon-minus"}}
        {{>svg name="plus" viewBox="0 0 14 14" className="accordion__item-icon-plus"}}
    </span>
    </button>
    </h3>
    <div role="region" class="accordion__item-panel">
      <div class="accordion__item-content">
        {{#if heading}}
        <h4 class="accordion__item-heading">{{heading}}</h4>
        {{/if}}
        <div class="rtf accordion__item-description">
          {{{content}}}
        </div>
        {{#if videoPlayer}}
          <div class="accordion__video">
            {{>@video videoPlayer=videoPlayer videoId=videoId background=background poster=poster}}
          </div>
        {{/if}}
        {{#if buttons}}
        <aside class="buttons-row">
          {{{buttons}}}
        </aside>
        {{/if}}
      </div>
    </div>
  </div>
{{/inline}}

<section class="accordion" data-module="accordion" aria-labelledby="accordionTitle">
  <header class="accordion__header">
    {{#if title}}<h2 class="accordion__title" id="accordionTitle">{{title}}</h2>{{/if}}
    {{#if description}}<p class="accordion__description">{{{description}}}</p>{{/if}}
  </header>
  <div class="accordion__items">
    {{#json items}}
      {{#each this}}
        {{> accordion-tab}}
      {{/each}}
    {{/json}}
  </div>
</section>
{
  "title": "Accordion Heading",
  "description": "Praesent dui elit, porttitor sed vulputate id, mollis sed nibh. Morbi molestie scelerisque diam, at efficitur erat auctor vitae. Proin vehicula volutpat consequat. Donec sit amet magna sed urna egestas feugiat in et nisi. Suspendisse risus dolor, maximus sit amet pharetra sed, convallis sed orci. Nulla sit amet nisi cursus, blandit ipsum vel, feugiat nisl.",
  "items": [
    {
      "expanded": true,
      "title": "Accordion Tab Title",
      "content": "<h4>Putting you at the center of it all</h4><p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>"
    },
    {
      "title": "Accordion Tab With Image",
      "content": "<p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p><img src=\"https://verndale-image-tools.herokuapp.com/id/EFvP9cHipMQ?w=900&h=450\" alt=\"Image Description\">"
    },
    {
      "title": "Accordion Tab With Video",
      "content": "<p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>",
      "videoId": "DSLgAsrcpGQ",
      "videoPlayer": "youtube",
      "background": true,
      "image": {
        "srcset": {
          "767": "https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=767&h=430",
          "1279": "https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=1280&h=717"
        },
        "src": "https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=790&h=444",
        "description": "Image Description"
      },
      "autoplay": false
    },
    {
      "title": "Accordion Tab With Buttons",
      "content": "<p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>",
      "buttons": "<a href=\"#\" class=\"btn btn--primary\">Document Name</a><a href=\"#\" class=\"btn btn--primary\">Document Name</a>"
    },
    {
      "title": "Accordion Tab With Image and Paragraph",
      "content": "<p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p><img src=\"https://verndale-image-tools.herokuapp.com/id/EFvP9cHipMQ?w=900&h=450\" alt=\"Image Description\"><p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>",
      "buttons": "<a href=\"#\" class=\"btn btn--primary\">Document Name</a><a href=\"#\" class=\"btn btn--primary\">Document Name</a>"
    },
    {
      "title": "Accordion Tab With Video, Paragraph and buttons",
      "content": "<p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p><img src=\"https://verndale-image-tools.herokuapp.com/id/EFvP9cHipMQ?w=900&h=450\" alt=\"Image Description\"><p>Nullam quis risus eget urna mollis ornare vel eu leo. Vestibulum id ligula porta felis euismod semper. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Maecenas sed diam eget risus varius blandit sit amet non magna. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.</p>",
      "buttons": "<a href=\"#\" class=\"btn btn--primary\">Document Name</a><a href=\"#\" class=\"btn btn--primary\">Document Name</a>",
      "videoId": "DSLgAsrcpGQ",
      "videoPlayer": "youtube",
      "background": true,
      "image": {
        "srcset": {
          "767": "https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=767&h=430",
          "1279": "https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=1280&h=717"
        },
        "src": "https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=790&h=444",
        "description": "Image Description"
      },
      "autoplay": false
    }
  ]
}
  • Content:
    import { Component } from '@verndale/core';
    import { v4 as uuidv4 } from 'uuid';
    import { keyCode } from '../helpers';
    import { rovingIndex } from '@verndale/roving-ux'; // npm es6/common modules
    
    /**
     * `Accordion`
     *
     *
     * @example
     * import { Accordion } from '@verndale/front-end-components';
     *
     * class Foo {
     *   construction(){
     *
     *     cont Accordion = new Accordion('.accordion');
     *   }
     * }
     */
    class Accordion extends Component {
      constructor(el) {
        super(el);
    
        this.initAccordion();
      }
    
      setupDefaults() {
        this.dom = {
          container: this.el.querySelector('.accordion__items'),
          items: this.el.querySelectorAll('.accordion__item'),
          triggers: [...this.el.querySelectorAll('.accordion__item-trigger')],
          panels: [...this.el.querySelectorAll('.accordion__item-panel')]
        }
        const self = this;
        rovingIndex({
          element: self.el, // required: the container to get roving index ux
          target: '.accordion__item-trigger' // optional: a query selector for which children should be focusable
        });
      }
    
      addListeners() {
        this.dom.container.addEventListener(
          'keydown',
          this.handleKeyDown.bind(this)
        );
        this.dom.triggers.forEach((trigger) =>
          trigger.addEventListener('click', this.handleClick.bind(this))
        );
    
        this.dom.panels.forEach((el) =>
          el.addEventListener('transitionend', this.handleTransitionEnd.bind(this))
        );
      }
    
      initAccordion() {
        this.dom.items.forEach((item) => {
          const guid = uuidv4();
    
          const trigger = item.querySelector('.accordion__item-trigger');
          const content = item.querySelector('.accordion__item-panel');
    
          if (trigger.getAttribute('aria-expanded') === 'true') {
            const height = content.querySelector(
              '.accordion__item-content'
            ).offsetHeight;
    
            content.style.height = `${height}px`;
            content.style.visibility = 'visible';
          }
    
          trigger.setAttribute('aria-controls', `tabcontent-${guid}`);
          trigger.setAttribute('id', `tab-${guid}`);
          content.setAttribute('aria-labelledby', `tab-${guid}`);
          content.setAttribute('id', `tabcontent-${guid}`);
        })
      }
    
      handleClick(e) {
        const button = e.currentTarget;
    
        if (button.getAttribute('aria-expanded') === 'true') {
          this.closeItem(button);
        } else {
          this.openItem(button);
        }
      }
    
      handleKeyDown(e) {
        const target = e.target;
        const key = e.which || e.keyCode;
    
        const ctrlModifier =
          e.ctrlKey && (key === keyCode.PAGEUP || key === keyCode.PAGEDOWN);
    
        if (target.classList.contains('accordion__item-trigger')) {
          if (key === keyCode.UP || key === keyCode.DOWN || ctrlModifier) {
            const index = this.dom.triggers.indexOf(target);
            const direction =
              key === keyCode.PAGEDOWN || key === keyCode.DOWN ? 1 : -1;
            const length = this.dom.triggers.length;
            const newIndex = (index + length + direction) % length;
    
            this.dom.triggers[newIndex].focus();
    
            e.preventDefault()
          } else if (key === keyCode.END || key === keyCode.HOME) {
            switch (key) {
              case keyCode.HOME:
                this.dom.triggers[0].focus();
                break;
              case keyCode.END:
                this.dom.triggers[this.dom.triggers.length - 1].focus();
                break;
            }
            e.preventDefault();
          }
        }
      }
    
      openItem(trigger) {
        const content = document.getElementById(
          trigger.getAttribute('aria-controls')
        );
    
        trigger.setAttribute('aria-expanded', true);
        content.style.visibility = 'visible';
        const height = content.querySelector(
          '.accordion__item-content'
        ).offsetHeight;
    
        content.style.maxHeight = `${height}px`;
        content.style.visibility = 'visible';
        this.open(content);
      }
    
      closeItem(trigger) {
        const content = document.getElementById(
          trigger.getAttribute('aria-controls')
        );
    
        trigger.setAttribute('aria-expanded', false);
        content.style = null;
        this.close(content);
      }
    
      open(el) {
        el.style.height = `${el.scrollHeight}px`;
      }
    
      close(el) {
        el.style.height = `${el.scrollHeight}px`;
        el.style.height = 0;
      }
    
      handleTransitionEnd(e) {
        const el = e.target;
        const height = el.style.height;
        if (height !== '0' || height !== 0) {
          el.style.height = 'auto';
        }
      }
    }
    
    export default Accordion
    
  • URL: /components/raw/c-fmt-1-accordions-module/Accordion.js
  • Filesystem Path: src/components/C-FMT-1-accordions-module/Accordion.js
  • Size: 4.4 KB
  • Content:
    @import '../theme', 'variables';
    
    .accordion {
      margin-bottom: $accordion-mobile-margin-bottom;
      margin-top: $accordion-mobile-margin-top;
    
      @include mq(desktop) {
        margin-bottom: $accordion-desktop-margin-bottom;
        margin-top: $accordion-desktop-margin-top;
      }
    }
    
    .accordion__header {
      margin-bottom: 29px;
    
      @include mq(desktop) {
        margin-bottom: 60px;
      }
    }
    
    .accordion__title {
      font-family: $accordion-item-title-font-family;
      font-size: 30px;
      font-weight: 700;
      line-height: 1.13;
      margin: 0 0 10px;
    
      @include mq(desktop) {
        font-size: 40px;
        line-height: 1.09;
      }
    
      @include mq(wide) {
        font-size: 44px;
      }
    }
    
    .accordion__description {
      @include mq(desktop) {
        max-width: calc(66% - 51px);
      }
    }
    
    .accordion__item {
      border: $accordion-item-border;
    
      & + .accordion__item {
        margin-top: 20px;
    
        @include mq(desktop) {
          margin-top: 30px;
        }
      }
    }
    
    .accordion__item-trigger {
      align-items: center;
      appearance: none;
      background-color: transparent;
      border: 0;
      border-radius: 0;
      cursor: pointer;
      display: flex;
      height: auto;
      justify-content: space-between;
      min-height: 60px;
      padding: 9px 20px;
      text-align: left;
      transition: background-color 0.2s ease-in-out;
      width: 100%;
    
      @include mq(desktop) {
        height: 50px;
        padding: 0 25px;
      }
    
      @media (any-hover: hover) {
        &:hover,
        &:focus {
          background-color: $accordion-item-focus-background;
          color: $accordion-item-focus-text-color;
    
          .accordion__item-icon-plus,
          .accordion__item-icon-minus {
            fill: $accordion-item-focus-text-color;
          }
        }
      }
    
      &[aria-expanded='true'] {
        .accordion__item-icon-plus {
          display: none;
        }
    
        .accordion__item-icon-minus {
          display: block;
        }
      }
    }
    
    .accordion__item-title {
      font-family: $accordion-item-font-family;
      font-size: 18px;
      font-weight: 600;
      line-height: 1.78;
      margin: 0;
      transition: color 0.2s ease-in-out;
    }
    
    .accordion__item-icon {
      flex-shrink: 0;
      height: 14px;
      position: relative;
      width: 14px;
    }
    
    .accordion__item-icon-plus,
    .accordion__item-icon-minus {
      fill: $accordion-item-icon-fill;
      height: 14px;
      left: 50%;
      position: absolute;
      top: 50%;
      transform: translate(-50%, -50%);
      transition: fill 0.2s ease-in-out;
      width: 14px;
    }
    
    .accordion__item-icon-minus {
      display: none;
    }
    
    .accordion__item-panel {
      height: 0;
      overflow: hidden;
      visibility: hidden;
      transition: height 0.25s ease;
    
      video,
      picture,
      img,
      iframe {
        width: 100%;
      }
    }
    
    .accordion__item-content {
      font-size: 18px;
      line-height: 1.78;
      padding: 2px 20px 20px;
    
      @include mq(desktop) {
        padding: 28px 100px 45px;
      }
    
      * {
        & + video,
        & + picture,
        & + img,
        & + iframe,
        & + .buttons-row {
          margin-top: 20px;
    
          @include mq(desktop) {
            margin-top: 60px;
          }
        }
      }
    
      .buttons-row {
        margin-left: -10px;
        margin-right: -10px;
    
        .btn {
          margin: 10px;
        }
      }
    }
    
    .accordion__item-description {
      h4 {
        font-family: $accordion-item-heading-font-family;
        font-size: 21px;
        font-weight: 700;
        line-height: 1.19;
        margin: 0 0 10px;
    
        @include mq(desktop) {
          font-size: 19px;
          line-height: 1.33;
        }
    
        @include mq(wide) {
          font-size: 24px;
        }
      }
    }
    
    .accordion__video {
      iframe {
        margin-top: 10px;
      }
    }
    
  • URL: /components/raw/c-fmt-1-accordions-module/_styles.scss
  • Filesystem Path: src/components/C-FMT-1-accordions-module/_styles.scss
  • Size: 3.4 KB
  • Content:
    $accordion-mobile-margin-bottom: map-get($module-spacing, "mobile") !default;
    $accordion-mobile-margin-top: map-get($module-spacing, "mobile") !default;
    $accordion-desktop-margin-bottom: map-get($module-spacing, "desktop") !default;
    $accordion-desktop-margin-top: map-get($module-spacing, "desktop") !default;
    $accordion-item-border: solid 1px map-get($theme-colors, "primary") !default;
    $accordion-item-focus-background: map-get($theme-colors, "primary") !default;
    $accordion-item-focus-text-color: #FFF !default;
    $accordion-item-font-family: $primary-font !default;
    $accordion-item-title-font-family: $secondary-font !default;
    $accordion-item-heading-font-family: $secondary-font !default;
    $accordion-item-icon-fill: map-get($theme-colors, "primary") !default;
    
  • URL: /components/raw/c-fmt-1-accordions-module/_variables.scss
  • Filesystem Path: src/components/C-FMT-1-accordions-module/_variables.scss
  • Size: 763 Bytes
  • Handle: @c-fmt-1-accordions-module
  • Preview:
  • Filesystem Path: src/components/C-FMT-1-accordions-module/C-FMT-1-accordions-module.hbs
  • References (1): @video

Accordion

An accordion is a vertically stacked set of elements, such as labels or thumbnails, that allow the user to toggle the display of sections of content. Each labeling element can be expanded or collapsed to reveal or hide its associated content. Accordions are commonly used to reduce the need to scroll when presenting multiple sections of content on a single page.

This component is WAI-ARIA compliant and is AA compliant.

Keyboard interactions

When focus is on a header, the following key commands are available:

  • TAB: When focus moves into the accordion, places focus on the active tab element. When the tab list contains the focus, moves focus to the next element in the tab sequence, which is the tabpanel element.
  • UP: Move focus to the previous header. If on first header, moves focus to last header.
  • DOWN: Move focus to the next header. If on last header, moves focus to first header.
  • SPACE/ENTER/RETURN: Open/close a panel associated with focused header.
  • SHIFT + TAB: Moves focus to the previous focusable element.
  • HOME: Move focus to the first header.
  • END: Move focus to the last header.

Styling

The component will already have a default style/theme set, so it will work out of the box. The button has a set of variables that may be overriden, or you may choose to just override the actual styles in your project. It is recommended to use the overrides if you can as it will be less code in your project.

Below is the list of variables you can override. You may also find these in the Assets tab under _variables.scss

$accordion-mobile-margin-bottom
$accordion-mobile-margin-top
$accordion-desktop-margin-bottom
$accordion-desktop-margin-top
$accordion-item-border
$accordion-item-focus-background
$accordion-item-focus-text-color
$accordion-item-font-family
$accordion-item-title-font-family
$accordion-item-heading-font-family
$accordion-item-icon-fill

You always need to set your overrides before the import of you component - for example:

$accordion-mobile-margin-bottom: 20px;
$accordion-mobile-margin-top: 40px;

@import "../../node_modules/@verndale/front-end-components/lib/accotdion/styles";

Instantiation