<link media="all" rel="stylesheet" href="/assets/themes/default/css/accordion.css?cb=">

<h2 class="accordion__heading">Section 1</h2>

<div class="accordion" data-module="accordion" data-hide-all-on-open="false">
    <div data-accordion-title class="accordion__title">item 1 title <span class="icon-toggle js-toggle"></span></div>
    <div data-accordion-panel class="accordion__panel">
        <div class="richtext">
            <p><strong>a piece of bold text here</strong> and some more lorem ipsum and <em>a piece of italic text here</em></p>
        </div>
    </div>
    <div data-accordion-title class="accordion__title">item 2 title <span class="icon-toggle js-toggle"></span></div>
    <div data-accordion-panel class="accordion__panel">
        <div class="richtext">
            <p><strong> a piece of bold text here</strong> and some more lorem ipsum and <em>a piece of italic text here</em></p>
        </div>
    </div>
    <div data-accordion-title class="accordion__title">item 3 title <span class="icon-toggle js-toggle"></span></div>
    <div data-accordion-panel class="accordion__panel">
        <div class="richtext">
            <p><strong> a piece of bold text here</strong> and some more lorem ipsum and <em>a piece of italic text here</em></p>
        </div>
    </div>
</div>
{{#if firstInstance}}
<link media="all" rel="stylesheet" href="/assets/themes/{{theme}}/css/accordion.css?cb={{cacheBuster}}">
{{/if}}

{{#if title}}
<h2 class="accordion__heading">{{title}}</h2>
{{/if}}

<div class="accordion" data-module="accordion" data-hide-all-on-open="{{hideAllOnOpen}}">
    {{#each items}}
        <div data-accordion-title class="accordion__title">{{#if title}}{{title}}{{else}}&nbsp;{{/if}} <span class="icon-toggle js-toggle"></span></div>
        <div data-accordion-panel class="accordion__panel">{{> @rich-text html=content}}</div>
    {{/each}}
</div>
{
  "theme": "default",
  "firstInstance": true,
  "hideAllOnOpen": false,
  "title": "Section 1",
  "items": [
    {
      "title": "item 1 title",
      "content": "<p><strong>a piece of bold text here</strong> and some more lorem ipsum and <em>a piece of italic text here</em></p>"
    },
    {
      "title": "item 2 title",
      "content": "<p><strong> a piece of bold text here</strong> and some more lorem ipsum and <em>a piece of italic text here</em></p>"
    },
    {
      "title": "item 3 title",
      "content": "<p><strong> a piece of bold text here</strong> and some more lorem ipsum and <em>a piece of italic text here</em></p>"
    }
  ]
}
  • Content:
    import { addClass, removeClass, hasClass } from '../../../../js/utils/_helpers';
    import addToDataLayer from '../../../../js/utils/datalayer';
    
    export class Accordion {
        constructor(module) {
            this.titles = module.querySelectorAll('[data-accordion-title]');
            this.panels = module.querySelectorAll('[data-accordion-panel]');
            this.hideAllOnOpen = module.dataset.hideAllOnOpen && module.dataset.hideAllOnOpen.toLowerCase() === 'true';
    
            this.titles.forEach((title) => {
                title.setAttribute('tabindex', '0');
                title.addEventListener('click', (e) => {
                    if (hasClass(e.target, 'is-open')) {
                        Accordion.hidePanel(e.target);
                    } else {
                        this.showPanel(e.target);
                    }
                });
                title.querySelector('.js-toggle').addEventListener('click', () => {
                    if (hasClass(title, 'is-open')) {
                        Accordion.hidePanel(title);
                    } else {
                        this.showPanel(title);
                    }
                });
                title.addEventListener('keypress', (e) => {
                    if (e.keyCode === 32 || e.keyCode === 13) { // space bar || enter
                        if (hasClass(e.target, 'is-open')) {
                            Accordion.hidePanel(e.target);
                        } else {
                            this.showPanel(e.target);
                        }
                    }
                });
            });
        }
    
        static hidePanel(title) {
            removeClass(title, 'is-open');
            removeClass(title.nextElementSibling, 'is-open');
        }
    
        showPanel(title) {
            Accordion.trackClick(title);
            if (this.hideAllOnOpen) {
                // remove show state on titles
                this.titles.forEach((t) => {
                    removeClass(t, 'is-open');
                });
                // remove show state on content
                this.panels.forEach((panel) => {
                    removeClass(panel, 'is-open');
                });
            }
    
            addClass(title, 'is-open');
            addClass(title.nextElementSibling, 'is-open');
        }
    
        static trackClick(title) {
            addToDataLayer({
                'event': 'link.click',
                'linkName': title.innerText,
                'linkType': 'accordion',
            });
        }
    }
    
    export default (module) => new Accordion(module);
    
  • URL: /components/raw/accordion/accordion.js
  • Filesystem Path: source/patterns/03-components/text/accordion/accordion.js
  • Size: 2.4 KB
  • Content:
    @import 'source/scss/01-settings/_import';
    @import 'source/scss/02-tools/_import';
    
    [data-accordion-title] {
        cursor: pointer;
    }
    
    .accordion {
        &__heading {
            @extend %heading02;
        }
    
        &__panel {
            border-bottom: 1px solid;
            display: none;
            padding: 0 30px 30px 0;
    
            &.is-open {
                display: block;
            }
    
            p:last-of-type {
                margin-bottom: 0;
                padding-bottom: 0;
            }
        }
    
        &__title {
            @extend %heading03;
            border-bottom: 1px solid;
            outline: none;
            padding: 20px 80px 20px 0;
            position: relative;
    
            .icon-toggle {
                border-style: solid;
                border-width: .1em .1em 0 0;
                content: '';
                display: inline-block;
                height: .85em;
                position: absolute;
                right: 10px;
                top: 20px;
                transform: rotate(135deg);
                transition: all .3s;
                vertical-align: top;
                width: .85em;
                z-index: -1;
            }
    
            &.is-open {
                border-bottom: 0;
    
                .icon-toggle {
                    top: 20px;
                    transform: rotate(-45deg);
                }
            }
        }
    }
    
  • URL: /components/raw/accordion/accordion.scss
  • Filesystem Path: source/patterns/03-components/text/accordion/accordion.scss
  • Size: 1.2 KB

No notes defined.