UNPKG

jcore-ui

Version:

jcore-ui - components for building an interface

204 lines 8.33 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const Component_1 = __importDefault(require("../core/Component")); const config_1 = __importDefault(require("../../config")); const JDom_1 = require("../core/JDom"); const selectors = { element: `.${config_1.default.prefix}-accordion`, panel: `.${config_1.default.prefix}-accordion-panel`, tab: `.${config_1.default.prefix}-accordion-tab`, content: `.${config_1.default.prefix}-accordion-content` }; class Accordion extends Component_1.default { constructor(props = {}) { super(Object.assign(Object.assign({}, props), { Component: Accordion, selectors: Object.assign(selectors, props.selectors || {}) })); if (this.options && this.options.mount) { this.mount(); } } mount() { if (!this.$element || this._mount || this.$element.hasAttr('data-mount')) { return; } ; super.mount(); this.options = Object.assign({ active: this.$element.dataset.active || false, multiple: this.$element.dataset.multiple || false, duration: this.$element.dataset.duration || 300 }, this.options); this.on = Object.assign({ toggle: () => { } }, this.on); this.handlers = { // change: this.change.bind(this), resize: this.resize.bind(this), toggle: this.toggle.bind(this) }; this.id = 0; this.$tab = null; this.isShow = false; this.isShowTabs = []; this.$tabs = JDom_1.$(this.$element).find(this.selectors.tab); this.addEvents(); this.on.mount(this); this.emitter.emit('mount', this); } addEvents() { this.$tabs.element.forEach((tab, i) => { const $tab = JDom_1.$(tab); const $panel = $tab.closest(this.selectors.panel); const $content = $panel.find(this.selectors.content); const id = this.setId($tab); $content.style.setProperty('transition', `height ease-in-out ${this.options.duration}ms`); this.isShowTabs.push({ tab, id, isShow: false }); if (this.options.active && i === 0) { this.toggle($tab, $content); } $tab.on('click', this.handlers.toggle); }); window.addEventListener('resize', this.handlers.resize); } unmount() { super.unmount(); this.$tabs.element.forEach(tab => JDom_1.$(tab).off('click', this.handlers.toggle, null)); window.removeEventListener('resize', this.handlers.resize); this.on.unmount(this); this.emitter.emit('unmount', this); } toggle(e, cont) { var _a; const tab = JDom_1.$((e instanceof HTMLElement ? e : e instanceof JDom_1.JDom ? e : e.target)).closest(this.selectors.tab); const panel = tab.closest(this.selectors.panel); const content = cont || panel.find(this.selectors.content); // Если последний активный таб не равен текущему, сбрасываем состояние if (((_a = this.$tab) === null || _a === void 0 ? void 0 : _a.dataset.id) !== tab.dataset.id && !this.options.multiple && this.$tabs.element.length > 1) { this.isShow = false; // если в аккордеоне несколько панелей, скрываем все, кроме текущей this.hideAll(tab); } // Если multiple не вклчюен, то у всех общее состояние if (!this.options.multiple) { if (this.isShow) { this.hide(tab, content); } else { this.show(tab, content); } this.isShow = !this.isShow; } else { const tabParam = this.isShowTabs.filter(param => param.tab.dataset.id === tab.dataset.id)[0]; if (tabParam.isShow) { this.setShowTab(tab, false); this.hide(tab, content); } else { this.setShowTab(tab, true); this.show(tab, content); } this.isShow = !this.isShow; } this.on.toggle(this); this.emitter.emit('toggle', this); } setId(tab) { tab.attr('data-id', `${this.id++}`); return this.id; } show(tab, content) { const height = content.scrollHeight; this.$tab = tab; JDom_1.$(this.$element).attr('data-active', ''); tab.attr('data-active', ''); content.addClass('is-showing', 'is-active'); this.setHeight(`${height}px`, content); setTimeout(() => { this.showEnd(content); }, this.options.duration); } showEnd(content) { content.removeClass('is-showing'); this.emitter.emit('show', this); // content.style.setProperty('height', `auto`) } hide(tab, content) { tab.attr('data-active', null); content.removeClass('is-active'); content.addClass('is-hiding'); const active = this.isShowTabs.filter(param => param.isShow).length; /** Если нет активного таба, то вырубаем основной элемент */ if (!active) { JDom_1.$(this.$element).attr('data-active', null); } this.setHeight(0, content); setTimeout(() => { this.hideEnd(content); }, this.options.duration); } hideEnd(content) { // content.removeAttr('show'); // content.removeAttr('hiding'); content.removeClass('is-hiding'); this.emitter.emit('hide', this); } hideAll(currentTab) { if (currentTab) { const needTabsHidden = this.$tabs.element.filter(tab => tab !== currentTab.get()); needTabsHidden.forEach(tab => { const panel = JDom_1.$(tab).closest(this.selectors.panel); const content = panel.find(this.selectors.content); // content.removeAttr('showing'); // content.removeAttr('show'); // content.removeAttr('hiding'); JDom_1.$(tab).attr('data-active', null); this.setHeight(0, content); }); this.$tab = currentTab; } else { this.$tabs.element.forEach(tab => { const panel = JDom_1.$(tab).closest(this.selectors.panel); const content = panel.find(this.selectors.content); // content.removeAttr('showing'); // content.removeAttr('show'); // content.removeAttr('hiding'); JDom_1.$(tab).attr('data-active', null); this.setHeight(0, content); }); this.$tab = null; } } setHeight(height, content) { content.style.setProperty('height', `${content.scrollHeight}px`); window.requestAnimationFrame(() => { content.style.setProperty('height', `${height}`); }); } setShowTab(tab, state) { const needTab = this.isShowTabs.filter(param => param.tab === tab.get())[0]; this.isShowTabs = this.isShowTabs.map(param => { if (param.tab === needTab.tab) { param.isShow = state; } return param; }); } resize() { this.$tabs.element.forEach((tab, i) => { const $tab = JDom_1.$(tab); if (!$tab.hasAttr('data-active')) { return; } const panel = $tab.closest(this.selectors.panel); const content = panel.find(this.selectors.content); content.style.setProperty('height', `auto`); this.setHeight(tab, content); }); } } exports.default = Accordion; //# sourceMappingURL=Accordion.js.map