@coreui/coreui 4.1.4 → 4.2.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 (208) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +64 -11
  3. package/dist/css/bootstrap-reboot.css +488 -0
  4. package/dist/css/bootstrap-reboot.css.map +1 -0
  5. package/dist/css/bootstrap-reboot.min.css +8 -0
  6. package/dist/css/bootstrap-reboot.min.css.map +1 -0
  7. package/dist/css/coreui-grid.css +23 -949
  8. package/dist/css/coreui-grid.css.map +1 -1
  9. package/dist/css/coreui-grid.min.css +3 -3
  10. package/dist/css/coreui-grid.min.css.map +1 -1
  11. package/dist/css/coreui-grid.rtl.css +25 -951
  12. package/dist/css/coreui-grid.rtl.css.map +1 -1
  13. package/dist/css/coreui-grid.rtl.min.css +5 -5
  14. package/dist/css/coreui-grid.rtl.min.css.map +1 -1
  15. package/dist/css/coreui-reboot.css +35 -42
  16. package/dist/css/coreui-reboot.css.map +1 -1
  17. package/dist/css/coreui-reboot.min.css +3 -3
  18. package/dist/css/coreui-reboot.min.css.map +1 -1
  19. package/dist/css/coreui-reboot.rtl.css +36 -44
  20. package/dist/css/coreui-reboot.rtl.css.map +1 -1
  21. package/dist/css/coreui-reboot.rtl.min.css +5 -5
  22. package/dist/css/coreui-reboot.rtl.min.css.map +1 -1
  23. package/dist/css/coreui-utilities.css +279 -951
  24. package/dist/css/coreui-utilities.css.map +1 -1
  25. package/dist/css/coreui-utilities.min.css +3 -3
  26. package/dist/css/coreui-utilities.min.css.map +1 -1
  27. package/dist/css/coreui-utilities.rtl.css +275 -953
  28. package/dist/css/coreui-utilities.rtl.css.map +1 -1
  29. package/dist/css/coreui-utilities.rtl.min.css +5 -5
  30. package/dist/css/coreui-utilities.rtl.min.css.map +1 -1
  31. package/dist/css/coreui.css +2203 -2295
  32. package/dist/css/coreui.css.map +1 -1
  33. package/dist/css/coreui.min.css +3 -3
  34. package/dist/css/coreui.min.css.map +1 -1
  35. package/dist/css/coreui.rtl.css +2190 -2289
  36. package/dist/css/coreui.rtl.css.map +1 -1
  37. package/dist/css/coreui.rtl.min.css +5 -5
  38. package/dist/css/coreui.rtl.min.css.map +1 -1
  39. package/dist/js/coreui.bundle.js +2101 -1908
  40. package/dist/js/coreui.bundle.js.map +1 -1
  41. package/dist/js/coreui.bundle.min.js +2 -2
  42. package/dist/js/coreui.bundle.min.js.map +1 -1
  43. package/dist/js/coreui.esm.js +2098 -1909
  44. package/dist/js/coreui.esm.js.map +1 -1
  45. package/dist/js/coreui.esm.min.js +2 -2
  46. package/dist/js/coreui.esm.min.js.map +1 -1
  47. package/dist/js/coreui.js +2099 -1910
  48. package/dist/js/coreui.js.map +1 -1
  49. package/dist/js/coreui.min.js +2 -2
  50. package/dist/js/coreui.min.js.map +1 -1
  51. package/js/dist/alert.js +10 -148
  52. package/js/dist/alert.js.map +1 -1
  53. package/js/dist/base-component.js +36 -122
  54. package/js/dist/base-component.js.map +1 -1
  55. package/js/dist/button.js +9 -76
  56. package/js/dist/button.js.map +1 -1
  57. package/js/dist/carousel.js +212 -507
  58. package/js/dist/carousel.js.map +1 -1
  59. package/js/dist/collapse.js +64 -251
  60. package/js/dist/collapse.js.map +1 -1
  61. package/js/dist/dom/data.js +2 -4
  62. package/js/dist/dom/data.js.map +1 -1
  63. package/js/dist/dom/event-handler.js +82 -133
  64. package/js/dist/dom/event-handler.js.map +1 -1
  65. package/js/dist/dom/manipulator.js +22 -26
  66. package/js/dist/dom/manipulator.js.map +1 -1
  67. package/js/dist/dom/selector-engine.js +16 -81
  68. package/js/dist/dom/selector-engine.js.map +1 -1
  69. package/js/dist/dropdown.js +99 -338
  70. package/js/dist/dropdown.js.map +1 -1
  71. package/js/dist/modal.js +106 -774
  72. package/js/dist/modal.js.map +1 -1
  73. package/js/dist/navigation.js +309 -0
  74. package/js/dist/navigation.js.map +1 -0
  75. package/js/dist/offcanvas.js +88 -680
  76. package/js/dist/offcanvas.js.map +1 -1
  77. package/js/dist/popover.js +35 -120
  78. package/js/dist/popover.js.map +1 -1
  79. package/js/dist/scrollspy.js +178 -264
  80. package/js/dist/scrollspy.js.map +1 -1
  81. package/js/dist/sidebar.js +347 -0
  82. package/js/dist/sidebar.js.map +1 -0
  83. package/js/dist/tab.js +226 -216
  84. package/js/dist/tab.js.map +1 -1
  85. package/js/dist/toast.js +27 -216
  86. package/js/dist/toast.js.map +1 -1
  87. package/js/dist/tooltip.js +271 -618
  88. package/js/dist/tooltip.js.map +1 -1
  89. package/js/dist/util/backdrop.js +166 -0
  90. package/js/dist/util/backdrop.js.map +1 -0
  91. package/js/dist/util/component-functions.js +47 -0
  92. package/js/dist/util/component-functions.js.map +1 -0
  93. package/js/dist/util/config.js +80 -0
  94. package/js/dist/util/config.js.map +1 -0
  95. package/js/dist/util/focustrap.js +130 -0
  96. package/js/dist/util/focustrap.js.map +1 -0
  97. package/js/dist/util/index.js +354 -0
  98. package/js/dist/util/index.js.map +1 -0
  99. package/js/dist/util/sanitizer.js +126 -0
  100. package/js/dist/util/sanitizer.js.map +1 -0
  101. package/js/dist/util/scrollbar.js +139 -0
  102. package/js/dist/util/scrollbar.js.map +1 -0
  103. package/js/dist/util/swipe.js +156 -0
  104. package/js/dist/util/swipe.js.map +1 -0
  105. package/js/dist/util/template-factory.js +178 -0
  106. package/js/dist/util/template-factory.js.map +1 -0
  107. package/js/src/alert.js +3 -15
  108. package/js/src/base-component.js +28 -18
  109. package/js/src/button.js +3 -15
  110. package/js/src/carousel.js +203 -320
  111. package/js/src/collapse.js +61 -94
  112. package/js/src/dom/data.js +1 -3
  113. package/js/src/dom/event-handler.js +74 -107
  114. package/js/src/dom/manipulator.js +22 -31
  115. package/js/src/dom/selector-engine.js +10 -19
  116. package/js/src/dropdown.js +84 -138
  117. package/js/src/modal.js +94 -158
  118. package/js/src/navigation.js +12 -13
  119. package/js/src/offcanvas.js +71 -60
  120. package/js/src/popover.js +31 -62
  121. package/js/src/scrollspy.js +166 -171
  122. package/js/src/sidebar.js +5 -8
  123. package/js/src/tab.js +201 -110
  124. package/js/src/toast.js +19 -41
  125. package/js/src/tooltip.js +264 -374
  126. package/js/src/util/backdrop.js +55 -36
  127. package/js/src/util/component-functions.js +1 -1
  128. package/js/src/util/config.js +66 -0
  129. package/js/src/util/focustrap.js +38 -28
  130. package/js/src/util/index.js +41 -57
  131. package/js/src/util/sanitizer.js +9 -17
  132. package/js/src/util/scrollbar.js +47 -30
  133. package/js/src/util/swipe.js +146 -0
  134. package/js/src/util/template-factory.js +160 -0
  135. package/package.json +40 -40
  136. package/scss/_accordion.scss +53 -25
  137. package/scss/_alert.scss +29 -9
  138. package/scss/_badge.scss +15 -6
  139. package/scss/_breadcrumb.scss +23 -11
  140. package/scss/_button-group.scss +3 -0
  141. package/scss/_buttons.scss +71 -50
  142. package/scss/_callout.scss +18 -6
  143. package/scss/_card.scss +55 -37
  144. package/scss/_carousel.scss +6 -6
  145. package/scss/_close.scss +4 -4
  146. package/scss/_containers.scss +1 -1
  147. package/scss/_dropdown.scss +86 -64
  148. package/scss/_footer.scss +15 -5
  149. package/scss/_functions.scss +11 -24
  150. package/scss/_grid.scss +3 -3
  151. package/scss/_header.scss +59 -34
  152. package/scss/_helpers.scss +1 -0
  153. package/scss/_images.scss +3 -3
  154. package/scss/_list-group.scss +47 -29
  155. package/scss/_maps.scss +54 -0
  156. package/scss/_modal.scss +70 -43
  157. package/scss/_nav.scss +53 -20
  158. package/scss/_navbar.scss +84 -94
  159. package/scss/_offcanvas.scss +120 -60
  160. package/scss/_pagination.scss +66 -21
  161. package/scss/_popover.scss +90 -52
  162. package/scss/_progress.scss +20 -9
  163. package/scss/_reboot.scss +31 -58
  164. package/scss/_root.scss +41 -21
  165. package/scss/_spinners.scss +37 -21
  166. package/scss/_subheader.scss +9 -9
  167. package/scss/_tables.scss +34 -36
  168. package/scss/_toasts.scss +35 -19
  169. package/scss/_tooltip.scss +61 -56
  170. package/scss/_utilities.scss +42 -27
  171. package/scss/_variables.scss +169 -148
  172. package/scss/bootstrap-reboot.scss +14 -0
  173. package/scss/coreui-grid.rtl.scss +2 -2
  174. package/scss/coreui-grid.scss +3 -2
  175. package/scss/coreui-reboot.rtl.scss +2 -2
  176. package/scss/coreui-reboot.scss +2 -2
  177. package/scss/coreui-utilities.rtl.scss +2 -2
  178. package/scss/coreui-utilities.scss +3 -2
  179. package/scss/coreui.rtl.scss +2 -2
  180. package/scss/coreui.scss +3 -2
  181. package/scss/forms/_floating-labels.scss +14 -3
  182. package/scss/forms/_form-check.scss +42 -19
  183. package/scss/forms/_form-control.scss +25 -50
  184. package/scss/forms/_form-range.scss +8 -8
  185. package/scss/forms/_form-select.scss +8 -8
  186. package/scss/forms/_form-text.scss +1 -1
  187. package/scss/forms/_input-group.scss +3 -3
  188. package/scss/forms/_labels.scss +2 -2
  189. package/scss/helpers/_color-bg.scss +10 -0
  190. package/scss/helpers/_colored-links.scss +2 -2
  191. package/scss/helpers/_position.scss +7 -1
  192. package/scss/helpers/_ratio.scss +2 -2
  193. package/scss/helpers/_vr.scss +1 -0
  194. package/scss/mixins/_alert.scss +10 -10
  195. package/scss/mixins/_breakpoints.scss +8 -8
  196. package/scss/mixins/_buttons.scss +45 -47
  197. package/scss/mixins/_container.scss +4 -2
  198. package/scss/mixins/_css-vars.scss +47 -47
  199. package/scss/mixins/_forms.scss +10 -2
  200. package/scss/mixins/_gradients.scss +1 -1
  201. package/scss/mixins/_grid.scss +11 -11
  202. package/scss/mixins/_list-group.scss +7 -9
  203. package/scss/mixins/_pagination.scss +4 -25
  204. package/scss/mixins/_table-variants.scss +20 -12
  205. package/scss/mixins/_utilities.scss +8 -3
  206. package/scss/sidebar/_sidebar-narrow.scss +10 -10
  207. package/scss/sidebar/_sidebar-nav.scss +33 -32
  208. package/scss/sidebar/_sidebar.scss +110 -56
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * --------------------------------------------------------------------------
3
- * CoreUI (v4.1.4): scrollspy.js
3
+ * CoreUI (v4.2.0): scrollspy.js
4
4
  * Licensed under MIT (https://coreui.io/license)
5
5
  *
6
6
  * This component is a modified version of the Bootstrap's scrollspy.js
@@ -8,21 +8,13 @@
8
8
  * --------------------------------------------------------------------------
9
9
  */
10
10
 
11
- import {
12
- defineJQueryPlugin,
13
- getElement,
14
- getSelectorFromElement,
15
- typeCheckConfig
16
- } from './util/index'
11
+ import { defineJQueryPlugin, getElement, isDisabled, isVisible } from './util/index'
17
12
  import EventHandler from './dom/event-handler'
18
- import Manipulator from './dom/manipulator'
19
13
  import SelectorEngine from './dom/selector-engine'
20
14
  import BaseComponent from './base-component'
21
15
 
22
16
  /**
23
- * ------------------------------------------------------------------------
24
17
  * Constants
25
- * ------------------------------------------------------------------------
26
18
  */
27
19
 
28
20
  const NAME = 'scrollspy'
@@ -30,234 +22,241 @@ const DATA_KEY = 'coreui.scrollspy'
30
22
  const EVENT_KEY = `.${DATA_KEY}`
31
23
  const DATA_API_KEY = '.data-api'
32
24
 
33
- const Default = {
34
- offset: 10,
35
- method: 'auto',
36
- target: ''
37
- }
38
-
39
- const DefaultType = {
40
- offset: 'number',
41
- method: 'string',
42
- target: '(string|element)'
43
- }
44
-
45
25
  const EVENT_ACTIVATE = `activate${EVENT_KEY}`
46
- const EVENT_SCROLL = `scroll${EVENT_KEY}`
26
+ const EVENT_CLICK = `click${EVENT_KEY}`
47
27
  const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
48
28
 
49
29
  const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'
50
30
  const CLASS_NAME_ACTIVE = 'active'
51
31
 
52
32
  const SELECTOR_DATA_SPY = '[data-coreui-spy="scroll"]'
33
+ const SELECTOR_TARGET_LINKS = '[href]'
53
34
  const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'
54
35
  const SELECTOR_NAV_LINKS = '.nav-link'
55
36
  const SELECTOR_NAV_ITEMS = '.nav-item'
56
37
  const SELECTOR_LIST_ITEMS = '.list-group-item'
57
- const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`
38
+ const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`
58
39
  const SELECTOR_DROPDOWN = '.dropdown'
59
40
  const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'
60
41
 
61
- const METHOD_OFFSET = 'offset'
62
- const METHOD_POSITION = 'position'
42
+ const Default = {
43
+ offset: null, // TODO: v6 @deprecated, keep it for backwards compatibility reasons
44
+ rootMargin: '0px 0px -25%',
45
+ smoothScroll: false,
46
+ target: null
47
+ }
48
+
49
+ const DefaultType = {
50
+ offset: '(number|null)', // TODO v6 @deprecated, keep it for backwards compatibility reasons
51
+ rootMargin: 'string',
52
+ smoothScroll: 'boolean',
53
+ target: 'element'
54
+ }
63
55
 
64
56
  /**
65
- * ------------------------------------------------------------------------
66
- * Class Definition
67
- * ------------------------------------------------------------------------
57
+ * Class definition
68
58
  */
69
59
 
70
60
  class ScrollSpy extends BaseComponent {
71
61
  constructor(element, config) {
72
- super(element)
73
- this._scrollElement = this._element.tagName === 'BODY' ? window : this._element
74
- this._config = this._getConfig(config)
75
- this._offsets = []
76
- this._targets = []
77
- this._activeTarget = null
78
- this._scrollHeight = 0
79
-
80
- EventHandler.on(this._scrollElement, EVENT_SCROLL, () => this._process())
62
+ super(element, config)
81
63
 
82
- this.refresh()
83
- this._process()
64
+ // this._element is the observablesContainer and config.target the menu links wrapper
65
+ this._targetLinks = new Map()
66
+ this._observableSections = new Map()
67
+ this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element
68
+ this._activeTarget = null
69
+ this._observer = null
70
+ this._previousScrollData = {
71
+ visibleEntryTop: 0,
72
+ parentScrollTop: 0
73
+ }
74
+ this.refresh() // initialize
84
75
  }
85
76
 
86
77
  // Getters
87
-
88
78
  static get Default() {
89
79
  return Default
90
80
  }
91
81
 
82
+ static get DefaultType() {
83
+ return DefaultType
84
+ }
85
+
92
86
  static get NAME() {
93
87
  return NAME
94
88
  }
95
89
 
96
90
  // Public
97
-
98
91
  refresh() {
99
- const autoMethod = this._scrollElement === this._scrollElement.window ?
100
- METHOD_OFFSET :
101
- METHOD_POSITION
102
-
103
- const offsetMethod = this._config.method === 'auto' ?
104
- autoMethod :
105
- this._config.method
106
-
107
- const offsetBase = offsetMethod === METHOD_POSITION ?
108
- this._getScrollTop() :
109
- 0
110
-
111
- this._offsets = []
112
- this._targets = []
113
- this._scrollHeight = this._getScrollHeight()
114
-
115
- const targets = SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target)
116
-
117
- targets.map(element => {
118
- const targetSelector = getSelectorFromElement(element)
119
- const target = targetSelector ? SelectorEngine.findOne(targetSelector) : null
120
-
121
- if (target) {
122
- const targetBCR = target.getBoundingClientRect()
123
- if (targetBCR.width || targetBCR.height) {
124
- return [
125
- Manipulator[offsetMethod](target).top + offsetBase,
126
- targetSelector
127
- ]
128
- }
129
- }
92
+ this._initializeTargetsAndObservables()
93
+ this._maybeEnableSmoothScroll()
130
94
 
131
- return null
132
- })
133
- .filter(item => item)
134
- .sort((a, b) => a[0] - b[0])
135
- .forEach(item => {
136
- this._offsets.push(item[0])
137
- this._targets.push(item[1])
138
- })
95
+ if (this._observer) {
96
+ this._observer.disconnect()
97
+ } else {
98
+ this._observer = this._getNewObserver()
99
+ }
100
+
101
+ for (const section of this._observableSections.values()) {
102
+ this._observer.observe(section)
103
+ }
139
104
  }
140
105
 
141
106
  dispose() {
142
- EventHandler.off(this._scrollElement, EVENT_KEY)
107
+ this._observer.disconnect()
143
108
  super.dispose()
144
109
  }
145
110
 
146
111
  // Private
112
+ _configAfterMerge(config) {
113
+ // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case
114
+ config.target = getElement(config.target) || document.body
147
115
 
148
- _getConfig(config) {
149
- config = {
150
- ...Default,
151
- ...Manipulator.getDataAttributes(this._element),
152
- ...(typeof config === 'object' && config ? config : {})
153
- }
116
+ return config
117
+ }
154
118
 
155
- config.target = getElement(config.target) || document.documentElement
119
+ _maybeEnableSmoothScroll() {
120
+ if (!this._config.smoothScroll) {
121
+ return
122
+ }
156
123
 
157
- typeCheckConfig(NAME, config, DefaultType)
124
+ // unregister any previous listeners
125
+ EventHandler.off(this._config.target, EVENT_CLICK)
126
+
127
+ EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {
128
+ const observableSection = this._observableSections.get(event.target.hash)
129
+ if (observableSection) {
130
+ event.preventDefault()
131
+ const root = this._rootElement || window
132
+ const height = observableSection.offsetTop - this._element.offsetTop
133
+ if (root.scrollTo) {
134
+ root.scrollTo({ top: height, behavior: 'smooth' })
135
+ return
136
+ }
158
137
 
159
- return config
138
+ // Chrome 60 doesn't support `scrollTo`
139
+ root.scrollTop = height
140
+ }
141
+ })
160
142
  }
161
143
 
162
- _getScrollTop() {
163
- return this._scrollElement === window ?
164
- this._scrollElement.pageYOffset :
165
- this._scrollElement.scrollTop
166
- }
144
+ _getNewObserver() {
145
+ const options = {
146
+ root: this._rootElement,
147
+ threshold: [0.1, 0.5, 1],
148
+ rootMargin: this._getRootMargin()
149
+ }
167
150
 
168
- _getScrollHeight() {
169
- return this._scrollElement.scrollHeight || Math.max(
170
- document.body.scrollHeight,
171
- document.documentElement.scrollHeight
172
- )
151
+ return new IntersectionObserver(entries => this._observerCallback(entries), options)
173
152
  }
174
153
 
175
- _getOffsetHeight() {
176
- return this._scrollElement === window ?
177
- window.innerHeight :
178
- this._scrollElement.getBoundingClientRect().height
179
- }
154
+ // The logic of selection
155
+ _observerCallback(entries) {
156
+ const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`)
157
+ const activate = entry => {
158
+ this._previousScrollData.visibleEntryTop = entry.target.offsetTop
159
+ this._process(targetElement(entry))
160
+ }
180
161
 
181
- _process() {
182
- const scrollTop = this._getScrollTop() + this._config.offset
183
- const scrollHeight = this._getScrollHeight()
184
- const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight()
162
+ const parentScrollTop = (this._rootElement || document.documentElement).scrollTop
163
+ const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop
164
+ this._previousScrollData.parentScrollTop = parentScrollTop
185
165
 
186
- if (this._scrollHeight !== scrollHeight) {
187
- this.refresh()
188
- }
166
+ for (const entry of entries) {
167
+ if (!entry.isIntersecting) {
168
+ this._activeTarget = null
169
+ this._clearActiveClass(targetElement(entry))
170
+
171
+ continue
172
+ }
189
173
 
190
- if (scrollTop >= maxScroll) {
191
- const target = this._targets[this._targets.length - 1]
174
+ const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop
175
+ // if we are scrolling down, pick the bigger offsetTop
176
+ if (userScrollsDown && entryIsLowerThanPrevious) {
177
+ activate(entry)
178
+ // if parent isn't scrolled, let's keep the first visible item, breaking the iteration
179
+ if (!parentScrollTop) {
180
+ return
181
+ }
192
182
 
193
- if (this._activeTarget !== target) {
194
- this._activate(target)
183
+ continue
195
184
  }
196
185
 
197
- return
186
+ // if we are scrolling up, pick the smallest offsetTop
187
+ if (!userScrollsDown && !entryIsLowerThanPrevious) {
188
+ activate(entry)
189
+ }
198
190
  }
191
+ }
199
192
 
200
- if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
201
- this._activeTarget = null
202
- this._clear()
203
- return
204
- }
193
+ // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only
194
+ _getRootMargin() {
195
+ return this._config.offset ? `${this._config.offset}px 0px -30%` : this._config.rootMargin
196
+ }
197
+
198
+ _initializeTargetsAndObservables() {
199
+ this._targetLinks = new Map()
200
+ this._observableSections = new Map()
201
+
202
+ const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target)
205
203
 
206
- for (let i = this._offsets.length; i--;) {
207
- const isActiveTarget = this._activeTarget !== this._targets[i] &&
208
- scrollTop >= this._offsets[i] &&
209
- (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1])
204
+ for (const anchor of targetLinks) {
205
+ // ensure that the anchor has an id and is not disabled
206
+ if (!anchor.hash || isDisabled(anchor)) {
207
+ continue
208
+ }
209
+
210
+ const observableSection = SelectorEngine.findOne(anchor.hash, this._element)
210
211
 
211
- if (isActiveTarget) {
212
- this._activate(this._targets[i])
212
+ // ensure that the observableSection exists & is visible
213
+ if (isVisible(observableSection)) {
214
+ this._targetLinks.set(anchor.hash, anchor)
215
+ this._observableSections.set(anchor.hash, observableSection)
213
216
  }
214
217
  }
215
218
  }
216
219
 
217
- _activate(target) {
218
- this._activeTarget = target
219
-
220
- this._clear()
220
+ _process(target) {
221
+ if (this._activeTarget === target) {
222
+ return
223
+ }
221
224
 
222
- const queries = SELECTOR_LINK_ITEMS.split(',')
223
- .map(selector => `${selector}[data-coreui-target="${target}"],${selector}[href="${target}"]`)
225
+ this._clearActiveClass(this._config.target)
226
+ this._activeTarget = target
227
+ target.classList.add(CLASS_NAME_ACTIVE)
228
+ this._activateParents(target)
224
229
 
225
- const link = SelectorEngine.findOne(queries.join(','), this._config.target)
230
+ EventHandler.trigger(this._element, EVENT_ACTIVATE, { relatedTarget: target })
231
+ }
226
232
 
227
- link.classList.add(CLASS_NAME_ACTIVE)
228
- if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
229
- SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, link.closest(SELECTOR_DROPDOWN))
233
+ _activateParents(target) {
234
+ // Activate dropdown parents
235
+ if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
236
+ SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, target.closest(SELECTOR_DROPDOWN))
230
237
  .classList.add(CLASS_NAME_ACTIVE)
231
- } else {
232
- SelectorEngine.parents(link, SELECTOR_NAV_LIST_GROUP)
233
- .forEach(listGroup => {
234
- // Set triggered links parents as active
235
- // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
236
- SelectorEngine.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)
237
- .forEach(item => item.classList.add(CLASS_NAME_ACTIVE))
238
-
239
- // Handle special case when .nav-link is inside .nav-item
240
- SelectorEngine.prev(listGroup, SELECTOR_NAV_ITEMS)
241
- .forEach(navItem => {
242
- SelectorEngine.children(navItem, SELECTOR_NAV_LINKS)
243
- .forEach(item => item.classList.add(CLASS_NAME_ACTIVE))
244
- })
245
- })
238
+ return
246
239
  }
247
240
 
248
- EventHandler.trigger(this._scrollElement, EVENT_ACTIVATE, {
249
- relatedTarget: target
250
- })
241
+ for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {
242
+ // Set triggered links parents as active
243
+ // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
244
+ for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) {
245
+ item.classList.add(CLASS_NAME_ACTIVE)
246
+ }
247
+ }
251
248
  }
252
249
 
253
- _clear() {
254
- SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target)
255
- .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))
256
- .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))
250
+ _clearActiveClass(parent) {
251
+ parent.classList.remove(CLASS_NAME_ACTIVE)
252
+
253
+ const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE}`, parent)
254
+ for (const node of activeNodes) {
255
+ node.classList.remove(CLASS_NAME_ACTIVE)
256
+ }
257
257
  }
258
258
 
259
259
  // Static
260
-
261
260
  static jQueryInterface(config) {
262
261
  return this.each(function () {
263
262
  const data = ScrollSpy.getOrCreateInstance(this, config)
@@ -266,7 +265,7 @@ class ScrollSpy extends BaseComponent {
266
265
  return
267
266
  }
268
267
 
269
- if (typeof data[config] === 'undefined') {
268
+ if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
270
269
  throw new TypeError(`No method named "${config}"`)
271
270
  }
272
271
 
@@ -276,21 +275,17 @@ class ScrollSpy extends BaseComponent {
276
275
  }
277
276
 
278
277
  /**
279
- * ------------------------------------------------------------------------
280
- * Data Api implementation
281
- * ------------------------------------------------------------------------
278
+ * Data API implementation
282
279
  */
283
280
 
284
281
  EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
285
- SelectorEngine.find(SELECTOR_DATA_SPY)
286
- .forEach(spy => new ScrollSpy(spy))
282
+ for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) {
283
+ ScrollSpy.getOrCreateInstance(spy)
284
+ }
287
285
  })
288
286
 
289
287
  /**
290
- * ------------------------------------------------------------------------
291
288
  * jQuery
292
- * ------------------------------------------------------------------------
293
- * add .ScrollSpy to jQuery only if jQuery is present
294
289
  */
295
290
 
296
291
  defineJQueryPlugin(ScrollSpy)
package/js/src/sidebar.js CHANGED
@@ -1,14 +1,11 @@
1
1
  /**
2
2
  * --------------------------------------------------------------------------
3
- * CoreUI (v4.1.4): sidebar.js
3
+ * CoreUI (v4.2.0): sidebar.js
4
4
  * Licensed under MIT (https://coreui.io/license)
5
5
  * --------------------------------------------------------------------------
6
6
  */
7
7
 
8
- import {
9
- defineJQueryPlugin,
10
- typeCheckConfig
11
- } from './util/index'
8
+ import { defineJQueryPlugin } from './util/index'
12
9
  import ScrollBarHelper from './util/scrollbar'
13
10
  import EventHandler from './dom/event-handler'
14
11
  import BaseComponent from './base-component'
@@ -204,7 +201,7 @@ class Sidebar extends BaseComponent {
204
201
  ...Manipulator.getDataAttributes(this._element),
205
202
  ...(typeof config === 'object' ? config : {})
206
203
  }
207
- typeCheckConfig(NAME, config, DefaultType)
204
+
208
205
  return config
209
206
  }
210
207
 
@@ -327,9 +324,9 @@ class Sidebar extends BaseComponent {
327
324
  */
328
325
 
329
326
  EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
330
- Array.from(document.querySelectorAll(SELECTOR_SIDEBAR)).forEach(element => {
327
+ for (const element of Array.from(document.querySelectorAll(SELECTOR_SIDEBAR))) {
331
328
  Sidebar.sidebarInterface(element)
332
- })
329
+ }
333
330
  })
334
331
 
335
332
  /**