Skip to content
Snippets Groups Projects
accordion-item.js 7.65 KiB
Newer Older
  • Learn to ignore specific revisions
  • Tuukka Turu's avatar
    Tuukka Turu committed
    import { Component, Prop, State, Element, h } from '@stencil/core';
    
    Tuukka Turu's avatar
    Tuukka Turu committed
    export class AccordionItem {
        constructor() {
            this.ready = false;
        }
        componentDidLoad() {
            this.ready = true;
        }
        render() {
    
    Tuukka Turu's avatar
    Tuukka Turu committed
            const containerId = this.el.parentElement.id;
    
    Tuukka Turu's avatar
    Tuukka Turu committed
            function collapseSection(element) {
                element.style.height = 0 + 'px';
                element.setAttribute('data-collapsed', 'true');
            }
            function expandSection(element) {
                element.style.height = element.scrollHeight + 'px';
                element.setAttribute('data-collapsed', 'false');
            }
    
    Tuukka Turu's avatar
    Tuukka Turu committed
            if (this.ready && containerId.length > 0) {
                document.querySelectorAll(`#${containerId}`).forEach(function (accordion) {
    
    Tuukka Turu's avatar
    Tuukka Turu committed
                    const allowMultiple = accordion.hasAttribute('data-allow-multiple');
                    const allowToggle = (allowMultiple) ? allowMultiple : accordion.hasAttribute('data-allow-toggle');
                    const triggers = Array.prototype.slice.call(accordion.querySelectorAll('.hy-accordion__button'));
                    accordion.addEventListener('click', function (event) {
                        let target = event.target;
                        if (target && target.classList.contains('hy-accordion__button')) {
                            let targetParent = target.closest('.hy-accordion__item');
                            let targetContent = targetParent.querySelectorAll('.hy-accordion__content')[0];
                            const isExpanded = target.getAttribute('aria-expanded') == 'true';
                            const active = accordion.querySelector('[aria-expanded="true"]');
                            if (!allowMultiple && active && active !== target) {
                                active.setAttribute('aria-expanded', 'false');
                                collapseSection(targetContent);
                                if (targetParent.classList.contains('hy-accordion__item__is-open')) {
                                    targetParent.classList.remove('hy-accordion__item__is-open');
                                }
    
    Tuukka Turu's avatar
    Tuukka Turu committed
                                accordion.querySelector(`#${active.getAttribute('aria-controls')}`).setAttribute('aria-hidden', 'true');
    
    Tuukka Turu's avatar
    Tuukka Turu committed
                                if (!allowToggle) {
                                    active.removeAttribute('aria-disabled');
                                }
                            }
                            if (!isExpanded) {
                                expandSection(targetContent);
                                target.setAttribute('aria-expanded', 'true');
                                targetParent.classList.add('hy-accordion__item__is-open');
    
    Tuukka Turu's avatar
    Tuukka Turu committed
                                accordion.querySelector(`#${target.getAttribute('aria-controls')}`).setAttribute('aria-hidden', 'false');
    
    Tuukka Turu's avatar
    Tuukka Turu committed
                                if (!allowToggle) {
                                    target.setAttribute('aria-disabled', 'true');
                                }
                            }
                            else if (allowToggle && isExpanded) {
                                target.setAttribute('aria-expanded', 'false');
                                collapseSection(targetContent);
                                if (targetParent.classList.contains('hy-accordion__item__is-open')) {
                                    targetParent.classList.remove('hy-accordion__item__is-open');
                                }
    
    Tuukka Turu's avatar
    Tuukka Turu committed
                                accordion.querySelector(`#${target.getAttribute('aria-controls')}`).setAttribute('aria-hidden', 'true');
    
    Tuukka Turu's avatar
    Tuukka Turu committed
                            }
                            event.preventDefault();
    
                            event.stopImmediatePropagation();
    
    Tuukka Turu's avatar
    Tuukka Turu committed
                        }
                    });
                    if (accordion) {
                        accordion.addEventListener('keydown', function (event) {
                            const target = event.target;
                            const key = event.which.toString();
                            // 33 = Page Up, 34 = Page Down
                            const ctrlModifier = (event.ctrlKey && key.match(/33|34/));
                            if (target.classList.contains('hy-accordion__button')) {
                                // Up/ Down arrow and Control + Page Up/ Page Down keyboard operations
                                // 38 = Up, 40 = Down
                                if (key.match(/38|40/) || ctrlModifier) {
                                    const index = triggers.indexOf(target);
                                    const direction = (key.match(/34|40/)) ? 1 : -1;
                                    const length = triggers.length;
                                    const newIndex = (index + length + direction) % length;
                                    triggers[newIndex].focus();
                                    event.preventDefault();
                                }
                                else if (key.match(/35|36/)) {
                                    // 35 = End, 36 = Home keyboard operations
                                    switch (key) {
                                        // Go to first accordion
                                        case '36':
                                            triggers[0].focus();
                                            break;
                                        // Go to last accordion
                                        case '35':
                                            triggers[triggers.length - 1].focus();
                                            break;
                                    }
                                    event.preventDefault();
                                }
                            }
                        });
                        accordion.querySelectorAll('.hy-accordion__button').forEach(function (trigger) {
                            trigger.addEventListener('focus', function () {
                                trigger.classList.add('focus');
                            });
                            trigger.addEventListener('blur', function () {
                                trigger.classList.remove('focus');
                            });
                        });
                    }
                });
            }
            const classAttributes = ["hy-accordion__item"];
            const titleAsId = this.accordiontitle.toLowerCase().replace(/\W/g, '-');
            return (h("div", { class: classAttributes.join(" ") },
    
    Tuukka Turu's avatar
    Tuukka Turu committed
                h("div", { class: "hy-accordion--heading" },
    
    Tuukka Turu's avatar
    Tuukka Turu committed
                    h("button", { "aria-expanded": "false", "aria-controls": `${titleAsId}--content`, class: "hy-accordion__button", id: `${titleAsId}--title` },
                        h("span", { class: "hy-accordion--heading__icon" },
                            h("hy-icon", { icon: 'hy-icon-caret-down', size: 16 })),
                        this.accordiontitle)),
                h("div", { "aria-labelledBy": `${titleAsId}--title`, class: "hy-accordion__content", id: `${titleAsId}--content`, role: "region" },
                    h("div", { class: "hy-accordion__content--inner-wrapper" },
                        h("slot", null)))));
        }
        static get is() { return "hy-accordion-item"; }
        static get originalStyleUrls() { return {
            "$": ["accordion-item.scss"]
        }; }
        static get styleUrls() { return {
            "$": ["accordion-item.css"]
        }; }
        static get properties() { return {
            "accordiontitle": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "attribute": "accordiontitle",
                "reflect": false
            }
        }; }
        static get states() { return {
            "ready": {}
        }; }
    
    Tuukka Turu's avatar
    Tuukka Turu committed
        static get elementRef() { return "el"; }
    
    Tuukka Turu's avatar
    Tuukka Turu committed
    }