mirror of
https://github.com/tenrok/bootstrap.git
synced 2026-06-11 18:02:28 +03:00
Extract Component config functionality to a separate class (#33872)
Co-authored-by: XhmikosR <xhmikosr@gmail.com>
This commit is contained in:
+18
-9
@@ -6,7 +6,8 @@
|
||||
*/
|
||||
|
||||
import EventHandler from '../dom/event-handler'
|
||||
import { execute, executeAfterTransition, getElement, reflow, typeCheckConfig } from './index'
|
||||
import { execute, executeAfterTransition, getElement, reflow } from './index'
|
||||
import Config from './config'
|
||||
|
||||
/**
|
||||
* Constants
|
||||
@@ -37,13 +38,27 @@ const DefaultType = {
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Backdrop {
|
||||
class Backdrop extends Config {
|
||||
constructor(config) {
|
||||
super()
|
||||
this._config = this._getConfig(config)
|
||||
this._isAppended = false
|
||||
this._element = null
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default
|
||||
}
|
||||
|
||||
static get DefaultType() {
|
||||
return DefaultType
|
||||
}
|
||||
|
||||
static get NAME() {
|
||||
return NAME
|
||||
}
|
||||
|
||||
// Public
|
||||
show(callback) {
|
||||
if (!this._config.isVisible) {
|
||||
@@ -104,15 +119,9 @@ class Backdrop {
|
||||
return this._element
|
||||
}
|
||||
|
||||
_getConfig(config) {
|
||||
config = {
|
||||
...Default,
|
||||
...(typeof config === 'object' ? config : {})
|
||||
}
|
||||
|
||||
_configAfterMerge(config) {
|
||||
// use getElement() with the default "body" to get a fresh Element on each instantiation
|
||||
config.rootElement = getElement(config.rootElement)
|
||||
typeCheckConfig(NAME, config, DefaultType)
|
||||
return config
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/config.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
import { isElement, toType } from './index'
|
||||
import Manipulator from '../dom/manipulator'
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Config {
|
||||
// Getters
|
||||
static get Default() {
|
||||
return {}
|
||||
}
|
||||
|
||||
static get DefaultType() {
|
||||
return {}
|
||||
}
|
||||
|
||||
static get NAME() {
|
||||
throw new Error('You have to implement the static method "NAME", for each component!')
|
||||
}
|
||||
|
||||
_getConfig(config) {
|
||||
config = this._mergeConfigObj(config)
|
||||
config = this._configAfterMerge(config)
|
||||
this._typeCheckConfig(config)
|
||||
return config
|
||||
}
|
||||
|
||||
_configAfterMerge(config) {
|
||||
return config
|
||||
}
|
||||
|
||||
_mergeConfigObj(config, element) {
|
||||
return {
|
||||
...this.constructor.Default,
|
||||
...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),
|
||||
...(typeof config === 'object' ? config : {})
|
||||
}
|
||||
}
|
||||
|
||||
_typeCheckConfig(config, configTypes = this.constructor.DefaultType) {
|
||||
for (const property of Object.keys(configTypes)) {
|
||||
const expectedTypes = configTypes[property]
|
||||
const value = config[property]
|
||||
const valueType = isElement(value) ? 'element' : toType(value)
|
||||
|
||||
if (!new RegExp(expectedTypes).test(valueType)) {
|
||||
throw new TypeError(
|
||||
`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Config
|
||||
+16
-11
@@ -7,7 +7,7 @@
|
||||
|
||||
import EventHandler from '../dom/event-handler'
|
||||
import SelectorEngine from '../dom/selector-engine'
|
||||
import { typeCheckConfig } from './index'
|
||||
import Config from './config'
|
||||
|
||||
/**
|
||||
* Constants
|
||||
@@ -37,13 +37,27 @@ const DefaultType = {
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class FocusTrap {
|
||||
class FocusTrap extends Config {
|
||||
constructor(config) {
|
||||
super()
|
||||
this._config = this._getConfig(config)
|
||||
this._isActive = false
|
||||
this._lastTabNavDirection = null
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default
|
||||
}
|
||||
|
||||
static get DefaultType() {
|
||||
return DefaultType
|
||||
}
|
||||
|
||||
static get NAME() {
|
||||
return NAME
|
||||
}
|
||||
|
||||
// Public
|
||||
activate() {
|
||||
const { trapElement, autofocus } = this._config
|
||||
@@ -99,15 +113,6 @@ class FocusTrap {
|
||||
|
||||
this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD
|
||||
}
|
||||
|
||||
_getConfig(config) {
|
||||
config = {
|
||||
...Default,
|
||||
...(typeof config === 'object' ? config : {})
|
||||
}
|
||||
typeCheckConfig(NAME, config, DefaultType)
|
||||
return config
|
||||
}
|
||||
}
|
||||
|
||||
export default FocusTrap
|
||||
|
||||
+1
-15
@@ -123,20 +123,6 @@ const getElement = object => {
|
||||
return null
|
||||
}
|
||||
|
||||
const typeCheckConfig = (componentName, config, configTypes) => {
|
||||
for (const property of Object.keys(configTypes)) {
|
||||
const expectedTypes = configTypes[property]
|
||||
const value = config[property]
|
||||
const valueType = value && isElement(value) ? 'element' : toType(value)
|
||||
|
||||
if (!new RegExp(expectedTypes).test(valueType)) {
|
||||
throw new TypeError(
|
||||
`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const isVisible = element => {
|
||||
if (!isElement(element) || element.getClientRects().length === 0) {
|
||||
return false
|
||||
@@ -327,5 +313,5 @@ export {
|
||||
onDOMContentLoaded,
|
||||
reflow,
|
||||
triggerTransitionEnd,
|
||||
typeCheckConfig
|
||||
toType
|
||||
}
|
||||
|
||||
+17
-11
@@ -5,8 +5,9 @@
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
import Config from './config'
|
||||
import EventHandler from '../dom/event-handler'
|
||||
import { execute, typeCheckConfig } from './index'
|
||||
import { execute } from './index'
|
||||
|
||||
/**
|
||||
* Constants
|
||||
@@ -40,8 +41,9 @@ const DefaultType = {
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Swipe {
|
||||
class Swipe extends Config {
|
||||
constructor(element, config) {
|
||||
super()
|
||||
this._element = element
|
||||
|
||||
if (!element || !Swipe.isSupported()) {
|
||||
@@ -54,6 +56,19 @@ class Swipe {
|
||||
this._initEvents()
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default
|
||||
}
|
||||
|
||||
static get DefaultType() {
|
||||
return DefaultType
|
||||
}
|
||||
|
||||
static get NAME() {
|
||||
return NAME
|
||||
}
|
||||
|
||||
// Public
|
||||
dispose() {
|
||||
EventHandler.off(this._element, EVENT_KEY)
|
||||
@@ -118,15 +133,6 @@ class Swipe {
|
||||
}
|
||||
}
|
||||
|
||||
_getConfig(config) {
|
||||
config = {
|
||||
...Default,
|
||||
...(typeof config === 'object' ? config : {})
|
||||
}
|
||||
typeCheckConfig(NAME, config, DefaultType)
|
||||
return config
|
||||
}
|
||||
|
||||
_eventIsPointerPenTouch(event) {
|
||||
return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
*/
|
||||
|
||||
import { DefaultAllowlist, sanitizeHtml } from './sanitizer'
|
||||
import { getElement, isElement, typeCheckConfig } from '../util/index'
|
||||
import { getElement, isElement } from '../util/index'
|
||||
import SelectorEngine from '../dom/selector-engine'
|
||||
import Config from './config'
|
||||
|
||||
/**
|
||||
* Constants
|
||||
@@ -44,20 +45,25 @@ const DefaultContentType = {
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class TemplateFactory {
|
||||
class TemplateFactory extends Config {
|
||||
constructor(config) {
|
||||
super()
|
||||
this._config = this._getConfig(config)
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get NAME() {
|
||||
return NAME
|
||||
}
|
||||
|
||||
static get Default() {
|
||||
return Default
|
||||
}
|
||||
|
||||
static get DefaultType() {
|
||||
return DefaultType
|
||||
}
|
||||
|
||||
static get NAME() {
|
||||
return NAME
|
||||
}
|
||||
|
||||
// Public
|
||||
getContent() {
|
||||
return Object.values(this._config.content)
|
||||
@@ -94,21 +100,14 @@ class TemplateFactory {
|
||||
}
|
||||
|
||||
// Private
|
||||
_getConfig(config) {
|
||||
config = {
|
||||
...Default,
|
||||
...(typeof config === 'object' ? config : {})
|
||||
}
|
||||
|
||||
typeCheckConfig(NAME, config, DefaultType)
|
||||
_typeCheckConfig(config) {
|
||||
super._typeCheckConfig(config)
|
||||
this._checkContent(config.content)
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
_checkContent(arg) {
|
||||
for (const [selector, content] of Object.entries(arg)) {
|
||||
typeCheckConfig(NAME, { selector, entry: content }, DefaultContentType)
|
||||
super._typeCheckConfig({ selector, entry: content }, DefaultContentType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user