@openeuropa/bcl-bootstrap 0.25.1 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/bootstrap-icons.svg +1 -1
  2. package/icons/apple.svg +2 -2
  3. package/icons/boombox-fill.svg +2 -2
  4. package/icons/cup-fill.svg +1 -1
  5. package/icons/cup.svg +1 -1
  6. package/js/dist/alert.js +3 -12
  7. package/js/dist/alert.js.map +1 -1
  8. package/js/dist/base-component.js +32 -18
  9. package/js/dist/base-component.js.map +1 -1
  10. package/js/dist/button.js +3 -12
  11. package/js/dist/button.js.map +1 -1
  12. package/js/dist/carousel.js +207 -307
  13. package/js/dist/carousel.js.map +1 -1
  14. package/js/dist/collapse.js +57 -88
  15. package/js/dist/collapse.js.map +1 -1
  16. package/js/dist/dom/data.js +1 -3
  17. package/js/dist/dom/data.js.map +1 -1
  18. package/js/dist/dom/event-handler.js +87 -106
  19. package/js/dist/dom/event-handler.js.map +1 -1
  20. package/js/dist/dom/manipulator.js +21 -25
  21. package/js/dist/dom/manipulator.js.map +1 -1
  22. package/js/dist/dom/selector-engine.js +11 -10
  23. package/js/dist/dom/selector-engine.js.map +1 -1
  24. package/js/dist/dropdown.js +83 -115
  25. package/js/dist/dropdown.js.map +1 -1
  26. package/js/dist/modal.js +95 -152
  27. package/js/dist/modal.js.map +1 -1
  28. package/js/dist/offcanvas.js +75 -58
  29. package/js/dist/offcanvas.js.map +1 -1
  30. package/js/dist/popover.js +29 -56
  31. package/js/dist/popover.js.map +1 -1
  32. package/js/dist/scrollspy.js +176 -125
  33. package/js/dist/scrollspy.js.map +1 -1
  34. package/js/dist/tab.js +207 -92
  35. package/js/dist/tab.js.map +1 -1
  36. package/js/dist/toast.js +23 -37
  37. package/js/dist/toast.js.map +1 -1
  38. package/js/dist/tooltip.js +259 -348
  39. package/js/dist/tooltip.js.map +1 -1
  40. package/js/dist/util/backdrop.js +62 -39
  41. package/js/dist/util/backdrop.js.map +1 -1
  42. package/js/dist/util/component-functions.js +1 -1
  43. package/js/dist/util/component-functions.js.map +1 -1
  44. package/js/dist/util/config.js +75 -0
  45. package/js/dist/util/config.js.map +1 -0
  46. package/js/dist/util/focustrap.js +41 -34
  47. package/js/dist/util/focustrap.js.map +1 -1
  48. package/js/dist/util/index.js +56 -52
  49. package/js/dist/util/index.js.map +1 -1
  50. package/js/dist/util/sanitizer.js +12 -19
  51. package/js/dist/util/sanitizer.js.map +1 -1
  52. package/js/dist/util/scrollbar.js +49 -34
  53. package/js/dist/util/scrollbar.js.map +1 -1
  54. package/js/dist/util/swipe.js +151 -0
  55. package/js/dist/util/swipe.js.map +1 -0
  56. package/js/dist/util/template-factory.js +173 -0
  57. package/js/dist/util/template-factory.js.map +1 -0
  58. package/js/src/alert.js +3 -15
  59. package/js/src/base-component.js +28 -18
  60. package/js/src/button.js +3 -17
  61. package/js/src/carousel.js +203 -319
  62. package/js/src/collapse.js +61 -94
  63. package/js/src/dom/data.js +1 -3
  64. package/js/src/dom/event-handler.js +80 -108
  65. package/js/src/dom/manipulator.js +22 -31
  66. package/js/src/dom/selector-engine.js +10 -19
  67. package/js/src/dropdown.js +84 -138
  68. package/js/src/modal.js +94 -158
  69. package/js/src/offcanvas.js +72 -61
  70. package/js/src/popover.js +31 -62
  71. package/js/src/scrollspy.js +166 -171
  72. package/js/src/tab.js +193 -110
  73. package/js/src/toast.js +19 -41
  74. package/js/src/tooltip.js +259 -371
  75. package/js/src/util/backdrop.js +55 -36
  76. package/js/src/util/component-functions.js +1 -1
  77. package/js/src/util/config.js +66 -0
  78. package/js/src/util/focustrap.js +38 -28
  79. package/js/src/util/index.js +67 -64
  80. package/js/src/util/sanitizer.js +11 -19
  81. package/js/src/util/scrollbar.js +47 -30
  82. package/js/src/util/swipe.js +146 -0
  83. package/js/src/util/template-factory.js +160 -0
  84. package/package.json +4 -4
  85. package/scss/_accordion.scss +52 -24
  86. package/scss/_alert.scss +18 -4
  87. package/scss/_badge.scss +14 -5
  88. package/scss/_breadcrumb.scss +22 -10
  89. package/scss/_button-group.scss +3 -0
  90. package/scss/_buttons.scss +97 -22
  91. package/scss/_card.scss +55 -37
  92. package/scss/_close.scss +1 -1
  93. package/scss/_containers.scss +1 -1
  94. package/scss/_dropdown.scss +83 -75
  95. package/scss/_functions.scss +7 -7
  96. package/scss/_grid.scss +3 -3
  97. package/scss/_helpers.scss +1 -0
  98. package/scss/_list-group.scss +44 -27
  99. package/scss/_maps.scss +54 -0
  100. package/scss/_modal.scss +71 -43
  101. package/scss/_nav.scss +53 -20
  102. package/scss/_navbar.scss +91 -150
  103. package/scss/_offcanvas.scss +119 -59
  104. package/scss/_pagination.scss +66 -21
  105. package/scss/_placeholders.scss +1 -1
  106. package/scss/_popover.scss +90 -52
  107. package/scss/_progress.scss +20 -9
  108. package/scss/_reboot.scss +25 -40
  109. package/scss/_root.scss +40 -21
  110. package/scss/_spinners.scss +38 -22
  111. package/scss/_tables.scss +32 -23
  112. package/scss/_toasts.scss +35 -16
  113. package/scss/_tooltip.scss +61 -56
  114. package/scss/_type.scss +2 -0
  115. package/scss/_utilities.scss +43 -26
  116. package/scss/_variables.scss +113 -121
  117. package/scss/bootstrap-grid.scss +3 -6
  118. package/scss/bootstrap-reboot.scss +3 -7
  119. package/scss/bootstrap-utilities.scss +3 -6
  120. package/scss/bootstrap.scss +4 -6
  121. package/scss/forms/_floating-labels.scss +14 -3
  122. package/scss/forms/_form-check.scss +28 -5
  123. package/scss/forms/_form-control.scss +12 -37
  124. package/scss/forms/_form-select.scss +0 -1
  125. package/scss/forms/_input-group.scss +15 -7
  126. package/scss/helpers/_color-bg.scss +10 -0
  127. package/scss/helpers/_colored-links.scss +2 -2
  128. package/scss/helpers/_position.scss +7 -1
  129. package/scss/helpers/_ratio.scss +2 -2
  130. package/scss/helpers/_vr.scss +1 -1
  131. package/scss/mixins/_alert.scss +7 -3
  132. package/scss/mixins/_banner.scss +9 -0
  133. package/scss/mixins/_breakpoints.scss +8 -8
  134. package/scss/mixins/_buttons.scss +32 -95
  135. package/scss/mixins/_container.scss +4 -2
  136. package/scss/mixins/_forms.scss +8 -0
  137. package/scss/mixins/_gradients.scss +1 -1
  138. package/scss/mixins/_grid.scss +12 -12
  139. package/scss/mixins/_pagination.scss +4 -25
  140. package/scss/mixins/_reset-text.scss +1 -1
  141. package/scss/mixins/_table-variants.scss +12 -9
  142. package/scss/mixins/_utilities.scss +12 -4
package/js/src/tab.js CHANGED
@@ -1,202 +1,281 @@
1
1
  /**
2
2
  * --------------------------------------------------------------------------
3
- * Bootstrap (v5.1.3): tab.js
3
+ * Bootstrap (v5.2.0): tab.js
4
4
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
5
  * --------------------------------------------------------------------------
6
6
  */
7
7
 
8
- import {
9
- defineJQueryPlugin,
10
- getElementFromSelector,
11
- isDisabled,
12
- reflow
13
- } from './util/index'
8
+ import { defineJQueryPlugin, getElementFromSelector, getNextActiveElement, isDisabled } from './util/index'
14
9
  import EventHandler from './dom/event-handler'
15
10
  import SelectorEngine from './dom/selector-engine'
16
11
  import BaseComponent from './base-component'
17
12
 
18
13
  /**
19
- * ------------------------------------------------------------------------
20
14
  * Constants
21
- * ------------------------------------------------------------------------
22
15
  */
23
16
 
24
17
  const NAME = 'tab'
25
18
  const DATA_KEY = 'bs.tab'
26
19
  const EVENT_KEY = `.${DATA_KEY}`
27
- const DATA_API_KEY = '.data-api'
28
20
 
29
21
  const EVENT_HIDE = `hide${EVENT_KEY}`
30
22
  const EVENT_HIDDEN = `hidden${EVENT_KEY}`
31
23
  const EVENT_SHOW = `show${EVENT_KEY}`
32
24
  const EVENT_SHOWN = `shown${EVENT_KEY}`
33
- const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
25
+ const EVENT_CLICK_DATA_API = `click${EVENT_KEY}`
26
+ const EVENT_KEYDOWN = `keydown${EVENT_KEY}`
27
+ const EVENT_LOAD_DATA_API = `load${EVENT_KEY}`
28
+
29
+ const ARROW_LEFT_KEY = 'ArrowLeft'
30
+ const ARROW_RIGHT_KEY = 'ArrowRight'
31
+ const ARROW_UP_KEY = 'ArrowUp'
32
+ const ARROW_DOWN_KEY = 'ArrowDown'
34
33
 
35
- const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'
36
34
  const CLASS_NAME_ACTIVE = 'active'
37
35
  const CLASS_NAME_FADE = 'fade'
38
36
  const CLASS_NAME_SHOW = 'show'
37
+ const CLASS_DROPDOWN = 'dropdown'
39
38
 
40
- const SELECTOR_DROPDOWN = '.dropdown'
41
- const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'
42
- const SELECTOR_ACTIVE = '.active'
43
- const SELECTOR_ACTIVE_UL = ':scope > li > .active'
44
- const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'
45
39
  const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'
46
- const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active'
40
+ const SELECTOR_DROPDOWN_MENU = '.dropdown-menu'
41
+ const SELECTOR_DROPDOWN_ITEM = '.dropdown-item'
42
+ const NOT_SELECTOR_DROPDOWN_TOGGLE = ':not(.dropdown-toggle)'
43
+
44
+ const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]'
45
+ const SELECTOR_OUTER = '.nav-item, .list-group-item'
46
+ const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`
47
+ const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]' // todo:v6: could be only `tab`
48
+ const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`
49
+
50
+ const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`
47
51
 
48
52
  /**
49
- * ------------------------------------------------------------------------
50
- * Class Definition
51
- * ------------------------------------------------------------------------
53
+ * Class definition
52
54
  */
53
55
 
54
56
  class Tab extends BaseComponent {
55
- // Getters
57
+ constructor(element) {
58
+ super(element)
59
+ this._parent = this._element.closest(SELECTOR_TAB_PANEL)
60
+
61
+ if (!this._parent) {
62
+ return
63
+ // todo: should Throw exception on v6
64
+ // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`)
65
+ }
66
+
67
+ // Set up initial aria attributes
68
+ this._setInitialAttributes(this._parent, this._getChildren())
69
+
70
+ EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event))
71
+ }
56
72
 
73
+ // Getters
57
74
  static get NAME() {
58
75
  return NAME
59
76
  }
60
77
 
61
78
  // Public
62
-
63
- show() {
64
- if ((this._element.parentNode &&
65
- this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
66
- this._element.classList.contains(CLASS_NAME_ACTIVE))) {
79
+ show() { // Shows this elem and deactivate the active sibling if exists
80
+ const innerElem = this._element
81
+ if (this._elemIsActive(innerElem)) {
67
82
  return
68
83
  }
69
84
 
70
- let previous
71
- const target = getElementFromSelector(this._element)
72
- const listElement = this._element.closest(SELECTOR_NAV_LIST_GROUP)
85
+ // Search for active tab on same parent to deactivate it
86
+ const active = this._getActiveElem()
73
87
 
74
- if (listElement) {
75
- const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE
76
- previous = SelectorEngine.find(itemSelector, listElement)
77
- previous = previous[previous.length - 1]
78
- }
79
-
80
- const hideEvent = previous ?
81
- EventHandler.trigger(previous, EVENT_HIDE, {
82
- relatedTarget: this._element
83
- }) :
88
+ const hideEvent = active ?
89
+ EventHandler.trigger(active, EVENT_HIDE, { relatedTarget: innerElem }) :
84
90
  null
85
91
 
86
- const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
87
- relatedTarget: previous
88
- })
92
+ const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW, { relatedTarget: active })
93
+
94
+ if (showEvent.defaultPrevented || (hideEvent && hideEvent.defaultPrevented)) {
95
+ return
96
+ }
97
+
98
+ this._deactivate(active, innerElem)
99
+ this._activate(innerElem, active)
100
+ }
89
101
 
90
- if (showEvent.defaultPrevented || (hideEvent !== null && hideEvent.defaultPrevented)) {
102
+ // Private
103
+ _activate(element, relatedElem) {
104
+ if (!element) {
91
105
  return
92
106
  }
93
107
 
94
- this._activate(this._element, listElement)
108
+ element.classList.add(CLASS_NAME_ACTIVE)
109
+
110
+ this._activate(getElementFromSelector(element)) // Search and activate/show the proper section
95
111
 
96
112
  const complete = () => {
97
- EventHandler.trigger(previous, EVENT_HIDDEN, {
98
- relatedTarget: this._element
99
- })
100
- EventHandler.trigger(this._element, EVENT_SHOWN, {
101
- relatedTarget: previous
113
+ if (element.getAttribute('role') !== 'tab') {
114
+ element.classList.add(CLASS_NAME_SHOW)
115
+ return
116
+ }
117
+
118
+ element.focus()
119
+ element.removeAttribute('tabindex')
120
+ element.setAttribute('aria-selected', true)
121
+ this._toggleDropDown(element, true)
122
+ EventHandler.trigger(element, EVENT_SHOWN, {
123
+ relatedTarget: relatedElem
102
124
  })
103
125
  }
104
126
 
105
- if (target) {
106
- this._activate(target, target.parentNode, complete)
107
- } else {
108
- complete()
109
- }
127
+ this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE))
110
128
  }
111
129
 
112
- // Private
130
+ _deactivate(element, relatedElem) {
131
+ if (!element) {
132
+ return
133
+ }
113
134
 
114
- _activate(element, container, callback) {
115
- const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?
116
- SelectorEngine.find(SELECTOR_ACTIVE_UL, container) :
117
- SelectorEngine.children(container, SELECTOR_ACTIVE)
135
+ element.classList.remove(CLASS_NAME_ACTIVE)
136
+ element.blur()
118
137
 
119
- const active = activeElements[0]
120
- const isTransitioning = callback && (active && active.classList.contains(CLASS_NAME_FADE))
138
+ this._deactivate(getElementFromSelector(element)) // Search and deactivate the shown section too
121
139
 
122
- const complete = () => this._transitionComplete(element, active, callback)
140
+ const complete = () => {
141
+ if (element.getAttribute('role') !== 'tab') {
142
+ element.classList.remove(CLASS_NAME_SHOW)
143
+ return
144
+ }
123
145
 
124
- if (active && isTransitioning) {
125
- active.classList.remove(CLASS_NAME_SHOW)
126
- this._queueCallback(complete, element, true)
127
- } else {
128
- complete()
146
+ element.setAttribute('aria-selected', false)
147
+ element.setAttribute('tabindex', '-1')
148
+ this._toggleDropDown(element, false)
149
+ EventHandler.trigger(element, EVENT_HIDDEN, { relatedTarget: relatedElem })
129
150
  }
151
+
152
+ this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE))
130
153
  }
131
154
 
132
- _transitionComplete(element, active, callback) {
133
- if (active) {
134
- active.classList.remove(CLASS_NAME_ACTIVE)
155
+ _keydown(event) {
156
+ if (!([ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key))) {
157
+ return
158
+ }
135
159
 
136
- const dropdownChild = SelectorEngine.findOne(SELECTOR_DROPDOWN_ACTIVE_CHILD, active.parentNode)
160
+ event.stopPropagation()// stopPropagation/preventDefault both added to support up/down keys without scrolling the page
161
+ event.preventDefault()
162
+ const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key)
163
+ const nextActiveElement = getNextActiveElement(this._getChildren().filter(element => !isDisabled(element)), event.target, isNext, true)
137
164
 
138
- if (dropdownChild) {
139
- dropdownChild.classList.remove(CLASS_NAME_ACTIVE)
140
- }
165
+ if (nextActiveElement) {
166
+ Tab.getOrCreateInstance(nextActiveElement).show()
167
+ }
168
+ }
141
169
 
142
- if (active.getAttribute('role') === 'tab') {
143
- active.setAttribute('aria-selected', false)
144
- }
170
+ _getChildren() { // collection of inner elements
171
+ return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent)
172
+ }
173
+
174
+ _getActiveElem() {
175
+ return this._getChildren().find(child => this._elemIsActive(child)) || null
176
+ }
177
+
178
+ _setInitialAttributes(parent, children) {
179
+ this._setAttributeIfNotExists(parent, 'role', 'tablist')
180
+
181
+ for (const child of children) {
182
+ this._setInitialAttributesOnChild(child)
145
183
  }
184
+ }
146
185
 
147
- element.classList.add(CLASS_NAME_ACTIVE)
148
- if (element.getAttribute('role') === 'tab') {
149
- element.setAttribute('aria-selected', true)
186
+ _setInitialAttributesOnChild(child) {
187
+ child = this._getInnerElement(child)
188
+ const isActive = this._elemIsActive(child)
189
+ const outerElem = this._getOuterElement(child)
190
+ child.setAttribute('aria-selected', isActive)
191
+
192
+ if (outerElem !== child) {
193
+ this._setAttributeIfNotExists(outerElem, 'role', 'presentation')
150
194
  }
151
195
 
152
- reflow(element)
196
+ if (!isActive) {
197
+ child.setAttribute('tabindex', '-1')
198
+ }
153
199
 
154
- if (element.classList.contains(CLASS_NAME_FADE)) {
155
- element.classList.add(CLASS_NAME_SHOW)
200
+ this._setAttributeIfNotExists(child, 'role', 'tab')
201
+
202
+ // set attributes to the related panel too
203
+ this._setInitialAttributesOnTargetPanel(child)
204
+ }
205
+
206
+ _setInitialAttributesOnTargetPanel(child) {
207
+ const target = getElementFromSelector(child)
208
+
209
+ if (!target) {
210
+ return
156
211
  }
157
212
 
158
- let parent = element.parentNode
159
- if (parent && parent.nodeName === 'LI') {
160
- parent = parent.parentNode
213
+ this._setAttributeIfNotExists(target, 'role', 'tabpanel')
214
+
215
+ if (child.id) {
216
+ this._setAttributeIfNotExists(target, 'aria-labelledby', `#${child.id}`)
161
217
  }
218
+ }
162
219
 
163
- if (parent && parent.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {
164
- const dropdownElement = element.closest(SELECTOR_DROPDOWN)
220
+ _toggleDropDown(element, open) {
221
+ const outerElem = this._getOuterElement(element)
222
+ if (!outerElem.classList.contains(CLASS_DROPDOWN)) {
223
+ return
224
+ }
165
225
 
166
- if (dropdownElement) {
167
- SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE, dropdownElement)
168
- .forEach(dropdown => dropdown.classList.add(CLASS_NAME_ACTIVE))
226
+ const toggle = (selector, className) => {
227
+ const element = SelectorEngine.findOne(selector, outerElem)
228
+ if (element) {
229
+ element.classList.toggle(className, open)
169
230
  }
170
-
171
- element.setAttribute('aria-expanded', true)
172
231
  }
173
232
 
174
- if (callback) {
175
- callback()
233
+ toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE)
234
+ toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW)
235
+ toggle(SELECTOR_DROPDOWN_ITEM, CLASS_NAME_ACTIVE)
236
+ outerElem.setAttribute('aria-expanded', open)
237
+ }
238
+
239
+ _setAttributeIfNotExists(element, attribute, value) {
240
+ if (!element.hasAttribute(attribute)) {
241
+ element.setAttribute(attribute, value)
176
242
  }
177
243
  }
178
244
 
179
- // Static
245
+ _elemIsActive(elem) {
246
+ return elem.classList.contains(CLASS_NAME_ACTIVE)
247
+ }
248
+
249
+ // Try to get the inner element (usually the .nav-link)
250
+ _getInnerElement(elem) {
251
+ return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem)
252
+ }
180
253
 
254
+ // Try to get the outer element (usually the .nav-item)
255
+ _getOuterElement(elem) {
256
+ return elem.closest(SELECTOR_OUTER) || elem
257
+ }
258
+
259
+ // Static
181
260
  static jQueryInterface(config) {
182
261
  return this.each(function () {
183
262
  const data = Tab.getOrCreateInstance(this)
184
263
 
185
- if (typeof config === 'string') {
186
- if (typeof data[config] === 'undefined') {
187
- throw new TypeError(`No method named "${config}"`)
188
- }
264
+ if (typeof config !== 'string') {
265
+ return
266
+ }
189
267
 
190
- data[config]()
268
+ if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
269
+ throw new TypeError(`No method named "${config}"`)
191
270
  }
271
+
272
+ data[config]()
192
273
  })
193
274
  }
194
275
  }
195
276
 
196
277
  /**
197
- * ------------------------------------------------------------------------
198
- * Data Api implementation
199
- * ------------------------------------------------------------------------
278
+ * Data API implementation
200
279
  */
201
280
 
202
281
  EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
@@ -208,15 +287,19 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
208
287
  return
209
288
  }
210
289
 
211
- const data = Tab.getOrCreateInstance(this)
212
- data.show()
290
+ Tab.getOrCreateInstance(this).show()
213
291
  })
214
292
 
215
293
  /**
216
- * ------------------------------------------------------------------------
294
+ * Initialize on focus
295
+ */
296
+ EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
297
+ for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) {
298
+ Tab.getOrCreateInstance(element)
299
+ }
300
+ })
301
+ /**
217
302
  * jQuery
218
- * ------------------------------------------------------------------------
219
- * add .Tab to jQuery only if jQuery is present
220
303
  */
221
304
 
222
305
  defineJQueryPlugin(Tab)
package/js/src/toast.js CHANGED
@@ -1,24 +1,17 @@
1
1
  /**
2
2
  * --------------------------------------------------------------------------
3
- * Bootstrap (v5.1.3): toast.js
3
+ * Bootstrap (v5.2.0): toast.js
4
4
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
5
  * --------------------------------------------------------------------------
6
6
  */
7
7
 
8
- import {
9
- defineJQueryPlugin,
10
- reflow,
11
- typeCheckConfig
12
- } from './util/index'
8
+ import { defineJQueryPlugin, reflow } from './util/index'
13
9
  import EventHandler from './dom/event-handler'
14
- import Manipulator from './dom/manipulator'
15
10
  import BaseComponent from './base-component'
16
11
  import { enableDismissTrigger } from './util/component-functions'
17
12
 
18
13
  /**
19
- * ------------------------------------------------------------------------
20
14
  * Constants
21
- * ------------------------------------------------------------------------
22
15
  */
23
16
 
24
17
  const NAME = 'toast'
@@ -52,16 +45,13 @@ const Default = {
52
45
  }
53
46
 
54
47
  /**
55
- * ------------------------------------------------------------------------
56
- * Class Definition
57
- * ------------------------------------------------------------------------
48
+ * Class definition
58
49
  */
59
50
 
60
51
  class Toast extends BaseComponent {
61
52
  constructor(element, config) {
62
- super(element)
53
+ super(element, config)
63
54
 
64
- this._config = this._getConfig(config)
65
55
  this._timeout = null
66
56
  this._hasMouseInteraction = false
67
57
  this._hasKeyboardInteraction = false
@@ -69,21 +59,19 @@ class Toast extends BaseComponent {
69
59
  }
70
60
 
71
61
  // Getters
62
+ static get Default() {
63
+ return Default
64
+ }
72
65
 
73
66
  static get DefaultType() {
74
67
  return DefaultType
75
68
  }
76
69
 
77
- static get Default() {
78
- return Default
79
- }
80
-
81
70
  static get NAME() {
82
71
  return NAME
83
72
  }
84
73
 
85
74
  // Public
86
-
87
75
  show() {
88
76
  const showEvent = EventHandler.trigger(this._element, EVENT_SHOW)
89
77
 
@@ -106,14 +94,13 @@ class Toast extends BaseComponent {
106
94
 
107
95
  this._element.classList.remove(CLASS_NAME_HIDE) // @deprecated
108
96
  reflow(this._element)
109
- this._element.classList.add(CLASS_NAME_SHOW)
110
- this._element.classList.add(CLASS_NAME_SHOWING)
97
+ this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING)
111
98
 
112
99
  this._queueCallback(complete, this._element, this._config.animation)
113
100
  }
114
101
 
115
102
  hide() {
116
- if (!this._element.classList.contains(CLASS_NAME_SHOW)) {
103
+ if (!this.isShown()) {
117
104
  return
118
105
  }
119
106
 
@@ -125,8 +112,7 @@ class Toast extends BaseComponent {
125
112
 
126
113
  const complete = () => {
127
114
  this._element.classList.add(CLASS_NAME_HIDE) // @deprecated
128
- this._element.classList.remove(CLASS_NAME_SHOWING)
129
- this._element.classList.remove(CLASS_NAME_SHOW)
115
+ this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW)
130
116
  EventHandler.trigger(this._element, EVENT_HIDDEN)
131
117
  }
132
118
 
@@ -137,27 +123,19 @@ class Toast extends BaseComponent {
137
123
  dispose() {
138
124
  this._clearTimeout()
139
125
 
140
- if (this._element.classList.contains(CLASS_NAME_SHOW)) {
126
+ if (this.isShown()) {
141
127
  this._element.classList.remove(CLASS_NAME_SHOW)
142
128
  }
143
129
 
144
130
  super.dispose()
145
131
  }
146
132
 
147
- // Private
148
-
149
- _getConfig(config) {
150
- config = {
151
- ...Default,
152
- ...Manipulator.getDataAttributes(this._element),
153
- ...(typeof config === 'object' && config ? config : {})
154
- }
155
-
156
- typeCheckConfig(NAME, config, this.constructor.DefaultType)
157
-
158
- return config
133
+ isShown() {
134
+ return this._element.classList.contains(CLASS_NAME_SHOW)
159
135
  }
160
136
 
137
+ // Private
138
+
161
139
  _maybeScheduleHide() {
162
140
  if (!this._config.autohide) {
163
141
  return
@@ -212,7 +190,6 @@ class Toast extends BaseComponent {
212
190
  }
213
191
 
214
192
  // Static
215
-
216
193
  static jQueryInterface(config) {
217
194
  return this.each(function () {
218
195
  const data = Toast.getOrCreateInstance(this, config)
@@ -228,13 +205,14 @@ class Toast extends BaseComponent {
228
205
  }
229
206
  }
230
207
 
208
+ /**
209
+ * Data API implementation
210
+ */
211
+
231
212
  enableDismissTrigger(Toast)
232
213
 
233
214
  /**
234
- * ------------------------------------------------------------------------
235
215
  * jQuery
236
- * ------------------------------------------------------------------------
237
- * add .Toast to jQuery only if jQuery is present
238
216
  */
239
217
 
240
218
  defineJQueryPlugin(Toast)