API Docs for:
Show:

File: development/modules/accordion/js/list.js

import $ from 'jquery';
import DOMModule from '../../__base/dommodule';
import Accordion from './accordion';

/** @module Modules */

const AccordionListStates = [
    {name: 'init', events: {render: 'rendered'}},
    {name: 'rendered', events: {start: 'running'}},
    {name: 'running', events: {}}
];

// PRIVATE METHODS
const handleClick = Symbol('_handleClick');



/**
 * AccordionList module
 * @class Modules.AccordionList
 * @constructor
 * @extends Modules._DOMModule
 */
class AccordionList extends DOMModule {
    constructor(options) {
        super(options);

        this.addStates(AccordionListStates);
        this.autoOpenFirst = this.$data('accordion-openfirst') || false;
    }
    /**
     * Creates a new AccordionList instance without the "new" keyword but does not
     *     initialize it
     * @method of
     * @static
     * @for Modules.AccordionList
     * @param {node|string|configs} node Node, CSS selector or configuration object
     * @return {AccordionList} A new instance
     * 
     * @example
     *     import AccordionList from './modules/accordion/js/list';
     *
     *     const myList = AccordionList.of('[data-widget=AccordionList]');
     *     myList.render().startUp();
     */
    static of (node) {
        return new AccordionList(node);
    }
    /**
     * Finds and initializes all AccordionLists on a page at once
     * @method findAll
     * @static
     * @for Modules.AccordionList
     * @param {string} selector CSS selector to match nodes against
     * @return {array} A list of instances
     * 
     * @example
     *     import AccordionList from './modules/accordion/js/list';
     *
     *     AccordionList.findAll('[data-widget=AccordionList]');
     */
    static findAll(selector) {
        return $(selector).toArray().map((node) => {
            const acc = AccordionList.of(node);
            acc.render().startUp();
            return acc;
        });
    }
    /**
     * Renders the inner Accordion instances and starts them
     * @method render
     * @for Modules.AccordionList
     * @return {this} The instance
     * 
     * @example
     *     import AccordionList from './modules/accordion/js/list';
     *
     *     const myList = AccordionList.of('[data-widget=AccordionList]');
     *     myList.render();
     */
    render() {
        if (this.getState() === 'init') {
            this.consume('render');
            this.$accordions = this.$findChilds('[data-widget="Accordion"]').
                toArray().
                map((node) => {
                    const accordion = Accordion.of(node);
                    accordion.render().startUp();
                    return accordion;
                });
            this.activeAccordion = this.$accordions[0];
        }
        return this;
    }
    /**
     * Attaches eventlisteners to the instance
     * @method startUp
     * @for Modules.AccordionList
     * @return {undefined} Nothing
     * 
     * @example
     *     import AccordionList from './modules/accordion/js/list';
     *
     *     const myList = AccordionList.of('[data-widget=AccordionList]');
     *     myList.render().startUp();
     */
    startUp() {
        if (this.getState() === 'rendered') {
            this.consume('start');
            this.onClick('[data-accordion-action]', handleClick);

            if (this.autoOpenFirst) {
                this.activeAccordion.show();
            }
        }
    }
    // === PRIVATE STUFF ===
    /**
     * Used when an inner accordion is clicked. Takes a DOMNode and returns the
     *     accordion which contains the node or null
     * @method _getClicked
     * @for Modules.AccordionList
     * @private
     * @param {DOMNode} node The node to match against
     * @return {Accordion|null} The matched instance or nothing
     */
    _getClicked(node) {
        return this.$accordions.reduce((match, acc) => {
            return !match && acc.$headNode[0] === node ? acc : match;
        }, null);
    }
    // === EVENT HANDLERS ===
    [handleClick](event) {
        if (event.currentTarget === this.activeAccordion.$headNode[0]) {
            return null;
        }
        this.activeAccordion.hide();

        this.activeAccordion = this._getClicked(event.currentTarget);
        this.activeAccordion.show();
    }
}



export default AccordionList;