Copy environment

Accordion

<div class="accordion js-accordion-group  ">
    <div class="accordion__item js-accordion" id="accordion-item-1">
        <a href="#accordion-item-1" class="accordion__header js-accordion-control">
            <svg class="icon  accordion__icon" focusable="false">
                <use href="../../inc/svg/global.4609ec92109fc41e7ad4764ef897ea8e.svg#chevron-bottom"></use>
            </svg>
            <div class="accordion__title">Mis juhtub siis, kui ma ei saa kaupa valitud ajaks tagastatud?</div>
        </a>
        <div class="accordion__content js-accordion-content">
            <div class="accordion__inner">
                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 nisi ut aliquip ex ea commodo consequat. 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 id est laborum.
            </div>
        </div>
    </div>
    <div class="accordion__item js-accordion" id="accordion-item-2">
        <a href="#accordion-item-2" class="accordion__header js-accordion-control">
            <svg class="icon  accordion__icon" focusable="false">
                <use href="../../inc/svg/global.4609ec92109fc41e7ad4764ef897ea8e.svg#chevron-bottom"></use>
            </svg>
            <div class="accordion__title">Kuidas toimub kauba tagastamine? </div>
        </a>
        <div class="accordion__content js-accordion-content">
            <div class="accordion__inner">
                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 nisi ut aliquip ex ea commodo consequat. 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 id est laborum.
            </div>
        </div>
    </div>
    <div class="accordion__item js-accordion" id="accordion-item-3">
        <a href="#accordion-item-3" class="accordion__header js-accordion-control">
            <svg class="icon  accordion__icon" focusable="false">
                <use href="../../inc/svg/global.4609ec92109fc41e7ad4764ef897ea8e.svg#chevron-bottom"></use>
            </svg>
            <div class="accordion__title">Kus ma näen transpordikulu?</div>
        </a>
        <div class="accordion__content js-accordion-content">
            <div class="accordion__inner">
                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 nisi ut aliquip ex ea commodo consequat. 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 id est laborum.
            </div>
        </div>
    </div>
    <div class="accordion__item js-accordion" id="accordion-item-4">
        <a href="#accordion-item-4" class="accordion__header js-accordion-control">
            <svg class="icon  accordion__icon" focusable="false">
                <use href="../../inc/svg/global.4609ec92109fc41e7ad4764ef897ea8e.svg#chevron-bottom"></use>
            </svg>
            <div class="accordion__title">Kuidas saan katkestada või muuta tellimust?</div>
        </a>
        <div class="accordion__content js-accordion-content">
            <div class="accordion__inner">
                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 nisi ut aliquip ex ea commodo consequat. 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 id est laborum.
            </div>
        </div>
    </div>
</div>
<div class="accordion js-accordion-group {{ modifier }} {{ class }}">
    {% if data.items %}
        {% for item in data.items %}
            <div class="accordion__item js-accordion" id="{{ item.id }}">
                <a href="#{{ item.id }}" class="accordion__header js-accordion-control">
                    {% include '@icon' with { class: 'accordion__icon', modifier: '', name: 'chevron-bottom' } %}
                    <div class="accordion__title">{{ item.title }}</div>
                </a>
                <div class="accordion__content js-accordion-content">
                    <div class="accordion__inner">
                        {{ item.content }}
                    </div>
                </div>
            </div>
        {% endfor %}
    {% endif %}
</div>
{
  "language": "en-US",
  "data": {
    "items": [
      {
        "id": "accordion-item-1",
        "title": "Mis juhtub siis, kui ma ei saa kaupa valitud ajaks tagastatud?",
        "content": "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 nisi ut aliquip ex ea commodo consequat. 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 id est laborum."
      },
      {
        "id": "accordion-item-2",
        "title": "Kuidas toimub kauba tagastamine? ",
        "content": "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 nisi ut aliquip ex ea commodo consequat. 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 id est laborum."
      },
      {
        "id": "accordion-item-3",
        "title": "Kus ma näen transpordikulu?",
        "content": "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 nisi ut aliquip ex ea commodo consequat. 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 id est laborum."
      },
      {
        "id": "accordion-item-4",
        "title": "Kuidas saan katkestada või muuta tellimust?",
        "content": "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 nisi ut aliquip ex ea commodo consequat. 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 id est laborum."
      }
    ]
  }
}
  • Content:
    .accordion__item {
        font-size: $font-size-base;
        line-height: $line-height-base;
        letter-spacing: $letter-spacing-50;
    
        + .accordion__item {
            margin-top: 16px;
        }
    }
    
    .accordion__header {
        display: block;
        position: relative;
        padding: 0 0 0 32px;
        background: transparent;
        color: $L-text;
        font-weight: $font-weight-regular;
        text-decoration: none;
    
        &:focus {
            color: initial;
        }
    
        &:hover {
            color: $L-link-hover;
        }
    
        .accordion__item.is-open > & {
            font-weight: $font-weight-medium;
        }
    }
    
    .accordion__content {
        display: none;
    
        html.no-js &,
        .accordion__item.is-open > & {
            display: block;
        }
    }
    
    .accordion__inner {
        padding: 16px 0 0 32px;
    }
    
    .accordion__icon {
        position: absolute;
        top: 0;
        left: 0;
        font-size: 24px;
        transition: transform $transition-duration $transition-easing;
    
        .accordion__item.is-open > .accordion__header > & {
            transform: rotate(180deg);
        }
    }
    
  • URL: /components/raw/accordion/accordion.scss
  • Filesystem Path: src/patterns/components/accordion/accordion.scss
  • Size: 1 KB
  • Content:
    import Helpers from '../helpers/helpers';
    
    import './accordion.scss';
    
    export enum AccordionAnimationType {
        slide,
        fadeAndSlide,
    }
    
    export enum AccordionAnimationDirection {
        in,
        out,
    }
    
    export interface IAccordionSettings {
        openClass?: string;
        accordionClass?: string;
        groupClass?: string;
        controlClass?: string;
        contentClass?: string;
        animationSlideTime?: number;
        animationFadeTime?: number;
        scrollDelay?: number;
        animationSlideEase?: string;
        animationFadeEase?: string;
        animationType?: AccordionAnimationType;
    }
    
    export const accordionSettings: IAccordionSettings = {
        accordionClass: 'js-accordion',
        animationFadeEase: 'swing',
        animationFadeTime: 300,
        animationSlideEase: 'swing',
        animationSlideTime: 300,
        animationType: AccordionAnimationType.slide,
        contentClass: 'js-accordion-content',
        controlClass: 'js-accordion-control',
        groupClass: 'js-accordion-group',
        openClass: 'is-open',
        scrollDelay: 300,
    };
    
    export default class Accordion {
    
        settings: IAccordionSettings;
        element: JQuery;
    
        constructor(target: HTMLElement, settings: IAccordionSettings = {}) {
            this.settings = jQuery.extend(accordionSettings, settings) as IAccordionSettings;
            this.element = $(target);
        }
    
        getAccordion(): JQuery {
            let accordion: JQuery;
    
            if (this.element.hasClass(this.settings.accordionClass)) {
                accordion = this.element.addClass(this.settings.accordionClass);
            } else {
                accordion = this.element.parents('.' + this.settings.accordionClass);
            }
    
            return accordion.length ? $(accordion.get(0)) : accordion;
        }
    
        toggle(accordion: JQuery = this.getAccordion()): void {
            if (accordion.length) {
                if (accordion.hasClass(this.settings.openClass)) {
                    this.close(accordion);
                } else {
                    this.open(accordion);
                }
            }
        }
    
        open(accordion: JQuery = this.getAccordion(), recursive: boolean = false, initialLoad: boolean = false): void {
            if (accordion?.length) {
                this.closeOpen(accordion, recursive);
                const parent: JQuery = accordion.parents('.' + this.settings.accordionClass);
    
                if (parent.length) {
                    const parentAccordion: Accordion = new Accordion(parent.get(0));
    
                    parentAccordion.open(null, true, initialLoad);
                }
                accordion.addClass(this.settings.openClass);
                const content: JQuery = accordion.find('.' + this.settings.contentClass);
    
                if (content.length) {
                    if (!recursive) {
                        setTimeout((): void => {
                            if (!Helpers.isOnScreen($(content.get(0)))) {
                                Helpers.scrollToTarget(accordion);
                            }
                        }, this.settings.scrollDelay);
                    }
                }
                if (!recursive && !initialLoad) {
                    this.animate(AccordionAnimationDirection.in, accordion);
                }
            }
        }
    
        close(accordion: JQuery = this.getAccordion(), recursive: boolean = false): void {
            if (accordion.length) {
                if (!recursive) {
                    this.animate(AccordionAnimationDirection.out, accordion, (): void => {
                        accordion.removeClass(this.settings.openClass);
                    });
                } else {
                    accordion.removeClass(this.settings.openClass);
                }
            }
        }
    
        closeOpen(accordion: JQuery = this.getAccordion(), recursive: boolean = false): void {
            let group: JQuery = accordion.parents('.' + this.settings.groupClass);
    
            if (group.length) {
                group = $(group.get(0));
                const open: JQuery = group.find('> .' + this.settings.accordionClass + '.' + this.settings.openClass);
    
                open.each((index: number, element: HTMLElement): void => {
                    this.close($(element), recursive);
                });
            }
        }
    
        animate(type: AccordionAnimationDirection, accordion: JQuery = this.getAccordion(), onComplete: () => void = null): void {
            if (accordion.length) {
                let content: JQuery = accordion.find('.' + this.settings.contentClass);
                const triggerOnComplete: () => void = (): void => {
                    content.removeAttr('style');
                    if (onComplete) {
                        onComplete();
                    }
                };
    
                if (content.length) {
                    const contentHeight: string = content.get(0).offsetHeight + 'px';
    
                    content = content.length ? $(content.get(0)) : content;
                    switch (this.settings.animationType) {
                        case AccordionAnimationType.slide:
                            switch (type) {
                                case AccordionAnimationDirection.in:
                                    content.stop().css({
                                        height: 0,
                                    }).animate({
                                        height: contentHeight,
                                    }, this.settings.animationFadeTime, this.settings.animationFadeEase, triggerOnComplete);
                                    break;
                                case AccordionAnimationDirection.out:
                                    content.stop().animate({
                                        height: 0,
                                    }, this.settings.animationSlideTime, this.settings.animationSlideEase, triggerOnComplete);
                                    break;
                            }
                            break;
                        case AccordionAnimationType.fadeAndSlide:
                            switch (type) {
                                case AccordionAnimationDirection.in:
                                    content.stop().css({
                                        height: 0,
                                        opacity: 0,
                                    }).animate({
                                        height: contentHeight,
                                    }, this.settings.animationSlideTime, this.settings.animationSlideEase, (): void => {
                                        content.stop().animate({
                                            opacity: 1,
                                        }, this.settings.animationFadeTime, this.settings.animationFadeEase, triggerOnComplete);
                                    });
                                    break;
                                case AccordionAnimationDirection.out:
                                    content.stop().animate({
                                        opacity: 0,
                                    }, this.settings.animationFadeTime, this.settings.animationFadeEase, (): void => {
                                        content.stop().animate({
                                            height: 0,
                                        }, this.settings.animationSlideTime, this.settings.animationSlideEase, triggerOnComplete);
                                    });
                                    break;
                            }
                            break;
                    }
                }
            }
        }
    }
    
    function onControlClick(event: JQuery.Event): void {
        event.preventDefault();
        const accordion: Accordion = new Accordion(this);
    
        accordion.toggle();
    }
    
    const onLoadHashCheck: () => void = (): void => {
        if (window.location.hash && $(window.location.hash).length && $(window.location.hash).hasClass(accordionSettings.accordionClass)) {
            const accordion: Accordion = new Accordion($(window.location.hash).get(0));
    
            accordion.open(null, false, true);
        }
    };
    
    $((): void => {
        $(document).on('click', '.' + accordionSettings.controlClass, onControlClick);
        onLoadHashCheck();
    });
    
  • URL: /components/raw/accordion/accordion.ts
  • Filesystem Path: src/patterns/components/accordion/accordion.ts
  • Size: 7.8 KB