@openeuropa/bcl-bootstrap 0.24.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.
- package/bootstrap-icons.svg +1 -1
- package/icons/apple.svg +2 -2
- package/icons/boombox-fill.svg +2 -2
- package/icons/cup-fill.svg +1 -1
- package/icons/cup.svg +1 -1
- package/js/dist/alert.js +3 -12
- package/js/dist/alert.js.map +1 -1
- package/js/dist/base-component.js +32 -18
- package/js/dist/base-component.js.map +1 -1
- package/js/dist/button.js +3 -12
- package/js/dist/button.js.map +1 -1
- package/js/dist/carousel.js +207 -307
- package/js/dist/carousel.js.map +1 -1
- package/js/dist/collapse.js +57 -88
- package/js/dist/collapse.js.map +1 -1
- package/js/dist/dom/data.js +1 -3
- package/js/dist/dom/data.js.map +1 -1
- package/js/dist/dom/event-handler.js +87 -106
- package/js/dist/dom/event-handler.js.map +1 -1
- package/js/dist/dom/manipulator.js +21 -25
- package/js/dist/dom/manipulator.js.map +1 -1
- package/js/dist/dom/selector-engine.js +11 -10
- package/js/dist/dom/selector-engine.js.map +1 -1
- package/js/dist/dropdown.js +83 -115
- package/js/dist/dropdown.js.map +1 -1
- package/js/dist/modal.js +95 -152
- package/js/dist/modal.js.map +1 -1
- package/js/dist/offcanvas.js +75 -58
- package/js/dist/offcanvas.js.map +1 -1
- package/js/dist/popover.js +29 -56
- package/js/dist/popover.js.map +1 -1
- package/js/dist/scrollspy.js +176 -125
- package/js/dist/scrollspy.js.map +1 -1
- package/js/dist/tab.js +207 -92
- package/js/dist/tab.js.map +1 -1
- package/js/dist/toast.js +23 -37
- package/js/dist/toast.js.map +1 -1
- package/js/dist/tooltip.js +259 -348
- package/js/dist/tooltip.js.map +1 -1
- package/js/dist/util/backdrop.js +62 -39
- package/js/dist/util/backdrop.js.map +1 -1
- package/js/dist/util/component-functions.js +1 -1
- package/js/dist/util/component-functions.js.map +1 -1
- package/js/dist/util/config.js +75 -0
- package/js/dist/util/config.js.map +1 -0
- package/js/dist/util/focustrap.js +41 -34
- package/js/dist/util/focustrap.js.map +1 -1
- package/js/dist/util/index.js +56 -52
- package/js/dist/util/index.js.map +1 -1
- package/js/dist/util/sanitizer.js +12 -19
- package/js/dist/util/sanitizer.js.map +1 -1
- package/js/dist/util/scrollbar.js +49 -34
- package/js/dist/util/scrollbar.js.map +1 -1
- package/js/dist/util/swipe.js +151 -0
- package/js/dist/util/swipe.js.map +1 -0
- package/js/dist/util/template-factory.js +173 -0
- package/js/dist/util/template-factory.js.map +1 -0
- package/js/src/alert.js +3 -15
- package/js/src/base-component.js +28 -18
- package/js/src/button.js +3 -17
- package/js/src/carousel.js +203 -319
- package/js/src/collapse.js +61 -94
- package/js/src/dom/data.js +1 -3
- package/js/src/dom/event-handler.js +80 -108
- package/js/src/dom/manipulator.js +22 -31
- package/js/src/dom/selector-engine.js +10 -19
- package/js/src/dropdown.js +84 -138
- package/js/src/modal.js +94 -158
- package/js/src/offcanvas.js +72 -61
- package/js/src/popover.js +31 -62
- package/js/src/scrollspy.js +166 -171
- package/js/src/tab.js +193 -110
- package/js/src/toast.js +19 -41
- package/js/src/tooltip.js +259 -371
- package/js/src/util/backdrop.js +55 -36
- package/js/src/util/component-functions.js +1 -1
- package/js/src/util/config.js +66 -0
- package/js/src/util/focustrap.js +38 -28
- package/js/src/util/index.js +67 -64
- package/js/src/util/sanitizer.js +11 -19
- package/js/src/util/scrollbar.js +47 -30
- package/js/src/util/swipe.js +146 -0
- package/js/src/util/template-factory.js +160 -0
- package/package.json +4 -4
- package/scss/_accordion.scss +52 -24
- package/scss/_alert.scss +18 -4
- package/scss/_badge.scss +14 -5
- package/scss/_breadcrumb.scss +22 -10
- package/scss/_button-group.scss +3 -0
- package/scss/_buttons.scss +97 -22
- package/scss/_card.scss +55 -37
- package/scss/_close.scss +1 -1
- package/scss/_containers.scss +1 -1
- package/scss/_dropdown.scss +83 -75
- package/scss/_functions.scss +7 -7
- package/scss/_grid.scss +3 -3
- package/scss/_helpers.scss +1 -0
- package/scss/_list-group.scss +44 -27
- package/scss/_maps.scss +54 -0
- package/scss/_modal.scss +71 -43
- package/scss/_nav.scss +53 -20
- package/scss/_navbar.scss +91 -150
- package/scss/_offcanvas.scss +119 -59
- package/scss/_pagination.scss +66 -21
- package/scss/_placeholders.scss +1 -1
- package/scss/_popover.scss +90 -52
- package/scss/_progress.scss +20 -9
- package/scss/_reboot.scss +25 -40
- package/scss/_root.scss +40 -21
- package/scss/_spinners.scss +38 -22
- package/scss/_tables.scss +32 -23
- package/scss/_toasts.scss +35 -16
- package/scss/_tooltip.scss +61 -56
- package/scss/_type.scss +2 -0
- package/scss/_utilities.scss +43 -26
- package/scss/_variables.scss +113 -121
- package/scss/bootstrap-grid.scss +3 -6
- package/scss/bootstrap-reboot.scss +3 -7
- package/scss/bootstrap-utilities.scss +3 -6
- package/scss/bootstrap.scss +4 -6
- package/scss/forms/_floating-labels.scss +14 -3
- package/scss/forms/_form-check.scss +28 -5
- package/scss/forms/_form-control.scss +12 -37
- package/scss/forms/_form-select.scss +0 -1
- package/scss/forms/_input-group.scss +15 -7
- package/scss/helpers/_color-bg.scss +10 -0
- package/scss/helpers/_colored-links.scss +2 -2
- package/scss/helpers/_position.scss +7 -1
- package/scss/helpers/_ratio.scss +2 -2
- package/scss/helpers/_vr.scss +1 -1
- package/scss/mixins/_alert.scss +7 -3
- package/scss/mixins/_banner.scss +9 -0
- package/scss/mixins/_breakpoints.scss +8 -8
- package/scss/mixins/_buttons.scss +32 -95
- package/scss/mixins/_container.scss +4 -2
- package/scss/mixins/_forms.scss +8 -0
- package/scss/mixins/_gradients.scss +1 -1
- package/scss/mixins/_grid.scss +12 -12
- package/scss/mixins/_pagination.scss +4 -25
- package/scss/mixins/_reset-text.scss +1 -1
- package/scss/mixins/_table-variants.scss +12 -9
- package/scss/mixins/_utilities.scss +12 -4
|
@@ -1,28 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* --------------------------------------------------------------------------
|
|
3
|
-
* Bootstrap (v5.
|
|
3
|
+
* Bootstrap (v5.2.0): dom/manipulator.js
|
|
4
4
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
5
5
|
* --------------------------------------------------------------------------
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
function normalizeData(
|
|
9
|
-
if (
|
|
8
|
+
function normalizeData(value) {
|
|
9
|
+
if (value === 'true') {
|
|
10
10
|
return true
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
if (
|
|
13
|
+
if (value === 'false') {
|
|
14
14
|
return false
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
if (
|
|
18
|
-
return Number(
|
|
17
|
+
if (value === Number(value).toString()) {
|
|
18
|
+
return Number(value)
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
if (
|
|
21
|
+
if (value === '' || value === 'null') {
|
|
22
22
|
return null
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
if (typeof value !== 'string') {
|
|
26
|
+
return value
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
return JSON.parse(decodeURIComponent(value))
|
|
31
|
+
} catch {
|
|
32
|
+
return value
|
|
33
|
+
}
|
|
26
34
|
}
|
|
27
35
|
|
|
28
36
|
function normalizeDataKey(key) {
|
|
@@ -44,36 +52,19 @@ const Manipulator = {
|
|
|
44
52
|
}
|
|
45
53
|
|
|
46
54
|
const attributes = {}
|
|
55
|
+
const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'))
|
|
47
56
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
attributes[pureKey] = normalizeData(element.dataset[key])
|
|
54
|
-
})
|
|
57
|
+
for (const key of bsKeys) {
|
|
58
|
+
let pureKey = key.replace(/^bs/, '')
|
|
59
|
+
pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length)
|
|
60
|
+
attributes[pureKey] = normalizeData(element.dataset[key])
|
|
61
|
+
}
|
|
55
62
|
|
|
56
63
|
return attributes
|
|
57
64
|
},
|
|
58
65
|
|
|
59
66
|
getDataAttribute(element, key) {
|
|
60
67
|
return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`))
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
offset(element) {
|
|
64
|
-
const rect = element.getBoundingClientRect()
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
top: rect.top + window.pageYOffset,
|
|
68
|
-
left: rect.left + window.pageXOffset
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
position(element) {
|
|
73
|
-
return {
|
|
74
|
-
top: element.offsetTop,
|
|
75
|
-
left: element.offsetLeft
|
|
76
|
-
}
|
|
77
68
|
}
|
|
78
69
|
}
|
|
79
70
|
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* --------------------------------------------------------------------------
|
|
3
|
-
* Bootstrap (v5.
|
|
3
|
+
* Bootstrap (v5.2.0): dom/selector-engine.js
|
|
4
4
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
5
5
|
* --------------------------------------------------------------------------
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import { isDisabled, isVisible } from '../util/index'
|
|
9
|
+
|
|
8
10
|
/**
|
|
9
|
-
* ------------------------------------------------------------------------
|
|
10
11
|
* Constants
|
|
11
|
-
* ------------------------------------------------------------------------
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { isDisabled, isVisible } from '../util/index'
|
|
15
|
-
|
|
16
|
-
const NODE_TEXT = 3
|
|
17
|
-
|
|
18
14
|
const SelectorEngine = {
|
|
19
15
|
find(selector, element = document.documentElement) {
|
|
20
16
|
return [].concat(...Element.prototype.querySelectorAll.call(element, selector))
|
|
@@ -25,21 +21,16 @@ const SelectorEngine = {
|
|
|
25
21
|
},
|
|
26
22
|
|
|
27
23
|
children(element, selector) {
|
|
28
|
-
return [].concat(...element.children)
|
|
29
|
-
.filter(child => child.matches(selector))
|
|
24
|
+
return [].concat(...element.children).filter(child => child.matches(selector))
|
|
30
25
|
},
|
|
31
26
|
|
|
32
27
|
parents(element, selector) {
|
|
33
28
|
const parents = []
|
|
29
|
+
let ancestor = element.parentNode.closest(selector)
|
|
34
30
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (ancestor.matches(selector)) {
|
|
39
|
-
parents.push(ancestor)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
ancestor = ancestor.parentNode
|
|
31
|
+
while (ancestor) {
|
|
32
|
+
parents.push(ancestor)
|
|
33
|
+
ancestor = ancestor.parentNode.closest(selector)
|
|
43
34
|
}
|
|
44
35
|
|
|
45
36
|
return parents
|
|
@@ -58,7 +49,7 @@ const SelectorEngine = {
|
|
|
58
49
|
|
|
59
50
|
return []
|
|
60
51
|
},
|
|
61
|
-
|
|
52
|
+
// TODO: this is now unused; remove later along with prev()
|
|
62
53
|
next(element, selector) {
|
|
63
54
|
let next = element.nextElementSibling
|
|
64
55
|
|
|
@@ -83,7 +74,7 @@ const SelectorEngine = {
|
|
|
83
74
|
'details',
|
|
84
75
|
'[tabindex]',
|
|
85
76
|
'[contenteditable="true"]'
|
|
86
|
-
].map(selector => `${selector}:not([tabindex^="-"])`).join(',
|
|
77
|
+
].map(selector => `${selector}:not([tabindex^="-"])`).join(',')
|
|
87
78
|
|
|
88
79
|
return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el))
|
|
89
80
|
}
|
package/js/src/dropdown.js
CHANGED
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* --------------------------------------------------------------------------
|
|
3
|
-
* Bootstrap (v5.
|
|
3
|
+
* Bootstrap (v5.2.0): dropdown.js
|
|
4
4
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
5
5
|
* --------------------------------------------------------------------------
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import * as Popper from '@popperjs/core'
|
|
9
|
-
|
|
10
9
|
import {
|
|
11
10
|
defineJQueryPlugin,
|
|
12
11
|
getElement,
|
|
13
|
-
getElementFromSelector,
|
|
14
12
|
getNextActiveElement,
|
|
15
13
|
isDisabled,
|
|
16
14
|
isElement,
|
|
17
15
|
isRTL,
|
|
18
16
|
isVisible,
|
|
19
|
-
noop
|
|
20
|
-
typeCheckConfig
|
|
17
|
+
noop
|
|
21
18
|
} from './util/index'
|
|
22
19
|
import EventHandler from './dom/event-handler'
|
|
23
20
|
import Manipulator from './dom/manipulator'
|
|
@@ -25,9 +22,7 @@ import SelectorEngine from './dom/selector-engine'
|
|
|
25
22
|
import BaseComponent from './base-component'
|
|
26
23
|
|
|
27
24
|
/**
|
|
28
|
-
* ------------------------------------------------------------------------
|
|
29
25
|
* Constants
|
|
30
|
-
* ------------------------------------------------------------------------
|
|
31
26
|
*/
|
|
32
27
|
|
|
33
28
|
const NAME = 'dropdown'
|
|
@@ -36,14 +31,11 @@ const EVENT_KEY = `.${DATA_KEY}`
|
|
|
36
31
|
const DATA_API_KEY = '.data-api'
|
|
37
32
|
|
|
38
33
|
const ESCAPE_KEY = 'Escape'
|
|
39
|
-
const SPACE_KEY = 'Space'
|
|
40
34
|
const TAB_KEY = 'Tab'
|
|
41
35
|
const ARROW_UP_KEY = 'ArrowUp'
|
|
42
36
|
const ARROW_DOWN_KEY = 'ArrowDown'
|
|
43
37
|
const RIGHT_MOUSE_BUTTON = 2 // MouseEvent.button value for the secondary button, usually the right button
|
|
44
38
|
|
|
45
|
-
const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEY}|${ARROW_DOWN_KEY}|${ESCAPE_KEY}`)
|
|
46
|
-
|
|
47
39
|
const EVENT_HIDE = `hide${EVENT_KEY}`
|
|
48
40
|
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
|
|
49
41
|
const EVENT_SHOW = `show${EVENT_KEY}`
|
|
@@ -56,10 +48,13 @@ const CLASS_NAME_SHOW = 'show'
|
|
|
56
48
|
const CLASS_NAME_DROPUP = 'dropup'
|
|
57
49
|
const CLASS_NAME_DROPEND = 'dropend'
|
|
58
50
|
const CLASS_NAME_DROPSTART = 'dropstart'
|
|
59
|
-
const
|
|
51
|
+
const CLASS_NAME_DROPUP_CENTER = 'dropup-center'
|
|
52
|
+
const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center'
|
|
60
53
|
|
|
61
|
-
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="dropdown"]'
|
|
54
|
+
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)'
|
|
55
|
+
const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE}.${CLASS_NAME_SHOW}`
|
|
62
56
|
const SELECTOR_MENU = '.dropdown-menu'
|
|
57
|
+
const SELECTOR_NAVBAR = '.navbar'
|
|
63
58
|
const SELECTOR_NAVBAR_NAV = '.navbar-nav'
|
|
64
59
|
const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
|
|
65
60
|
|
|
@@ -69,43 +64,42 @@ const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start'
|
|
|
69
64
|
const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end'
|
|
70
65
|
const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start'
|
|
71
66
|
const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start'
|
|
67
|
+
const PLACEMENT_TOPCENTER = 'top'
|
|
68
|
+
const PLACEMENT_BOTTOMCENTER = 'bottom'
|
|
72
69
|
|
|
73
70
|
const Default = {
|
|
74
|
-
|
|
71
|
+
autoClose: true,
|
|
75
72
|
boundary: 'clippingParents',
|
|
76
|
-
reference: 'toggle',
|
|
77
73
|
display: 'dynamic',
|
|
74
|
+
offset: [0, 2],
|
|
78
75
|
popperConfig: null,
|
|
79
|
-
|
|
76
|
+
reference: 'toggle'
|
|
80
77
|
}
|
|
81
78
|
|
|
82
79
|
const DefaultType = {
|
|
83
|
-
|
|
80
|
+
autoClose: '(boolean|string)',
|
|
84
81
|
boundary: '(string|element)',
|
|
85
|
-
reference: '(string|element|object)',
|
|
86
82
|
display: 'string',
|
|
83
|
+
offset: '(array|string|function)',
|
|
87
84
|
popperConfig: '(null|object|function)',
|
|
88
|
-
|
|
85
|
+
reference: '(string|element|object)'
|
|
89
86
|
}
|
|
90
87
|
|
|
91
88
|
/**
|
|
92
|
-
*
|
|
93
|
-
* Class Definition
|
|
94
|
-
* ------------------------------------------------------------------------
|
|
89
|
+
* Class definition
|
|
95
90
|
*/
|
|
96
91
|
|
|
97
92
|
class Dropdown extends BaseComponent {
|
|
98
93
|
constructor(element, config) {
|
|
99
|
-
super(element)
|
|
94
|
+
super(element, config)
|
|
100
95
|
|
|
101
96
|
this._popper = null
|
|
102
|
-
this.
|
|
103
|
-
this._menu = this.
|
|
97
|
+
this._parent = this._element.parentNode // dropdown wrapper
|
|
98
|
+
this._menu = SelectorEngine.findOne(SELECTOR_MENU, this._parent)
|
|
104
99
|
this._inNavbar = this._detectNavbar()
|
|
105
100
|
}
|
|
106
101
|
|
|
107
102
|
// Getters
|
|
108
|
-
|
|
109
103
|
static get Default() {
|
|
110
104
|
return Default
|
|
111
105
|
}
|
|
@@ -119,13 +113,12 @@ class Dropdown extends BaseComponent {
|
|
|
119
113
|
}
|
|
120
114
|
|
|
121
115
|
// Public
|
|
122
|
-
|
|
123
116
|
toggle() {
|
|
124
117
|
return this._isShown() ? this.hide() : this.show()
|
|
125
118
|
}
|
|
126
119
|
|
|
127
120
|
show() {
|
|
128
|
-
if (isDisabled(this._element) || this._isShown(
|
|
121
|
+
if (isDisabled(this._element) || this._isShown()) {
|
|
129
122
|
return
|
|
130
123
|
}
|
|
131
124
|
|
|
@@ -139,22 +132,16 @@ class Dropdown extends BaseComponent {
|
|
|
139
132
|
return
|
|
140
133
|
}
|
|
141
134
|
|
|
142
|
-
|
|
143
|
-
// Totally disable Popper for Dropdowns in Navbar
|
|
144
|
-
if (this._inNavbar) {
|
|
145
|
-
Manipulator.setDataAttribute(this._menu, 'popper', 'none')
|
|
146
|
-
} else {
|
|
147
|
-
this._createPopper(parent)
|
|
148
|
-
}
|
|
135
|
+
this._createPopper()
|
|
149
136
|
|
|
150
137
|
// If this is a touch-enabled device we add extra
|
|
151
138
|
// empty mouseover listeners to the body's immediate children;
|
|
152
139
|
// only needed because of broken event delegation on iOS
|
|
153
140
|
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
|
154
|
-
if ('ontouchstart' in document.documentElement &&
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
141
|
+
if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {
|
|
142
|
+
for (const element of [].concat(...document.body.children)) {
|
|
143
|
+
EventHandler.on(element, 'mouseover', noop)
|
|
144
|
+
}
|
|
158
145
|
}
|
|
159
146
|
|
|
160
147
|
this._element.focus()
|
|
@@ -166,7 +153,7 @@ class Dropdown extends BaseComponent {
|
|
|
166
153
|
}
|
|
167
154
|
|
|
168
155
|
hide() {
|
|
169
|
-
if (isDisabled(this._element) || !this._isShown(
|
|
156
|
+
if (isDisabled(this._element) || !this._isShown()) {
|
|
170
157
|
return
|
|
171
158
|
}
|
|
172
159
|
|
|
@@ -193,7 +180,6 @@ class Dropdown extends BaseComponent {
|
|
|
193
180
|
}
|
|
194
181
|
|
|
195
182
|
// Private
|
|
196
|
-
|
|
197
183
|
_completeHide(relatedTarget) {
|
|
198
184
|
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget)
|
|
199
185
|
if (hideEvent.defaultPrevented) {
|
|
@@ -203,8 +189,9 @@ class Dropdown extends BaseComponent {
|
|
|
203
189
|
// If this is a touch-enabled device we remove the extra
|
|
204
190
|
// empty mouseover listeners we added for iOS support
|
|
205
191
|
if ('ontouchstart' in document.documentElement) {
|
|
206
|
-
[].concat(...document.body.children)
|
|
207
|
-
|
|
192
|
+
for (const element of [].concat(...document.body.children)) {
|
|
193
|
+
EventHandler.off(element, 'mouseover', noop)
|
|
194
|
+
}
|
|
208
195
|
}
|
|
209
196
|
|
|
210
197
|
if (this._popper) {
|
|
@@ -219,13 +206,7 @@ class Dropdown extends BaseComponent {
|
|
|
219
206
|
}
|
|
220
207
|
|
|
221
208
|
_getConfig(config) {
|
|
222
|
-
config =
|
|
223
|
-
...this.constructor.Default,
|
|
224
|
-
...Manipulator.getDataAttributes(this._element),
|
|
225
|
-
...config
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
typeCheckConfig(NAME, config, this.constructor.DefaultType)
|
|
209
|
+
config = super._getConfig(config)
|
|
229
210
|
|
|
230
211
|
if (typeof config.reference === 'object' && !isElement(config.reference) &&
|
|
231
212
|
typeof config.reference.getBoundingClientRect !== 'function'
|
|
@@ -237,7 +218,7 @@ class Dropdown extends BaseComponent {
|
|
|
237
218
|
return config
|
|
238
219
|
}
|
|
239
220
|
|
|
240
|
-
_createPopper(
|
|
221
|
+
_createPopper() {
|
|
241
222
|
if (typeof Popper === 'undefined') {
|
|
242
223
|
throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)')
|
|
243
224
|
}
|
|
@@ -245,7 +226,7 @@ class Dropdown extends BaseComponent {
|
|
|
245
226
|
let referenceElement = this._element
|
|
246
227
|
|
|
247
228
|
if (this._config.reference === 'parent') {
|
|
248
|
-
referenceElement =
|
|
229
|
+
referenceElement = this._parent
|
|
249
230
|
} else if (isElement(this._config.reference)) {
|
|
250
231
|
referenceElement = getElement(this._config.reference)
|
|
251
232
|
} else if (typeof this._config.reference === 'object') {
|
|
@@ -253,25 +234,15 @@ class Dropdown extends BaseComponent {
|
|
|
253
234
|
}
|
|
254
235
|
|
|
255
236
|
const popperConfig = this._getPopperConfig()
|
|
256
|
-
const isDisplayStatic = popperConfig.modifiers.find(modifier => modifier.name === 'applyStyles' && modifier.enabled === false)
|
|
257
|
-
|
|
258
237
|
this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig)
|
|
259
|
-
|
|
260
|
-
if (isDisplayStatic) {
|
|
261
|
-
Manipulator.setDataAttribute(this._menu, 'popper', 'static')
|
|
262
|
-
}
|
|
263
238
|
}
|
|
264
239
|
|
|
265
|
-
_isShown(
|
|
266
|
-
return
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
_getMenuElement() {
|
|
270
|
-
return SelectorEngine.next(this._element, SELECTOR_MENU)[0]
|
|
240
|
+
_isShown() {
|
|
241
|
+
return this._menu.classList.contains(CLASS_NAME_SHOW)
|
|
271
242
|
}
|
|
272
243
|
|
|
273
244
|
_getPlacement() {
|
|
274
|
-
const parentDropdown = this.
|
|
245
|
+
const parentDropdown = this._parent
|
|
275
246
|
|
|
276
247
|
if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {
|
|
277
248
|
return PLACEMENT_RIGHT
|
|
@@ -281,6 +252,14 @@ class Dropdown extends BaseComponent {
|
|
|
281
252
|
return PLACEMENT_LEFT
|
|
282
253
|
}
|
|
283
254
|
|
|
255
|
+
if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {
|
|
256
|
+
return PLACEMENT_TOPCENTER
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {
|
|
260
|
+
return PLACEMENT_BOTTOMCENTER
|
|
261
|
+
}
|
|
262
|
+
|
|
284
263
|
// We need to trim the value because custom properties can also include spaces
|
|
285
264
|
const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'
|
|
286
265
|
|
|
@@ -292,14 +271,14 @@ class Dropdown extends BaseComponent {
|
|
|
292
271
|
}
|
|
293
272
|
|
|
294
273
|
_detectNavbar() {
|
|
295
|
-
return this._element.closest(
|
|
274
|
+
return this._element.closest(SELECTOR_NAVBAR) !== null
|
|
296
275
|
}
|
|
297
276
|
|
|
298
277
|
_getOffset() {
|
|
299
278
|
const { offset } = this._config
|
|
300
279
|
|
|
301
280
|
if (typeof offset === 'string') {
|
|
302
|
-
return offset.split(',').map(
|
|
281
|
+
return offset.split(',').map(value => Number.parseInt(value, 10))
|
|
303
282
|
}
|
|
304
283
|
|
|
305
284
|
if (typeof offset === 'function') {
|
|
@@ -326,8 +305,9 @@ class Dropdown extends BaseComponent {
|
|
|
326
305
|
}]
|
|
327
306
|
}
|
|
328
307
|
|
|
329
|
-
// Disable Popper if we have a static display
|
|
330
|
-
if (this._config.display === 'static') {
|
|
308
|
+
// Disable Popper if we have a static display or Dropdown is in Navbar
|
|
309
|
+
if (this._inNavbar || this._config.display === 'static') {
|
|
310
|
+
Manipulator.setDataAttribute(this._menu, 'popper', 'static') // todo:v6 remove
|
|
331
311
|
defaultBsPopperConfig.modifiers = [{
|
|
332
312
|
name: 'applyStyles',
|
|
333
313
|
enabled: false
|
|
@@ -341,7 +321,7 @@ class Dropdown extends BaseComponent {
|
|
|
341
321
|
}
|
|
342
322
|
|
|
343
323
|
_selectMenuItem({ key, target }) {
|
|
344
|
-
const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(isVisible)
|
|
324
|
+
const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element))
|
|
345
325
|
|
|
346
326
|
if (!items.length) {
|
|
347
327
|
return
|
|
@@ -353,7 +333,6 @@ class Dropdown extends BaseComponent {
|
|
|
353
333
|
}
|
|
354
334
|
|
|
355
335
|
// Static
|
|
356
|
-
|
|
357
336
|
static jQueryInterface(config) {
|
|
358
337
|
return this.each(function () {
|
|
359
338
|
const data = Dropdown.getOrCreateInstance(this, config)
|
|
@@ -371,111 +350,81 @@ class Dropdown extends BaseComponent {
|
|
|
371
350
|
}
|
|
372
351
|
|
|
373
352
|
static clearMenus(event) {
|
|
374
|
-
if (event
|
|
353
|
+
if (event.button === RIGHT_MOUSE_BUTTON || (event.type === 'keyup' && event.key !== TAB_KEY)) {
|
|
375
354
|
return
|
|
376
355
|
}
|
|
377
356
|
|
|
378
|
-
const
|
|
357
|
+
const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN)
|
|
379
358
|
|
|
380
|
-
for (
|
|
381
|
-
const context = Dropdown.getInstance(
|
|
359
|
+
for (const toggle of openToggles) {
|
|
360
|
+
const context = Dropdown.getInstance(toggle)
|
|
382
361
|
if (!context || context._config.autoClose === false) {
|
|
383
362
|
continue
|
|
384
363
|
}
|
|
385
364
|
|
|
386
|
-
|
|
365
|
+
const composedPath = event.composedPath()
|
|
366
|
+
const isMenuTarget = composedPath.includes(context._menu)
|
|
367
|
+
if (
|
|
368
|
+
composedPath.includes(context._element) ||
|
|
369
|
+
(context._config.autoClose === 'inside' && !isMenuTarget) ||
|
|
370
|
+
(context._config.autoClose === 'outside' && isMenuTarget)
|
|
371
|
+
) {
|
|
387
372
|
continue
|
|
388
373
|
}
|
|
389
374
|
|
|
390
|
-
|
|
391
|
-
|
|
375
|
+
// Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
|
|
376
|
+
if (context._menu.contains(event.target) && ((event.type === 'keyup' && event.key === TAB_KEY) || /input|select|option|textarea|form/i.test(event.target.tagName))) {
|
|
377
|
+
continue
|
|
392
378
|
}
|
|
393
379
|
|
|
394
|
-
|
|
395
|
-
const composedPath = event.composedPath()
|
|
396
|
-
const isMenuTarget = composedPath.includes(context._menu)
|
|
397
|
-
if (
|
|
398
|
-
composedPath.includes(context._element) ||
|
|
399
|
-
(context._config.autoClose === 'inside' && !isMenuTarget) ||
|
|
400
|
-
(context._config.autoClose === 'outside' && isMenuTarget)
|
|
401
|
-
) {
|
|
402
|
-
continue
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
// Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
|
|
406
|
-
if (context._menu.contains(event.target) && ((event.type === 'keyup' && event.key === TAB_KEY) || /input|select|option|textarea|form/i.test(event.target.tagName))) {
|
|
407
|
-
continue
|
|
408
|
-
}
|
|
380
|
+
const relatedTarget = { relatedTarget: context._element }
|
|
409
381
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
}
|
|
382
|
+
if (event.type === 'click') {
|
|
383
|
+
relatedTarget.clickEvent = event
|
|
413
384
|
}
|
|
414
385
|
|
|
415
386
|
context._completeHide(relatedTarget)
|
|
416
387
|
}
|
|
417
388
|
}
|
|
418
389
|
|
|
419
|
-
static getParentFromElement(element) {
|
|
420
|
-
return getElementFromSelector(element) || element.parentNode
|
|
421
|
-
}
|
|
422
|
-
|
|
423
390
|
static dataApiKeydownHandler(event) {
|
|
424
|
-
// If not
|
|
425
|
-
//
|
|
426
|
-
// If input/textarea:
|
|
427
|
-
// - If space key => not a dropdown command
|
|
428
|
-
// - If key is other than escape
|
|
429
|
-
// - If key is not up or down => not a dropdown command
|
|
430
|
-
// - If trigger inside the menu => not a dropdown command
|
|
431
|
-
if (/input|textarea/i.test(event.target.tagName) ?
|
|
432
|
-
event.key === SPACE_KEY || (event.key !== ESCAPE_KEY &&
|
|
433
|
-
((event.key !== ARROW_DOWN_KEY && event.key !== ARROW_UP_KEY) ||
|
|
434
|
-
event.target.closest(SELECTOR_MENU))) :
|
|
435
|
-
!REGEXP_KEYDOWN.test(event.key)) {
|
|
436
|
-
return
|
|
437
|
-
}
|
|
391
|
+
// If not an UP | DOWN | ESCAPE key => not a dropdown command
|
|
392
|
+
// If input/textarea && if key is other than ESCAPE => not a dropdown command
|
|
438
393
|
|
|
439
|
-
const
|
|
394
|
+
const isInput = /input|textarea/i.test(event.target.tagName)
|
|
395
|
+
const isEscapeEvent = event.key === ESCAPE_KEY
|
|
396
|
+
const isUpOrDownEvent = [ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key)
|
|
440
397
|
|
|
441
|
-
if (!
|
|
398
|
+
if (!isUpOrDownEvent && !isEscapeEvent) {
|
|
442
399
|
return
|
|
443
400
|
}
|
|
444
401
|
|
|
445
|
-
|
|
446
|
-
event.stopPropagation()
|
|
447
|
-
|
|
448
|
-
if (isDisabled(this)) {
|
|
402
|
+
if (isInput && !isEscapeEvent) {
|
|
449
403
|
return
|
|
450
404
|
}
|
|
451
405
|
|
|
452
|
-
|
|
453
|
-
const instance = Dropdown.getOrCreateInstance(getToggleButton)
|
|
454
|
-
|
|
455
|
-
if (event.key === ESCAPE_KEY) {
|
|
456
|
-
instance.hide()
|
|
457
|
-
return
|
|
458
|
-
}
|
|
406
|
+
event.preventDefault()
|
|
459
407
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
instance.show()
|
|
463
|
-
}
|
|
408
|
+
const getToggleButton = SelectorEngine.findOne(SELECTOR_DATA_TOGGLE, event.delegateTarget.parentNode)
|
|
409
|
+
const instance = Dropdown.getOrCreateInstance(getToggleButton)
|
|
464
410
|
|
|
411
|
+
if (isUpOrDownEvent) {
|
|
412
|
+
event.stopPropagation()
|
|
413
|
+
instance.show()
|
|
465
414
|
instance._selectMenuItem(event)
|
|
466
415
|
return
|
|
467
416
|
}
|
|
468
417
|
|
|
469
|
-
if (
|
|
470
|
-
|
|
418
|
+
if (instance._isShown()) { // else is escape and we check if it is shown
|
|
419
|
+
event.stopPropagation()
|
|
420
|
+
instance.hide()
|
|
421
|
+
getToggleButton.focus()
|
|
471
422
|
}
|
|
472
423
|
}
|
|
473
424
|
}
|
|
474
425
|
|
|
475
426
|
/**
|
|
476
|
-
*
|
|
477
|
-
* Data Api implementation
|
|
478
|
-
* ------------------------------------------------------------------------
|
|
427
|
+
* Data API implementation
|
|
479
428
|
*/
|
|
480
429
|
|
|
481
430
|
EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler)
|
|
@@ -488,10 +437,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
|
|
|
488
437
|
})
|
|
489
438
|
|
|
490
439
|
/**
|
|
491
|
-
* ------------------------------------------------------------------------
|
|
492
440
|
* jQuery
|
|
493
|
-
* ------------------------------------------------------------------------
|
|
494
|
-
* add .Dropdown to jQuery only if jQuery is present
|
|
495
441
|
*/
|
|
496
442
|
|
|
497
443
|
defineJQueryPlugin(Dropdown)
|