@coreui/coreui 4.1.6 → 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 +62 -10
  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 +22 -4
  8. package/dist/css/coreui-grid.css.map +1 -1
  9. package/dist/css/coreui-grid.min.css +2 -2
  10. package/dist/css/coreui-grid.min.css.map +1 -1
  11. package/dist/css/coreui-grid.rtl.css +23 -5
  12. package/dist/css/coreui-grid.rtl.css.map +1 -1
  13. package/dist/css/coreui-grid.rtl.min.css +3 -3
  14. package/dist/css/coreui-grid.rtl.min.css.map +1 -1
  15. package/dist/css/coreui-reboot.css +34 -41
  16. package/dist/css/coreui-reboot.css.map +1 -1
  17. package/dist/css/coreui-reboot.min.css +2 -2
  18. package/dist/css/coreui-reboot.min.css.map +1 -1
  19. package/dist/css/coreui-reboot.rtl.css +34 -42
  20. package/dist/css/coreui-reboot.rtl.css.map +1 -1
  21. package/dist/css/coreui-reboot.rtl.min.css +3 -3
  22. package/dist/css/coreui-reboot.rtl.min.css.map +1 -1
  23. package/dist/css/coreui-utilities.css +278 -163
  24. package/dist/css/coreui-utilities.css.map +1 -1
  25. package/dist/css/coreui-utilities.min.css +2 -2
  26. package/dist/css/coreui-utilities.min.css.map +1 -1
  27. package/dist/css/coreui-utilities.rtl.css +273 -164
  28. package/dist/css/coreui-utilities.rtl.css.map +1 -1
  29. package/dist/css/coreui-utilities.rtl.min.css +3 -3
  30. package/dist/css/coreui-utilities.rtl.min.css.map +1 -1
  31. package/dist/css/coreui.css +2168 -1240
  32. package/dist/css/coreui.css.map +1 -1
  33. package/dist/css/coreui.min.css +2 -2
  34. package/dist/css/coreui.min.css.map +1 -1
  35. package/dist/css/coreui.rtl.css +2150 -1228
  36. package/dist/css/coreui.rtl.css.map +1 -1
  37. package/dist/css/coreui.rtl.min.css +3 -3
  38. package/dist/css/coreui.rtl.min.css.map +1 -1
  39. package/dist/js/coreui.bundle.js +2095 -1906
  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 +36 -36
  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 -19
  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 -25
  171. package/scss/_variables.scss +169 -148
  172. package/scss/bootstrap-reboot.scss +14 -0
  173. package/scss/coreui-grid.rtl.scss +1 -1
  174. package/scss/coreui-grid.scss +2 -1
  175. package/scss/coreui-reboot.rtl.scss +1 -1
  176. package/scss/coreui-reboot.scss +1 -1
  177. package/scss/coreui-utilities.rtl.scss +1 -1
  178. package/scss/coreui-utilities.scss +2 -1
  179. package/scss/coreui.rtl.scss +1 -1
  180. package/scss/coreui.scss +2 -1
  181. package/scss/forms/_floating-labels.scss +14 -3
  182. package/scss/forms/_form-check.scss +41 -18
  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 +8 -0
  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,161 +1,23 @@
1
1
  /*!
2
- * CoreUI scrollspy.js v4.1.6 (https://coreui.io)
2
+ * CoreUI scrollspy.js v4.2.0 (https://coreui.io)
3
3
  * Copyright 2022 The CoreUI Team (https://github.com/orgs/coreui/people)
4
4
  * Licensed under MIT (https://coreui.io)
5
5
  */
6
6
  (function (global, factory) {
7
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./base-component.js')) :
8
- typeof define === 'function' && define.amd ? define(['./dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'], factory) :
9
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ScrollSpy = factory(global.EventHandler, global.Manipulator, global.SelectorEngine, global.Base));
10
- })(this, (function (EventHandler, Manipulator, SelectorEngine, BaseComponent) { 'use strict';
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./util/index'), require('./dom/event-handler'), require('./dom/selector-engine'), require('./base-component')) :
8
+ typeof define === 'function' && define.amd ? define(['./util/index', './dom/event-handler', './dom/selector-engine', './base-component'], factory) :
9
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Scrollspy = factory(global.Index, global.EventHandler, global.SelectorEngine, global.BaseComponent));
10
+ })(this, (function (index, EventHandler, SelectorEngine, BaseComponent) { 'use strict';
11
11
 
12
12
  const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
13
13
 
14
14
  const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
15
- const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
16
15
  const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
17
16
  const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
18
17
 
19
18
  /**
20
19
  * --------------------------------------------------------------------------
21
- * CoreUI (v4.1.6): alert.js
22
- * Licensed under MIT (https://coreui.io/license)
23
- *
24
- * This component is a modified version of the Bootstrap's util/index.js
25
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
26
- * --------------------------------------------------------------------------
27
- */
28
-
29
- const toType = object => {
30
- if (object === null || object === undefined) {
31
- return `${object}`;
32
- }
33
-
34
- return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();
35
- };
36
-
37
- const getSelector = element => {
38
- let selector = element.getAttribute('data-coreui-target');
39
-
40
- if (!selector || selector === '#') {
41
- let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
42
- // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
43
- // `document.querySelector` will rightfully complain it is invalid.
44
- // See https://github.com/twbs/bootstrap/issues/32273
45
-
46
- if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
47
- return null;
48
- } // Just in case some CMS puts out a full URL with the anchor appended
49
-
50
-
51
- if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
52
- hrefAttr = `#${hrefAttr.split('#')[1]}`;
53
- }
54
-
55
- selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
56
- }
57
-
58
- return selector;
59
- };
60
-
61
- const getSelectorFromElement = element => {
62
- const selector = getSelector(element);
63
-
64
- if (selector) {
65
- return document.querySelector(selector) ? selector : null;
66
- }
67
-
68
- return null;
69
- };
70
-
71
- const isElement = obj => {
72
- if (!obj || typeof obj !== 'object') {
73
- return false;
74
- }
75
-
76
- if (typeof obj.jquery !== 'undefined') {
77
- obj = obj[0];
78
- }
79
-
80
- return typeof obj.nodeType !== 'undefined';
81
- };
82
-
83
- const getElement = obj => {
84
- if (isElement(obj)) {
85
- // it's a jQuery object or a node element
86
- return obj.jquery ? obj[0] : obj;
87
- }
88
-
89
- if (typeof obj === 'string' && obj.length > 0) {
90
- return document.querySelector(obj);
91
- }
92
-
93
- return null;
94
- };
95
-
96
- const typeCheckConfig = (componentName, config, configTypes) => {
97
- Object.keys(configTypes).forEach(property => {
98
- const expectedTypes = configTypes[property];
99
- const value = config[property];
100
- const valueType = value && isElement(value) ? 'element' : toType(value);
101
-
102
- if (!new RegExp(expectedTypes).test(valueType)) {
103
- throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
104
- }
105
- });
106
- };
107
-
108
- const getjQuery = () => {
109
- const {
110
- jQuery
111
- } = window;
112
-
113
- if (jQuery && !document.body.hasAttribute('data-coreui-no-jquery')) {
114
- return jQuery;
115
- }
116
-
117
- return null;
118
- };
119
-
120
- const DOMContentLoadedCallbacks = [];
121
-
122
- const onDOMContentLoaded = callback => {
123
- if (document.readyState === 'loading') {
124
- // add listener on the first call when the document is in loading state
125
- if (!DOMContentLoadedCallbacks.length) {
126
- document.addEventListener('DOMContentLoaded', () => {
127
- DOMContentLoadedCallbacks.forEach(callback => callback());
128
- });
129
- }
130
-
131
- DOMContentLoadedCallbacks.push(callback);
132
- } else {
133
- callback();
134
- }
135
- };
136
-
137
- const defineJQueryPlugin = plugin => {
138
- onDOMContentLoaded(() => {
139
- const $ = getjQuery();
140
- /* istanbul ignore if */
141
-
142
- if ($) {
143
- const name = plugin.NAME;
144
- const JQUERY_NO_CONFLICT = $.fn[name];
145
- $.fn[name] = plugin.jQueryInterface;
146
- $.fn[name].Constructor = plugin;
147
-
148
- $.fn[name].noConflict = () => {
149
- $.fn[name] = JQUERY_NO_CONFLICT;
150
- return plugin.jQueryInterface;
151
- };
152
- }
153
- });
154
- };
155
-
156
- /**
157
- * --------------------------------------------------------------------------
158
- * CoreUI (v4.1.6): scrollspy.js
20
+ * CoreUI (v4.2.0): scrollspy.js
159
21
  * Licensed under MIT (https://coreui.io/license)
160
22
  *
161
23
  * This component is a modified version of the Bootstrap's scrollspy.js
@@ -163,59 +25,59 @@
163
25
  * --------------------------------------------------------------------------
164
26
  */
165
27
  /**
166
- * ------------------------------------------------------------------------
167
28
  * Constants
168
- * ------------------------------------------------------------------------
169
29
  */
170
30
 
171
31
  const NAME = 'scrollspy';
172
32
  const DATA_KEY = 'coreui.scrollspy';
173
33
  const EVENT_KEY = `.${DATA_KEY}`;
174
34
  const DATA_API_KEY = '.data-api';
175
- const Default = {
176
- offset: 10,
177
- method: 'auto',
178
- target: ''
179
- };
180
- const DefaultType = {
181
- offset: 'number',
182
- method: 'string',
183
- target: '(string|element)'
184
- };
185
35
  const EVENT_ACTIVATE = `activate${EVENT_KEY}`;
186
- const EVENT_SCROLL = `scroll${EVENT_KEY}`;
36
+ const EVENT_CLICK = `click${EVENT_KEY}`;
187
37
  const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`;
188
38
  const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
189
39
  const CLASS_NAME_ACTIVE = 'active';
190
40
  const SELECTOR_DATA_SPY = '[data-coreui-spy="scroll"]';
41
+ const SELECTOR_TARGET_LINKS = '[href]';
191
42
  const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
192
43
  const SELECTOR_NAV_LINKS = '.nav-link';
193
44
  const SELECTOR_NAV_ITEMS = '.nav-item';
194
45
  const SELECTOR_LIST_ITEMS = '.list-group-item';
195
- const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`;
46
+ const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;
196
47
  const SELECTOR_DROPDOWN = '.dropdown';
197
48
  const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
198
- const METHOD_OFFSET = 'offset';
199
- const METHOD_POSITION = 'position';
49
+ const Default = {
50
+ offset: null,
51
+ // TODO: v6 @deprecated, keep it for backwards compatibility reasons
52
+ rootMargin: '0px 0px -25%',
53
+ smoothScroll: false,
54
+ target: null
55
+ };
56
+ const DefaultType = {
57
+ offset: '(number|null)',
58
+ // TODO v6 @deprecated, keep it for backwards compatibility reasons
59
+ rootMargin: 'string',
60
+ smoothScroll: 'boolean',
61
+ target: 'element'
62
+ };
200
63
  /**
201
- * ------------------------------------------------------------------------
202
- * Class Definition
203
- * ------------------------------------------------------------------------
64
+ * Class definition
204
65
  */
205
66
 
206
67
  class ScrollSpy extends BaseComponent__default.default {
207
68
  constructor(element, config) {
208
- super(element);
209
- this._scrollElement = this._element.tagName === 'BODY' ? window : this._element;
210
- this._config = this._getConfig(config);
211
- this._offsets = [];
212
- this._targets = [];
213
- this._activeTarget = null;
214
- this._scrollHeight = 0;
215
- EventHandler__default.default.on(this._scrollElement, EVENT_SCROLL, () => this._process());
216
- this.refresh();
69
+ super(element, config); // this._element is the observablesContainer and config.target the menu links wrapper
217
70
 
218
- this._process();
71
+ this._targetLinks = new Map();
72
+ this._observableSections = new Map();
73
+ this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;
74
+ this._activeTarget = null;
75
+ this._observer = null;
76
+ this._previousScrollData = {
77
+ visibleEntryTop: 0,
78
+ parentScrollTop: 0
79
+ };
80
+ this.refresh(); // initialize
219
81
  } // Getters
220
82
 
221
83
 
@@ -223,135 +85,190 @@
223
85
  return Default;
224
86
  }
225
87
 
88
+ static get DefaultType() {
89
+ return DefaultType;
90
+ }
91
+
226
92
  static get NAME() {
227
93
  return NAME;
228
94
  } // Public
229
95
 
230
96
 
231
97
  refresh() {
232
- const autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;
233
- const offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
234
- const offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;
235
- this._offsets = [];
236
- this._targets = [];
237
- this._scrollHeight = this._getScrollHeight();
238
- const targets = SelectorEngine__default.default.find(SELECTOR_LINK_ITEMS, this._config.target);
239
- targets.map(element => {
240
- const targetSelector = getSelectorFromElement(element);
241
- const target = targetSelector ? SelectorEngine__default.default.findOne(targetSelector) : null;
242
-
243
- if (target) {
244
- const targetBCR = target.getBoundingClientRect();
245
-
246
- if (targetBCR.width || targetBCR.height) {
247
- return [Manipulator__default.default[offsetMethod](target).top + offsetBase, targetSelector];
248
- }
249
- }
98
+ this._initializeTargetsAndObservables();
250
99
 
251
- return null;
252
- }).filter(item => item).sort((a, b) => a[0] - b[0]).forEach(item => {
253
- this._offsets.push(item[0]);
100
+ this._maybeEnableSmoothScroll();
254
101
 
255
- this._targets.push(item[1]);
256
- });
102
+ if (this._observer) {
103
+ this._observer.disconnect();
104
+ } else {
105
+ this._observer = this._getNewObserver();
106
+ }
107
+
108
+ for (const section of this._observableSections.values()) {
109
+ this._observer.observe(section);
110
+ }
257
111
  }
258
112
 
259
113
  dispose() {
260
- EventHandler__default.default.off(this._scrollElement, EVENT_KEY);
114
+ this._observer.disconnect();
115
+
261
116
  super.dispose();
262
117
  } // Private
263
118
 
264
119
 
265
- _getConfig(config) {
266
- config = { ...Default,
267
- ...Manipulator__default.default.getDataAttributes(this._element),
268
- ...(typeof config === 'object' && config ? config : {})
269
- };
270
- config.target = getElement(config.target) || document.documentElement;
271
- typeCheckConfig(NAME, config, DefaultType);
120
+ _configAfterMerge(config) {
121
+ // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case
122
+ config.target = index.getElement(config.target) || document.body;
272
123
  return config;
273
124
  }
274
125
 
275
- _getScrollTop() {
276
- return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
277
- }
126
+ _maybeEnableSmoothScroll() {
127
+ if (!this._config.smoothScroll) {
128
+ return;
129
+ } // unregister any previous listeners
130
+
131
+
132
+ EventHandler__default.default.off(this._config.target, EVENT_CLICK);
133
+ EventHandler__default.default.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {
134
+ const observableSection = this._observableSections.get(event.target.hash);
135
+
136
+ if (observableSection) {
137
+ event.preventDefault();
138
+ const root = this._rootElement || window;
139
+ const height = observableSection.offsetTop - this._element.offsetTop;
140
+
141
+ if (root.scrollTo) {
142
+ root.scrollTo({
143
+ top: height,
144
+ behavior: 'smooth'
145
+ });
146
+ return;
147
+ } // Chrome 60 doesn't support `scrollTo`
278
148
 
279
- _getScrollHeight() {
280
- return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
281
- }
282
149
 
283
- _getOffsetHeight() {
284
- return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
150
+ root.scrollTop = height;
151
+ }
152
+ });
285
153
  }
286
154
 
287
- _process() {
288
- const scrollTop = this._getScrollTop() + this._config.offset;
155
+ _getNewObserver() {
156
+ const options = {
157
+ root: this._rootElement,
158
+ threshold: [0.1, 0.5, 1],
159
+ rootMargin: this._getRootMargin()
160
+ };
161
+ return new IntersectionObserver(entries => this._observerCallback(entries), options);
162
+ } // The logic of selection
289
163
 
290
- const scrollHeight = this._getScrollHeight();
291
164
 
292
- const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
165
+ _observerCallback(entries) {
166
+ const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);
293
167
 
294
- if (this._scrollHeight !== scrollHeight) {
295
- this.refresh();
296
- }
168
+ const activate = entry => {
169
+ this._previousScrollData.visibleEntryTop = entry.target.offsetTop;
170
+
171
+ this._process(targetElement(entry));
172
+ };
173
+
174
+ const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;
175
+ const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;
176
+ this._previousScrollData.parentScrollTop = parentScrollTop;
297
177
 
298
- if (scrollTop >= maxScroll) {
299
- const target = this._targets[this._targets.length - 1];
178
+ for (const entry of entries) {
179
+ if (!entry.isIntersecting) {
180
+ this._activeTarget = null;
300
181
 
301
- if (this._activeTarget !== target) {
302
- this._activate(target);
182
+ this._clearActiveClass(targetElement(entry));
183
+
184
+ continue;
303
185
  }
304
186
 
305
- return;
306
- }
187
+ const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop; // if we are scrolling down, pick the bigger offsetTop
307
188
 
308
- if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
309
- this._activeTarget = null;
189
+ if (userScrollsDown && entryIsLowerThanPrevious) {
190
+ activate(entry); // if parent isn't scrolled, let's keep the first visible item, breaking the iteration
310
191
 
311
- this._clear();
192
+ if (!parentScrollTop) {
193
+ return;
194
+ }
312
195
 
313
- return;
314
- }
196
+ continue;
197
+ } // if we are scrolling up, pick the smallest offsetTop
315
198
 
316
- for (let i = this._offsets.length; i--;) {
317
- const isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
318
199
 
319
- if (isActiveTarget) {
320
- this._activate(this._targets[i]);
200
+ if (!userScrollsDown && !entryIsLowerThanPrevious) {
201
+ activate(entry);
321
202
  }
322
203
  }
204
+ } // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only
205
+
206
+
207
+ _getRootMargin() {
208
+ return this._config.offset ? `${this._config.offset}px 0px -30%` : this._config.rootMargin;
323
209
  }
324
210
 
325
- _activate(target) {
326
- this._activeTarget = target;
211
+ _initializeTargetsAndObservables() {
212
+ this._targetLinks = new Map();
213
+ this._observableSections = new Map();
214
+ const targetLinks = SelectorEngine__default.default.find(SELECTOR_TARGET_LINKS, this._config.target);
215
+
216
+ for (const anchor of targetLinks) {
217
+ // ensure that the anchor has an id and is not disabled
218
+ if (!anchor.hash || index.isDisabled(anchor)) {
219
+ continue;
220
+ }
327
221
 
328
- this._clear();
222
+ const observableSection = SelectorEngine__default.default.findOne(anchor.hash, this._element); // ensure that the observableSection exists & is visible
329
223
 
330
- const queries = SELECTOR_LINK_ITEMS.split(',').map(selector => `${selector}[data-coreui-target="${target}"],${selector}[href="${target}"]`);
331
- const link = SelectorEngine__default.default.findOne(queries.join(','), this._config.target);
332
- link.classList.add(CLASS_NAME_ACTIVE);
224
+ if (index.isVisible(observableSection)) {
225
+ this._targetLinks.set(anchor.hash, anchor);
333
226
 
334
- if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
335
- SelectorEngine__default.default.findOne(SELECTOR_DROPDOWN_TOGGLE, link.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE);
336
- } else {
337
- SelectorEngine__default.default.parents(link, SELECTOR_NAV_LIST_GROUP).forEach(listGroup => {
338
- // Set triggered links parents as active
339
- // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
340
- SelectorEngine__default.default.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`).forEach(item => item.classList.add(CLASS_NAME_ACTIVE)); // Handle special case when .nav-link is inside .nav-item
341
-
342
- SelectorEngine__default.default.prev(listGroup, SELECTOR_NAV_ITEMS).forEach(navItem => {
343
- SelectorEngine__default.default.children(navItem, SELECTOR_NAV_LINKS).forEach(item => item.classList.add(CLASS_NAME_ACTIVE));
344
- });
345
- });
227
+ this._observableSections.set(anchor.hash, observableSection);
228
+ }
346
229
  }
230
+ }
347
231
 
348
- EventHandler__default.default.trigger(this._scrollElement, EVENT_ACTIVATE, {
232
+ _process(target) {
233
+ if (this._activeTarget === target) {
234
+ return;
235
+ }
236
+
237
+ this._clearActiveClass(this._config.target);
238
+
239
+ this._activeTarget = target;
240
+ target.classList.add(CLASS_NAME_ACTIVE);
241
+
242
+ this._activateParents(target);
243
+
244
+ EventHandler__default.default.trigger(this._element, EVENT_ACTIVATE, {
349
245
  relatedTarget: target
350
246
  });
351
247
  }
352
248
 
353
- _clear() {
354
- SelectorEngine__default.default.find(SELECTOR_LINK_ITEMS, this._config.target).filter(node => node.classList.contains(CLASS_NAME_ACTIVE)).forEach(node => node.classList.remove(CLASS_NAME_ACTIVE));
249
+ _activateParents(target) {
250
+ // Activate dropdown parents
251
+ if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
252
+ SelectorEngine__default.default.findOne(SELECTOR_DROPDOWN_TOGGLE, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE);
253
+ return;
254
+ }
255
+
256
+ for (const listGroup of SelectorEngine__default.default.parents(target, SELECTOR_NAV_LIST_GROUP)) {
257
+ // Set triggered links parents as active
258
+ // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
259
+ for (const item of SelectorEngine__default.default.prev(listGroup, SELECTOR_LINK_ITEMS)) {
260
+ item.classList.add(CLASS_NAME_ACTIVE);
261
+ }
262
+ }
263
+ }
264
+
265
+ _clearActiveClass(parent) {
266
+ parent.classList.remove(CLASS_NAME_ACTIVE);
267
+ const activeNodes = SelectorEngine__default.default.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE}`, parent);
268
+
269
+ for (const node of activeNodes) {
270
+ node.classList.remove(CLASS_NAME_ACTIVE);
271
+ }
355
272
  } // Static
356
273
 
357
274
 
@@ -363,7 +280,7 @@
363
280
  return;
364
281
  }
365
282
 
366
- if (typeof data[config] === 'undefined') {
283
+ if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
367
284
  throw new TypeError(`No method named "${config}"`);
368
285
  }
369
286
 
@@ -373,23 +290,20 @@
373
290
 
374
291
  }
375
292
  /**
376
- * ------------------------------------------------------------------------
377
- * Data Api implementation
378
- * ------------------------------------------------------------------------
293
+ * Data API implementation
379
294
  */
380
295
 
381
296
 
382
297
  EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () => {
383
- SelectorEngine__default.default.find(SELECTOR_DATA_SPY).forEach(spy => new ScrollSpy(spy));
298
+ for (const spy of SelectorEngine__default.default.find(SELECTOR_DATA_SPY)) {
299
+ ScrollSpy.getOrCreateInstance(spy);
300
+ }
384
301
  });
385
302
  /**
386
- * ------------------------------------------------------------------------
387
303
  * jQuery
388
- * ------------------------------------------------------------------------
389
- * add .ScrollSpy to jQuery only if jQuery is present
390
304
  */
391
305
 
392
- defineJQueryPlugin(ScrollSpy);
306
+ index.defineJQueryPlugin(ScrollSpy);
393
307
 
394
308
  return ScrollSpy;
395
309