tab.js 6.63 KiB
import Util from './util'
/**
 * --------------------------------------------------------------------------
 * Bootstrap (v4.0.0): tab.js
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */
const Tab = (($) => {
  /**
   * ------------------------------------------------------------------------
   * Constants
   * ------------------------------------------------------------------------
  const NAME                = 'tab'
  const VERSION             = '4.0.0'
  const DATA_KEY            = 'bs.tab'
  const EVENT_KEY           = `.${DATA_KEY}`
  const DATA_API_KEY        = '.data-api'
  const JQUERY_NO_CONFLICT  = $.fn[NAME]
  const TRANSITION_DURATION = 150
  const Event = {
    HIDE           : `hide${EVENT_KEY}`,
    HIDDEN         : `hidden${EVENT_KEY}`,
    SHOW           : `show${EVENT_KEY}`,
    SHOWN          : `shown${EVENT_KEY}`,
    CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
  const ClassName = {
    DROPDOWN_MENU : 'dropdown-menu',
    ACTIVE        : 'active',
    FADE          : 'fade',
    IN            : 'in'
  const Selector = {
    A                     : 'a',
    LI                    : 'li',
    DROPDOWN              : '.dropdown',
    UL                    : 'ul:not(.dropdown-menu)',
    FADE_CHILD            : '> .nav-item .fade, > .fade',
    ACTIVE                : '.active',
    ACTIVE_CHILD          : '> .nav-item > .active, > .active',
    DATA_TOGGLE           : '[data-toggle="tab"], [data-toggle="pill"]',
    DROPDOWN_TOGGLE       : '.dropdown-toggle',
    DROPDOWN_ACTIVE_CHILD : '> .dropdown-menu .active'
  /**
   * ------------------------------------------------------------------------
   * Class Definition
   * ------------------------------------------------------------------------
  class Tab {
    constructor(element) {
      this._element = element
    // getters
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
static get VERSION() { return VERSION } // public show() { if (this._element.parentNode && (this._element.parentNode.nodeType === Node.ELEMENT_NODE) && ($(this._element).hasClass(ClassName.ACTIVE))) { return } let target let previous let ulElement = $(this._element).closest(Selector.UL)[0] let selector = Util.getSelectorFromElement(this._element) if (ulElement) { previous = $.makeArray($(ulElement).find(Selector.ACTIVE)) previous = previous[previous.length - 1] } let hideEvent = $.Event(Event.HIDE, { relatedTarget: this._element }) let showEvent = $.Event(Event.SHOW, { relatedTarget: previous }) if (previous) { $(previous).trigger(hideEvent) } $(this._element).trigger(showEvent) if (showEvent.isDefaultPrevented() || (hideEvent.isDefaultPrevented())) { return } if (selector) { target = $(selector)[0] } this._activate( this._element, ulElement ) let complete = () => { let hiddenEvent = $.Event(Event.HIDDEN, { relatedTarget: this._element }) let shownEvent = $.Event(Event.SHOWN, { relatedTarget: previous }) $(previous).trigger(hiddenEvent) $(this._element).trigger(shownEvent) } if (target) { this._activate(target, target.parentNode, complete) } else { complete()
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
} } dispose() { $.removeClass(this._element, DATA_KEY) this._element = null } // private _activate(element, container, callback) { let active = $(container).find(Selector.ACTIVE_CHILD)[0] let isTransitioning = callback && Util.supportsTransitionEnd() && ((active && $(active).hasClass(ClassName.FADE)) || Boolean($(container).find(Selector.FADE_CHILD)[0])) let complete = $.proxy( this._transitionComplete, this, element, active, isTransitioning, callback ) if (active && isTransitioning) { $(active) .one(Util.TRANSITION_END, complete) .emulateTransitionEnd(TRANSITION_DURATION) } else { complete() } if (active) { $(active).removeClass(ClassName.IN) } } _transitionComplete(element, active, isTransitioning, callback) { if (active) { $(active).removeClass(ClassName.ACTIVE) let dropdownChild = $(active).find( Selector.DROPDOWN_ACTIVE_CHILD )[0] if (dropdownChild) { $(dropdownChild).removeClass(ClassName.ACTIVE) } active.setAttribute('aria-expanded', false) } $(element).addClass(ClassName.ACTIVE) element.setAttribute('aria-expanded', true) if (isTransitioning) { Util.reflow(element) $(element).addClass(ClassName.IN) } else { $(element).removeClass(ClassName.FADE) } if (element.parentNode && ($(element.parentNode).hasClass(ClassName.DROPDOWN_MENU))) { let dropdownElement = $(element).closest(Selector.DROPDOWN)[0]
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
if (dropdownElement) { $(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE) } element.setAttribute('aria-expanded', true) } if (callback) { callback() } } // static static _jQueryInterface(config) { return this.each(function () { let $this = $(this) let data = $this.data(DATA_KEY) if (!data) { data = data = new Tab(this) $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() Tab._jQueryInterface.call($(this), 'show') }) /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ */ $.fn[NAME] = Tab._jQueryInterface $.fn[NAME].Constructor = Tab $.fn[NAME].noConflict = function () { $.fn[NAME] = JQUERY_NO_CONFLICT return Tab._jQueryInterface } return Tab })(jQuery) export default Tab