Skip to content

Commit

Permalink
Extract Component config functionality to a separate class (#33872)
Browse files Browse the repository at this point in the history
Co-authored-by: XhmikosR <xhmikosr@gmail.com>
  • Loading branch information
GeoSot and XhmikosR committed Dec 10, 2021
1 parent 68f2267 commit 886b940
Show file tree
Hide file tree
Showing 18 changed files with 283 additions and 240 deletions.
26 changes: 15 additions & 11 deletions js/src/base-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
*/

import Data from './dom/data'
import {
executeAfterTransition,
getElement
} from './util/index'
import { executeAfterTransition, getElement } from './util/index'
import EventHandler from './dom/event-handler'
import Config from './util/config'

/**
* Constants
Expand All @@ -22,15 +20,18 @@ const VERSION = '5.1.3'
* Class definition
*/

class BaseComponent {
constructor(element) {
element = getElement(element)
class BaseComponent extends Config {
constructor(element, config) {
super()

element = getElement(element)
if (!element) {
return
}

this._element = element
this._config = this._getConfig(config)

Data.set(this._element, this.constructor.DATA_KEY, this)
}

Expand All @@ -48,6 +49,13 @@ class BaseComponent {
executeAfterTransition(callback, element, isAnimated)
}

_getConfig(config) {
config = this._mergeConfigObj(config, this._element)
config = this._configAfterMerge(config)
this._typeCheckConfig(config)
return config
}

// Static
static getInstance(element) {
return Data.get(getElement(element), this.DATA_KEY)
Expand All @@ -61,10 +69,6 @@ class BaseComponent {
return VERSION
}

static get NAME() {
throw new Error('You have to implement the static method "NAME" for each component!')
}

static get DATA_KEY() {
return `bs.${this.NAME}`
}
Expand Down
20 changes: 6 additions & 14 deletions js/src/carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import {
isRTL,
isVisible,
reflow,
triggerTransitionEnd,
typeCheckConfig
triggerTransitionEnd
} from './util/index'
import EventHandler from './dom/event-handler'
import Manipulator from './dom/manipulator'
Expand Down Expand Up @@ -95,7 +94,7 @@ const DefaultType = {

class Carousel extends BaseComponent {
constructor(element, config) {
super(element)
super(element, config)

this._items = null
this._interval = null
Expand All @@ -105,7 +104,6 @@ class Carousel extends BaseComponent {
this.touchTimeout = null
this._swipeHelper = null

this._config = this._getConfig(config)
this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element)
this._addEventListeners()
}
Expand All @@ -115,6 +113,10 @@ class Carousel extends BaseComponent {
return Default
}

static get DefaultType() {
return DefaultType
}

static get NAME() {
return NAME
}
Expand Down Expand Up @@ -205,16 +207,6 @@ class Carousel extends BaseComponent {
}

// Private
_getConfig(config) {
config = {
...Default,
...Manipulator.getDataAttributes(this._element),
...(typeof config === 'object' ? config : {})
}
typeCheckConfig(NAME, config, DefaultType)
return config
}

_addEventListeners() {
if (this._config.keyboard) {
EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event))
Expand Down
19 changes: 7 additions & 12 deletions js/src/collapse.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ import {
getElement,
getElementFromSelector,
getSelectorFromElement,
reflow,
typeCheckConfig
reflow
} from './util/index'
import EventHandler from './dom/event-handler'
import Manipulator from './dom/manipulator'
import SelectorEngine from './dom/selector-engine'
import BaseComponent from './base-component'

Expand Down Expand Up @@ -62,10 +60,9 @@ const DefaultType = {

class Collapse extends BaseComponent {
constructor(element, config) {
super(element)
super(element, config)

this._isTransitioning = false
this._config = this._getConfig(config)
this._triggerArray = []

const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE)
Expand Down Expand Up @@ -96,6 +93,10 @@ class Collapse extends BaseComponent {
return Default
}

static get DefaultType() {
return DefaultType
}

static get NAME() {
return NAME
}
Expand Down Expand Up @@ -210,15 +211,9 @@ class Collapse extends BaseComponent {
}

// Private
_getConfig(config) {
config = {
...Default,
...Manipulator.getDataAttributes(this._element),
...config
}
_configAfterMerge(config) {
config.toggle = Boolean(config.toggle) // Coerce string values
config.parent = getElement(config.parent)
typeCheckConfig(NAME, config, DefaultType)
return config
}

Expand Down
14 changes: 3 additions & 11 deletions js/src/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import {
isElement,
isRTL,
isVisible,
noop,
typeCheckConfig
noop
} from './util/index'
import EventHandler from './dom/event-handler'
import Manipulator from './dom/manipulator'
Expand Down Expand Up @@ -88,10 +87,9 @@ const DefaultType = {

class Dropdown extends BaseComponent {
constructor(element, config) {
super(element)
super(element, config)

this._popper = null
this._config = this._getConfig(config)
this._menu = this._getMenuElement()
this._inNavbar = this._detectNavbar()
}
Expand Down Expand Up @@ -205,13 +203,7 @@ class Dropdown extends BaseComponent {
}

_getConfig(config) {
config = {
...this.constructor.Default,
...Manipulator.getDataAttributes(this._element),
...config
}

typeCheckConfig(NAME, config, this.constructor.DefaultType)
config = super._getConfig(config)

if (typeof config.reference === 'object' && !isElement(config.reference) &&
typeof config.reference.getBoundingClientRect !== 'function'
Expand Down
27 changes: 6 additions & 21 deletions js/src/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,8 @@
* --------------------------------------------------------------------------
*/

import {
defineJQueryPlugin,
getElementFromSelector,
isRTL,
isVisible,
reflow,
typeCheckConfig
} from './util/index'
import { defineJQueryPlugin, getElementFromSelector, isRTL, isVisible, reflow } from './util/index'
import EventHandler from './dom/event-handler'
import Manipulator from './dom/manipulator'
import SelectorEngine from './dom/selector-engine'
import ScrollBarHelper from './util/scrollbar'
import BaseComponent from './base-component'
Expand Down Expand Up @@ -70,9 +62,8 @@ const DefaultType = {

class Modal extends BaseComponent {
constructor(element, config) {
super(element)
super(element, config)

this._config = this._getConfig(config)
this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element)
this._backdrop = this._initializeBackDrop()
this._focustrap = this._initializeFocusTrap()
Expand All @@ -86,6 +77,10 @@ class Modal extends BaseComponent {
return Default
}

static get DefaultType() {
return DefaultType
}

static get NAME() {
return NAME
}
Expand Down Expand Up @@ -175,16 +170,6 @@ class Modal extends BaseComponent {
})
}

_getConfig(config) {
config = {
...Default,
...Manipulator.getDataAttributes(this._element),
...(typeof config === 'object' ? config : {})
}
typeCheckConfig(NAME, config, DefaultType)
return config
}

_showElement(relatedTarget) {
// try to append dynamic modal
if (!document.body.contains(this._element)) {
Expand Down
29 changes: 10 additions & 19 deletions js/src/offcanvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ import {
defineJQueryPlugin,
getElementFromSelector,
isDisabled,
isVisible,
typeCheckConfig
isVisible
} from './util/index'
import ScrollBarHelper from './util/scrollbar'
import EventHandler from './dom/event-handler'
import BaseComponent from './base-component'
import SelectorEngine from './dom/selector-engine'
import Manipulator from './dom/manipulator'
import Backdrop from './util/backdrop'
import FocusTrap from './util/focustrap'
import { enableDismissTrigger } from './util/component-functions'
Expand Down Expand Up @@ -63,24 +61,27 @@ const DefaultType = {

class Offcanvas extends BaseComponent {
constructor(element, config) {
super(element)
super(element, config)

this._config = this._getConfig(config)
this._isShown = false
this._backdrop = this._initializeBackDrop()
this._focustrap = this._initializeFocusTrap()
this._addEventListeners()
}

// Getters
static get NAME() {
return NAME
}

static get Default() {
return Default
}

static get DefaultType() {
return DefaultType
}

static get NAME() {
return NAME
}

// Public
toggle(relatedTarget) {
return this._isShown ? this.hide() : this.show(relatedTarget)
Expand Down Expand Up @@ -162,16 +163,6 @@ class Offcanvas extends BaseComponent {
}

// Private
_getConfig(config) {
config = {
...Default,
...Manipulator.getDataAttributes(this._element),
...(typeof config === 'object' ? config : {})
}
typeCheckConfig(NAME, config, DefaultType)
return config
}

_initializeBackDrop() {
return new Backdrop({
className: CLASS_NAME_BACKDROP,
Expand Down
8 changes: 4 additions & 4 deletions js/src/popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ class Popover extends Tooltip {
return Default
}

static get DefaultType() {
return DefaultType
}

static get NAME() {
return NAME
}
Expand All @@ -68,10 +72,6 @@ class Popover extends Tooltip {
return Event
}

static get DefaultType() {
return DefaultType
}

// Overrides
_isWithContent() {
return this._getTitle() || this._getContent()
Expand Down
Loading

0 comments on commit 886b940

Please sign in to comment.