API Docs for:
Show:

File: development/modules/tabs/js/tabs.js

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


/**
 * @module Modules
 */


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



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

        this.$tabNodes = this.$findChilds('[data-tabbox-action]');
        this.$contentNodes = this.$findChilds('[data-tabbox-effect]');
        this.$bodyNode = this.$findChilds('.tabbox_body');
        this.$maskNode = $('<div></div>').addClass('tabbox_mask');
    }
    /**
     * Creates a new Tabbox instance without the "new" keyword but does not
     *     initialize it
     * @method of
     * @static
     * @for Modules.Tabbox
     * @param {node|string|configs} node Node, CSS selector or configuration object
     * @return {Tabbox} A new instance
     * 
     * @example
     *     import Tabbox from './modules/tabs/js/tabs';
     *
     *     const myTabbox = Tabbox.of('[data-widget=Tabbox]');
     *     myTabbox.render().startUp();
     */
    static of (node) {
        return new Tabbox(node);
    }
    /**
     * Finds and initializes all Tabbox on a page at once
     * @method findAll
     * @static
     * @for Modules.Tabbox
     * @param {string} selector CSS selector to match nodes against
     * @return {array} A list of instances
     * 
     * @example
     *     import Tabbox from './modules/tabs/js/tabs';
     *
     *     Tabbox.findAll('[data-widget=Tabbox]');
     */
    static findAll(selector) {
        return $(selector).toArray().map((node) => {
            const tabbox = Tabbox.of(node);
            tabbox.render().startUp();
            return tabbox;
        });
    }

    /**
     * Renders missing nodes into the instance and returns it
     * @method render
     * @for Modules.Tabbox
     * @return {this} The instance
     * 
     * @example
     *     import Tabbox from './modules/tabs/js/tabs';
     *
     *     const myTabbox = Tabbox.of('[data-widget=Tabbox]');
     *     myTabbox.render();
     */
    render() {
        const contents = this.$contentNodes.detach();
        this.$maskNode.
            append(contents).
            css('height', '0').
            addClass('tabbox_mask--hidden');
        this.$bodyNode.append(this.$maskNode);

        return this;
    }

    /**
     * Attaches all eventlisteners to the tabbox instance and opens the one tab
     *     that holds the class `is-active`. If more than one tab in the same
     *     tabbox hold the class `is-active`, the first one is being activated.
     *     If none of the tabs in one tabbox hold the class `is-active`, the 
     *     first tab is being activated
     * @method startUp
     * @for Modules.Tabbox
     * @return {undefined} Nothing
     * 
     * @example
     *     import Tabbox from './modules/tabs/js/tabs';
     *
     *     const myTabbox = Tabbox.of('[data-widget=Tabbox]');
     *     myTabbox.render().startUp();
     */
    startUp() {
        const activeTabs = this.$tabNodes.
            toArray().
            filter((tab) => $(tab).hasClass('is-active'));

        if (activeTabs.length > 0) {
            this.hideAll();
            this.show($(activeTabs[0]));
        } else {
            this.show(this.$tabNodes.first());
        }

        this.onClick('[data-tabbox-action]', handleClick);
    }
    

    /**
     * Sets all tabs to inactive state when one tab is being opened
     * @method hideAll
     * @for Modules.Tabbox
     * @return {undefined} Nothing
     * 
     * @example
     *     import Tabbox from './modules/tabs/js/tabs';
     *
     *     const myTabbox = Tabbox.of('[data-widget=Tabbox]');
     *     myTabbox.render().startUp();
     *
     *     myTabbox.hideAll();
     */
    hideAll() {
        this.$tabNodes.removeClass('is-active');
        this.$contentNodes.removeClass('is-active');
    }

    /**
     * Sets the tab and its content to active state
     * @method show
     * @for Modules.Tabbox
     * @param {node} node Node
     * @return {undefined} Nothing
     * 
     * @example
     *     import Tabbox from './modules/tabs/js/tabs';
     *
     *     const myTabbox = Tabbox.of('[data-widget=Tabbox]');
     *     myTabbox.render().startUp();
     *
     *     myTabbox.show($('[href="#tab-a"]'));
     */
    show($tab) {
        const ref = $tab.attr('href').split("#")[1];
        const $content = $('[id="' + ref +'"]');

        if (!$content.length) {
            throw `Tabbox: Unable to find matching content for tab "#${ref}"`
        }

        $content.addClass('is-active');
        $tab.addClass('is-active');

        this.$maskNode.css({
            height: $content.outerHeight()
        });
    }

    // === EVENT HANDLERS ===
    [handleClick](event) {
        event.preventDefault();

        this.hideAll();
        this.show($(event.currentTarget));
    }
}

export default Tabbox;