bootstrap 5.1.3 → 5.3.5

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 (127) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +61 -0
  3. data/CHANGELOG.md +9 -0
  4. data/Gemfile +1 -0
  5. data/README.md +35 -14
  6. data/Rakefile +16 -5
  7. data/assets/javascripts/bootstrap/alert.js +22 -167
  8. data/assets/javascripts/bootstrap/base-component.js +34 -133
  9. data/assets/javascripts/bootstrap/button.js +19 -86
  10. data/assets/javascripts/bootstrap/carousel.js +209 -564
  11. data/assets/javascripts/bootstrap/collapse.js +78 -324
  12. data/assets/javascripts/bootstrap/dom/data.js +8 -14
  13. data/assets/javascripts/bootstrap/dom/event-handler.js +89 -174
  14. data/assets/javascripts/bootstrap/dom/manipulator.js +22 -39
  15. data/assets/javascripts/bootstrap/dom/selector-engine.js +47 -71
  16. data/assets/javascripts/bootstrap/dropdown.js +135 -420
  17. data/assets/javascripts/bootstrap/modal.js +115 -837
  18. data/assets/javascripts/bootstrap/offcanvas.js +93 -714
  19. data/assets/javascripts/bootstrap/popover.js +42 -130
  20. data/assets/javascripts/bootstrap/scrollspy.js +180 -296
  21. data/assets/javascripts/bootstrap/tab.js +197 -245
  22. data/assets/javascripts/bootstrap/toast.js +52 -276
  23. data/assets/javascripts/bootstrap/tooltip.js +283 -744
  24. data/assets/javascripts/bootstrap/util/backdrop.js +138 -0
  25. data/assets/javascripts/bootstrap/util/component-functions.js +41 -0
  26. data/assets/javascripts/bootstrap/util/config.js +67 -0
  27. data/assets/javascripts/bootstrap/util/focustrap.js +112 -0
  28. data/assets/javascripts/bootstrap/util/index.js +280 -0
  29. data/assets/javascripts/bootstrap/util/sanitizer.js +113 -0
  30. data/assets/javascripts/bootstrap/util/scrollbar.js +112 -0
  31. data/assets/javascripts/bootstrap/util/swipe.js +134 -0
  32. data/assets/javascripts/bootstrap/util/template-factory.js +150 -0
  33. data/assets/javascripts/bootstrap-global-this-define.js +1 -1
  34. data/assets/javascripts/bootstrap-sprockets.js +15 -6
  35. data/assets/javascripts/bootstrap.js +2278 -2831
  36. data/assets/javascripts/bootstrap.min.js +3 -3
  37. data/assets/stylesheets/_bootstrap-grid.scss +4 -9
  38. data/assets/stylesheets/_bootstrap-reboot.scss +4 -7
  39. data/assets/stylesheets/_bootstrap-utilities.scss +19 -0
  40. data/assets/stylesheets/_bootstrap.scss +5 -6
  41. data/assets/stylesheets/bootstrap/_accordion.scss +68 -33
  42. data/assets/stylesheets/bootstrap/_alert.scss +25 -14
  43. data/assets/stylesheets/bootstrap/_badge.scss +14 -5
  44. data/assets/stylesheets/bootstrap/_breadcrumb.scss +22 -10
  45. data/assets/stylesheets/bootstrap/_button-group.scss +12 -4
  46. data/assets/stylesheets/bootstrap/_buttons.scss +133 -28
  47. data/assets/stylesheets/bootstrap/_card.scss +61 -39
  48. data/assets/stylesheets/bootstrap/_carousel.scss +22 -25
  49. data/assets/stylesheets/bootstrap/_close.scss +36 -10
  50. data/assets/stylesheets/bootstrap/_containers.scss +1 -1
  51. data/assets/stylesheets/bootstrap/_dropdown.scss +86 -76
  52. data/assets/stylesheets/bootstrap/_functions.scss +10 -10
  53. data/assets/stylesheets/bootstrap/_grid.scss +9 -3
  54. data/assets/stylesheets/bootstrap/_helpers.scss +3 -0
  55. data/assets/stylesheets/bootstrap/_list-group.scss +81 -56
  56. data/assets/stylesheets/bootstrap/_maps.scss +174 -0
  57. data/assets/stylesheets/bootstrap/_mixins.scss +1 -2
  58. data/assets/stylesheets/bootstrap/_modal.scss +76 -45
  59. data/assets/stylesheets/bootstrap/_nav.scss +87 -29
  60. data/assets/stylesheets/bootstrap/_navbar.scss +102 -148
  61. data/assets/stylesheets/bootstrap/_offcanvas.scss +125 -61
  62. data/assets/stylesheets/bootstrap/_pagination.scss +66 -21
  63. data/assets/stylesheets/bootstrap/_placeholders.scss +1 -1
  64. data/assets/stylesheets/bootstrap/_popover.scss +90 -52
  65. data/assets/stylesheets/bootstrap/_progress.scss +31 -11
  66. data/assets/stylesheets/bootstrap/_reboot.scss +32 -46
  67. data/assets/stylesheets/bootstrap/_root.scss +155 -22
  68. data/assets/stylesheets/bootstrap/_spinners.scss +38 -22
  69. data/assets/stylesheets/bootstrap/_tables.scss +40 -24
  70. data/assets/stylesheets/bootstrap/_toasts.scss +38 -16
  71. data/assets/stylesheets/bootstrap/_tooltip.scss +60 -56
  72. data/assets/stylesheets/bootstrap/_type.scss +3 -1
  73. data/assets/stylesheets/bootstrap/_utilities.scss +209 -33
  74. data/assets/stylesheets/bootstrap/_variables-dark.scss +102 -0
  75. data/assets/stylesheets/bootstrap/_variables.scss +415 -303
  76. data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +39 -5
  77. data/assets/stylesheets/bootstrap/forms/_form-check.scss +51 -14
  78. data/assets/stylesheets/bootstrap/forms/_form-control.scss +36 -41
  79. data/assets/stylesheets/bootstrap/forms/_form-range.scss +3 -3
  80. data/assets/stylesheets/bootstrap/forms/_form-select.scss +12 -4
  81. data/assets/stylesheets/bootstrap/forms/_input-group.scss +20 -9
  82. data/assets/stylesheets/bootstrap/helpers/_color-bg.scss +7 -0
  83. data/assets/stylesheets/bootstrap/helpers/_colored-links.scss +20 -2
  84. data/assets/stylesheets/bootstrap/helpers/_focus-ring.scss +5 -0
  85. data/assets/stylesheets/bootstrap/helpers/_icon-link.scss +25 -0
  86. data/assets/stylesheets/bootstrap/helpers/_position.scss +7 -1
  87. data/assets/stylesheets/bootstrap/helpers/_ratio.scss +2 -2
  88. data/assets/stylesheets/bootstrap/helpers/_vr.scss +2 -2
  89. data/assets/stylesheets/bootstrap/mixins/_alert.scss +11 -4
  90. data/assets/stylesheets/bootstrap/mixins/_banner.scss +7 -0
  91. data/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +8 -8
  92. data/assets/stylesheets/bootstrap/mixins/_buttons.scss +32 -95
  93. data/assets/stylesheets/bootstrap/mixins/_caret.scss +30 -25
  94. data/assets/stylesheets/bootstrap/mixins/_color-mode.scss +21 -0
  95. data/assets/stylesheets/bootstrap/mixins/_container.scss +4 -2
  96. data/assets/stylesheets/bootstrap/mixins/_forms.scss +38 -19
  97. data/assets/stylesheets/bootstrap/mixins/_gradients.scss +1 -1
  98. data/assets/stylesheets/bootstrap/mixins/_grid.scss +15 -15
  99. data/assets/stylesheets/bootstrap/mixins/_list-group.scss +2 -0
  100. data/assets/stylesheets/bootstrap/mixins/_pagination.scss +4 -25
  101. data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +1 -1
  102. data/assets/stylesheets/bootstrap/mixins/_table-variants.scss +12 -9
  103. data/assets/stylesheets/bootstrap/mixins/_utilities.scss +14 -6
  104. data/assets/stylesheets/bootstrap/mixins/_visually-hidden.scss +6 -2
  105. data/assets/stylesheets/bootstrap/vendor/_rfs.scss +23 -29
  106. data/bootstrap.gemspec +3 -3
  107. data/lib/bootstrap/engine.rb +17 -2
  108. data/lib/bootstrap/version.rb +2 -2
  109. data/tasks/updater/js.rb +10 -5
  110. data/tasks/updater/network.rb +2 -2
  111. data/tasks/updater/scss.rb +2 -2
  112. data/tasks/updater.rb +2 -2
  113. data/test/dummy_rails/config/application.rb +0 -2
  114. data/test/dummy_rails/public/favicon.ico +0 -0
  115. data/test/gemfiles/rails_4_2.gemfile +2 -1
  116. data/test/gemfiles/rails_5_0.gemfile +1 -2
  117. data/test/gemfiles/rails_5_1.gemfile +1 -2
  118. data/test/gemfiles/rails_5_2.gemfile +7 -0
  119. data/test/gemfiles/rails_6_0.gemfile +1 -1
  120. data/test/gemfiles/rails_6_1.gemfile +1 -1
  121. data/test/gemfiles/rails_7_0_dartsass.gemfile +7 -0
  122. data/test/gemfiles/rails_7_0_sassc.gemfile +7 -0
  123. data/test/rails_test.rb +0 -5
  124. data/test/test_helper.rb +3 -2
  125. metadata +49 -29
  126. data/.travis.yml +0 -32
  127. data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +0 -18
@@ -1,620 +1,24 @@
1
1
  /*!
2
- * Bootstrap offcanvas.js v5.1.3 (https://getbootstrap.com/)
3
- * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
2
+ * Bootstrap offcanvas.js v5.3.5 (https://getbootstrap.com/)
3
+ * Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4
4
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
5
  */
6
6
  (function (global, factory) {
7
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/selector-engine.js'), require('./dom/manipulator.js'), require('./dom/event-handler.js'), require('./base-component.js')) :
8
- typeof define === 'function' && define.amd ? define(['./dom/selector-engine', './dom/manipulator', './dom/event-handler', './base-component'], factory) :
9
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Offcanvas = factory(global.SelectorEngine, global.Manipulator, global.EventHandler, global.Base));
10
- })(this, (function (SelectorEngine, Manipulator, EventHandler, BaseComponent) { 'use strict';
11
-
12
- const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
13
-
14
- const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
15
- const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
16
- const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
17
- const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./dom/selector-engine.js'), require('./util/backdrop.js'), require('./util/component-functions.js'), require('./util/focustrap.js'), require('./util/index.js'), require('./util/scrollbar.js')) :
8
+ typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './dom/selector-engine', './util/backdrop', './util/component-functions', './util/focustrap', './util/index', './util/scrollbar'], factory) :
9
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Offcanvas = factory(global.BaseComponent, global.EventHandler, global.SelectorEngine, global.Backdrop, global.ComponentFunctions, global.Focustrap, global.Index, global.Scrollbar));
10
+ })(this, (function (BaseComponent, EventHandler, SelectorEngine, Backdrop, componentFunctions_js, FocusTrap, index_js, ScrollBarHelper) { 'use strict';
18
11
 
19
12
  /**
20
13
  * --------------------------------------------------------------------------
21
- * Bootstrap (v5.1.3): util/index.js
14
+ * Bootstrap offcanvas.js
22
15
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
23
16
  * --------------------------------------------------------------------------
24
17
  */
25
- const MILLISECONDS_MULTIPLIER = 1000;
26
- const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
27
-
28
- const toType = obj => {
29
- if (obj === null || obj === undefined) {
30
- return `${obj}`;
31
- }
32
-
33
- return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
34
- };
35
-
36
- const getSelector = element => {
37
- let selector = element.getAttribute('data-bs-target');
38
-
39
- if (!selector || selector === '#') {
40
- let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
41
- // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
42
- // `document.querySelector` will rightfully complain it is invalid.
43
- // See https://github.com/twbs/bootstrap/issues/32273
44
-
45
- if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
46
- return null;
47
- } // Just in case some CMS puts out a full URL with the anchor appended
48
-
49
-
50
- if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
51
- hrefAttr = `#${hrefAttr.split('#')[1]}`;
52
- }
53
-
54
- selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
55
- }
56
-
57
- return selector;
58
- };
59
-
60
- const getElementFromSelector = element => {
61
- const selector = getSelector(element);
62
- return selector ? document.querySelector(selector) : null;
63
- };
64
-
65
- const getTransitionDurationFromElement = element => {
66
- if (!element) {
67
- return 0;
68
- } // Get transition-duration of the element
69
-
70
-
71
- let {
72
- transitionDuration,
73
- transitionDelay
74
- } = window.getComputedStyle(element);
75
- const floatTransitionDuration = Number.parseFloat(transitionDuration);
76
- const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
77
-
78
- if (!floatTransitionDuration && !floatTransitionDelay) {
79
- return 0;
80
- } // If multiple durations are defined, take the first
81
-
82
-
83
- transitionDuration = transitionDuration.split(',')[0];
84
- transitionDelay = transitionDelay.split(',')[0];
85
- return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
86
- };
87
-
88
- const triggerTransitionEnd = element => {
89
- element.dispatchEvent(new Event(TRANSITION_END));
90
- };
91
-
92
- const isElement = obj => {
93
- if (!obj || typeof obj !== 'object') {
94
- return false;
95
- }
96
-
97
- if (typeof obj.jquery !== 'undefined') {
98
- obj = obj[0];
99
- }
100
-
101
- return typeof obj.nodeType !== 'undefined';
102
- };
103
-
104
- const getElement = obj => {
105
- if (isElement(obj)) {
106
- // it's a jQuery object or a node element
107
- return obj.jquery ? obj[0] : obj;
108
- }
109
-
110
- if (typeof obj === 'string' && obj.length > 0) {
111
- return document.querySelector(obj);
112
- }
113
-
114
- return null;
115
- };
116
-
117
- const typeCheckConfig = (componentName, config, configTypes) => {
118
- Object.keys(configTypes).forEach(property => {
119
- const expectedTypes = configTypes[property];
120
- const value = config[property];
121
- const valueType = value && isElement(value) ? 'element' : toType(value);
122
-
123
- if (!new RegExp(expectedTypes).test(valueType)) {
124
- throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
125
- }
126
- });
127
- };
128
-
129
- const isVisible = element => {
130
- if (!isElement(element) || element.getClientRects().length === 0) {
131
- return false;
132
- }
133
-
134
- return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
135
- };
136
-
137
- const isDisabled = element => {
138
- if (!element || element.nodeType !== Node.ELEMENT_NODE) {
139
- return true;
140
- }
141
-
142
- if (element.classList.contains('disabled')) {
143
- return true;
144
- }
145
18
 
146
- if (typeof element.disabled !== 'undefined') {
147
- return element.disabled;
148
- }
149
19
 
150
- return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
151
- };
152
20
  /**
153
- * Trick to restart an element's animation
154
- *
155
- * @param {HTMLElement} element
156
- * @return void
157
- *
158
- * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
159
- */
160
-
161
-
162
- const reflow = element => {
163
- // eslint-disable-next-line no-unused-expressions
164
- element.offsetHeight;
165
- };
166
-
167
- const getjQuery = () => {
168
- const {
169
- jQuery
170
- } = window;
171
-
172
- if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
173
- return jQuery;
174
- }
175
-
176
- return null;
177
- };
178
-
179
- const DOMContentLoadedCallbacks = [];
180
-
181
- const onDOMContentLoaded = callback => {
182
- if (document.readyState === 'loading') {
183
- // add listener on the first call when the document is in loading state
184
- if (!DOMContentLoadedCallbacks.length) {
185
- document.addEventListener('DOMContentLoaded', () => {
186
- DOMContentLoadedCallbacks.forEach(callback => callback());
187
- });
188
- }
189
-
190
- DOMContentLoadedCallbacks.push(callback);
191
- } else {
192
- callback();
193
- }
194
- };
195
-
196
- const defineJQueryPlugin = plugin => {
197
- onDOMContentLoaded(() => {
198
- const $ = getjQuery();
199
- /* istanbul ignore if */
200
-
201
- if ($) {
202
- const name = plugin.NAME;
203
- const JQUERY_NO_CONFLICT = $.fn[name];
204
- $.fn[name] = plugin.jQueryInterface;
205
- $.fn[name].Constructor = plugin;
206
-
207
- $.fn[name].noConflict = () => {
208
- $.fn[name] = JQUERY_NO_CONFLICT;
209
- return plugin.jQueryInterface;
210
- };
211
- }
212
- });
213
- };
214
-
215
- const execute = callback => {
216
- if (typeof callback === 'function') {
217
- callback();
218
- }
219
- };
220
-
221
- const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
222
- if (!waitForTransition) {
223
- execute(callback);
224
- return;
225
- }
226
-
227
- const durationPadding = 5;
228
- const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
229
- let called = false;
230
-
231
- const handler = ({
232
- target
233
- }) => {
234
- if (target !== transitionElement) {
235
- return;
236
- }
237
-
238
- called = true;
239
- transitionElement.removeEventListener(TRANSITION_END, handler);
240
- execute(callback);
241
- };
242
-
243
- transitionElement.addEventListener(TRANSITION_END, handler);
244
- setTimeout(() => {
245
- if (!called) {
246
- triggerTransitionEnd(transitionElement);
247
- }
248
- }, emulatedDuration);
249
- };
250
-
251
- /**
252
- * --------------------------------------------------------------------------
253
- * Bootstrap (v5.1.3): util/scrollBar.js
254
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
255
- * --------------------------------------------------------------------------
256
- */
257
- const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
258
- const SELECTOR_STICKY_CONTENT = '.sticky-top';
259
-
260
- class ScrollBarHelper {
261
- constructor() {
262
- this._element = document.body;
263
- }
264
-
265
- getWidth() {
266
- // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
267
- const documentWidth = document.documentElement.clientWidth;
268
- return Math.abs(window.innerWidth - documentWidth);
269
- }
270
-
271
- hide() {
272
- const width = this.getWidth();
273
-
274
- this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width
275
-
276
-
277
- this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
278
-
279
-
280
- this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width);
281
-
282
- this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);
283
- }
284
-
285
- _disableOverFlow() {
286
- this._saveInitialAttribute(this._element, 'overflow');
287
-
288
- this._element.style.overflow = 'hidden';
289
- }
290
-
291
- _setElementAttributes(selector, styleProp, callback) {
292
- const scrollbarWidth = this.getWidth();
293
-
294
- const manipulationCallBack = element => {
295
- if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
296
- return;
297
- }
298
-
299
- this._saveInitialAttribute(element, styleProp);
300
-
301
- const calculatedValue = window.getComputedStyle(element)[styleProp];
302
- element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;
303
- };
304
-
305
- this._applyManipulationCallback(selector, manipulationCallBack);
306
- }
307
-
308
- reset() {
309
- this._resetElementAttributes(this._element, 'overflow');
310
-
311
- this._resetElementAttributes(this._element, 'paddingRight');
312
-
313
- this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
314
-
315
- this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
316
- }
317
-
318
- _saveInitialAttribute(element, styleProp) {
319
- const actualValue = element.style[styleProp];
320
-
321
- if (actualValue) {
322
- Manipulator__default.default.setDataAttribute(element, styleProp, actualValue);
323
- }
324
- }
325
-
326
- _resetElementAttributes(selector, styleProp) {
327
- const manipulationCallBack = element => {
328
- const value = Manipulator__default.default.getDataAttribute(element, styleProp);
329
-
330
- if (typeof value === 'undefined') {
331
- element.style.removeProperty(styleProp);
332
- } else {
333
- Manipulator__default.default.removeDataAttribute(element, styleProp);
334
- element.style[styleProp] = value;
335
- }
336
- };
337
-
338
- this._applyManipulationCallback(selector, manipulationCallBack);
339
- }
340
-
341
- _applyManipulationCallback(selector, callBack) {
342
- if (isElement(selector)) {
343
- callBack(selector);
344
- } else {
345
- SelectorEngine__default.default.find(selector, this._element).forEach(callBack);
346
- }
347
- }
348
-
349
- isOverflowing() {
350
- return this.getWidth() > 0;
351
- }
352
-
353
- }
354
-
355
- /**
356
- * --------------------------------------------------------------------------
357
- * Bootstrap (v5.1.3): util/backdrop.js
358
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
359
- * --------------------------------------------------------------------------
360
- */
361
- const Default$2 = {
362
- className: 'modal-backdrop',
363
- isVisible: true,
364
- // if false, we use the backdrop helper without adding any element to the dom
365
- isAnimated: false,
366
- rootElement: 'body',
367
- // give the choice to place backdrop under different elements
368
- clickCallback: null
369
- };
370
- const DefaultType$2 = {
371
- className: 'string',
372
- isVisible: 'boolean',
373
- isAnimated: 'boolean',
374
- rootElement: '(element|string)',
375
- clickCallback: '(function|null)'
376
- };
377
- const NAME$2 = 'backdrop';
378
- const CLASS_NAME_FADE = 'fade';
379
- const CLASS_NAME_SHOW$1 = 'show';
380
- const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$2}`;
381
-
382
- class Backdrop {
383
- constructor(config) {
384
- this._config = this._getConfig(config);
385
- this._isAppended = false;
386
- this._element = null;
387
- }
388
-
389
- show(callback) {
390
- if (!this._config.isVisible) {
391
- execute(callback);
392
- return;
393
- }
394
-
395
- this._append();
396
-
397
- if (this._config.isAnimated) {
398
- reflow(this._getElement());
399
- }
400
-
401
- this._getElement().classList.add(CLASS_NAME_SHOW$1);
402
-
403
- this._emulateAnimation(() => {
404
- execute(callback);
405
- });
406
- }
407
-
408
- hide(callback) {
409
- if (!this._config.isVisible) {
410
- execute(callback);
411
- return;
412
- }
413
-
414
- this._getElement().classList.remove(CLASS_NAME_SHOW$1);
415
-
416
- this._emulateAnimation(() => {
417
- this.dispose();
418
- execute(callback);
419
- });
420
- } // Private
421
-
422
-
423
- _getElement() {
424
- if (!this._element) {
425
- const backdrop = document.createElement('div');
426
- backdrop.className = this._config.className;
427
-
428
- if (this._config.isAnimated) {
429
- backdrop.classList.add(CLASS_NAME_FADE);
430
- }
431
-
432
- this._element = backdrop;
433
- }
434
-
435
- return this._element;
436
- }
437
-
438
- _getConfig(config) {
439
- config = { ...Default$2,
440
- ...(typeof config === 'object' ? config : {})
441
- }; // use getElement() with the default "body" to get a fresh Element on each instantiation
442
-
443
- config.rootElement = getElement(config.rootElement);
444
- typeCheckConfig(NAME$2, config, DefaultType$2);
445
- return config;
446
- }
447
-
448
- _append() {
449
- if (this._isAppended) {
450
- return;
451
- }
452
-
453
- this._config.rootElement.append(this._getElement());
454
-
455
- EventHandler__default.default.on(this._getElement(), EVENT_MOUSEDOWN, () => {
456
- execute(this._config.clickCallback);
457
- });
458
- this._isAppended = true;
459
- }
460
-
461
- dispose() {
462
- if (!this._isAppended) {
463
- return;
464
- }
465
-
466
- EventHandler__default.default.off(this._element, EVENT_MOUSEDOWN);
467
-
468
- this._element.remove();
469
-
470
- this._isAppended = false;
471
- }
472
-
473
- _emulateAnimation(callback) {
474
- executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
475
- }
476
-
477
- }
478
-
479
- /**
480
- * --------------------------------------------------------------------------
481
- * Bootstrap (v5.1.3): util/focustrap.js
482
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
483
- * --------------------------------------------------------------------------
484
- */
485
- const Default$1 = {
486
- trapElement: null,
487
- // The element to trap focus inside of
488
- autofocus: true
489
- };
490
- const DefaultType$1 = {
491
- trapElement: 'element',
492
- autofocus: 'boolean'
493
- };
494
- const NAME$1 = 'focustrap';
495
- const DATA_KEY$1 = 'bs.focustrap';
496
- const EVENT_KEY$1 = `.${DATA_KEY$1}`;
497
- const EVENT_FOCUSIN = `focusin${EVENT_KEY$1}`;
498
- const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$1}`;
499
- const TAB_KEY = 'Tab';
500
- const TAB_NAV_FORWARD = 'forward';
501
- const TAB_NAV_BACKWARD = 'backward';
502
-
503
- class FocusTrap {
504
- constructor(config) {
505
- this._config = this._getConfig(config);
506
- this._isActive = false;
507
- this._lastTabNavDirection = null;
508
- }
509
-
510
- activate() {
511
- const {
512
- trapElement,
513
- autofocus
514
- } = this._config;
515
-
516
- if (this._isActive) {
517
- return;
518
- }
519
-
520
- if (autofocus) {
521
- trapElement.focus();
522
- }
523
-
524
- EventHandler__default.default.off(document, EVENT_KEY$1); // guard against infinite focus loop
525
-
526
- EventHandler__default.default.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event));
527
- EventHandler__default.default.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
528
- this._isActive = true;
529
- }
530
-
531
- deactivate() {
532
- if (!this._isActive) {
533
- return;
534
- }
535
-
536
- this._isActive = false;
537
- EventHandler__default.default.off(document, EVENT_KEY$1);
538
- } // Private
539
-
540
-
541
- _handleFocusin(event) {
542
- const {
543
- target
544
- } = event;
545
- const {
546
- trapElement
547
- } = this._config;
548
-
549
- if (target === document || target === trapElement || trapElement.contains(target)) {
550
- return;
551
- }
552
-
553
- const elements = SelectorEngine__default.default.focusableChildren(trapElement);
554
-
555
- if (elements.length === 0) {
556
- trapElement.focus();
557
- } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
558
- elements[elements.length - 1].focus();
559
- } else {
560
- elements[0].focus();
561
- }
562
- }
563
-
564
- _handleKeydown(event) {
565
- if (event.key !== TAB_KEY) {
566
- return;
567
- }
568
-
569
- this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
570
- }
571
-
572
- _getConfig(config) {
573
- config = { ...Default$1,
574
- ...(typeof config === 'object' ? config : {})
575
- };
576
- typeCheckConfig(NAME$1, config, DefaultType$1);
577
- return config;
578
- }
579
-
580
- }
581
-
582
- /**
583
- * --------------------------------------------------------------------------
584
- * Bootstrap (v5.1.3): util/component-functions.js
585
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
586
- * --------------------------------------------------------------------------
587
- */
588
-
589
- const enableDismissTrigger = (component, method = 'hide') => {
590
- const clickEvent = `click.dismiss${component.EVENT_KEY}`;
591
- const name = component.NAME;
592
- EventHandler__default.default.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
593
- if (['A', 'AREA'].includes(this.tagName)) {
594
- event.preventDefault();
595
- }
596
-
597
- if (isDisabled(this)) {
598
- return;
599
- }
600
-
601
- const target = getElementFromSelector(this) || this.closest(`.${name}`);
602
- const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
603
-
604
- instance[method]();
605
- });
606
- };
607
-
608
- /**
609
- * --------------------------------------------------------------------------
610
- * Bootstrap (v5.1.3): offcanvas.js
611
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
612
- * --------------------------------------------------------------------------
613
- */
614
- /**
615
- * ------------------------------------------------------------------------
616
21
  * Constants
617
- * ------------------------------------------------------------------------
618
22
  */
619
23
 
620
24
  const NAME = 'offcanvas';
@@ -623,243 +27,218 @@
623
27
  const DATA_API_KEY = '.data-api';
624
28
  const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`;
625
29
  const ESCAPE_KEY = 'Escape';
626
- const Default = {
627
- backdrop: true,
628
- keyboard: true,
629
- scroll: false
630
- };
631
- const DefaultType = {
632
- backdrop: 'boolean',
633
- keyboard: 'boolean',
634
- scroll: 'boolean'
635
- };
636
30
  const CLASS_NAME_SHOW = 'show';
31
+ const CLASS_NAME_SHOWING = 'showing';
32
+ const CLASS_NAME_HIDING = 'hiding';
637
33
  const CLASS_NAME_BACKDROP = 'offcanvas-backdrop';
638
34
  const OPEN_SELECTOR = '.offcanvas.show';
639
35
  const EVENT_SHOW = `show${EVENT_KEY}`;
640
36
  const EVENT_SHOWN = `shown${EVENT_KEY}`;
641
37
  const EVENT_HIDE = `hide${EVENT_KEY}`;
38
+ const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`;
642
39
  const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
40
+ const EVENT_RESIZE = `resize${EVENT_KEY}`;
643
41
  const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
644
42
  const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`;
645
43
  const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]';
44
+ const Default = {
45
+ backdrop: true,
46
+ keyboard: true,
47
+ scroll: false
48
+ };
49
+ const DefaultType = {
50
+ backdrop: '(boolean|string)',
51
+ keyboard: 'boolean',
52
+ scroll: 'boolean'
53
+ };
54
+
646
55
  /**
647
- * ------------------------------------------------------------------------
648
- * Class Definition
649
- * ------------------------------------------------------------------------
56
+ * Class definition
650
57
  */
651
58
 
652
- class Offcanvas extends BaseComponent__default.default {
59
+ class Offcanvas extends BaseComponent {
653
60
  constructor(element, config) {
654
- super(element);
655
- this._config = this._getConfig(config);
61
+ super(element, config);
656
62
  this._isShown = false;
657
63
  this._backdrop = this._initializeBackDrop();
658
64
  this._focustrap = this._initializeFocusTrap();
659
-
660
65
  this._addEventListeners();
661
- } // Getters
662
-
663
-
664
- static get NAME() {
665
- return NAME;
666
66
  }
667
67
 
68
+ // Getters
668
69
  static get Default() {
669
70
  return Default;
670
- } // Public
671
-
71
+ }
72
+ static get DefaultType() {
73
+ return DefaultType;
74
+ }
75
+ static get NAME() {
76
+ return NAME;
77
+ }
672
78
 
79
+ // Public
673
80
  toggle(relatedTarget) {
674
81
  return this._isShown ? this.hide() : this.show(relatedTarget);
675
82
  }
676
-
677
83
  show(relatedTarget) {
678
84
  if (this._isShown) {
679
85
  return;
680
86
  }
681
-
682
- const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW, {
87
+ const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
683
88
  relatedTarget
684
89
  });
685
-
686
90
  if (showEvent.defaultPrevented) {
687
91
  return;
688
92
  }
689
-
690
93
  this._isShown = true;
691
- this._element.style.visibility = 'visible';
692
-
693
94
  this._backdrop.show();
694
-
695
95
  if (!this._config.scroll) {
696
96
  new ScrollBarHelper().hide();
697
97
  }
698
-
699
- this._element.removeAttribute('aria-hidden');
700
-
701
98
  this._element.setAttribute('aria-modal', true);
702
-
703
99
  this._element.setAttribute('role', 'dialog');
704
-
705
- this._element.classList.add(CLASS_NAME_SHOW);
706
-
100
+ this._element.classList.add(CLASS_NAME_SHOWING);
707
101
  const completeCallBack = () => {
708
- if (!this._config.scroll) {
102
+ if (!this._config.scroll || this._config.backdrop) {
709
103
  this._focustrap.activate();
710
104
  }
711
-
712
- EventHandler__default.default.trigger(this._element, EVENT_SHOWN, {
105
+ this._element.classList.add(CLASS_NAME_SHOW);
106
+ this._element.classList.remove(CLASS_NAME_SHOWING);
107
+ EventHandler.trigger(this._element, EVENT_SHOWN, {
713
108
  relatedTarget
714
109
  });
715
110
  };
716
-
717
111
  this._queueCallback(completeCallBack, this._element, true);
718
112
  }
719
-
720
113
  hide() {
721
114
  if (!this._isShown) {
722
115
  return;
723
116
  }
724
-
725
- const hideEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE);
726
-
117
+ const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);
727
118
  if (hideEvent.defaultPrevented) {
728
119
  return;
729
120
  }
730
-
731
121
  this._focustrap.deactivate();
732
-
733
122
  this._element.blur();
734
-
735
123
  this._isShown = false;
736
-
737
- this._element.classList.remove(CLASS_NAME_SHOW);
738
-
124
+ this._element.classList.add(CLASS_NAME_HIDING);
739
125
  this._backdrop.hide();
740
-
741
126
  const completeCallback = () => {
742
- this._element.setAttribute('aria-hidden', true);
743
-
127
+ this._element.classList.remove(CLASS_NAME_SHOW, CLASS_NAME_HIDING);
744
128
  this._element.removeAttribute('aria-modal');
745
-
746
129
  this._element.removeAttribute('role');
747
-
748
- this._element.style.visibility = 'hidden';
749
-
750
130
  if (!this._config.scroll) {
751
131
  new ScrollBarHelper().reset();
752
132
  }
753
-
754
- EventHandler__default.default.trigger(this._element, EVENT_HIDDEN);
133
+ EventHandler.trigger(this._element, EVENT_HIDDEN);
755
134
  };
756
-
757
135
  this._queueCallback(completeCallback, this._element, true);
758
136
  }
759
-
760
137
  dispose() {
761
138
  this._backdrop.dispose();
762
-
763
139
  this._focustrap.deactivate();
764
-
765
140
  super.dispose();
766
- } // Private
767
-
768
-
769
- _getConfig(config) {
770
- config = { ...Default,
771
- ...Manipulator__default.default.getDataAttributes(this._element),
772
- ...(typeof config === 'object' ? config : {})
773
- };
774
- typeCheckConfig(NAME, config, DefaultType);
775
- return config;
776
141
  }
777
142
 
143
+ // Private
778
144
  _initializeBackDrop() {
145
+ const clickCallback = () => {
146
+ if (this._config.backdrop === 'static') {
147
+ EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
148
+ return;
149
+ }
150
+ this.hide();
151
+ };
152
+
153
+ // 'static' option will be translated to true, and booleans will keep their value
154
+ const isVisible = Boolean(this._config.backdrop);
779
155
  return new Backdrop({
780
156
  className: CLASS_NAME_BACKDROP,
781
- isVisible: this._config.backdrop,
157
+ isVisible,
782
158
  isAnimated: true,
783
159
  rootElement: this._element.parentNode,
784
- clickCallback: () => this.hide()
160
+ clickCallback: isVisible ? clickCallback : null
785
161
  });
786
162
  }
787
-
788
163
  _initializeFocusTrap() {
789
164
  return new FocusTrap({
790
165
  trapElement: this._element
791
166
  });
792
167
  }
793
-
794
168
  _addEventListeners() {
795
- EventHandler__default.default.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
796
- if (this._config.keyboard && event.key === ESCAPE_KEY) {
169
+ EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
170
+ if (event.key !== ESCAPE_KEY) {
171
+ return;
172
+ }
173
+ if (this._config.keyboard) {
797
174
  this.hide();
175
+ return;
798
176
  }
177
+ EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
799
178
  });
800
- } // Static
801
-
179
+ }
802
180
 
181
+ // Static
803
182
  static jQueryInterface(config) {
804
183
  return this.each(function () {
805
184
  const data = Offcanvas.getOrCreateInstance(this, config);
806
-
807
185
  if (typeof config !== 'string') {
808
186
  return;
809
187
  }
810
-
811
188
  if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
812
189
  throw new TypeError(`No method named "${config}"`);
813
190
  }
814
-
815
191
  data[config](this);
816
192
  });
817
193
  }
818
-
819
194
  }
195
+
820
196
  /**
821
- * ------------------------------------------------------------------------
822
- * Data Api implementation
823
- * ------------------------------------------------------------------------
197
+ * Data API implementation
824
198
  */
825
199
 
826
-
827
- EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
828
- const target = getElementFromSelector(this);
829
-
200
+ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
201
+ const target = SelectorEngine.getElementFromSelector(this);
830
202
  if (['A', 'AREA'].includes(this.tagName)) {
831
203
  event.preventDefault();
832
204
  }
833
-
834
- if (isDisabled(this)) {
205
+ if (index_js.isDisabled(this)) {
835
206
  return;
836
207
  }
837
-
838
- EventHandler__default.default.one(target, EVENT_HIDDEN, () => {
208
+ EventHandler.one(target, EVENT_HIDDEN, () => {
839
209
  // focus on trigger when it is closed
840
- if (isVisible(this)) {
210
+ if (index_js.isVisible(this)) {
841
211
  this.focus();
842
212
  }
843
- }); // avoid conflict when clicking a toggler of an offcanvas, while another is open
844
-
845
- const allReadyOpen = SelectorEngine__default.default.findOne(OPEN_SELECTOR);
213
+ });
846
214
 
847
- if (allReadyOpen && allReadyOpen !== target) {
848
- Offcanvas.getInstance(allReadyOpen).hide();
215
+ // avoid conflict when clicking a toggler of an offcanvas, while another is open
216
+ const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
217
+ if (alreadyOpen && alreadyOpen !== target) {
218
+ Offcanvas.getInstance(alreadyOpen).hide();
849
219
  }
850
-
851
220
  const data = Offcanvas.getOrCreateInstance(target);
852
221
  data.toggle(this);
853
222
  });
854
- EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () => SelectorEngine__default.default.find(OPEN_SELECTOR).forEach(el => Offcanvas.getOrCreateInstance(el).show()));
855
- enableDismissTrigger(Offcanvas);
223
+ EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
224
+ for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {
225
+ Offcanvas.getOrCreateInstance(selector).show();
226
+ }
227
+ });
228
+ EventHandler.on(window, EVENT_RESIZE, () => {
229
+ for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {
230
+ if (getComputedStyle(element).position !== 'fixed') {
231
+ Offcanvas.getOrCreateInstance(element).hide();
232
+ }
233
+ }
234
+ });
235
+ componentFunctions_js.enableDismissTrigger(Offcanvas);
236
+
856
237
  /**
857
- * ------------------------------------------------------------------------
858
238
  * jQuery
859
- * ------------------------------------------------------------------------
860
239
  */
861
240
 
862
- defineJQueryPlugin(Offcanvas);
241
+ index_js.defineJQueryPlugin(Offcanvas);
863
242
 
864
243
  return Offcanvas;
865
244