import Util from './util'; /** * -------------------------------------------------------------------------- * Bootstrap (v4.0.0-alpha.6): collapse.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ const Collapse = ($ => { /** * ------------------------------------------------------------------------ * Constants * ------------------------------------------------------------------------ */ const NAME = 'collapse'; const VERSION = '4.0.0-alpha.6'; const DATA_KEY = 'bs.collapse'; const EVENT_KEY = `.${DATA_KEY}`; const DATA_API_KEY = '.data-api'; const JQUERY_NO_CONFLICT = $.fn[NAME]; const TRANSITION_DURATION = 600; const Default = { toggle: true, parent: '' }; const DefaultType = { toggle: 'boolean', parent: 'string' }; const Event = { SHOW: `show${EVENT_KEY}`, SHOWN: `shown${EVENT_KEY}`, HIDE: `hide${EVENT_KEY}`, HIDDEN: `hidden${EVENT_KEY}`, CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}` }; const ClassName = { SHOW: 'show', COLLAPSE: 'collapse', COLLAPSING: 'collapsing', COLLAPSED: 'collapsed' }; const Dimension = { WIDTH: 'width', HEIGHT: 'height' }; const Selector = { ACTIVES: '.card > .show, .card > .collapsing', DATA_TOGGLE: '[data-toggle="collapse"]' }; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ class Collapse { constructor(element, config) { this._isTransitioning = false; this._element = element; this._config = this._getConfig(config); this._triggerArray = $.makeArray($(`[data-toggle="collapse"][href="#${element.id}"],` + `[data-toggle="collapse"][data-target="#${element.id}"]`)); this._parent = this._config.parent ? this._getParent() : null; if (!this._config.parent) { this._addAriaAndCollapsedClass(this._element, this._triggerArray); } if (this._config.toggle) { this.toggle(); } } // getters static get VERSION() { return VERSION; } static get Default() { return Default; } // public toggle() { if ($(this._element).hasClass(ClassName.SHOW)) { this.hide(); } else { this.show(); } } show() { if (this._isTransitioning) { throw new Error('Collapse is transitioning'); } if ($(this._element).hasClass(ClassName.SHOW)) { return; } let actives; let activesData; if (this._parent) { actives = $.makeArray($(this._parent).find(Selector.ACTIVES)); if (!actives.length) { actives = null; } } if (actives) { activesData = $(actives).data(DATA_KEY); if (activesData && activesData._isTransitioning) { return; } } const startEvent = $.Event(Event.SHOW); $(this._element).trigger(startEvent); if (startEvent.isDefaultPrevented()) { return; } if (actives) { Collapse._jQueryInterface.call($(actives), 'hide'); if (!activesData) { $(actives).data(DATA_KEY, null); } } const dimension = this._getDimension(); $(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING); this._element.style[dimension] = 0; this._element.setAttribute('aria-expanded', true); if (this._triggerArray.length) { $(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true); } this.setTransitioning(true); const complete = () => { $(this._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.SHOW); this._element.style[dimension] = ''; this.setTransitioning(false); $(this._element).trigger(Event.SHOWN); }; if (!Util.supportsTransitionEnd()) { complete(); return; } const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); const scrollSize = `scroll${capitalizedDimension}`; $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION); this._element.style[dimension] = `${this._element[scrollSize]}px`; } hide() { if (this._isTransitioning) { throw new Error('Collapse is transitioning'); } if (!$(this._element).hasClass(ClassName.SHOW)) { return; } const startEvent = $.Event(Event.HIDE); $(this._element).trigger(startEvent); if (startEvent.isDefaultPrevented()) { return; } const dimension = this._getDimension(); const offsetDimension = dimension === Dimension.WIDTH ? 'offsetWidth' : 'offsetHeight'; this._element.style[dimension] = `${this._element[offsetDimension]}px`; Util.reflow(this._element); $(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW); this._element.setAttribute('aria-expanded', false); if (this._triggerArray.length) { $(this._triggerArray).addClass(ClassName.COLLAPSED).attr('aria-expanded', false); } this.setTransitioning(true); const complete = () => { this.setTransitioning(false); $(this._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN); }; this._element.style[dimension] = ''; if (!Util.supportsTransitionEnd()) { complete(); return; } $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION); } setTransitioning(isTransitioning) { this._isTransitioning = isTransitioning; } dispose() { $.removeData(this._element, DATA_KEY); this._config = null; this._parent = null; this._element = null; this._triggerArray = null; this._isTransitioning = null; } // private _getConfig(config) { config = $.extend({}, Default, config); config.toggle = Boolean(config.toggle); // coerce string values Util.typeCheckConfig(NAME, config, DefaultType); return config; } _getDimension() { const hasWidth = $(this._element).hasClass(Dimension.WIDTH); return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT; } _getParent() { const parent = $(this._config.parent)[0]; const selector = `[data-toggle="collapse"][data-parent="${this._config.parent}"]`; $(parent).find(selector).each((i, element) => { this._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]); }); return parent; } _addAriaAndCollapsedClass(element, triggerArray) { if (element) { const isOpen = $(element).hasClass(ClassName.SHOW); element.setAttribute('aria-expanded', isOpen); if (triggerArray.length) { $(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen); } } } // static static _getTargetFromElement(element) { const selector = Util.getSelectorFromElement(element); return selector ? $(selector)[0] : null; } static _jQueryInterface(config) { return this.each(function () { const $this = $(this); let data = $this.data(DATA_KEY); const _config = $.extend({}, Default, $this.data(), typeof config === 'object' && config); if (!data && _config.toggle && /show|hide/.test(config)) { _config.toggle = false; } if (!data) { data = new Collapse(this, _config); $this.data(DATA_KEY, data); } if (typeof config === 'string') { if (data[config] === undefined) { throw new Error(`No method named "${config}"`); } data[config](); } }); } } /** * ------------------------------------------------------------------------ * Data Api implementation * ------------------------------------------------------------------------ */ $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { event.preventDefault(); const target = Collapse._getTargetFromElement(this); const data = $(target).data(DATA_KEY); const config = data ? 'toggle' : $(this).data(); Collapse._jQueryInterface.call($(target), config); }); /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ */ $.fn[NAME] = Collapse._jQueryInterface; $.fn[NAME].Constructor = Collapse; $.fn[NAME].noConflict = function () { $.fn[NAME] = JQUERY_NO_CONFLICT; return Collapse._jQueryInterface; }; return Collapse; })(jQuery); export default Collapse; //# sourceMappingURL=collapse.js.map