@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
package/js/dist/tab.js CHANGED
@@ -1,13 +1,13 @@
1
1
  /*!
2
- * CoreUI tab.js v4.1.4 (https://coreui.io)
2
+ * CoreUI tab.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/selector-engine.js'), require('./base-component.js')) :
8
- typeof define === 'function' && define.amd ? define(['./dom/event-handler', './dom/selector-engine', './base-component'], factory) :
9
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tab = factory(global.EventHandler, global.SelectorEngine, global.Base));
10
- })(this, (function (EventHandler, 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.Tab = 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
 
@@ -17,124 +17,7 @@
17
17
 
18
18
  /**
19
19
  * --------------------------------------------------------------------------
20
- * CoreUI (v4.1.4): alert.js
21
- * Licensed under MIT (https://coreui.io/license)
22
- *
23
- * This component is a modified version of the Bootstrap's util/index.js
24
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
25
- * --------------------------------------------------------------------------
26
- */
27
-
28
- const getSelector = element => {
29
- let selector = element.getAttribute('data-coreui-target');
30
-
31
- if (!selector || selector === '#') {
32
- let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
33
- // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
34
- // `document.querySelector` will rightfully complain it is invalid.
35
- // See https://github.com/twbs/bootstrap/issues/32273
36
-
37
- if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
38
- return null;
39
- } // Just in case some CMS puts out a full URL with the anchor appended
40
-
41
-
42
- if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
43
- hrefAttr = `#${hrefAttr.split('#')[1]}`;
44
- }
45
-
46
- selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
47
- }
48
-
49
- return selector;
50
- };
51
-
52
- const getElementFromSelector = element => {
53
- const selector = getSelector(element);
54
- return selector ? document.querySelector(selector) : null;
55
- };
56
-
57
- const isDisabled = element => {
58
- if (!element || element.nodeType !== Node.ELEMENT_NODE) {
59
- return true;
60
- }
61
-
62
- if (element.classList.contains('disabled')) {
63
- return true;
64
- }
65
-
66
- if (typeof element.disabled !== 'undefined') {
67
- return element.disabled;
68
- }
69
-
70
- return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
71
- };
72
- /**
73
- * Trick to restart an element's animation
74
- *
75
- * @param {HTMLElement} element
76
- * @return void
77
- *
78
- * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
79
- */
80
-
81
-
82
- const reflow = element => {
83
- // eslint-disable-next-line no-unused-expressions
84
- element.offsetHeight;
85
- };
86
-
87
- const getjQuery = () => {
88
- const {
89
- jQuery
90
- } = window;
91
-
92
- if (jQuery && !document.body.hasAttribute('data-coreui-no-jquery')) {
93
- return jQuery;
94
- }
95
-
96
- return null;
97
- };
98
-
99
- const DOMContentLoadedCallbacks = [];
100
-
101
- const onDOMContentLoaded = callback => {
102
- if (document.readyState === 'loading') {
103
- // add listener on the first call when the document is in loading state
104
- if (!DOMContentLoadedCallbacks.length) {
105
- document.addEventListener('DOMContentLoaded', () => {
106
- DOMContentLoadedCallbacks.forEach(callback => callback());
107
- });
108
- }
109
-
110
- DOMContentLoadedCallbacks.push(callback);
111
- } else {
112
- callback();
113
- }
114
- };
115
-
116
- const defineJQueryPlugin = plugin => {
117
- onDOMContentLoaded(() => {
118
- const $ = getjQuery();
119
- /* istanbul ignore if */
120
-
121
- if ($) {
122
- const name = plugin.NAME;
123
- const JQUERY_NO_CONFLICT = $.fn[name];
124
- $.fn[name] = plugin.jQueryInterface;
125
- $.fn[name].Constructor = plugin;
126
-
127
- $.fn[name].noConflict = () => {
128
- $.fn[name] = JQUERY_NO_CONFLICT;
129
- return plugin.jQueryInterface;
130
- };
131
- }
132
- });
133
- };
134
-
135
- /**
136
- * --------------------------------------------------------------------------
137
- * CoreUI (v4.1.4): tab.js
20
+ * CoreUI (v4.2.0): tab.js
138
21
  * Licensed under MIT (https://coreui.io/license)
139
22
  *
140
23
  * This component is a modified version of the Bootstrap's tab.js
@@ -142,151 +25,273 @@
142
25
  * --------------------------------------------------------------------------
143
26
  */
144
27
  /**
145
- * ------------------------------------------------------------------------
146
28
  * Constants
147
- * ------------------------------------------------------------------------
148
29
  */
149
30
 
150
31
  const NAME = 'tab';
151
32
  const DATA_KEY = 'coreui.tab';
152
33
  const EVENT_KEY = `.${DATA_KEY}`;
153
- const DATA_API_KEY = '.data-api';
154
34
  const EVENT_HIDE = `hide${EVENT_KEY}`;
155
35
  const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
156
36
  const EVENT_SHOW = `show${EVENT_KEY}`;
157
37
  const EVENT_SHOWN = `shown${EVENT_KEY}`;
158
- const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
159
- const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu';
38
+ const EVENT_CLICK_DATA_API = `click${EVENT_KEY}`;
39
+ const EVENT_KEYDOWN = `keydown${EVENT_KEY}`;
40
+ const EVENT_LOAD_DATA_API = `load${EVENT_KEY}`;
41
+ const ARROW_LEFT_KEY = 'ArrowLeft';
42
+ const ARROW_RIGHT_KEY = 'ArrowRight';
43
+ const ARROW_UP_KEY = 'ArrowUp';
44
+ const ARROW_DOWN_KEY = 'ArrowDown';
160
45
  const CLASS_NAME_ACTIVE = 'active';
161
46
  const CLASS_NAME_FADE = 'fade';
162
47
  const CLASS_NAME_SHOW = 'show';
163
- const SELECTOR_DROPDOWN = '.dropdown';
164
- const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
165
- const SELECTOR_ACTIVE = '.active';
166
- const SELECTOR_ACTIVE_UL = ':scope > li > .active';
167
- const SELECTOR_DATA_TOGGLE = '[data-coreui-toggle="tab"], [data-coreui-toggle="pill"], [data-coreui-toggle="list"]';
48
+ const CLASS_DROPDOWN = 'dropdown';
168
49
  const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
169
- const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active';
50
+ const SELECTOR_DROPDOWN_MENU = '.dropdown-menu';
51
+ const SELECTOR_DROPDOWN_ITEM = '.dropdown-item';
52
+ const NOT_SELECTOR_DROPDOWN_TOGGLE = ':not(.dropdown-toggle)';
53
+ const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]';
54
+ const SELECTOR_OUTER = '.nav-item, .list-group-item';
55
+ const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`;
56
+ const SELECTOR_DATA_TOGGLE = '[data-coreui-toggle="tab"], [data-coreui-toggle="pill"], [data-coreui-toggle="list"]'; // todo:v6: could be only `tab`
57
+
58
+ const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`;
59
+ const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-coreui-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-coreui-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-coreui-toggle="list"]`;
170
60
  /**
171
- * ------------------------------------------------------------------------
172
- * Class Definition
173
- * ------------------------------------------------------------------------
61
+ * Class definition
174
62
  */
175
63
 
176
64
  class Tab extends BaseComponent__default.default {
177
- // Getters
65
+ constructor(element) {
66
+ super(element);
67
+ this._parent = this._element.closest(SELECTOR_TAB_PANEL);
68
+
69
+ if (!this._parent) {
70
+ return; // todo: should Throw exception on v6
71
+ // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`)
72
+ } // Set up initial aria attributes
73
+
74
+
75
+ this._setInitialAttributes(this._parent, this._getChildren());
76
+
77
+ EventHandler__default.default.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));
78
+ } // Getters
79
+
80
+
178
81
  static get NAME() {
179
82
  return NAME;
180
83
  } // Public
181
84
 
182
85
 
183
86
  show() {
184
- if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && this._element.classList.contains(CLASS_NAME_ACTIVE)) {
185
- return;
186
- }
87
+ // Shows this elem and deactivate the active sibling if exists
88
+ const innerElem = this._element;
187
89
 
188
- let previous;
189
- const target = getElementFromSelector(this._element);
90
+ if (this._elemIsActive(innerElem)) {
91
+ return;
92
+ } // Search for active tab on same parent to deactivate it
190
93
 
191
- const listElement = this._element.closest(SELECTOR_NAV_LIST_GROUP);
192
94
 
193
- if (listElement) {
194
- const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE;
195
- previous = SelectorEngine__default.default.find(itemSelector, listElement);
196
- previous = previous[previous.length - 1];
197
- }
95
+ const active = this._getActiveElem();
198
96
 
199
- const hideEvent = previous ? EventHandler__default.default.trigger(previous, EVENT_HIDE, {
200
- relatedTarget: this._element
97
+ const hideEvent = active ? EventHandler__default.default.trigger(active, EVENT_HIDE, {
98
+ relatedTarget: innerElem
201
99
  }) : null;
202
- const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW, {
203
- relatedTarget: previous
100
+ const showEvent = EventHandler__default.default.trigger(innerElem, EVENT_SHOW, {
101
+ relatedTarget: active
204
102
  });
205
103
 
206
- if (showEvent.defaultPrevented || hideEvent !== null && hideEvent.defaultPrevented) {
104
+ if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) {
105
+ return;
106
+ }
107
+
108
+ this._deactivate(active, innerElem);
109
+
110
+ this._activate(innerElem, active);
111
+ } // Private
112
+
113
+
114
+ _activate(element, relatedElem) {
115
+ if (!element) {
207
116
  return;
208
117
  }
209
118
 
210
- this._activate(this._element, listElement);
119
+ element.classList.add(CLASS_NAME_ACTIVE);
120
+
121
+ this._activate(index.getElementFromSelector(element)); // Search and activate/show the proper section
122
+
123
+
124
+ const isAnimated = element.classList.contains(CLASS_NAME_FADE);
211
125
 
212
126
  const complete = () => {
213
- EventHandler__default.default.trigger(previous, EVENT_HIDDEN, {
214
- relatedTarget: this._element
127
+ if (isAnimated) {
128
+ // todo: maybe is redundant
129
+ element.classList.add(CLASS_NAME_SHOW);
130
+ }
131
+
132
+ if (element.getAttribute('role') !== 'tab') {
133
+ return;
134
+ }
135
+
136
+ element.focus();
137
+ element.removeAttribute('tabindex');
138
+ element.setAttribute('aria-selected', true);
139
+
140
+ this._toggleDropDown(element, true);
141
+
142
+ EventHandler__default.default.trigger(element, EVENT_SHOWN, {
143
+ relatedTarget: relatedElem
215
144
  });
216
- EventHandler__default.default.trigger(this._element, EVENT_SHOWN, {
217
- relatedTarget: previous
145
+ };
146
+
147
+ this._queueCallback(complete, element, isAnimated);
148
+ }
149
+
150
+ _deactivate(element, relatedElem) {
151
+ if (!element) {
152
+ return;
153
+ }
154
+
155
+ element.classList.remove(CLASS_NAME_ACTIVE);
156
+ element.blur();
157
+
158
+ this._deactivate(index.getElementFromSelector(element)); // Search and deactivate the shown section too
159
+
160
+
161
+ const isAnimated = element.classList.contains(CLASS_NAME_FADE);
162
+
163
+ const complete = () => {
164
+ if (isAnimated) {
165
+ // todo maybe is redundant
166
+ element.classList.remove(CLASS_NAME_SHOW);
167
+ }
168
+
169
+ if (element.getAttribute('role') !== 'tab') {
170
+ return;
171
+ }
172
+
173
+ element.setAttribute('aria-selected', false);
174
+ element.setAttribute('tabindex', '-1');
175
+
176
+ this._toggleDropDown(element, false);
177
+
178
+ EventHandler__default.default.trigger(element, EVENT_HIDDEN, {
179
+ relatedTarget: relatedElem
218
180
  });
219
181
  };
220
182
 
221
- if (target) {
222
- this._activate(target, target.parentNode, complete);
223
- } else {
224
- complete();
183
+ this._queueCallback(complete, element, isAnimated);
184
+ }
185
+
186
+ _keydown(event) {
187
+ if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key)) {
188
+ return;
225
189
  }
226
- } // Private
227
190
 
191
+ event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page
192
+
193
+ event.preventDefault();
194
+ const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key);
195
+ const nextActiveElement = index.getNextActiveElement(this._getChildren().filter(element => !index.isDisabled(element)), event.target, isNext, true);
228
196
 
229
- _activate(element, container, callback) {
230
- const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? SelectorEngine__default.default.find(SELECTOR_ACTIVE_UL, container) : SelectorEngine__default.default.children(container, SELECTOR_ACTIVE);
231
- const active = activeElements[0];
232
- const isTransitioning = callback && active && active.classList.contains(CLASS_NAME_FADE);
197
+ if (nextActiveElement) {
198
+ Tab.getOrCreateInstance(nextActiveElement).show();
199
+ }
200
+ }
233
201
 
234
- const complete = () => this._transitionComplete(element, active, callback);
202
+ _getChildren() {
203
+ // collection of inner elements
204
+ return SelectorEngine__default.default.find(SELECTOR_INNER_ELEM, this._parent);
205
+ }
235
206
 
236
- if (active && isTransitioning) {
237
- active.classList.remove(CLASS_NAME_SHOW);
207
+ _getActiveElem() {
208
+ return this._getChildren().find(child => this._elemIsActive(child)) || null;
209
+ }
238
210
 
239
- this._queueCallback(complete, element, true);
240
- } else {
241
- complete();
211
+ _setInitialAttributes(parent, children) {
212
+ this._setAttributeIfNotExists(parent, 'role', 'tablist');
213
+
214
+ for (const child of children) {
215
+ this._setInitialAttributesOnChild(child);
242
216
  }
243
217
  }
244
218
 
245
- _transitionComplete(element, active, callback) {
246
- if (active) {
247
- active.classList.remove(CLASS_NAME_ACTIVE);
248
- const dropdownChild = SelectorEngine__default.default.findOne(SELECTOR_DROPDOWN_ACTIVE_CHILD, active.parentNode);
219
+ _setInitialAttributesOnChild(child) {
220
+ child = this._getInnerElement(child);
249
221
 
250
- if (dropdownChild) {
251
- dropdownChild.classList.remove(CLASS_NAME_ACTIVE);
252
- }
222
+ const isActive = this._elemIsActive(child);
253
223
 
254
- if (active.getAttribute('role') === 'tab') {
255
- active.setAttribute('aria-selected', false);
256
- }
224
+ const outerElem = this._getOuterElement(child);
225
+
226
+ child.setAttribute('aria-selected', isActive);
227
+
228
+ if (outerElem !== child) {
229
+ this._setAttributeIfNotExists(outerElem, 'role', 'presentation');
257
230
  }
258
231
 
259
- element.classList.add(CLASS_NAME_ACTIVE);
232
+ if (!isActive) {
233
+ child.setAttribute('tabindex', '-1');
234
+ }
260
235
 
261
- if (element.getAttribute('role') === 'tab') {
262
- element.setAttribute('aria-selected', true);
236
+ this._setAttributeIfNotExists(child, 'role', 'tab'); // set attributes to the related panel too
237
+
238
+
239
+ this._setInitialAttributesOnTargetPanel(child);
240
+ }
241
+
242
+ _setInitialAttributesOnTargetPanel(child) {
243
+ const target = index.getElementFromSelector(child);
244
+
245
+ if (!target) {
246
+ return;
263
247
  }
264
248
 
265
- reflow(element);
249
+ this._setAttributeIfNotExists(target, 'role', 'tabpanel');
266
250
 
267
- if (element.classList.contains(CLASS_NAME_FADE)) {
268
- element.classList.add(CLASS_NAME_SHOW);
251
+ if (child.id) {
252
+ this._setAttributeIfNotExists(target, 'aria-labelledby', `#${child.id}`);
269
253
  }
254
+ }
270
255
 
271
- let parent = element.parentNode;
256
+ _toggleDropDown(element, open) {
257
+ const outerElem = this._getOuterElement(element);
272
258
 
273
- if (parent && parent.nodeName === 'LI') {
274
- parent = parent.parentNode;
259
+ if (!outerElem.classList.contains(CLASS_DROPDOWN)) {
260
+ return;
275
261
  }
276
262
 
277
- if (parent && parent.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {
278
- const dropdownElement = element.closest(SELECTOR_DROPDOWN);
263
+ const toggle = (selector, className) => {
264
+ const element = SelectorEngine__default.default.findOne(selector, outerElem);
279
265
 
280
- if (dropdownElement) {
281
- SelectorEngine__default.default.find(SELECTOR_DROPDOWN_TOGGLE, dropdownElement).forEach(dropdown => dropdown.classList.add(CLASS_NAME_ACTIVE));
266
+ if (element) {
267
+ element.classList.toggle(className, open);
282
268
  }
269
+ };
283
270
 
284
- element.setAttribute('aria-expanded', true);
285
- }
271
+ toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE);
272
+ toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW);
273
+ toggle(SELECTOR_DROPDOWN_ITEM, CLASS_NAME_ACTIVE);
274
+ outerElem.setAttribute('aria-expanded', open);
275
+ }
286
276
 
287
- if (callback) {
288
- callback();
277
+ _setAttributeIfNotExists(element, attribute, value) {
278
+ if (!element.hasAttribute(attribute)) {
279
+ element.setAttribute(attribute, value);
289
280
  }
281
+ }
282
+
283
+ _elemIsActive(elem) {
284
+ return elem.classList.contains(CLASS_NAME_ACTIVE);
285
+ } // Try to get the inner element (usually the .nav-link)
286
+
287
+
288
+ _getInnerElement(elem) {
289
+ return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine__default.default.findOne(SELECTOR_INNER_ELEM, elem);
290
+ } // Try to get the outer element (usually the .nav-item)
291
+
292
+
293
+ _getOuterElement(elem) {
294
+ return elem.closest(SELECTOR_OUTER) || elem;
290
295
  } // Static
291
296
 
292
297
 
@@ -294,21 +299,21 @@
294
299
  return this.each(function () {
295
300
  const data = Tab.getOrCreateInstance(this);
296
301
 
297
- if (typeof config === 'string') {
298
- if (typeof data[config] === 'undefined') {
299
- throw new TypeError(`No method named "${config}"`);
300
- }
302
+ if (typeof config !== 'string') {
303
+ return;
304
+ }
301
305
 
302
- data[config]();
306
+ if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
307
+ throw new TypeError(`No method named "${config}"`);
303
308
  }
309
+
310
+ data[config]();
304
311
  });
305
312
  }
306
313
 
307
314
  }
308
315
  /**
309
- * ------------------------------------------------------------------------
310
- * Data Api implementation
311
- * ------------------------------------------------------------------------
316
+ * Data API implementation
312
317
  */
313
318
 
314
319
 
@@ -317,21 +322,26 @@
317
322
  event.preventDefault();
318
323
  }
319
324
 
320
- if (isDisabled(this)) {
325
+ if (index.isDisabled(this)) {
321
326
  return;
322
327
  }
323
328
 
324
- const data = Tab.getOrCreateInstance(this);
325
- data.show();
329
+ Tab.getOrCreateInstance(this).show();
330
+ });
331
+ /**
332
+ * Initialize on focus
333
+ */
334
+
335
+ EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () => {
336
+ for (const element of SelectorEngine__default.default.find(SELECTOR_DATA_TOGGLE_ACTIVE)) {
337
+ Tab.getOrCreateInstance(element);
338
+ }
326
339
  });
327
340
  /**
328
- * ------------------------------------------------------------------------
329
341
  * jQuery
330
- * ------------------------------------------------------------------------
331
- * add .Tab to jQuery only if jQuery is present
332
342
  */
333
343
 
334
- defineJQueryPlugin(Tab);
344
+ index.defineJQueryPlugin(Tab);
335
345
 
336
346
  return Tab;
337
347