]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Remove all of Modal
authorMark Otto <markdotto@gmail.com>
Thu, 11 Dec 2025 20:13:36 +0000 (12:13 -0800)
committerMark Otto <markdotto@gmail.com>
Fri, 12 Dec 2025 04:59:33 +0000 (20:59 -0800)
21 files changed:
js/dist/modal.js [deleted file]
js/dist/modal.js.map [deleted file]
js/src/modal.js [deleted file]
js/tests/unit/modal.spec.js [deleted file]
js/tests/visual/modal.html [deleted file]
scss/_modal.scss [deleted file]
scss/_variables.scss
scss/bootstrap.scss
site/data/sidebar.yml
site/src/assets/examples/cheatsheet-rtl/index.astro
site/src/assets/examples/cheatsheet/index.astro
site/src/assets/examples/modals/index.astro [deleted file]
site/src/assets/examples/modals/modals.css [deleted file]
site/src/assets/partials/snippets.js
site/src/components/home/Plugins.astro
site/src/content/docs/components/modal.mdx [deleted file]
site/src/content/docs/components/offcanvas.mdx
site/src/content/docs/components/popovers.mdx
site/src/content/docs/customize/optimize.mdx
site/src/content/docs/getting-started/javascript.mdx
site/src/content/docs/utilities/z-index.mdx

diff --git a/js/dist/modal.js b/js/dist/modal.js
deleted file mode 100644 (file)
index 21fe4e0..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-/*!
-  * Bootstrap modal.js v5.3.8 (https://getbootstrap.com/)
-  * Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
-  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
-  */
-(function (global, factory) {
-  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')) :
-  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) :
-  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Modal = factory(global.BaseComponent, global.EventHandler, global.SelectorEngine, global.Backdrop, global.ComponentFunctions, global.Focustrap, global.Index, global.Scrollbar));
-})(this, (function (BaseComponent, EventHandler, SelectorEngine, Backdrop, componentFunctions_js, FocusTrap, index_js, ScrollBarHelper) { 'use strict';
-
-  /**
-   * --------------------------------------------------------------------------
-   * Bootstrap modal.js
-   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
-   * --------------------------------------------------------------------------
-   */
-
-
-  /**
-   * Constants
-   */
-
-  const NAME = 'modal';
-  const DATA_KEY = 'bs.modal';
-  const EVENT_KEY = `.${DATA_KEY}`;
-  const DATA_API_KEY = '.data-api';
-  const ESCAPE_KEY = 'Escape';
-  const EVENT_HIDE = `hide${EVENT_KEY}`;
-  const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`;
-  const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
-  const EVENT_SHOW = `show${EVENT_KEY}`;
-  const EVENT_SHOWN = `shown${EVENT_KEY}`;
-  const EVENT_RESIZE = `resize${EVENT_KEY}`;
-  const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`;
-  const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`;
-  const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`;
-  const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
-  const CLASS_NAME_OPEN = 'modal-open';
-  const CLASS_NAME_FADE = 'fade';
-  const CLASS_NAME_SHOW = 'show';
-  const CLASS_NAME_STATIC = 'modal-static';
-  const OPEN_SELECTOR = '.modal.show';
-  const SELECTOR_DIALOG = '.modal-dialog';
-  const SELECTOR_MODAL_BODY = '.modal-body';
-  const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]';
-  const Default = {
-    backdrop: true,
-    focus: true,
-    keyboard: true
-  };
-  const DefaultType = {
-    backdrop: '(boolean|string)',
-    focus: 'boolean',
-    keyboard: 'boolean'
-  };
-
-  /**
-   * Class definition
-   */
-
-  class Modal extends BaseComponent {
-    constructor(element, config) {
-      super(element, config);
-      this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);
-      this._backdrop = this._initializeBackDrop();
-      this._focustrap = this._initializeFocusTrap();
-      this._isShown = false;
-      this._isTransitioning = false;
-      this._scrollBar = new ScrollBarHelper();
-      this._addEventListeners();
-    }
-
-    // Getters
-    static get Default() {
-      return Default;
-    }
-    static get DefaultType() {
-      return DefaultType;
-    }
-    static get NAME() {
-      return NAME;
-    }
-
-    // Public
-    toggle(relatedTarget) {
-      return this._isShown ? this.hide() : this.show(relatedTarget);
-    }
-    show(relatedTarget) {
-      if (this._isShown || this._isTransitioning) {
-        return;
-      }
-      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
-        relatedTarget
-      });
-      if (showEvent.defaultPrevented) {
-        return;
-      }
-      this._isShown = true;
-      this._isTransitioning = true;
-      this._scrollBar.hide();
-      document.body.classList.add(CLASS_NAME_OPEN);
-      this._adjustDialog();
-      this._backdrop.show(() => this._showElement(relatedTarget));
-    }
-    hide() {
-      if (!this._isShown || this._isTransitioning) {
-        return;
-      }
-      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);
-      if (hideEvent.defaultPrevented) {
-        return;
-      }
-      this._isShown = false;
-      this._isTransitioning = true;
-      this._focustrap.deactivate();
-      this._element.classList.remove(CLASS_NAME_SHOW);
-      this._queueCallback(() => this._hideModal(), this._element, this._isAnimated());
-    }
-    dispose() {
-      EventHandler.off(window, EVENT_KEY);
-      EventHandler.off(this._dialog, EVENT_KEY);
-      this._backdrop.dispose();
-      this._focustrap.deactivate();
-      super.dispose();
-    }
-    handleUpdate() {
-      this._adjustDialog();
-    }
-
-    // Private
-    _initializeBackDrop() {
-      return new Backdrop({
-        isVisible: Boolean(this._config.backdrop),
-        // 'static' option will be translated to true, and booleans will keep their value,
-        isAnimated: this._isAnimated()
-      });
-    }
-    _initializeFocusTrap() {
-      return new FocusTrap({
-        trapElement: this._element
-      });
-    }
-    _showElement(relatedTarget) {
-      // try to append dynamic modal
-      if (!document.body.contains(this._element)) {
-        document.body.append(this._element);
-      }
-      this._element.style.display = 'block';
-      this._element.removeAttribute('aria-hidden');
-      this._element.setAttribute('aria-modal', true);
-      this._element.setAttribute('role', 'dialog');
-      this._element.scrollTop = 0;
-      const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);
-      if (modalBody) {
-        modalBody.scrollTop = 0;
-      }
-      index_js.reflow(this._element);
-      this._element.classList.add(CLASS_NAME_SHOW);
-      const transitionComplete = () => {
-        if (this._config.focus) {
-          this._focustrap.activate();
-        }
-        this._isTransitioning = false;
-        EventHandler.trigger(this._element, EVENT_SHOWN, {
-          relatedTarget
-        });
-      };
-      this._queueCallback(transitionComplete, this._dialog, this._isAnimated());
-    }
-    _addEventListeners() {
-      EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
-        if (event.key !== ESCAPE_KEY) {
-          return;
-        }
-        if (this._config.keyboard) {
-          this.hide();
-          return;
-        }
-        this._triggerBackdropTransition();
-      });
-      EventHandler.on(window, EVENT_RESIZE, () => {
-        if (this._isShown && !this._isTransitioning) {
-          this._adjustDialog();
-        }
-      });
-      EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {
-        // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks
-        EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {
-          if (this._element !== event.target || this._element !== event2.target) {
-            return;
-          }
-          if (this._config.backdrop === 'static') {
-            this._triggerBackdropTransition();
-            return;
-          }
-          if (this._config.backdrop) {
-            this.hide();
-          }
-        });
-      });
-    }
-    _hideModal() {
-      this._element.style.display = 'none';
-      this._element.setAttribute('aria-hidden', true);
-      this._element.removeAttribute('aria-modal');
-      this._element.removeAttribute('role');
-      this._isTransitioning = false;
-      this._backdrop.hide(() => {
-        document.body.classList.remove(CLASS_NAME_OPEN);
-        this._resetAdjustments();
-        this._scrollBar.reset();
-        EventHandler.trigger(this._element, EVENT_HIDDEN);
-      });
-    }
-    _isAnimated() {
-      return this._element.classList.contains(CLASS_NAME_FADE);
-    }
-    _triggerBackdropTransition() {
-      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
-      if (hideEvent.defaultPrevented) {
-        return;
-      }
-      const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
-      const initialOverflowY = this._element.style.overflowY;
-      // return if the following background transition hasn't yet completed
-      if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {
-        return;
-      }
-      if (!isModalOverflowing) {
-        this._element.style.overflowY = 'hidden';
-      }
-      this._element.classList.add(CLASS_NAME_STATIC);
-      this._queueCallback(() => {
-        this._element.classList.remove(CLASS_NAME_STATIC);
-        this._queueCallback(() => {
-          this._element.style.overflowY = initialOverflowY;
-        }, this._dialog);
-      }, this._dialog);
-      this._element.focus();
-    }
-
-    /**
-     * The following methods are used to handle overflowing modals
-     */
-
-    _adjustDialog() {
-      const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
-      const scrollbarWidth = this._scrollBar.getWidth();
-      const isBodyOverflowing = scrollbarWidth > 0;
-      if (isBodyOverflowing && !isModalOverflowing) {
-        const property = index_js.isRTL() ? 'paddingLeft' : 'paddingRight';
-        this._element.style[property] = `${scrollbarWidth}px`;
-      }
-      if (!isBodyOverflowing && isModalOverflowing) {
-        const property = index_js.isRTL() ? 'paddingRight' : 'paddingLeft';
-        this._element.style[property] = `${scrollbarWidth}px`;
-      }
-    }
-    _resetAdjustments() {
-      this._element.style.paddingLeft = '';
-      this._element.style.paddingRight = '';
-    }
-  }
-
-  /**
-   * Data API implementation
-   */
-
-  EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
-    const target = SelectorEngine.getElementFromSelector(this);
-    if (['A', 'AREA'].includes(this.tagName)) {
-      event.preventDefault();
-    }
-    EventHandler.one(target, EVENT_SHOW, showEvent => {
-      if (showEvent.defaultPrevented) {
-        // only register focus restorer if modal will actually get shown
-        return;
-      }
-      EventHandler.one(target, EVENT_HIDDEN, () => {
-        if (index_js.isVisible(this)) {
-          this.focus();
-        }
-      });
-    });
-
-    // avoid conflict when clicking modal toggler while another one is open
-    const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
-    if (alreadyOpen) {
-      Modal.getInstance(alreadyOpen).hide();
-    }
-    const data = Modal.getOrCreateInstance(target);
-    data.toggle(this);
-  });
-  componentFunctions_js.enableDismissTrigger(Modal);
-
-  return Modal;
-
-}));
-//# sourceMappingURL=modal.js.map
diff --git a/js/dist/modal.js.map b/js/dist/modal.js.map
deleted file mode 100644 (file)
index 227a507..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"modal.js","sources":["../src/modal.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport Backdrop from './util/backdrop.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\nimport FocusTrap from './util/focustrap.js'\nimport {\n  isRTL, isVisible, reflow\n} from './util/index.js'\nimport ScrollBarHelper from './util/scrollbar.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'modal'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst ESCAPE_KEY = 'Escape'\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst OPEN_SELECTOR = '.modal.show'\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"modal\"]'\n\nconst Default = {\n  backdrop: true,\n  focus: true,\n  keyboard: true\n}\n\nconst DefaultType = {\n  backdrop: '(boolean|string)',\n  focus: 'boolean',\n  keyboard: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Modal extends BaseComponent {\n  constructor(element, config) {\n    super(element, config)\n\n    this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element)\n    this._backdrop = this._initializeBackDrop()\n    this._focustrap = this._initializeFocusTrap()\n    this._isShown = false\n    this._isTransitioning = false\n    this._scrollBar = new ScrollBarHelper()\n\n    this._addEventListeners()\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  toggle(relatedTarget) {\n    return this._isShown ? this.hide() : this.show(relatedTarget)\n  }\n\n  show(relatedTarget) {\n    if (this._isShown || this._isTransitioning) {\n      return\n    }\n\n    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {\n      relatedTarget\n    })\n\n    if (showEvent.defaultPrevented) {\n      return\n    }\n\n    this._isShown = true\n    this._isTransitioning = true\n\n    this._scrollBar.hide()\n\n    document.body.classList.add(CLASS_NAME_OPEN)\n\n    this._adjustDialog()\n\n    this._backdrop.show(() => this._showElement(relatedTarget))\n  }\n\n  hide() {\n    if (!this._isShown || this._isTransitioning) {\n      return\n    }\n\n    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n\n    if (hideEvent.defaultPrevented) {\n      return\n    }\n\n    this._isShown = false\n    this._isTransitioning = true\n    this._focustrap.deactivate()\n\n    this._element.classList.remove(CLASS_NAME_SHOW)\n\n    this._queueCallback(() => this._hideModal(), this._element, this._isAnimated())\n  }\n\n  dispose() {\n    EventHandler.off(window, EVENT_KEY)\n    EventHandler.off(this._dialog, EVENT_KEY)\n\n    this._backdrop.dispose()\n    this._focustrap.deactivate()\n\n    super.dispose()\n  }\n\n  handleUpdate() {\n    this._adjustDialog()\n  }\n\n  // Private\n  _initializeBackDrop() {\n    return new Backdrop({\n      isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value,\n      isAnimated: this._isAnimated()\n    })\n  }\n\n  _initializeFocusTrap() {\n    return new FocusTrap({\n      trapElement: this._element\n    })\n  }\n\n  _showElement(relatedTarget) {\n    // try to append dynamic modal\n    if (!document.body.contains(this._element)) {\n      document.body.append(this._element)\n    }\n\n    this._element.style.display = 'block'\n    this._element.removeAttribute('aria-hidden')\n    this._element.setAttribute('aria-modal', true)\n    this._element.setAttribute('role', 'dialog')\n    this._element.scrollTop = 0\n\n    const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog)\n    if (modalBody) {\n      modalBody.scrollTop = 0\n    }\n\n    reflow(this._element)\n\n    this._element.classList.add(CLASS_NAME_SHOW)\n\n    const transitionComplete = () => {\n      if (this._config.focus) {\n        this._focustrap.activate()\n      }\n\n      this._isTransitioning = false\n      EventHandler.trigger(this._element, EVENT_SHOWN, {\n        relatedTarget\n      })\n    }\n\n    this._queueCallback(transitionComplete, this._dialog, this._isAnimated())\n  }\n\n  _addEventListeners() {\n    EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n      if (event.key !== ESCAPE_KEY) {\n        return\n      }\n\n      if (this._config.keyboard) {\n        this.hide()\n        return\n      }\n\n      this._triggerBackdropTransition()\n    })\n\n    EventHandler.on(window, EVENT_RESIZE, () => {\n      if (this._isShown && !this._isTransitioning) {\n        this._adjustDialog()\n      }\n    })\n\n    EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {\n      // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks\n      EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {\n        if (this._element !== event.target || this._element !== event2.target) {\n          return\n        }\n\n        if (this._config.backdrop === 'static') {\n          this._triggerBackdropTransition()\n          return\n        }\n\n        if (this._config.backdrop) {\n          this.hide()\n        }\n      })\n    })\n  }\n\n  _hideModal() {\n    this._element.style.display = 'none'\n    this._element.setAttribute('aria-hidden', true)\n    this._element.removeAttribute('aria-modal')\n    this._element.removeAttribute('role')\n    this._isTransitioning = false\n\n    this._backdrop.hide(() => {\n      document.body.classList.remove(CLASS_NAME_OPEN)\n      this._resetAdjustments()\n      this._scrollBar.reset()\n      EventHandler.trigger(this._element, EVENT_HIDDEN)\n    })\n  }\n\n  _isAnimated() {\n    return this._element.classList.contains(CLASS_NAME_FADE)\n  }\n\n  _triggerBackdropTransition() {\n    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n    if (hideEvent.defaultPrevented) {\n      return\n    }\n\n    const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n    const initialOverflowY = this._element.style.overflowY\n    // return if the following background transition hasn't yet completed\n    if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {\n      return\n    }\n\n    if (!isModalOverflowing) {\n      this._element.style.overflowY = 'hidden'\n    }\n\n    this._element.classList.add(CLASS_NAME_STATIC)\n    this._queueCallback(() => {\n      this._element.classList.remove(CLASS_NAME_STATIC)\n      this._queueCallback(() => {\n        this._element.style.overflowY = initialOverflowY\n      }, this._dialog)\n    }, this._dialog)\n\n    this._element.focus()\n  }\n\n  /**\n   * The following methods are used to handle overflowing modals\n   */\n\n  _adjustDialog() {\n    const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n    const scrollbarWidth = this._scrollBar.getWidth()\n    const isBodyOverflowing = scrollbarWidth > 0\n\n    if (isBodyOverflowing && !isModalOverflowing) {\n      const property = isRTL() ? 'paddingLeft' : 'paddingRight'\n      this._element.style[property] = `${scrollbarWidth}px`\n    }\n\n    if (!isBodyOverflowing && isModalOverflowing) {\n      const property = isRTL() ? 'paddingRight' : 'paddingLeft'\n      this._element.style[property] = `${scrollbarWidth}px`\n    }\n  }\n\n  _resetAdjustments() {\n    this._element.style.paddingLeft = ''\n    this._element.style.paddingRight = ''\n  }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n  const target = SelectorEngine.getElementFromSelector(this)\n\n  if (['A', 'AREA'].includes(this.tagName)) {\n    event.preventDefault()\n  }\n\n  EventHandler.one(target, EVENT_SHOW, showEvent => {\n    if (showEvent.defaultPrevented) {\n      // only register focus restorer if modal will actually get shown\n      return\n    }\n\n    EventHandler.one(target, EVENT_HIDDEN, () => {\n      if (isVisible(this)) {\n        this.focus()\n      }\n    })\n  })\n\n  // avoid conflict when clicking modal toggler while another one is open\n  const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)\n  if (alreadyOpen) {\n    Modal.getInstance(alreadyOpen).hide()\n  }\n\n  const data = Modal.getOrCreateInstance(target)\n\n  data.toggle(this)\n})\n\nenableDismissTrigger(Modal)\n\nexport default Modal\n"],"names":["NAME","DATA_KEY","EVENT_KEY","DATA_API_KEY","ESCAPE_KEY","EVENT_HIDE","EVENT_HIDE_PREVENTED","EVENT_HIDDEN","EVENT_SHOW","EVENT_SHOWN","EVENT_RESIZE","EVENT_CLICK_DISMISS","EVENT_MOUSEDOWN_DISMISS","EVENT_KEYDOWN_DISMISS","EVENT_CLICK_DATA_API","CLASS_NAME_OPEN","CLASS_NAME_FADE","CLASS_NAME_SHOW","CLASS_NAME_STATIC","OPEN_SELECTOR","SELECTOR_DIALOG","SELECTOR_MODAL_BODY","SELECTOR_DATA_TOGGLE","Default","backdrop","focus","keyboard","DefaultType","Modal","BaseComponent","constructor","element","config","_dialog","SelectorEngine","findOne","_element","_backdrop","_initializeBackDrop","_focustrap","_initializeFocusTrap","_isShown","_isTransitioning","_scrollBar","ScrollBarHelper","_addEventListeners","toggle","relatedTarget","hide","show","showEvent","EventHandler","trigger","defaultPrevented","document","body","classList","add","_adjustDialog","_showElement","hideEvent","deactivate","remove","_queueCallback","_hideModal","_isAnimated","dispose","off","window","handleUpdate","Backdrop","isVisible","Boolean","_config","isAnimated","FocusTrap","trapElement","contains","append","style","display","removeAttribute","setAttribute","scrollTop","modalBody","reflow","transitionComplete","activate","on","event","key","_triggerBackdropTransition","one","event2","target","_resetAdjustments","reset","isModalOverflowing","scrollHeight","documentElement","clientHeight","initialOverflowY","overflowY","scrollbarWidth","getWidth","isBodyOverflowing","property","isRTL","paddingLeft","paddingRight","getElementFromSelector","includes","tagName","preventDefault","alreadyOpen","getInstance","data","getOrCreateInstance","enableDismissTrigger"],"mappings":"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"}
\ No newline at end of file
diff --git a/js/src/modal.js b/js/src/modal.js
deleted file mode 100644 (file)
index 538d218..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/**
- * --------------------------------------------------------------------------
- * Bootstrap modal.js
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
- * --------------------------------------------------------------------------
- */
-
-import BaseComponent from './base-component.js'
-import EventHandler from './dom/event-handler.js'
-import SelectorEngine from './dom/selector-engine.js'
-import Backdrop from './util/backdrop.js'
-import { enableDismissTrigger } from './util/component-functions.js'
-import FocusTrap from './util/focustrap.js'
-import {
-  isRTL, isVisible, reflow
-} from './util/index.js'
-import ScrollBarHelper from './util/scrollbar.js'
-
-/**
- * Constants
- */
-
-const NAME = 'modal'
-const DATA_KEY = 'bs.modal'
-const EVENT_KEY = `.${DATA_KEY}`
-const DATA_API_KEY = '.data-api'
-const ESCAPE_KEY = 'Escape'
-
-const EVENT_HIDE = `hide${EVENT_KEY}`
-const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`
-const EVENT_HIDDEN = `hidden${EVENT_KEY}`
-const EVENT_SHOW = `show${EVENT_KEY}`
-const EVENT_SHOWN = `shown${EVENT_KEY}`
-const EVENT_RESIZE = `resize${EVENT_KEY}`
-const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`
-const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`
-const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`
-const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
-
-const CLASS_NAME_OPEN = 'modal-open'
-const CLASS_NAME_FADE = 'fade'
-const CLASS_NAME_SHOW = 'show'
-const CLASS_NAME_STATIC = 'modal-static'
-
-const OPEN_SELECTOR = '.modal.show'
-const SELECTOR_DIALOG = '.modal-dialog'
-const SELECTOR_MODAL_BODY = '.modal-body'
-const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]'
-
-const Default = {
-  backdrop: true,
-  focus: true,
-  keyboard: true
-}
-
-const DefaultType = {
-  backdrop: '(boolean|string)',
-  focus: 'boolean',
-  keyboard: 'boolean'
-}
-
-/**
- * Class definition
- */
-
-class Modal extends BaseComponent {
-  constructor(element, config) {
-    super(element, config)
-
-    this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element)
-    this._backdrop = this._initializeBackDrop()
-    this._focustrap = this._initializeFocusTrap()
-    this._isShown = false
-    this._isTransitioning = false
-    this._scrollBar = new ScrollBarHelper()
-
-    this._addEventListeners()
-  }
-
-  // Getters
-  static get Default() {
-    return Default
-  }
-
-  static get DefaultType() {
-    return DefaultType
-  }
-
-  static get NAME() {
-    return NAME
-  }
-
-  // Public
-  toggle(relatedTarget) {
-    return this._isShown ? this.hide() : this.show(relatedTarget)
-  }
-
-  show(relatedTarget) {
-    if (this._isShown || this._isTransitioning) {
-      return
-    }
-
-    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
-      relatedTarget
-    })
-
-    if (showEvent.defaultPrevented) {
-      return
-    }
-
-    this._isShown = true
-    this._isTransitioning = true
-
-    this._scrollBar.hide()
-
-    document.body.classList.add(CLASS_NAME_OPEN)
-
-    this._adjustDialog()
-
-    this._backdrop.show(() => this._showElement(relatedTarget))
-  }
-
-  hide() {
-    if (!this._isShown || this._isTransitioning) {
-      return
-    }
-
-    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)
-
-    if (hideEvent.defaultPrevented) {
-      return
-    }
-
-    this._isShown = false
-    this._isTransitioning = true
-    this._focustrap.deactivate()
-
-    this._element.classList.remove(CLASS_NAME_SHOW)
-
-    this._queueCallback(() => this._hideModal(), this._element, this._isAnimated())
-  }
-
-  dispose() {
-    EventHandler.off(window, EVENT_KEY)
-    EventHandler.off(this._dialog, EVENT_KEY)
-
-    this._backdrop.dispose()
-    this._focustrap.deactivate()
-
-    super.dispose()
-  }
-
-  handleUpdate() {
-    this._adjustDialog()
-  }
-
-  // Private
-  _initializeBackDrop() {
-    return new Backdrop({
-      isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value,
-      isAnimated: this._isAnimated()
-    })
-  }
-
-  _initializeFocusTrap() {
-    return new FocusTrap({
-      trapElement: this._element
-    })
-  }
-
-  _showElement(relatedTarget) {
-    // try to append dynamic modal
-    if (!document.body.contains(this._element)) {
-      document.body.append(this._element)
-    }
-
-    this._element.style.display = 'block'
-    this._element.removeAttribute('aria-hidden')
-    this._element.setAttribute('aria-modal', true)
-    this._element.setAttribute('role', 'dialog')
-    this._element.scrollTop = 0
-
-    const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog)
-    if (modalBody) {
-      modalBody.scrollTop = 0
-    }
-
-    reflow(this._element)
-
-    this._element.classList.add(CLASS_NAME_SHOW)
-
-    const transitionComplete = () => {
-      if (this._config.focus) {
-        this._focustrap.activate()
-      }
-
-      this._isTransitioning = false
-      EventHandler.trigger(this._element, EVENT_SHOWN, {
-        relatedTarget
-      })
-    }
-
-    this._queueCallback(transitionComplete, this._dialog, this._isAnimated())
-  }
-
-  _addEventListeners() {
-    EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
-      if (event.key !== ESCAPE_KEY) {
-        return
-      }
-
-      if (this._config.keyboard) {
-        this.hide()
-        return
-      }
-
-      this._triggerBackdropTransition()
-    })
-
-    EventHandler.on(window, EVENT_RESIZE, () => {
-      if (this._isShown && !this._isTransitioning) {
-        this._adjustDialog()
-      }
-    })
-
-    EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {
-      // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks
-      EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {
-        if (this._element !== event.target || this._element !== event2.target) {
-          return
-        }
-
-        if (this._config.backdrop === 'static') {
-          this._triggerBackdropTransition()
-          return
-        }
-
-        if (this._config.backdrop) {
-          this.hide()
-        }
-      })
-    })
-  }
-
-  _hideModal() {
-    this._element.style.display = 'none'
-    this._element.setAttribute('aria-hidden', true)
-    this._element.removeAttribute('aria-modal')
-    this._element.removeAttribute('role')
-    this._isTransitioning = false
-
-    this._backdrop.hide(() => {
-      document.body.classList.remove(CLASS_NAME_OPEN)
-      this._resetAdjustments()
-      this._scrollBar.reset()
-      EventHandler.trigger(this._element, EVENT_HIDDEN)
-    })
-  }
-
-  _isAnimated() {
-    return this._element.classList.contains(CLASS_NAME_FADE)
-  }
-
-  _triggerBackdropTransition() {
-    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)
-    if (hideEvent.defaultPrevented) {
-      return
-    }
-
-    const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight
-    const initialOverflowY = this._element.style.overflowY
-    // return if the following background transition hasn't yet completed
-    if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {
-      return
-    }
-
-    if (!isModalOverflowing) {
-      this._element.style.overflowY = 'hidden'
-    }
-
-    this._element.classList.add(CLASS_NAME_STATIC)
-    this._queueCallback(() => {
-      this._element.classList.remove(CLASS_NAME_STATIC)
-      this._queueCallback(() => {
-        this._element.style.overflowY = initialOverflowY
-      }, this._dialog)
-    }, this._dialog)
-
-    this._element.focus()
-  }
-
-  /**
-   * The following methods are used to handle overflowing modals
-   */
-
-  _adjustDialog() {
-    const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight
-    const scrollbarWidth = this._scrollBar.getWidth()
-    const isBodyOverflowing = scrollbarWidth > 0
-
-    if (isBodyOverflowing && !isModalOverflowing) {
-      const property = isRTL() ? 'paddingLeft' : 'paddingRight'
-      this._element.style[property] = `${scrollbarWidth}px`
-    }
-
-    if (!isBodyOverflowing && isModalOverflowing) {
-      const property = isRTL() ? 'paddingRight' : 'paddingLeft'
-      this._element.style[property] = `${scrollbarWidth}px`
-    }
-  }
-
-  _resetAdjustments() {
-    this._element.style.paddingLeft = ''
-    this._element.style.paddingRight = ''
-  }
-}
-
-/**
- * Data API implementation
- */
-
-EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
-  const target = SelectorEngine.getElementFromSelector(this)
-
-  if (['A', 'AREA'].includes(this.tagName)) {
-    event.preventDefault()
-  }
-
-  EventHandler.one(target, EVENT_SHOW, showEvent => {
-    if (showEvent.defaultPrevented) {
-      // only register focus restorer if modal will actually get shown
-      return
-    }
-
-    EventHandler.one(target, EVENT_HIDDEN, () => {
-      if (isVisible(this)) {
-        this.focus()
-      }
-    })
-  })
-
-  // avoid conflict when clicking modal toggler while another one is open
-  const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)
-  if (alreadyOpen) {
-    Modal.getInstance(alreadyOpen).hide()
-  }
-
-  const data = Modal.getOrCreateInstance(target)
-
-  data.toggle(this)
-})
-
-enableDismissTrigger(Modal)
-
-export default Modal
diff --git a/js/tests/unit/modal.spec.js b/js/tests/unit/modal.spec.js
deleted file mode 100644 (file)
index 1480521..0000000
+++ /dev/null
@@ -1,1239 +0,0 @@
-import EventHandler from '../../src/dom/event-handler.js'
-import Modal from '../../src/modal.js'
-import ScrollBarHelper from '../../src/util/scrollbar.js'
-import {
-  clearBodyAndDocument, clearFixture, createEvent, getFixture
-} from '../helpers/fixture.js'
-
-describe('Modal', () => {
-  let fixtureEl
-
-  beforeAll(() => {
-    fixtureEl = getFixture()
-  })
-
-  afterEach(() => {
-    clearFixture()
-    clearBodyAndDocument()
-    document.body.classList.remove('modal-open')
-
-    for (const backdrop of document.querySelectorAll('.modal-backdrop')) {
-      backdrop.remove()
-    }
-  })
-
-  beforeEach(() => {
-    clearBodyAndDocument()
-  })
-
-  describe('VERSION', () => {
-    it('should return plugin version', () => {
-      expect(Modal.VERSION).toEqual(jasmine.any(String))
-    })
-  })
-
-  describe('Default', () => {
-    it('should return plugin default config', () => {
-      expect(Modal.Default).toEqual(jasmine.any(Object))
-    })
-  })
-
-  describe('DATA_KEY', () => {
-    it('should return plugin data key', () => {
-      expect(Modal.DATA_KEY).toEqual('bs.modal')
-    })
-  })
-
-  describe('constructor', () => {
-    it('should take care of element either passed as a CSS selector or DOM element', () => {
-      fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-      const modalEl = fixtureEl.querySelector('.modal')
-      const modalBySelector = new Modal('.modal')
-      const modalByElement = new Modal(modalEl)
-
-      expect(modalBySelector._element).toEqual(modalEl)
-      expect(modalByElement._element).toEqual(modalEl)
-    })
-  })
-
-  describe('toggle', () => {
-    it('should call ScrollBarHelper to handle scrollBar on body', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const spyHide = spyOn(ScrollBarHelper.prototype, 'hide').and.callThrough()
-        const spyReset = spyOn(ScrollBarHelper.prototype, 'reset').and.callThrough()
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          expect(spyHide).toHaveBeenCalled()
-          modal.toggle()
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          expect(spyReset).toHaveBeenCalled()
-          resolve()
-        })
-
-        modal.toggle()
-      })
-    })
-  })
-
-  describe('show', () => {
-    it('should show a modal', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-
-        modalEl.addEventListener('show.bs.modal', event => {
-          expect(event).toBeDefined()
-        })
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          expect(modalEl.getAttribute('aria-modal')).toEqual('true')
-          expect(modalEl.getAttribute('role')).toEqual('dialog')
-          expect(modalEl.getAttribute('aria-hidden')).toBeNull()
-          expect(modalEl.style.display).toEqual('block')
-          expect(document.querySelector('.modal-backdrop')).not.toBeNull()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should show a modal without backdrop', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl, {
-          backdrop: false
-        })
-
-        modalEl.addEventListener('show.bs.modal', event => {
-          expect(event).toBeDefined()
-        })
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          expect(modalEl.getAttribute('aria-modal')).toEqual('true')
-          expect(modalEl.getAttribute('role')).toEqual('dialog')
-          expect(modalEl.getAttribute('aria-hidden')).toBeNull()
-          expect(modalEl.style.display).toEqual('block')
-          expect(document.querySelector('.modal-backdrop')).toBeNull()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should show a modal and append the element', () => {
-      return new Promise(resolve => {
-        const modalEl = document.createElement('div')
-        const id = 'dynamicModal'
-
-        modalEl.setAttribute('id', id)
-        modalEl.classList.add('modal')
-        modalEl.innerHTML = '<div class="modal-dialog"></div>'
-
-        const modal = new Modal(modalEl)
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          const dynamicModal = document.getElementById(id)
-          expect(dynamicModal).not.toBeNull()
-          dynamicModal.remove()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should do nothing if a modal is shown', () => {
-      fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-      const modalEl = fixtureEl.querySelector('.modal')
-      const modal = new Modal(modalEl)
-
-      const spy = spyOn(EventHandler, 'trigger')
-      modal._isShown = true
-
-      modal.show()
-
-      expect(spy).not.toHaveBeenCalled()
-    })
-
-    it('should do nothing if a modal is transitioning', () => {
-      fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-      const modalEl = fixtureEl.querySelector('.modal')
-      const modal = new Modal(modalEl)
-
-      const spy = spyOn(EventHandler, 'trigger')
-      modal._isTransitioning = true
-
-      modal.show()
-
-      expect(spy).not.toHaveBeenCalled()
-    })
-
-    it('should not fire shown event when show is prevented', () => {
-      return new Promise((resolve, reject) => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-
-        modalEl.addEventListener('show.bs.modal', event => {
-          event.preventDefault()
-
-          const expectedDone = () => {
-            expect().nothing()
-            resolve()
-          }
-
-          setTimeout(expectedDone, 10)
-        })
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          reject(new Error('shown event triggered'))
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should be shown after the first call to show() has been prevented while fading is enabled ', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal fade"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-
-        let prevented = false
-        modalEl.addEventListener('show.bs.modal', event => {
-          if (!prevented) {
-            event.preventDefault()
-            prevented = true
-
-            setTimeout(() => {
-              modal.show()
-            })
-          }
-        })
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          expect(prevented).toBeTrue()
-          expect(modal._isAnimated()).toBeTrue()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-    it('should set is transitioning if fade class is present', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal fade"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-
-        modalEl.addEventListener('show.bs.modal', () => {
-          setTimeout(() => {
-            expect(modal._isTransitioning).toBeTrue()
-          })
-        })
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          expect(modal._isTransitioning).toBeFalse()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should close modal when a click occurred on data-bs-dismiss="modal" inside modal', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<div class="modal fade">',
-          '  <div class="modal-dialog">',
-          '    <div class="modal-header">',
-          '      <button type="button" data-bs-dismiss="modal"></button>',
-          '    </div>',
-          '  </div>',
-          '</div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const btnClose = fixtureEl.querySelector('[data-bs-dismiss="modal"]')
-        const modal = new Modal(modalEl)
-
-        const spy = spyOn(modal, 'hide').and.callThrough()
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          btnClose.click()
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          expect(spy).toHaveBeenCalled()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should close modal when a click occurred on a data-bs-dismiss="modal" with "bs-target" outside of modal element', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<button type="button" data-bs-dismiss="modal" data-bs-target="#modal1"></button>',
-          '<div id="modal1" class="modal fade">',
-          '  <div class="modal-dialog"></div>',
-          '</div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const btnClose = fixtureEl.querySelector('[data-bs-dismiss="modal"]')
-        const modal = new Modal(modalEl)
-
-        const spy = spyOn(modal, 'hide').and.callThrough()
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          btnClose.click()
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          expect(spy).toHaveBeenCalled()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should set .modal\'s scroll top to 0', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<div class="modal fade">',
-          '  <div class="modal-dialog"></div>',
-          '</div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          expect(modalEl.scrollTop).toEqual(0)
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should set modal body scroll top to 0 if modal body do not exists', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<div class="modal fade">',
-          '  <div class="modal-dialog">',
-          '    <div class="modal-body"></div>',
-          '  </div>',
-          '</div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modalBody = modalEl.querySelector('.modal-body')
-        const modal = new Modal(modalEl)
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          expect(modalBody.scrollTop).toEqual(0)
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should not trap focus if focus equal to false', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal fade"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl, {
-          focus: false
-        })
-
-        const spy = spyOn(modal._focustrap, 'activate').and.callThrough()
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          expect(spy).not.toHaveBeenCalled()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should add listener when escape touch is pressed', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-
-        const spy = spyOn(modal, 'hide').and.callThrough()
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          const keydownEscape = createEvent('keydown')
-          keydownEscape.key = 'Escape'
-
-          modalEl.dispatchEvent(keydownEscape)
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          expect(spy).toHaveBeenCalled()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should do nothing when the pressed key is not escape', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-
-        const spy = spyOn(modal, 'hide')
-
-        const expectDone = () => {
-          expect(spy).not.toHaveBeenCalled()
-
-          resolve()
-        }
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          const keydownTab = createEvent('keydown')
-          keydownTab.key = 'Tab'
-
-          modalEl.dispatchEvent(keydownTab)
-          setTimeout(expectDone, 30)
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should adjust dialog on resize', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-
-        const spy = spyOn(modal, '_adjustDialog').and.callThrough()
-
-        const expectDone = () => {
-          expect(spy).toHaveBeenCalled()
-
-          resolve()
-        }
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          const resizeEvent = createEvent('resize')
-
-          window.dispatchEvent(resizeEvent)
-          setTimeout(expectDone, 10)
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should not close modal when clicking on modal-content', () => {
-      return new Promise((resolve, reject) => {
-        fixtureEl.innerHTML = [
-          '<div class="modal">',
-          '  <div class="modal-dialog">',
-          '    <div class="modal-content"></div>',
-          '  </div>',
-          '</div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-
-        const shownCallback = () => {
-          setTimeout(() => {
-            expect(modal._isShown).toEqual(true)
-            resolve()
-          }, 10)
-        }
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          fixtureEl.querySelector('.modal-dialog').click()
-          fixtureEl.querySelector('.modal-content').click()
-          shownCallback()
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          reject(new Error('Should not hide a modal'))
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should not close modal when clicking outside of modal-content if backdrop = false', () => {
-      return new Promise((resolve, reject) => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl, {
-          backdrop: false
-        })
-
-        const shownCallback = () => {
-          setTimeout(() => {
-            expect(modal._isShown).toBeTrue()
-            resolve()
-          }, 10)
-        }
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          modalEl.click()
-          shownCallback()
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          reject(new Error('Should not hide a modal'))
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should not close modal when clicking outside of modal-content if backdrop = static', () => {
-      return new Promise((resolve, reject) => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl, {
-          backdrop: 'static'
-        })
-
-        const shownCallback = () => {
-          setTimeout(() => {
-            expect(modal._isShown).toBeTrue()
-            resolve()
-          }, 10)
-        }
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          modalEl.click()
-          shownCallback()
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          reject(new Error('Should not hide a modal'))
-        })
-
-        modal.show()
-      })
-    })
-    it('should close modal when escape key is pressed with keyboard = true and backdrop is static', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl, {
-          backdrop: 'static',
-          keyboard: true
-        })
-
-        const shownCallback = () => {
-          setTimeout(() => {
-            expect(modal._isShown).toBeFalse()
-            resolve()
-          }, 10)
-        }
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          const keydownEscape = createEvent('keydown')
-          keydownEscape.key = 'Escape'
-
-          modalEl.dispatchEvent(keydownEscape)
-          shownCallback()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should not close modal when escape key is pressed with keyboard = false', () => {
-      return new Promise((resolve, reject) => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl, {
-          keyboard: false
-        })
-
-        const shownCallback = () => {
-          setTimeout(() => {
-            expect(modal._isShown).toBeTrue()
-            resolve()
-          }, 10)
-        }
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          const keydownEscape = createEvent('keydown')
-          keydownEscape.key = 'Escape'
-
-          modalEl.dispatchEvent(keydownEscape)
-          shownCallback()
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          reject(new Error('Should not hide a modal'))
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should not overflow when clicking outside of modal-content if backdrop = static', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog" style="transition-duration: 20ms;"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl, {
-          backdrop: 'static'
-        })
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          modalEl.click()
-          setTimeout(() => {
-            expect(modalEl.clientHeight).toEqual(modalEl.scrollHeight)
-            resolve()
-          }, 20)
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should not queue multiple callbacks when clicking outside of modal-content and backdrop = static', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog" style="transition-duration: 50ms;"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl, {
-          backdrop: 'static'
-        })
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          const spy = spyOn(modal, '_queueCallback').and.callThrough()
-          const mouseDown = createEvent('mousedown')
-
-          modalEl.dispatchEvent(mouseDown)
-          modalEl.click()
-          modalEl.dispatchEvent(mouseDown)
-          modalEl.click()
-
-          setTimeout(() => {
-            expect(spy).toHaveBeenCalledTimes(1)
-            resolve()
-          }, 20)
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should trap focus', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-
-        const spy = spyOn(modal._focustrap, 'activate').and.callThrough()
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          expect(spy).toHaveBeenCalled()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-  })
-
-  describe('hide', () => {
-    it('should hide a modal', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-        const backdropSpy = spyOn(modal._backdrop, 'hide').and.callThrough()
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          modal.hide()
-        })
-
-        modalEl.addEventListener('hide.bs.modal', event => {
-          expect(event).toBeDefined()
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          expect(modalEl.getAttribute('aria-modal')).toBeNull()
-          expect(modalEl.getAttribute('role')).toBeNull()
-          expect(modalEl.getAttribute('aria-hidden')).toEqual('true')
-          expect(modalEl.style.display).toEqual('none')
-          expect(backdropSpy).toHaveBeenCalled()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should close modal when clicking outside of modal-content', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const dialogEl = modalEl.querySelector('.modal-dialog')
-        const modal = new Modal(modalEl)
-
-        const spy = spyOn(modal, 'hide')
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          const mouseDown = createEvent('mousedown')
-
-          dialogEl.dispatchEvent(mouseDown)
-          modalEl.click()
-          expect(spy).not.toHaveBeenCalled()
-
-          modalEl.dispatchEvent(mouseDown)
-          modalEl.click()
-          expect(spy).toHaveBeenCalled()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should not close modal when clicking on an element removed from modal content', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<div class="modal">',
-          ' <div class="modal-dialog">',
-          '   <button class="btn">BTN</button>',
-          ' </div>',
-          '</div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const buttonEl = modalEl.querySelector('.btn')
-        const modal = new Modal(modalEl)
-
-        const spy = spyOn(modal, 'hide')
-        buttonEl.addEventListener('click', () => {
-          buttonEl.remove()
-        })
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          modalEl.dispatchEvent(createEvent('mousedown'))
-          buttonEl.click()
-          expect(spy).not.toHaveBeenCalled()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should do nothing is the modal is not shown', () => {
-      fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-      const modalEl = fixtureEl.querySelector('.modal')
-      const modal = new Modal(modalEl)
-
-      modal.hide()
-
-      expect().nothing()
-    })
-
-    it('should do nothing is the modal is transitioning', () => {
-      fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-      const modalEl = fixtureEl.querySelector('.modal')
-      const modal = new Modal(modalEl)
-
-      modal._isTransitioning = true
-      modal.hide()
-
-      expect().nothing()
-    })
-
-    it('should not hide a modal if hide is prevented', () => {
-      return new Promise((resolve, reject) => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          modal.hide()
-        })
-
-        const hideCallback = () => {
-          setTimeout(() => {
-            expect(modal._isShown).toBeTrue()
-            resolve()
-          }, 10)
-        }
-
-        modalEl.addEventListener('hide.bs.modal', event => {
-          event.preventDefault()
-          hideCallback()
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          reject(new Error('should not trigger hidden'))
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should release focus trap', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-        const spy = spyOn(modal._focustrap, 'deactivate').and.callThrough()
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          modal.hide()
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          expect(spy).toHaveBeenCalled()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-  })
-
-  describe('dispose', () => {
-    it('should dispose a modal', () => {
-      fixtureEl.innerHTML = '<div id="exampleModal" class="modal"><div class="modal-dialog"></div></div>'
-
-      const modalEl = fixtureEl.querySelector('.modal')
-      const modal = new Modal(modalEl)
-      const focustrap = modal._focustrap
-      const spyDeactivate = spyOn(focustrap, 'deactivate').and.callThrough()
-
-      expect(Modal.getInstance(modalEl)).toEqual(modal)
-
-      const spyOff = spyOn(EventHandler, 'off')
-
-      modal.dispose()
-
-      expect(Modal.getInstance(modalEl)).toBeNull()
-      expect(spyOff).toHaveBeenCalledTimes(3)
-      expect(spyDeactivate).toHaveBeenCalled()
-    })
-  })
-
-  describe('handleUpdate', () => {
-    it('should call adjust dialog', () => {
-      fixtureEl.innerHTML = '<div id="exampleModal" class="modal"><div class="modal-dialog"></div></div>'
-
-      const modalEl = fixtureEl.querySelector('.modal')
-      const modal = new Modal(modalEl)
-
-      const spy = spyOn(modal, '_adjustDialog')
-
-      modal.handleUpdate()
-
-      expect(spy).toHaveBeenCalled()
-    })
-  })
-
-  describe('data-api', () => {
-    it('should toggle modal', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<button type="button" data-bs-toggle="modal" data-bs-target="#exampleModal"></button>',
-          '<div id="exampleModal" class="modal"><div class="modal-dialog"></div></div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const trigger = fixtureEl.querySelector('[data-bs-toggle="modal"]')
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          expect(modalEl.getAttribute('aria-modal')).toEqual('true')
-          expect(modalEl.getAttribute('role')).toEqual('dialog')
-          expect(modalEl.getAttribute('aria-hidden')).toBeNull()
-          expect(modalEl.style.display).toEqual('block')
-          expect(document.querySelector('.modal-backdrop')).not.toBeNull()
-          setTimeout(() => trigger.click(), 10)
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          expect(modalEl.getAttribute('aria-modal')).toBeNull()
-          expect(modalEl.getAttribute('role')).toBeNull()
-          expect(modalEl.getAttribute('aria-hidden')).toEqual('true')
-          expect(modalEl.style.display).toEqual('none')
-          expect(document.querySelector('.modal-backdrop')).toBeNull()
-          resolve()
-        })
-
-        trigger.click()
-      })
-    })
-
-    it('should not recreate a new modal', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<button type="button" data-bs-toggle="modal" data-bs-target="#exampleModal"></button>',
-          '<div id="exampleModal" class="modal"><div class="modal-dialog"></div></div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const modal = new Modal(modalEl)
-        const trigger = fixtureEl.querySelector('[data-bs-toggle="modal"]')
-
-        const spy = spyOn(modal, 'show').and.callThrough()
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          expect(spy).toHaveBeenCalled()
-          resolve()
-        })
-
-        trigger.click()
-      })
-    })
-
-    it('should prevent default when the trigger is <a> or <area>', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<a data-bs-toggle="modal" href="#" data-bs-target="#exampleModal"></a>',
-          '<div id="exampleModal" class="modal"><div class="modal-dialog"></div></div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const trigger = fixtureEl.querySelector('[data-bs-toggle="modal"]')
-
-        const spy = spyOn(Event.prototype, 'preventDefault').and.callThrough()
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          expect(modalEl.getAttribute('aria-modal')).toEqual('true')
-          expect(modalEl.getAttribute('role')).toEqual('dialog')
-          expect(modalEl.getAttribute('aria-hidden')).toBeNull()
-          expect(modalEl.style.display).toEqual('block')
-          expect(document.querySelector('.modal-backdrop')).not.toBeNull()
-          expect(spy).toHaveBeenCalled()
-          resolve()
-        })
-
-        trigger.click()
-      })
-    })
-
-    it('should focus the trigger on hide', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<a data-bs-toggle="modal" href="#" data-bs-target="#exampleModal"></a>',
-          '<div id="exampleModal" class="modal"><div class="modal-dialog"></div></div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const trigger = fixtureEl.querySelector('[data-bs-toggle="modal"]')
-
-        const spy = spyOn(trigger, 'focus')
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          const modal = Modal.getInstance(modalEl)
-
-          modal.hide()
-        })
-
-        const hideListener = () => {
-          setTimeout(() => {
-            expect(spy).toHaveBeenCalled()
-            resolve()
-          }, 20)
-        }
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          hideListener()
-        })
-
-        trigger.click()
-      })
-    })
-
-    it('should open modal, having special characters in its id', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#j_id22:exampleModal">',
-          '   Launch demo modal',
-          '</button>',
-          '<div class="modal fade" id="j_id22:exampleModal" aria-labelledby="exampleModalLabel" aria-hidden="true">',
-          '  <div class="modal-dialog">',
-          '    <div class="modal-content">',
-          '      <div class="modal-body">',
-          '        <p>modal body</p>',
-          '      </div>',
-          '    </div>',
-          '  </div>',
-          '</div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const trigger = fixtureEl.querySelector('[data-bs-toggle="modal"]')
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          resolve()
-        })
-
-        trigger.click()
-      })
-    })
-
-    it('should not prevent default when a click occurred on data-bs-dismiss="modal" where tagName is DIFFERENT than <a> or <area>', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<div class="modal">',
-          '  <div class="modal-dialog">',
-          '    <button type="button" data-bs-dismiss="modal"></button>',
-          '  </div>',
-          '</div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const btnClose = fixtureEl.querySelector('button[data-bs-dismiss="modal"]')
-        const modal = new Modal(modalEl)
-
-        const spy = spyOn(Event.prototype, 'preventDefault').and.callThrough()
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          btnClose.click()
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          expect(spy).not.toHaveBeenCalled()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-
-    it('should prevent default when a click occurred on data-bs-dismiss="modal" where tagName is <a> or <area>', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<div class="modal">',
-          '  <div class="modal-dialog">',
-          '    <a type="button" data-bs-dismiss="modal"></a>',
-          '  </div>',
-          '</div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const btnClose = fixtureEl.querySelector('a[data-bs-dismiss="modal"]')
-        const modal = new Modal(modalEl)
-
-        const spy = spyOn(Event.prototype, 'preventDefault').and.callThrough()
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          btnClose.click()
-        })
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          expect(spy).toHaveBeenCalled()
-          resolve()
-        })
-
-        modal.show()
-      })
-    })
-    it('should not focus the trigger if the modal is not visible', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<a data-bs-toggle="modal" href="#" data-bs-target="#exampleModal" style="display: none;"></a>',
-          '<div id="exampleModal" class="modal" style="display: none;"><div class="modal-dialog"></div></div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const trigger = fixtureEl.querySelector('[data-bs-toggle="modal"]')
-
-        const spy = spyOn(trigger, 'focus')
-
-        modalEl.addEventListener('shown.bs.modal', () => {
-          const modal = Modal.getInstance(modalEl)
-
-          modal.hide()
-        })
-
-        const hideListener = () => {
-          setTimeout(() => {
-            expect(spy).not.toHaveBeenCalled()
-            resolve()
-          }, 20)
-        }
-
-        modalEl.addEventListener('hidden.bs.modal', () => {
-          hideListener()
-        })
-
-        trigger.click()
-      })
-    })
-    it('should not focus the trigger if the modal is not shown', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<a data-bs-toggle="modal" href="#" data-bs-target="#exampleModal"></a>',
-          '<div id="exampleModal" class="modal"><div class="modal-dialog"></div></div>'
-        ].join('')
-
-        const modalEl = fixtureEl.querySelector('.modal')
-        const trigger = fixtureEl.querySelector('[data-bs-toggle="modal"]')
-
-        const spy = spyOn(trigger, 'focus')
-
-        const showListener = () => {
-          setTimeout(() => {
-            expect(spy).not.toHaveBeenCalled()
-            resolve()
-          }, 10)
-        }
-
-        modalEl.addEventListener('show.bs.modal', event => {
-          event.preventDefault()
-          showListener()
-        })
-
-        trigger.click()
-      })
-    })
-
-    it('should call hide first, if another modal is open', () => {
-      return new Promise(resolve => {
-        fixtureEl.innerHTML = [
-          '<button data-bs-toggle="modal"  data-bs-target="#modal2"></button>',
-          '<div id="modal1" class="modal fade"><div class="modal-dialog"></div></div>',
-          '<div id="modal2" class="modal"><div class="modal-dialog"></div></div>'
-        ].join('')
-
-        const trigger2 = fixtureEl.querySelector('button')
-        const modalEl1 = document.querySelector('#modal1')
-        const modalEl2 = document.querySelector('#modal2')
-        const modal1 = new Modal(modalEl1)
-
-        modalEl1.addEventListener('shown.bs.modal', () => {
-          trigger2.click()
-        })
-        modalEl1.addEventListener('hidden.bs.modal', () => {
-          expect(Modal.getInstance(modalEl2)).not.toBeNull()
-          expect(modalEl2).toHaveClass('show')
-          resolve()
-        })
-        modal1.show()
-      })
-    })
-  })
-
-  describe('getInstance', () => {
-    it('should return modal instance', () => {
-      fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-      const div = fixtureEl.querySelector('div')
-      const modal = new Modal(div)
-
-      expect(Modal.getInstance(div)).toEqual(modal)
-      expect(Modal.getInstance(div)).toBeInstanceOf(Modal)
-    })
-
-    it('should return null when there is no modal instance', () => {
-      fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
-
-      const div = fixtureEl.querySelector('div')
-
-      expect(Modal.getInstance(div)).toBeNull()
-    })
-  })
-
-  describe('getOrCreateInstance', () => {
-    it('should return modal instance', () => {
-      fixtureEl.innerHTML = '<div></div>'
-
-      const div = fixtureEl.querySelector('div')
-      const modal = new Modal(div)
-
-      expect(Modal.getOrCreateInstance(div)).toEqual(modal)
-      expect(Modal.getInstance(div)).toEqual(Modal.getOrCreateInstance(div, {}))
-      expect(Modal.getOrCreateInstance(div)).toBeInstanceOf(Modal)
-    })
-
-    it('should return new instance when there is no modal instance', () => {
-      fixtureEl.innerHTML = '<div></div>'
-
-      const div = fixtureEl.querySelector('div')
-
-      expect(Modal.getInstance(div)).toBeNull()
-      expect(Modal.getOrCreateInstance(div)).toBeInstanceOf(Modal)
-    })
-
-    it('should return new instance when there is no modal instance with given configuration', () => {
-      fixtureEl.innerHTML = '<div></div>'
-
-      const div = fixtureEl.querySelector('div')
-
-      expect(Modal.getInstance(div)).toBeNull()
-      const modal = Modal.getOrCreateInstance(div, {
-        backdrop: true
-      })
-      expect(modal).toBeInstanceOf(Modal)
-
-      expect(modal._config.backdrop).toBeTrue()
-    })
-
-    it('should return the instance when exists without given configuration', () => {
-      fixtureEl.innerHTML = '<div></div>'
-
-      const div = fixtureEl.querySelector('div')
-      const modal = new Modal(div, {
-        backdrop: true
-      })
-      expect(Modal.getInstance(div)).toEqual(modal)
-
-      const modal2 = Modal.getOrCreateInstance(div, {
-        backdrop: false
-      })
-      expect(modal).toBeInstanceOf(Modal)
-      expect(modal2).toEqual(modal)
-
-      expect(modal2._config.backdrop).toBeTrue()
-    })
-  })
-})
diff --git a/js/tests/visual/modal.html b/js/tests/visual/modal.html
deleted file mode 100644 (file)
index efb5127..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-<!doctype html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1">
-    <link href="../../../dist/css/bootstrap.min.css" rel="stylesheet">
-    <title>Modal</title>
-    <style>
-      #tall {
-        height: 1500px;
-        width: 100px;
-      }
-    </style>
-  </head>
-  <body>
-    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
-      <div class="container-fluid">
-        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
-          <span class="navbar-toggler-icon"></span>
-        </button>
-        <div class="collapse navbar-collapse" id="navbarResponsive">
-          <a class="navbar-brand" href="#">This shouldn't jump!</a>
-          <ul class="navbar-nav">
-            <li class="nav-item">
-              <a class="nav-link active" href="#" aria-current="page">Home</a>
-            </li>
-            <li class="nav-item">
-              <a class="nav-link" href="#">Link</a>
-            </li>
-            <li class="nav-item">
-              <a class="nav-link" href="#">Link</a>
-            </li>
-          </ul>
-        </div>
-      </div>
-    </nav>
-
-    <div class="container mt-3">
-      <h1>Modal <small>Bootstrap Visual Test</small></h1>
-
-      <div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="myModalLabel" aria-hidden="true">
-        <div class="modal-dialog">
-          <div class="modal-content">
-            <div class="modal-header">
-              <h1 class="modal-title fs-4" id="myModalLabel">Modal title</h1>
-              <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-            </div>
-            <div class="modal-body">
-              <h4>Text in a modal</h4>
-              <p>Duis mollis, est non commodo luctus, nisi erat porttitor ligula.</p>
-
-              <h4>Popover in a modal</h4>
-              <p>This <button type="button" class="btn btn-primary" data-bs-toggle="popover" data-bs-placement="left" title="Popover title" data-bs-content="And here's some amazing content. It's very engaging. Right?">button</button> should trigger a popover on click.</p>
-
-
-              <h4>Tooltips in a modal</h4>
-              <p><a href="#" data-bs-toggle="tooltip" data-bs-placement="top" title="Tooltip on top">This link</a> and <a href="#" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Tooltip on bottom">that link</a> should have tooltips on hover.</p>
-
-              <div id="accordion" role="tablist">
-                <div class="card" role="presentation">
-                  <div class="card-header" role="tab" id="headingOne">
-                    <h5 class="mb-0">
-                      <a data-bs-toggle="collapse" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
-                        Collapsible Group Item #1
-                      </a>
-                    </h5>
-                  </div>
-
-                  <div id="collapseOne" class="collapse show" data-bs-parent="#accordion" role="tabpanel" aria-labelledby="headingOne">
-                    <div class="card-body">
-                      Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
-                    </div>
-                  </div>
-                </div>
-                <div class="card" role="presentation">
-                  <div class="card-header" role="tab" id="headingTwo">
-                    <h5 class="mb-0">
-                      <a class="collapsed" data-bs-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
-                        Collapsible Group Item #2
-                      </a>
-                    </h5>
-                  </div>
-                  <div id="collapseTwo" class="collapse" data-bs-parent="#accordion" role="tabpanel" aria-labelledby="headingTwo">
-                    <div class="card-body">
-                      Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
-                    </div>
-                  </div>
-                </div>
-                <div class="card" role="presentation">
-                  <div class="card-header" role="tab" id="headingThree">
-                    <h5 class="mb-0">
-                      <a class="collapsed" data-bs-toggle="collapse" href="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
-                        Collapsible Group Item #3
-                      </a>
-                    </h5>
-                  </div>
-                  <div id="collapseThree" class="collapse" data-bs-parent="#accordion" role="tabpanel" aria-labelledby="headingThree">
-                    <div class="card-body">
-                      Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
-                    </div>
-                  </div>
-                </div>
-              </div>
-
-              <hr>
-
-              <h4>Overflowing text to show scroll behavior</h4>
-              <p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-              <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
-              <p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
-              <p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-              <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
-              <p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
-              <p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
-              <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
-              <p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
-            </div>
-            <div class="modal-footer">
-              <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-              <button type="button" class="btn btn-primary">Save changes</button>
-            </div>
-          </div>
-        </div>
-      </div>
-
-      <div class="modal fade" id="firefoxModal" tabindex="-1" aria-labelledby="firefoxModalLabel" aria-hidden="true">
-        <div class="modal-dialog">
-          <div class="modal-content">
-            <div class="modal-header">
-              <h1 class="modal-title fs-4" id="firefoxModalLabel">Firefox Bug Test</h1>
-              <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-            </div>
-            <div class="modal-body">
-              <ol>
-                <li>Ensure you're using Firefox.</li>
-                <li>Open a new tab and then switch back to this tab.</li>
-                <li>Click into this input: <input type="text" id="ff-bug-input"></li>
-                <li>Switch to the other tab and then back to this tab.</li>
-              </ol>
-              <p>Test result: <strong id="ff-bug-test-result"></strong></p>
-            </div>
-            <div class="modal-footer">
-              <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-              <button type="button" class="btn btn-primary">Save changes</button>
-            </div>
-          </div>
-        </div>
-      </div>
-
-      <div class="modal fade" id="slowModal" tabindex="-1" aria-labelledby="slowModalLabel" aria-hidden="true" style="transition-duration: 5s;">
-        <div class="modal-dialog" style="transition-duration: inherit;">
-          <div class="modal-content">
-            <div class="modal-header">
-              <h1 class="modal-title fs-4" id="slowModalLabel">Lorem slowly</h1>
-              <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-            </div>
-            <div class="modal-body">
-              <p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec sed odio dui. Nullam quis risus eget urna mollis ornare vel eu leo. Nulla vitae elit libero, a pharetra augue.</p>
-            </div>
-            <div class="modal-footer">
-              <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-              <button type="button" class="btn btn-primary">Save changes</button>
-            </div>
-          </div>
-        </div>
-      </div>
-
-      <button type="button" class="btn btn-primary btn-lg" data-bs-toggle="modal" data-bs-target="#myModal">
-        Launch demo modal
-      </button>
-
-      <button type="button" class="btn btn-primary btn-lg" id="tall-toggle">
-        Toggle tall &lt;body&gt; content
-      </button>
-
-      <br><br>
-
-      <button type="button" class="btn btn-secondary btn-lg" data-bs-toggle="modal" data-bs-target="#firefoxModal">
-        Launch Firefox bug test modal
-      </button>
-      (<a href="https://github.com/twbs/bootstrap/issues/18365">See Issue #18365</a>)
-
-      <br><br>
-
-      <button type="button" class="btn btn-secondary btn-lg" data-bs-toggle="modal" data-bs-target="#slowModal">
-        Launch modal with slow transition
-      </button>
-
-      <br><br>
-
-      <div class="text-bg-dark p-2" id="tall" style="display: none;">
-        Tall body content to force the page to have a scrollbar.
-      </div>
-
-      <button type="button" class="btn btn-secondary btn-lg" data-bs-toggle="modal" data-bs-target="&#x3C;div class=&#x22;modal fade the-bad&#x22; tabindex=&#x22;-1&#x22;&#x3E;&#x3C;div class=&#x22;modal-dialog&#x22;&#x3E;&#x3C;div class=&#x22;modal-content&#x22;&#x3E;&#x3C;div class=&#x22;modal-header&#x22;&#x3E;&#x3C;button type=&#x22;button&#x22; class=&#x22;btn-close&#x22; data-bs-dismiss=&#x22;modal&#x22; aria-label=&#x22;Close&#x22;&#x3E;&#x3C;span aria-hidden=&#x22;true&#x22;&#x3E;&#x26;times;&#x3C;/span&#x3E;&#x3C;/button&#x3E;&#x3C;h1 class=&#x22;modal-title fs-4&#x22;&#x3E;The Bad Modal&#x3C;/h1&#x3E;&#x3C;/div&#x3E;&#x3C;div class=&#x22;modal-body&#x22;&#x3E;This modal&#x27;s HTTML source code is declared inline, inside the data-bs-target attribute of it&#x27;s show-button&#x3C;/div&#x3E;&#x3C;/div&#x3E;&#x3C;/div&#x3E;&#x3C;/div&#x3E;">
-        Modal with an XSS inside the data-bs-target
-      </button>
-
-      <br><br>
-
-      <button type="button" class="btn btn-secondary btn-lg" id="btnPreventModal">
-        Launch prevented modal on hide (to see the result open your console)
-      </button>
-    </div>
-
-    <script src="../../../dist/js/bootstrap.bundle.js"></script>
-    <script>
-      /* global bootstrap: false */
-
-      const ffBugTestResult = document.getElementById('ff-bug-test-result')
-      const firefoxTestDone = false
-
-      function reportFirefoxTestResult(result) {
-        if (!firefoxTestDone) {
-          ffBugTestResult.classList.add(result ? 'text-success' : 'text-danger')
-          ffBugTestResult.textContent = result ? 'PASS' : 'FAIL'
-        }
-      }
-
-      document.querySelectorAll('[data-bs-toggle="popover"]').forEach(popoverEl => new bootstrap.Popover(popoverEl))
-
-      document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(tooltipEl => new bootstrap.Tooltip(tooltipEl))
-
-      const tall = document.getElementById('tall')
-      document.getElementById('tall-toggle').addEventListener('click', () => {
-        tall.style.display = tall.style.display === 'none' ? 'block' : 'none'
-      })
-
-      const ffBugInput = document.getElementById('ff-bug-input')
-      const firefoxModal = document.getElementById('firefoxModal')
-      function handlerClickFfBugInput() {
-        firefoxModal.addEventListener('focus', reportFirefoxTestResult.bind(false))
-        ffBugInput.addEventListener('focus', reportFirefoxTestResult.bind(true))
-        ffBugInput.removeEventListener('focus', handlerClickFfBugInput)
-      }
-
-      ffBugInput.addEventListener('focus', handlerClickFfBugInput)
-
-      const modalFf = new bootstrap.Modal(firefoxModal)
-
-      document.getElementById('btnPreventModal').addEventListener('click', () => {
-        const shownFirefoxModal = () => {
-          modalFf.hide()
-          firefoxModal.removeEventListener('shown.bs.modal', hideFirefoxModal)
-        }
-
-        const hideFirefoxModal = event => {
-          event.preventDefault()
-          firefoxModal.removeEventListener('hide.bs.modal', hideFirefoxModal)
-
-          if (modalFf._isTransitioning) {
-            console.error('Modal plugin should not set _isTransitioning when hide event is prevented')
-          } else {
-            console.log('Test passed')
-            modalFf.hide() // work as expected
-          }
-        }
-
-        firefoxModal.addEventListener('shown.bs.modal', shownFirefoxModal)
-        firefoxModal.addEventListener('hide.bs.modal', hideFirefoxModal)
-        modalFf.show()
-      })
-
-      // Test transition duration
-      let t0
-      let t1
-      const slowModal = document.getElementById('slowModal')
-
-      slowModal.addEventListener('shown.bs.modal', () => {
-        t1 = performance.now()
-        console.log(`transition-duration took ${t1 - t0}ms.`)
-      })
-
-      slowModal.addEventListener('show.bs.modal', () => {
-        t0 = performance.now()
-      })
-    </script>
-  </body>
-</html>
diff --git a/scss/_modal.scss b/scss/_modal.scss
deleted file mode 100644 (file)
index b6cee70..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-@use "sass:map";
-@use "config" as *;
-@use "variables" as *;
-@use "mixins/border-radius" as *;
-@use "mixins/box-shadow" as *;
-@use "mixins/transition" as *;
-@use "mixins/gradients" as *;
-@use "mixins/backdrop" as *;
-@use "vendor/rfs" as *;
-@use "layout/breakpoints" as *;
-
-// .modal-open      - body class for killing the scroll
-// .modal           - container to scroll within
-// .modal-dialog    - positioning shell for the actual modal
-// .modal-content   - actual modal w/ bg and corners and stuff
-
-@layer components {
-  // Container that the modal scrolls within
-  .modal {
-    // scss-docs-start modal-css-vars
-    --#{$prefix}modal-zindex: #{$zindex-modal};
-    --#{$prefix}modal-width: #{$modal-md};
-    --#{$prefix}modal-padding: #{$modal-inner-padding};
-    --#{$prefix}modal-margin: #{$modal-dialog-margin};
-    --#{$prefix}modal-color: #{$modal-content-color};
-    --#{$prefix}modal-bg: #{$modal-content-bg};
-    --#{$prefix}modal-border-color: #{$modal-content-border-color};
-    --#{$prefix}modal-border-width: #{$modal-content-border-width};
-    --#{$prefix}modal-border-radius: #{$modal-content-border-radius};
-    --#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-xs};
-    --#{$prefix}modal-inner-border-radius: #{$modal-content-inner-border-radius};
-    --#{$prefix}modal-header-padding-x: #{$modal-header-padding-x};
-    --#{$prefix}modal-header-padding-y: #{$modal-header-padding-y};
-    --#{$prefix}modal-header-padding: #{$modal-header-padding}; // Todo in v6: Split this padding into x and y
-    --#{$prefix}modal-header-border-color: #{$modal-header-border-color};
-    --#{$prefix}modal-header-border-width: #{$modal-header-border-width};
-    --#{$prefix}modal-title-line-height: #{$modal-title-line-height};
-    --#{$prefix}modal-footer-gap: #{$modal-footer-margin-between};
-    --#{$prefix}modal-footer-bg: #{$modal-footer-bg};
-    --#{$prefix}modal-footer-border-color: #{$modal-footer-border-color};
-    --#{$prefix}modal-footer-border-width: #{$modal-footer-border-width};
-    // scss-docs-end modal-css-vars
-
-    position: fixed;
-    inset: 0 auto auto 0;
-    z-index: var(--#{$prefix}modal-zindex);
-    display: none;
-    width: 100%;
-    height: 100%;
-    overflow-x: hidden;
-    overflow-y: auto;
-    // Prevent Chrome on Windows from adding a focus outline. For details, see
-    // https://github.com/twbs/bootstrap/pull/10951.
-    outline: 0;
-    // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
-    // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
-    // See also https://github.com/twbs/bootstrap/issues/17695
-  }
-
-  // Shell div to position the modal with bottom padding
-  .modal-dialog {
-    position: relative;
-    width: auto;
-    margin: var(--#{$prefix}modal-margin);
-    // allow clicks to pass through for custom click handling to close modal
-    pointer-events: none;
-
-    // When fading in the modal, animate it to slide down
-    .modal.fade & {
-      transform: $modal-fade-transform;
-      @include transition($modal-transition);
-    }
-    .modal.show & {
-      transform: $modal-show-transform;
-    }
-
-    // When trying to close, animate focus to scale
-    .modal.modal-static & {
-      transform: $modal-scale-transform;
-    }
-  }
-
-  .modal-dialog-scrollable {
-    height: calc(100% - var(--#{$prefix}modal-margin) * 2);
-
-    .modal-content {
-      max-height: 100%;
-      overflow: hidden;
-    }
-
-    .modal-body {
-      overflow-y: auto;
-    }
-  }
-
-  .modal-dialog-centered {
-    display: flex;
-    align-items: center;
-    min-height: calc(100% - var(--#{$prefix}modal-margin) * 2);
-  }
-
-  // Actual modal
-  .modal-content {
-    position: relative;
-    display: flex;
-    flex-direction: column;
-    width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
-    // counteract the pointer-events: none; in the .modal-dialog
-    color: var(--#{$prefix}modal-color);
-    pointer-events: auto;
-    background-color: var(--#{$prefix}modal-bg);
-    background-clip: padding-box;
-    border: var(--#{$prefix}modal-border-width) solid var(--#{$prefix}modal-border-color);
-    @include border-radius(var(--#{$prefix}modal-border-radius));
-    @include box-shadow(var(--#{$prefix}modal-box-shadow));
-    // Remove focus outline from opened modal
-    outline: 0;
-  }
-
-  // Modal background
-  .modal-backdrop {
-    // scss-docs-start modal-backdrop-css-vars
-    --#{$prefix}backdrop-zindex: #{$zindex-modal-backdrop};
-    --#{$prefix}backdrop-bg: #{$modal-backdrop-bg};
-    --#{$prefix}backdrop-opacity: #{$modal-backdrop-opacity};
-    // scss-docs-end modal-backdrop-css-vars
-
-    @include overlay-backdrop(var(--#{$prefix}backdrop-zindex), var(--#{$prefix}backdrop-bg), var(--#{$prefix}backdrop-opacity));
-  }
-
-  // Modal header
-  // Top section of the modal w/ title and dismiss
-  .modal-header {
-    display: flex;
-    flex-shrink: 0;
-    align-items: center;
-    padding: var(--#{$prefix}modal-header-padding);
-    border-block-end: var(--#{$prefix}modal-header-border-width) solid var(--#{$prefix}modal-header-border-color);
-    @include border-top-radius(var(--#{$prefix}modal-inner-border-radius));
-
-    .btn-close {
-      padding: calc(var(--#{$prefix}modal-header-padding-y) * .5) calc(var(--#{$prefix}modal-header-padding-x) * .5);
-      // Split properties to avoid invalid calc() function if value is 0
-      margin-inline-start: auto;
-      margin-inline-end: calc(-.5 * var(--#{$prefix}modal-header-padding-x));
-      margin-top: calc(-.5 * var(--#{$prefix}modal-header-padding-y));
-      margin-bottom: calc(-.5 * var(--#{$prefix}modal-header-padding-y));
-    }
-  }
-
-  // Title text within header
-  .modal-title {
-    margin-bottom: 0;
-    line-height: var(--#{$prefix}modal-title-line-height);
-  }
-
-  // Modal body
-  // Where all modal content resides (sibling of .modal-header and .modal-footer)
-  .modal-body {
-    position: relative;
-    // Enable `flex-grow: 1` so that the body take up as much space as possible
-    // when there should be a fixed height on `.modal-dialog`.
-    flex: 1 1 auto;
-    padding: var(--#{$prefix}modal-padding);
-  }
-
-  // Footer (for actions)
-  .modal-footer {
-    display: flex;
-    flex-shrink: 0;
-    flex-wrap: wrap;
-    align-items: center; // vertically center
-    justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
-    padding: calc(var(--#{$prefix}modal-padding) - var(--#{$prefix}modal-footer-gap) * .5);
-    background-color: var(--#{$prefix}modal-footer-bg);
-    border-block-start: var(--#{$prefix}modal-footer-border-width) solid var(--#{$prefix}modal-footer-border-color);
-    @include border-bottom-radius(var(--#{$prefix}modal-inner-border-radius));
-
-    // Place margin between footer elements
-    // This solution is far from ideal because of the universal selector usage,
-    // but is needed to fix https://github.com/twbs/bootstrap/issues/24800
-    > * {
-      margin: calc(var(--#{$prefix}modal-footer-gap) * .5); // Todo in v6: replace with gap on parent class
-    }
-  }
-
-  // Scale up the modal
-  @include media-breakpoint-up(sm) {
-    .modal {
-      --#{$prefix}modal-margin: #{$modal-dialog-margin-y-sm-up};
-      --#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-sm-up};
-    }
-
-    // Automatically set modal's width for larger viewports
-    .modal-dialog {
-      max-width: var(--#{$prefix}modal-width);
-      margin-inline: auto;
-    }
-
-    .modal-sm {
-      --#{$prefix}modal-width: #{$modal-sm};
-    }
-  }
-
-  @include media-breakpoint-up(lg) {
-    .modal-lg,
-    .modal-xl {
-      --#{$prefix}modal-width: #{$modal-lg};
-    }
-  }
-
-  @include media-breakpoint-up(xl) {
-    .modal-xl {
-      --#{$prefix}modal-width: #{$modal-xl};
-    }
-  }
-
-  // scss-docs-start modal-fullscreen-loop
-  @each $breakpoint in map.keys($grid-breakpoints) {
-    $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
-    $postfix: if($infix != "", $infix + "-down", "");
-
-    @include media-breakpoint-down($breakpoint) {
-      .modal-fullscreen#{$postfix} {
-        width: 100vw;
-        max-width: none;
-        height: 100%;
-        margin: 0;
-
-        .modal-content {
-          height: 100%;
-          border: 0;
-          @include border-radius(0);
-        }
-
-        .modal-header,
-        .modal-footer {
-          @include border-radius(0);
-        }
-
-        .modal-body {
-          overflow-y: auto;
-        }
-      }
-    }
-  }
-  // scss-docs-end modal-fullscreen-loop
-}
index 6d742f672aa858e45a982ae543f8b51a39d8843e..44c7693b7778ec6a7dd7aee78fa4c052dda05a3b 100644 (file)
@@ -7,7 +7,7 @@
 // Variables
 //
 // Variables should follow the `$component-state-property-size` formula for
-// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.
+// consistent naming. Ex: $nav-link-disabled-color and $btn-padding-y-lg.
 
 // scss-docs-start theme-color-variables
 // $primary:       $blue-500 !default;
@@ -454,67 +454,22 @@ $zindex-levels: (
 // scss-docs-end zindex-levels-map
 
 
-// Modals
-
-// scss-docs-start modal-variables
-$modal-inner-padding:               $spacer !default;
-
-$modal-footer-margin-between:       .5rem !default;
-
-$modal-dialog-margin:               .5rem !default;
-$modal-dialog-margin-y-sm-up:       1.75rem !default;
-
-$modal-title-line-height:           $line-height-base !default;
-
-$modal-content-color:               var(--#{$prefix}color-body) !default;
-$modal-content-bg:                  var(--#{$prefix}bg-body) !default;
-$modal-content-border-color:        var(--#{$prefix}border-color-translucent) !default;
-$modal-content-border-width:        var(--#{$prefix}border-width) !default;
-$modal-content-border-radius:       var(--#{$prefix}border-radius-lg) !default;
-$modal-content-inner-border-radius: calc(#{$modal-content-border-radius} - #{$modal-content-border-width}) !default;
-$modal-content-box-shadow-xs:       var(--#{$prefix}box-shadow-sm) !default;
-$modal-content-box-shadow-sm-up:    var(--#{$prefix}box-shadow) !default;
-
-$modal-backdrop-bg:                 $black !default;
-$modal-backdrop-opacity:            .5 !default;
-
-$modal-header-border-color:         var(--#{$prefix}border-color) !default;
-$modal-header-border-width:         $modal-content-border-width !default;
-$modal-header-padding-y:            $modal-inner-padding !default;
-$modal-header-padding-x:            $modal-inner-padding !default;
-$modal-header-padding:              $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility
-
-$modal-footer-bg:                   null !default;
-$modal-footer-border-color:         $modal-header-border-color !default;
-$modal-footer-border-width:         $modal-header-border-width !default;
-
-$modal-sm:                          300px !default;
-$modal-md:                          500px !default;
-$modal-lg:                          800px !default;
-$modal-xl:                          1200px !default;
-
-$modal-fade-transform:              translate(0, -50px) !default;
-$modal-show-transform:              none !default;
-$modal-transition:                  transform .3s ease-out !default;
-$modal-scale-transform:             scale(1.02) !default;
-// scss-docs-end modal-variables
-
 // Offcanvas
 
 // scss-docs-start offcanvas-variables
-$offcanvas-padding-y:               $modal-inner-padding !default;
-$offcanvas-padding-x:               $modal-inner-padding !default;
+$offcanvas-padding-y:               $spacer !default;
+$offcanvas-padding-x:               $spacer !default;
 $offcanvas-horizontal-width:        400px !default;
 $offcanvas-vertical-height:         30vh !default;
 $offcanvas-transition-duration:     .3s !default;
-$offcanvas-border-color:            $modal-content-border-color !default;
-$offcanvas-border-width:            $modal-content-border-width !default;
-$offcanvas-title-line-height:       $modal-title-line-height !default;
+$offcanvas-border-color:            var(--#{$prefix}border-color-translucent) !default;
+$offcanvas-border-width:            var(--#{$prefix}border-width) !default;
+$offcanvas-title-line-height:       $line-height-base !default;
 $offcanvas-bg-color:                var(--#{$prefix}bg-body) !default;
 $offcanvas-color:                   var(--#{$prefix}color-body) !default;
-$offcanvas-box-shadow:              $modal-content-box-shadow-xs !default;
-$offcanvas-backdrop-bg:             $modal-backdrop-bg !default;
-$offcanvas-backdrop-opacity:        $modal-backdrop-opacity !default;
+$offcanvas-box-shadow:              var(--#{$prefix}box-shadow-sm) !default;
+$offcanvas-backdrop-bg:             $black !default;
+$offcanvas-backdrop-opacity:        .5 !default;
 // scss-docs-end offcanvas-variables
 
 // Code
index f849163febe6b35b735b6fb399e42dffe6567469..52fc04d4b1793e3aa68bfd951cad4d5d4552df17 100644 (file)
@@ -20,7 +20,6 @@
 @forward "dialog";
 @forward "dropdown";
 @forward "list-group";
-@forward "modal";
 @forward "nav";
 @forward "navbar";
 @forward "offcanvas";
index bfa5c522a5a6980062db3b8db59cdea967bb7ccd..2cbfc909997cadea657306735ca0258bc61e44d7 100644 (file)
@@ -95,7 +95,6 @@
     - title: Dialog
     - title: Dropdowns
     - title: List group
-    - title: Modal
     - title: Navbar
     - title: Navs & tabs
     - title: Offcanvas
index 66a2ce8ef78ad09c2f64f0f98b00db16d48477ea..eb494e1572b62ed589f836a97d862f5405c7d343 100644 (file)
@@ -57,7 +57,6 @@ import Placeholder from "@shortcodes/Placeholder.astro"
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#carousel">شرائح العرض</a></li>
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#dropdowns">القوائم المنسدلة</a></li>
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#list-group">مجموعة العناصر</a></li>
-          <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#modal">الصندوق العائم</a></li>
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#navs">التنقل</a></li>
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#navbar">شريط التنقل</a></li>
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#pagination">ترقيم الصفحات</a></li>
@@ -1118,31 +1117,6 @@ import Placeholder from "@shortcodes/Placeholder.astro"
         `]} />
       </div>
     </article>
-    <article class="my-3" id="modal">
-      <div class="bd-heading sticky-xl-top align-self-start mt-5 mb-3 mt-xl-0 mb-xl-2">
-        <h3>الصندوق العائم</h3>
-        <a class="d-flex align-items-center" hreflang="en" href={getVersionedDocsPath('components/modal')}>دليل الإستخدام</a>
-      </div>
-
-      <div>
-        <Example showMarkup={false} code={`
-        <div class="d-flex justify-content-between flex-wrap">
-          <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalDefault">
-            إطلاق صندوق عائم تجريبي
-          </button>
-          <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdropLive">
-            إطلاق صندوق عائم عالق
-          </button>
-          <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalCenteredScrollable">
-            صندوق عائم متنصف عاموديًا وقابل للتمرير
-          </button>
-          <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalFullscreen">
-            صندوق عائم يملأ الشاشة
-          </button>
-        </div>
-        `} />
-      </div>
-    </article>
     <article class="my-3" id="navs">
       <div class="bd-heading sticky-xl-top align-self-start mt-5 mb-3 mt-xl-0 mb-xl-2">
         <h3>التنقل</h3>
@@ -1514,85 +1488,3 @@ import Placeholder from "@shortcodes/Placeholder.astro"
     </article>
   </section>
 </main>
-
-<div class="modal fade" id="exampleModalDefault" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="exampleModalLabel">عنوان الصندوق العائم</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="إغلاق"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إغلاق</button>
-        <button type="button" class="btn btn-primary">حفظ التغيرات</button>
-      </div>
-    </div>
-  </div>
-</div>
-<div class="modal fade" id="staticBackdropLive" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLiveLabel" aria-hidden="true">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="staticBackdropLiveLabel">عنوان الصندوق العائم</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="إغلاق"></button>
-      </div>
-      <div class="modal-body">
-        <p>لن أغلق إذا نقرت خارجي. لا تحاول حتى الضغط على مفتاح الهروب.</p>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إغلاق</button>
-        <button type="button" class="btn btn-primary">حسنًا</button>
-      </div>
-    </div>
-  </div>
-</div>
-<div class="modal fade" id="exampleModalCenteredScrollable" tabindex="-1" aria-labelledby="exampleModalCenteredScrollableTitle" aria-hidden="true">
-  <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="exampleModalCenteredScrollableTitle">عنوان الصندوق العائم</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="إغلاق"></button>
-      </div>
-      <div class="modal-body">
-        <p>نص لتوضيح عمل الصندوق العائم المتنصّف عاموديًا القابل للتمرير</p>
-        <p>في هذه الحالة، هذا الصندوق يحتوي على محتوى أكثر قليلًا، ولذلك لتوضيح كيف  يمكن إضافة خاصية الإنتصاف العامودي لصندوق عائم قابل للتمرير.</p>
-        <p>يعتبر كوب أو فنجان القهوة عادة يومية عند غالبية سكان الكرة الأرضية في الصباح والمساء، وفي حين تكثر الدراسات حول إيجابياتها هناك أيضا سلبيات كثيرة للمشروب المفضل للكثيرين.</p>
-        <p>وفي هذا الشأن، أظهرت دراسة جديدة أن تناول الكافيين بانتظام يقلل من حجم المادة الرمادية في الدماغ، مما يشير إلى أن تناول القهوة يمكن أن يضعف القدرة على معالجة المعلومات، وفقاً لما نشرته "ديلي ميل" البريطانية.</p>
-        <p>وأعطى باحثون سويسريون متطوعين ثلاث حصص من الكافيين 150 ملغم يوميًا لمدة 10 أيام - وهو مقدار كافيين يعادل حوالي أربعة أو خمسة أكواب صغيرة من القهوة المخمرة يوميًا، أو سبعة إسبريسو فردي.</p>
-        <p>وتبين حدوث انخفاض في المادة الرمادية، والتي توجد غالبًا في الطبقة الخارجية للدماغ، أو القشرة، وتعمل على معالجة المعلومات.</p>
-        <p>كما كان الانخفاض مذهلاً بشكل خاص في الفص الصدغي الإنسي الأيمن، بما في ذلك الحُصين، وهي منطقة من الدماغ ضرورية لتقوية الذاكرة.</p>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إغلاق</button>
-        <button type="button" class="btn btn-primary">حفظ التغيرات</button>
-      </div>
-    </div>
-  </div>
-</div>
-<div class="modal fade" id="exampleModalFullscreen" tabindex="-1" aria-labelledby="exampleModalFullscreenLabel" aria-hidden="true">
-  <div class="modal-dialog modal-fullscreen">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-4" id="exampleModalFullscreenLabel">صندوق عائم يملأ الشاشة</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="إغلاق"></button>
-      </div>
-      <div class="modal-body">
-        <p>في ما يلي، نص طويل لتعبئة كامل الشاشة. قد يبدو أنني أثرثر كثيرًا، لذا سأقوم بنسخ مقالة من إحدى الصحف العربية.</p>
-        <p>تكييف الهواء هو من التكنولوجيا التي ما إن نمتلكها حتى نصبح عاجزين عن تخيّل العيش من دونها. وتكييف الهواء في مناطق عديدة من العالم ليس ترفاً يمكن الاستغناء عنه. ولكن هذه الحاجة الحيوية تثير تحديات كبيرة على مستوى استهلاك الطاقة في معظم بلدان العالم. ويُتوقع أن تتفاقم هذه التحديات خلال العقود الثلاثة المقبلة، مع توقُّع ارتفاع عدد المكيفات في العالم نحو ثلاثة أضعاف. وفي حين أن الابتكارات التكنولوجية تحقِّق كل يوم إنجازاً جديداً، وعلى الرغم من بعض التحسينات والتدابير المحدودة التي طرأت على صناعة المكيفات، “فإن تكنولوجيتها الأساسية لا تزال تعمل كما كانت، منذ اعتمادها قبل نحو قرن من السنين"، حسبما جاء في تقرير لمعهد ماساشوستس للتكنولوجيا (MIT)، في الأول من سبتمبر 2020م. ولمعالجة هذه المشكلات الخطيرة، لا مفر من إعادة التفكير بجد.</p>
-        <p>التكييف حاجة حيويّة. فالتعرّض للحرارة لمدة طويلة ضارٌ بالصحة. ووفقاً لمنظمة الصحة العالميّة يمكن للتعرُّض الطويل للحرارة أيضاً أن يؤدي إلى "إعياء حراري، وضربة شمس، وتورّم في الرجلين، وطفح جلدي على العنق، وتشنج، وصداع، وحساسيّة، والخمول والوهَن. ويمكن للحرارة أن تسبِّب جفافاً خطراً، وأعراضاً حادة في أوعية الدماغ الدمويّة، وتسهم في تكوّن الجلطات".</p>
-        <p>وموجات الحر أيضاً من أشد المخاطر الطبيعيّة المميتة. إذ يقدَّر أن بين عامي 1998 و2017م، توفي نحو 166 ألف شخص من موجات الحر. ومات 70 ألفاً من هؤلاء في أوروبا سنة 2003م وحدها. ومن دون أن يصل الخطر إلى الموت، تتسبَّب الحرارة العالية بانخفاض الأداء المعرفي لدى الشبان البالغين في المباني غير المكيّفة. فقد بيّنت دراسة أجرتها "كليّة ت. هـ. تشان" للصحة العامة في جامعة هارفرد، نشرتها "بلوس ميديسين" في 10 يوليو 2018م، أن التلاميذ الذين ينامون في مهاجع غير مكيّفة، يقل أداؤهم عن أولئك الذين ينامون في مهاجع مكيّفة. ولتجنّب مخاطر التعرّض للحرارة، يلتفت الناس إلى استخدام التكييف.</p>
-        <p>يتطلّب التكييف كثيراً من الطاقة. فنحو %10 من استهلاك الكهرباء في العالم يُنفَق في تشغيل المكيّفات. وتصل هذه النسبة إلى %50 في المملكة حسب "المركز السعودي لكفاءة الطاقة". أضف إلى ذلك أن معظم البشر في بلدان العالم النامي، لم يقتنوا بعد مكيّفهم الأول، والمشكلة إلى ازدياد. فمعظم البلدان النامية هي من البلدان الأشد حرارة والأكثر اكتظاظاً بالسكان في العالم. وجاء في تقرير لوكالة الطاقة الدوليّة بعنوان "مستقبل التبريد"، ونُشر في مايو 2018م، أن في أجزاء من أمريكا الجنوبيّة وإفريقيا وآسيا والشرق الأوسط، يعيش 2.8 مليار نسمة، ولا يملك وحدات تكييف سوى %8 من المنازل. في حين الدول المتقدِّمة مثل كوريا الجنوبيّة، واليابان، والولايات المتحدة، فإن %89 من المنازل تملك مكيفات، وفي الصين %60 من البيوت تملكها أيضاً.</p>
-        <p>ولكن مع تنامي الدخل في بلدان الاقتصاد الصاعد، يتوقّع أن تزداد المنازل التي تقتني مكيّفاً. وبحسب مقالة نُشرت في صحيفة "نيويورك تايمز"، في 15 مايو 2018م، سيرتفع عدد المكيّفات في العالم من نحو 1.6 مليار حالياً، إلى 5.6 مليارات عام 2050م، طبقاً لمعدَّلات النمو الاقتصادي.</p>
-        <p>ومع الافتقار إلى الابتكار وتطوير النظم لفرض معايير الجدوى الأعلى، فسيتضاعف استهلاك الطاقة لتشغيل المكيّفات ثلاثة أضعاف. وسينتج من ذلك طلب إضافي للطاقة يساوي مجموع إنتاج الطاقة في الصين حالياً. فمبيعات المكيّفات ترتفع اليوم في البلدان النامية، لكن فعاليّة هذه الوحدات مشكوك فيها. فمثلاً، أوسع وحدات التكييف انتشاراً في بعض الأسواق الآسيوية تتطلّب ضعفي ما تتطلّبه وحدات تكييف أجدى. والمكيّفات التي تباع في اليابان والاتحاد الأوروبي أجدى بنسبة %25 عادة، من تلك التي تباع في الصين والولايات المتحدة.</p>
-        <p>وبصرف النظر عن كثير من الطاقة التي يحتاج إليها المكيّف، فإنه يبث مقادير وفيرة من غازات الدفيئة نفسها. وطبقاً لموقع تكييف الهواء (airconditioning.com)، فإن المبرِّدات في معظم المكيّفات مثل مواد مركبات الكربون الكلورية فلورية أو مواد هيدروفلوروولفينات، ومركبات ثاني أكسيد الكربون الهيدروكلورية فلورية، أسوأ بكثير للبيئة من ثاني أكسيد الكربون، لأنها تحتبس من الحرارة مقادير أكبر حين تتسرّب إلى الجو.</p>
-        <p>وبالإضافة إلى ظاهرة الدفيئة، فهذه الغازات تسهم أيضاً بالإضرار بطبقة الأوزون. ويمكن لهذه المواد الكيميائية أن تتسرّب خلال عملية التصنيع أو التصليح. ويعرف كل من يملك في منزله مكيّفاً كم تتكرر أعطال هذه الأجهزة. ثم إن المكيف يُرمَى حين يتعطّل نهائياً ولا يعود قابلاً للإصلاح، والمواد المبرِّدة فيه ستتسرّب على الأرجح لتلوث الهواء.</p>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إغلاق</button>
-      </div>
-    </div>
-  </div>
-</div>
index 08b18bb6a91357c036d02aa07e09b1e15aca7594..d5e5c6ad34bd410b0d1aa729f6ddb4969af5122e 100644 (file)
@@ -54,9 +54,9 @@ export const body_class = 'bg-body-tertiary'
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#button-group">Button group</a></li>
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#card">Card</a></li>
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#carousel">Carousel</a></li>
+          <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#dialog">Dialog</a></li>
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#dropdowns">Dropdowns</a></li>
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#list-group">List group</a></li>
-          <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#modal">Modal</a></li>
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#navs">Navs</a></li>
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#navbar">Navbar</a></li>
           <li><a class="d-inline-flex align-items-center rounded text-decoration-none" href="#pagination">Pagination</a></li>
@@ -879,6 +879,23 @@ export const body_class = 'bg-body-tertiary'
         `} />
       </div>
     </article>
+    <article class="my-3" id="dialog">
+      <div class="bd-heading sticky-xl-top align-self-start mt-5 mb-3 mt-xl-0 mb-xl-2">
+        <h3>Dialog</h3>
+        <a class="d-flex align-items-center" href={getVersionedDocsPath('components/dialog')}>Documentation</a>
+      </div>
+
+      <div>
+        <Example showMarkup={false} code={`
+        <button type="button" class="btn btn-primary" data-bs-toggle="dialog" data-bs-target="#exampleDialog">
+          Launch demo dialog
+        </button>
+        <button type="button" class="btn btn-primary" data-bs-toggle="dialog" data-bs-target="#staticBackdropDialog">
+          Launch static backdrop dialog
+        </button>
+        `} />
+      </div>
+    </article>
     <article class="my-3" id="dropdowns">
       <div class="bd-heading sticky-xl-top align-self-start mt-5 mb-3 mt-xl-0 mb-xl-2">
         <h3>Dropdowns</h3>
@@ -1097,31 +1114,6 @@ export const body_class = 'bg-body-tertiary'
         `]} />
       </div>
     </article>
-    <article class="my-3" id="modal">
-      <div class="bd-heading sticky-xl-top align-self-start mt-5 mb-3 mt-xl-0 mb-xl-2">
-        <h3>Modal</h3>
-        <a class="d-flex align-items-center" href={getVersionedDocsPath('components/modal')}>Documentation</a>
-      </div>
-
-      <div>
-        <Example showMarkup={false} code={`
-        <div class="d-flex justify-content-between flex-wrap">
-          <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalDefault">
-            Launch demo modal
-          </button>
-          <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdropLive">
-            Launch static backdrop modal
-          </button>
-          <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalCenteredScrollable">
-            Vertically centered scrollable modal
-          </button>
-          <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalFullscreen">
-            Full screen
-          </button>
-        </div>
-        `} />
-      </div>
-    </article>
     <article class="my-3" id="navs">
       <div class="bd-heading sticky-xl-top align-self-start mt-5 mb-3 mt-xl-0 mb-xl-2">
         <h3>Navs</h3>
@@ -1490,73 +1482,30 @@ export const body_class = 'bg-body-tertiary'
   </section>
 </main>
 
-<div class="modal fade" id="exampleModalDefault" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-        <button type="button" class="btn btn-primary">Save changes</button>
-      </div>
-    </div>
+<dialog class="dialog" id="exampleDialog">
+  <div class="dialog-header">
+    <h1 class="dialog-title fs-5">Dialog title</h1>
+    <button type="button" class="btn-close" data-bs-dismiss="dialog" aria-label="Close"></button>
   </div>
-</div>
-<div class="modal fade" id="staticBackdropLive" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLiveLabel" aria-hidden="true">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="staticBackdropLiveLabel">Modal title</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        <p>I will not close if you click outside me. Don't even try to press escape key.</p>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-        <button type="button" class="btn btn-primary">Understood</button>
-      </div>
-    </div>
+  <div class="dialog-body">
+    <p>This is a native dialog element using Bootstrap's Dialog component.</p>
   </div>
-</div>
-<div class="modal fade" id="exampleModalCenteredScrollable" tabindex="-1" aria-labelledby="exampleModalCenteredScrollableTitle" aria-hidden="true">
-  <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="exampleModalCenteredScrollableTitle">Modal title</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        <p>This is some placeholder content to show the scrolling behavior for modals. We use repeated line breaks to demonstrate how content can exceed minimum inner height, thereby showing inner scrolling. When content becomes longer than the predefined max-height of modal, content will be cropped and scrollable within the modal.</p>
-        <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
-        <p>This content should appear at the bottom after you scroll.</p>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-        <button type="button" class="btn btn-primary">Save changes</button>
-      </div>
-    </div>
+  <div class="dialog-footer">
+    <button type="button" class="btn btn-secondary" data-bs-dismiss="dialog">Close</button>
+    <button type="button" class="btn btn-primary">Save changes</button>
   </div>
-</div>
-<div class="modal fade" id="exampleModalFullscreen" tabindex="-1" aria-labelledby="exampleModalFullscreenLabel" aria-hidden="true">
-  <div class="modal-dialog modal-fullscreen">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-4" id="exampleModalFullscreenLabel">Full screen modal</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-      </div>
-    </div>
-  </div>
-</div>
+</dialog>
 
+<dialog class="dialog" id="staticBackdropDialog" data-bs-backdrop="static" data-bs-keyboard="false">
+  <div class="dialog-header">
+    <h1 class="dialog-title fs-5">Static backdrop</h1>
+    <button type="button" class="btn-close" data-bs-dismiss="dialog" aria-label="Close"></button>
+  </div>
+  <div class="dialog-body">
+    <p>I will not close if you click outside of me. Use the close button or press Escape.</p>
+  </div>
+  <div class="dialog-footer">
+    <button type="button" class="btn btn-secondary" data-bs-dismiss="dialog">Close</button>
+    <button type="button" class="btn btn-primary">Understood</button>
+  </div>
+</dialog>
diff --git a/site/src/assets/examples/modals/index.astro b/site/src/assets/examples/modals/index.astro
deleted file mode 100644 (file)
index 9514f6f..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
----
-export const title = 'Modals'
-export const extra_css = ['modals.css']
----
-
-<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
-  <symbol id="bookmark-star" viewBox="0 0 16 16">
-    <path d="M7.84 4.1a.178.178 0 0 1 .32 0l.634 1.285a.178.178 0 0 0 .134.098l1.42.206c.145.021.204.2.098.303L9.42 6.993a.178.178 0 0 0-.051.158l.242 1.414a.178.178 0 0 1-.258.187l-1.27-.668a.178.178 0 0 0-.165 0l-1.27.668a.178.178 0 0 1-.257-.187l.242-1.414a.178.178 0 0 0-.05-.158l-1.03-1.001a.178.178 0 0 1 .098-.303l1.42-.206a.178.178 0 0 0 .134-.098L7.84 4.1z"/>
-    <path d="M2 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v13.5a.5.5 0 0 1-.777.416L8 13.101l-5.223 2.815A.5.5 0 0 1 2 15.5V2zm2-1a1 1 0 0 0-1 1v12.566l4.723-2.482a.5.5 0 0 1 .554 0L13 14.566V2a1 1 0 0 0-1-1H4z"/>
-  </symbol>
-
-  <symbol id="grid-fill" viewBox="0 0 16 16">
-    <path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zm8 0A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm-8 8A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm8 0A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3z"/>
-  </symbol>
-
-  <symbol id="film" viewBox="0 0 16 16">
-    <path d="M0 1a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V1zm4 0v6h8V1H4zm8 8H4v6h8V9zM1 1v2h2V1H1zm2 3H1v2h2V4zM1 7v2h2V7H1zm2 3H1v2h2v-2zm-2 3v2h2v-2H1zM15 1h-2v2h2V1zm-2 3v2h2V4h-2zm2 3h-2v2h2V7zm-2 3v2h2v-2h-2zm2 3h-2v2h2v-2z"/>
-  </symbol>
-
-  <symbol id="google" viewBox="0 0 16 16">
-    <path d="M15.545 6.558a9.4 9.4 0 0 1 .139 1.626c0 2.434-.87 4.492-2.384 5.885h.002C11.978 15.292 10.158 16 8 16A8 8 0 1 1 8 0a7.7 7.7 0 0 1 5.352 2.082l-2.284 2.284A4.35 4.35 0 0 0 8 3.166c-2.087 0-3.86 1.408-4.492 3.304a4.8 4.8 0 0 0 0 3.063h.003c.635 1.893 2.405 3.301 4.492 3.301 1.078 0 2.004-.276 2.722-.764h-.003a3.7 3.7 0 0 0 1.599-2.431H8v-3.08z"/>
-  </symbol>
-
-  <symbol id="github" viewBox="0 0 16 16">
-    <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/>
-  </symbol>
-
-  <symbol id="facebook" viewBox="0 0 16 16">
-    <path d="M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951z"/>
-  </symbol>
-</svg>
-
-<div class="modal modal-sheet position-static d-block bg-body-secondary p-4 py-md-5" tabindex="-1" role="dialog" id="modalSheet">
-  <div class="modal-dialog">
-    <div class="modal-content rounded-4 shadow">
-      <div class="modal-header border-bottom-0">
-        <h1 class="modal-title fs-5">Modal title</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body py-0">
-        <p>This is a modal sheet, a variation of the modal that docs itself to the bottom of the viewport like the newer share sheets in iOS.</p>
-      </div>
-      <div class="modal-footer flex-column align-items-stretch w-100 gap-2 pb-3 border-top-0">
-        <button type="button" class="btn btn-lg btn-primary">Save changes</button>
-        <button type="button" class="btn btn-lg btn-secondary" data-bs-dismiss="modal">Close</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="b-example-divider"></div>
-
-<div class="modal modal-sheet position-static d-block bg-body-secondary p-4 py-md-5" tabindex="-1" role="dialog" id="modalChoice">
-  <div class="modal-dialog">
-    <div class="modal-content rounded-3 shadow">
-      <div class="modal-body p-4 text-center">
-        <h5 class="mb-0">Enable this setting?</h5>
-        <p class="mb-0">You can always change your mind in your account settings.</p>
-      </div>
-      <div class="modal-footer flex-nowrap p-0">
-        <button type="button" class="btn btn-lg btn-link fs-6 text-decoration-none col-6 py-3 m-0 rounded-0 border-end"><strong>Yes, enable</strong></button>
-        <button type="button" class="btn btn-lg btn-link fs-6 text-decoration-none col-6 py-3 m-0 rounded-0" data-bs-dismiss="modal">No thanks</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="b-example-divider"></div>
-
-<div class="modal modal-sheet position-static d-block bg-body-secondary p-4 py-md-5" tabindex="-1" role="dialog" id="modalTour">
-  <div class="modal-dialog">
-    <div class="modal-content rounded-4 shadow">
-      <div class="modal-body p-5">
-        <h2 class="fw-bold mb-0">What's new</h2>
-
-        <ul class="d-grid gap-4 my-5 list-unstyled small">
-          <li class="d-flex gap-4">
-            <svg class="bi text-body-secondary flex-shrink-0" width="48" height="48" aria-hidden="true"><use xlink:href="#grid-fill"/></svg>
-            <div>
-              <h5 class="mb-0">Grid view</h5>
-              Not into lists? Try the new grid view.
-            </div>
-          </li>
-          <li class="d-flex gap-4">
-            <svg class="bi text-warning flex-shrink-0" width="48" height="48" aria-hidden="true"><use xlink:href="#bookmark-star"/></svg>
-            <div>
-              <h5 class="mb-0">Bookmarks</h5>
-              Save items you love for easy access later.
-            </div>
-          </li>
-          <li class="d-flex gap-4">
-            <svg class="bi text-primary flex-shrink-0" width="48" height="48" aria-hidden="true"><use xlink:href="#film"/></svg>
-            <div>
-              <h5 class="mb-0">Video embeds</h5>
-              Share videos wherever you go.
-            </div>
-          </li>
-        </ul>
-        <button type="button" class="btn btn-lg btn-primary mt-5 w-100" data-bs-dismiss="modal">Great, thanks!</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="b-example-divider"></div>
-
-<div class="modal modal-sheet position-static d-block bg-body-secondary p-4 py-md-5" tabindex="-1" role="dialog" id="modalSignin">
-  <div class="modal-dialog">
-    <div class="modal-content rounded-4 shadow">
-      <div class="modal-header p-5 pb-4 border-bottom-0">
-        <h1 class="fw-bold mb-0 fs-2">Sign up for free</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-
-      <div class="modal-body p-5 pt-0">
-        <form class="">
-          <div class="form-floating mb-3">
-            <input type="email" class="form-control rounded-3" id="floatingInput" placeholder="name@example.com">
-            <label for="floatingInput">Email address</label>
-          </div>
-          <div class="form-floating mb-3">
-            <input type="password" class="form-control rounded-3" id="floatingPassword" placeholder="Password">
-            <label for="floatingPassword">Password</label>
-          </div>
-          <button class="w-100 mb-2 btn btn-lg rounded-3 btn-primary" type="submit">Sign up</button>
-          <small class="text-body-secondary">By clicking Sign up, you agree to the terms of use.</small>
-          <hr class="my-4">
-          <h2 class="fs-5 fw-bold mb-3">Or use a third-party</h2>
-          <button class="w-100 py-2 mb-2 btn btn-outline-secondary rounded-3" type="submit">
-            <svg class="bi me-1" width="16" height="16" aria-hidden="true"><use xlink:href="#google"/></svg>
-            Sign up with Google
-          </button>
-          <button class="w-100 py-2 mb-2 btn btn-outline-primary rounded-3" type="submit">
-            <svg class="bi me-1" width="16" height="16" aria-hidden="true"><use xlink:href="#facebook"/></svg>
-            Sign up with Facebook
-          </button>
-          <button class="w-100 py-2 mb-2 btn btn-outline-secondary rounded-3" type="submit">
-            <svg class="bi me-1" width="16" height="16" aria-hidden="true"><use xlink:href="#github"/></svg>
-            Sign up with GitHub
-          </button>
-        </form>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="b-example-divider"></div>
diff --git a/site/src/assets/examples/modals/modals.css b/site/src/assets/examples/modals/modals.css
deleted file mode 100644 (file)
index 194e16a..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-.modal-sheet .modal-dialog {
-  width: 380px;
-  transition: bottom .75s ease-in-out;
-}
-.modal-sheet .modal-footer {
-  padding-bottom: 2rem;
-}
index 498071b415a2f23e0198bb32c26d992501b9a0e8..3be645a3ba27ed345b319ffe152837e6635fb606 100644 (file)
@@ -128,31 +128,6 @@ export default () => {
       })
     })
 
-  // -------------------------------
-  // Modal
-  // -------------------------------
-  // Modal 'Varying modal content' example in docs and StackBlitz
-  // js-docs-start varying-modal-content
-  const exampleModal = document.getElementById('exampleModal')
-  if (exampleModal) {
-    exampleModal.addEventListener('show.bs.modal', event => {
-      // Button that triggered the modal
-      const button = event.relatedTarget
-      // Extract info from data-bs-* attributes
-      const recipient = button.getAttribute('data-bs-whatever')
-      // If necessary, you could initiate an Ajax request here
-      // and then do the updating in a callback.
-
-      // Update the modal's content.
-      const modalTitle = exampleModal.querySelector('.modal-title')
-      const modalBodyInput = exampleModal.querySelector('.modal-body input')
-
-      modalTitle.textContent = `New message to ${recipient}`
-      modalBodyInput.value = recipient
-    })
-  }
-  // js-docs-end varying-modal-content
-
   // -------------------------------
   // Offcanvas
   // -------------------------------
index 236ac5a151d65cd3ef0529cd166cd7d053589ed3..e8afcbbb8fbec67190193b17b4c6e497868696e3 100644 (file)
@@ -13,7 +13,7 @@ const plugins = getData('plugins')
     </div>
     <h2 class="display-5 mb-3 fw-semibold lh-sm">Powerful JavaScript plugins without&nbsp;jQuery</h2>
     <p class="lead fw-normal">
-      Add toggleable hidden elements, modals and offcanvas menus, popovers and tooltips, and so much more—all without
+      Add toggleable hidden elements, dialogs and offcanvas menus, popovers and tooltips, and so much more—all without
       jQuery. Bootstrap's JavaScript is HTML-first, meaning most plugins are added with <code>data</code> attributes in your
       HTML. Need more control? Include individual plugins programmatically.
     </p>
diff --git a/site/src/content/docs/components/modal.mdx b/site/src/content/docs/components/modal.mdx
deleted file mode 100644 (file)
index 0f8b510..0000000
+++ /dev/null
@@ -1,827 +0,0 @@
----
-title: Modal
-description: Use Bootstrap’s JavaScript modal plugin to add dialogs to your site for lightboxes, user notifications, or completely custom content.
-toc: true
----
-
-## How it works
-
-Before getting started with Bootstrap’s modal component, be sure to read the following as our menu options have recently changed.
-
-- Modals are built with HTML, CSS, and JavaScript. They’re positioned over everything else in the document and remove scroll from the `<body>` so that modal content scrolls instead.
-- Clicking on the modal “backdrop” will automatically close the modal.
-- Bootstrap only supports one modal window at a time. Nested modals aren’t supported as we believe them to be poor user experiences.
-- Modals use `position: fixed`, which can sometimes be a bit particular about its rendering. Whenever possible, place your modal HTML in a top-level position to avoid potential interference from other elements. You’ll likely run into issues when nesting a `.modal` within another fixed element.
-- Once again, due to `position: fixed`, there are some caveats with using modals on mobile devices.
-- Due to how HTML5 defines its semantics, [the `autofocus` HTML attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-autofocus) has no effect in Bootstrap modals. To achieve the same effect, use some custom JavaScript:
-
-```js
-const myModal = document.getElementById('myModal')
-const myInput = document.getElementById('myInput')
-
-myModal.addEventListener('shown.bs.modal', () => {
-  myInput.focus()
-})
-```
-
-<Callout name="info-prefersreducedmotion" />
-
-Keep reading for demos and usage guidelines.
-
-## Examples
-
-### Modal components
-
-Below is a _static_ modal example (meaning its `position` and `display` have been overridden). Included are the modal header, modal body (required for `padding`), and modal footer (optional). We ask that you include modal headers with dismiss actions whenever possible, or provide another explicit dismiss action.
-
-<Example class="bg-1" code={`<div class="modal position-static d-block max-w-100" tabindex="-1">
-    <div class="modal-dialog">
-      <div class="modal-content">
-        <div class="modal-header">
-          <h5 class="modal-title">Modal title</h5>
-          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-        </div>
-        <div class="modal-body">
-          <p>Modal body text goes here.</p>
-        </div>
-        <div class="modal-footer">
-          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-          <button type="button" class="btn btn-primary">Save changes</button>
-        </div>
-      </div>
-    </div>
-  </div>`} customMarkup={`<div class="modal" tabindex="-1">
-    <div class="modal-dialog">
-      <div class="modal-content">
-        <div class="modal-header">
-          <h5 class="modal-title">Modal title</h5>
-          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-        </div>
-        <div class="modal-body">
-          <p>Modal body text goes here.</p>
-        </div>
-        <div class="modal-footer">
-          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-          <button type="button" class="btn btn-primary">Save changes</button>
-        </div>
-      </div>
-    </div>
-  </div>`} />
-
-<Callout>
-In the above static example, we use `<h5>`, to avoid issues with the heading hierarchy in the documentation page. Structurally, however, a modal dialog represents its own separate document/context, so the `.modal-title` should ideally be an `<h1>`. If necessary, you can use the [font size utilities]([[docsref:/utilities/font-size]]) to control the heading’s appearance. All the following live examples use this approach.
-</Callout>
-
-### Live demo
-
-Toggle a working modal demo by clicking the button below. It will slide down and fade in from the top of the page.
-
-<div class="modal fade" id="exampleModalLive" tabindex="-1" aria-labelledby="exampleModalLiveLabel" aria-hidden="true">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="exampleModalLiveLabel">Modal title</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        <p>Woo-hoo, you’re reading this text in a modal!</p>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-        <button type="button" class="btn btn-primary">Save changes</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<Example showMarkup={false} code={`
-<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalLive">Launch demo modal</button>
-`} />
-
-```html
-<!-- Button trigger modal -->
-<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
-  Launch demo modal
-</button>
-
-<!-- Modal -->
-<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-        <button type="button" class="btn btn-primary">Save changes</button>
-      </div>
-    </div>
-  </div>
-</div>
-```
-
-### Static backdrop
-
-When backdrop is set to static, the modal will not close when clicking outside of it. Click the button below to try it.
-
-<div class="modal fade" id="staticBackdropLive" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLiveLabel" aria-hidden="true">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="staticBackdropLiveLabel">Modal title</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        <p>I will not close if you click outside of me. Don’t even try to press escape key.</p>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-        <button type="button" class="btn btn-primary">Understood</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<Example showMarkup={false} code={`
-<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdropLive">Launch static backdrop modal</button>
-`} />
-
-```html
-<!-- Button trigger modal -->
-<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdrop">
-  Launch static backdrop modal
-</button>
-
-<!-- Modal -->
-<div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="staticBackdropLabel">Modal title</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-        <button type="button" class="btn btn-primary">Understood</button>
-      </div>
-    </div>
-  </div>
-</div>
-```
-
-### Scrolling long content
-
-When modals become too long for the user’s viewport or device, they scroll independent of the page itself. Try the demo below to see what we mean.
-
-<div class="modal fade" id="exampleModalLong" tabindex="-1" aria-labelledby="exampleModalLongTitle" aria-hidden="true">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="exampleModalLongTitle">Modal title</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body" style="min-height: 100vh">
-        <p>This is some placeholder content to show the scrolling behavior for modals. Instead of repeating the text in the modal, we use an inline style to set a minimum height, thereby extending the length of the overall modal and demonstrating the overflow scrolling. When content becomes longer than the height of the viewport, scrolling will move the modal as needed.</p>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-        <button type="button" class="btn btn-primary">Save changes</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<Example showMarkup={false} code={`
-<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalLong">Launch demo modal</button>
-`} />
-
-You can also create a scrollable modal that allows scrolling the modal body by adding `.modal-dialog-scrollable` to `.modal-dialog`.
-
-<div class="modal fade" id="exampleModalScrollable" tabindex="-1" aria-labelledby="exampleModalScrollableTitle" aria-hidden="true">
-  <div class="modal-dialog modal-dialog-scrollable">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="exampleModalScrollableTitle">Modal title</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        <p>This is some placeholder content to show the scrolling behavior for modals. We use repeated line breaks to demonstrate how content can exceed minimum inner height, thereby showing inner scrolling. When content becomes longer than the predefined max-height of modal, content will be cropped and scrollable within the modal.</p>
-        <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
-        <p>This content should appear at the bottom after you scroll.</p>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-        <button type="button" class="btn btn-primary">Save changes</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<Example showMarkup={false} code={`
-<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalScrollable">Launch demo modal</button>
-`} />
-
-```html
-<!-- Scrollable modal -->
-<div class="modal-dialog modal-dialog-scrollable">
-  ...
-</div>
-```
-
-### Vertically centered
-
-Add `.modal-dialog-centered` to `.modal-dialog` to vertically center the modal.
-
-<Example showMarkup={false} code={`<div class="modal fade" id="exampleModalCenter" tabindex="-1" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
-    <div class="modal-dialog modal-dialog-centered">
-      <div class="modal-content">
-        <div class="modal-header">
-          <h1 class="modal-title fs-5" id="exampleModalCenterTitle">Modal title</h1>
-          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-        </div>
-        <div class="modal-body">
-          <p>This is a vertically centered modal.</p>
-        </div>
-        <div class="modal-footer">
-          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-          <button type="button" class="btn btn-primary">Save changes</button>
-        </div>
-      </div>
-    </div>
-  </div>
-
-  <div class="modal fade" id="exampleModalCenteredScrollable" tabindex="-1" aria-labelledby="exampleModalCenteredScrollableTitle" aria-hidden="true">
-    <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
-      <div class="modal-content">
-        <div class="modal-header">
-          <h1 class="modal-title fs-5" id="exampleModalCenteredScrollableTitle">Modal title</h1>
-          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-        </div>
-        <div class="modal-body">
-          <p>This is some placeholder content to show a vertically centered modal. We’ve added some extra copy here to show how vertically centering the modal works when combined with scrollable modals. We also use some repeated line breaks to quickly extend the height of the content, thereby triggering the scrolling. When content becomes longer than the predefined max-height of modal, content will be cropped and scrollable within the modal.</p>
-          <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
-          <p>Just like that.</p>
-        </div>
-        <div class="modal-footer">
-          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-          <button type="button" class="btn btn-primary">Save changes</button>
-        </div>
-      </div>
-    </div>
-  </div>
-
-  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalCenter">Vertically centered modal</button>
-  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalCenteredScrollable">Vertically centered scrollable modal</button>`} />
-
-```html
-<!-- Vertically centered modal -->
-<div class="modal-dialog modal-dialog-centered">
-  ...
-</div>
-
-<!-- Vertically centered scrollable modal -->
-<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
-  ...
-</div>
-```
-
-### Tooltips and popovers
-
-[Tooltips]([[docsref:/components/tooltips]]) and [popovers]([[docsref:/components/popovers]]) can be placed within modals as needed. When modals are closed, any tooltips and popovers within are also automatically dismissed.
-
-<Example showMarkup={false} code={`<div class="modal fade" id="exampleModalPopovers" tabindex="-1" aria-labelledby="exampleModalPopoversLabel" aria-hidden="true">
-    <div class="modal-dialog">
-      <div class="modal-content">
-        <div class="modal-header">
-          <h1 class="modal-title fs-5" id="exampleModalPopoversLabel">Modal title</h1>
-          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-        </div>
-        <div class="modal-body">
-          <h2 class="fs-5">Popover in a modal</h2>
-          <p>This <button class="btn btn-secondary" data-bs-toggle="popover" title="Popover title" data-bs-content="Popover body content is set in this attribute." data-bs-container="#exampleModalPopovers">button</button> triggers a popover on click.</p>
-          <hr>
-          <h2 class="fs-5">Tooltips in a modal</h2>
-          <p><a href="#" data-bs-toggle="tooltip" title="Tooltip" data-bs-container="#exampleModalPopovers">This link</a> and <a href="#" data-bs-toggle="tooltip" title="Tooltip" data-bs-container="#exampleModalPopovers">that link</a> have tooltips on hover.</p>
-        </div>
-        <div class="modal-footer">
-          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-          <button type="button" class="btn btn-primary">Save changes</button>
-        </div>
-      </div>
-    </div>
-  </div>
-
-  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalPopovers">Launch demo modal</button>`} />
-
-```html
-<div class="modal-body">
-  <h2 class="fs-5">Popover in a modal</h2>
-  <p>This <button class="btn btn-secondary" data-bs-toggle="popover" title="Popover title" data-bs-content="Popover body content is set in this attribute.">button</button> triggers a popover on click.</p>
-  <hr>
-  <h2 class="fs-5">Tooltips in a modal</h2>
-  <p><a href="#" data-bs-toggle="tooltip" title="Tooltip">This link</a> and <a href="#" data-bs-toggle="tooltip" title="Tooltip">that link</a> have tooltips on hover.</p>
-</div>
-```
-
-### Using the grid
-
-Utilize the Bootstrap grid system within a modal by nesting `.container-fluid` within the `.modal-body`. Then, use the normal grid system classes as you would anywhere else.
-
-<div class="modal fade" id="gridSystemModal" tabindex="-1" aria-labelledby="gridModalLabel" aria-hidden="true">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-5" id="gridModalLabel">Grids in modals</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        <div class="container-fluid bd-example-row">
-          <div class="row">
-            <div class="col-md-4">.col-md-4</div>
-            <div class="col-md-4 ms-auto">.col-md-4 .ms-auto</div>
-          </div>
-          <div class="row">
-            <div class="col-md-3 ms-auto">.col-md-3 .ms-auto</div>
-            <div class="col-md-2 ms-auto">.col-md-2 .ms-auto</div>
-          </div>
-          <div class="row">
-            <div class="col-md-6 ms-auto">.col-md-6 .ms-auto</div>
-          </div>
-          <div class="row">
-            <div class="col-sm-9">
-              Level 1: .col-sm-9
-              <div class="row">
-                <div class="col-8 col-sm-6">
-                  Level 2: .col-8 .col-sm-6
-                </div>
-                <div class="col-4 col-sm-6">
-                  Level 2: .col-4 .col-sm-6
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-        <button type="button" class="btn btn-primary">Save changes</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<Example showMarkup={false} code={`
-<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#gridSystemModal">Launch demo modal</button>
-`} />
-
-```html
-<div class="modal-body">
-  <div class="container-fluid">
-    <div class="row">
-      <div class="col-md-4">.col-md-4</div>
-      <div class="col-md-4 ms-auto">.col-md-4 .ms-auto</div>
-    </div>
-    <div class="row">
-      <div class="col-md-3 ms-auto">.col-md-3 .ms-auto</div>
-      <div class="col-md-2 ms-auto">.col-md-2 .ms-auto</div>
-    </div>
-    <div class="row">
-      <div class="col-md-6 ms-auto">.col-md-6 .ms-auto</div>
-    </div>
-    <div class="row">
-      <div class="col-sm-9">
-        Level 1: .col-sm-9
-        <div class="row">
-          <div class="col-8 col-sm-6">
-            Level 2: .col-8 .col-sm-6
-          </div>
-          <div class="col-4 col-sm-6">
-            Level 2: .col-4 .col-sm-6
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</div>
-```
-
-### Varying modal content
-
-Have a bunch of buttons that all trigger the same modal with slightly different contents? Use `event.relatedTarget` and [HTML `data-bs-*` attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes) to vary the contents of the modal depending on which button was clicked.
-
-Below is a live demo followed by example HTML and JavaScript. For more information, [read the modal events docs](#events) for details on `relatedTarget`.
-
-<Example addStackblitzJs code={`<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal" data-bs-whatever="@mdo">Open modal for @mdo</button>
-  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal" data-bs-whatever="@fat">Open modal for @fat</button>
-  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal" data-bs-whatever="@getbootstrap">Open modal for @getbootstrap</button>
-
-  <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
-    <div class="modal-dialog">
-      <div class="modal-content">
-        <div class="modal-header">
-          <h1 class="modal-title fs-5" id="exampleModalLabel">New message</h1>
-          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-        </div>
-        <div class="modal-body">
-          <form>
-            <div class="mb-3">
-              <label for="recipient-name" class="col-form-label">Recipient:</label>
-              <input type="text" class="form-control" id="recipient-name">
-            </div>
-            <div class="mb-3">
-              <label for="message-text" class="col-form-label">Message:</label>
-              <textarea class="form-control" id="message-text"></textarea>
-            </div>
-          </form>
-        </div>
-        <div class="modal-footer">
-          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-          <button type="button" class="btn btn-primary">Send message</button>
-        </div>
-      </div>
-    </div>
-  </div>`} />
-
-<JsDocs name="varying-modal-content" file="site/src/assets/partials/snippets.js" />
-
-### Toggle between modals
-
-Toggle between multiple modals with some clever placement of the `data-bs-target` and `data-bs-toggle` attributes. For example, you could toggle a password reset modal from within an already open sign in modal. **Please note multiple modals cannot be open at the same time**—this method simply toggles between two separate modals.
-
-<Example code={`<div class="modal fade" id="exampleModalToggle" aria-hidden="true" aria-labelledby="exampleModalToggleLabel" tabindex="-1">
-    <div class="modal-dialog modal-dialog-centered">
-      <div class="modal-content">
-        <div class="modal-header">
-          <h1 class="modal-title fs-5" id="exampleModalToggleLabel">Modal 1</h1>
-          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-        </div>
-        <div class="modal-body">
-          Show a second modal and hide this one with the button below.
-        </div>
-        <div class="modal-footer">
-          <button class="btn btn-primary" data-bs-target="#exampleModalToggle2" data-bs-toggle="modal">Open second modal</button>
-        </div>
-      </div>
-    </div>
-  </div>
-  <div class="modal fade" id="exampleModalToggle2" aria-hidden="true" aria-labelledby="exampleModalToggleLabel2" tabindex="-1">
-    <div class="modal-dialog modal-dialog-centered">
-      <div class="modal-content">
-        <div class="modal-header">
-          <h1 class="modal-title fs-5" id="exampleModalToggleLabel2">Modal 2</h1>
-          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-        </div>
-        <div class="modal-body">
-          Hide this modal and show the first with the button below.
-        </div>
-        <div class="modal-footer">
-          <button class="btn btn-primary" data-bs-target="#exampleModalToggle" data-bs-toggle="modal">Back to first</button>
-        </div>
-      </div>
-    </div>
-  </div>
-  <button class="btn btn-primary" data-bs-target="#exampleModalToggle" data-bs-toggle="modal">Open first modal</button>`} />
-
-### Change animation
-
-The `$modal-fade-transform` variable determines the transform state of `.modal-dialog` before the modal fade-in animation, the `$modal-show-transform` variable determines the transform of `.modal-dialog` at the end of the modal fade-in animation.
-
-If you want for example a zoom-in animation, you can set `$modal-fade-transform: scale(.8)`.
-
-### Remove animation
-
-For modals that simply appear rather than fade in to view, remove the `.fade` class from your modal markup.
-
-```html
-<div class="modal" tabindex="-1" aria-labelledby="..." aria-hidden="true">
-  ...
-</div>
-```
-
-### Dynamic heights
-
-If the height of a modal changes while it is open, you should call `myModal.handleUpdate()` to readjust the modal’s position in case a scrollbar appears.
-
-### Accessibility
-
-Be sure to add `aria-labelledby="..."`, referencing the modal title, to `.modal`. Additionally, you may give a description of your modal dialog with `aria-describedby` on `.modal`. Note that you don’t need to add `role="dialog"` since we already add it via JavaScript.
-
-### Embedding YouTube videos
-
-Embedding YouTube videos in modals requires additional JavaScript not in Bootstrap to automatically stop playback and more. [See this helpful Stack Overflow post](https://stackoverflow.com/questions/18622508/bootstrap-3-and-youtube-in-modal) for more information.
-
-## Optional sizes
-
-Modals have three optional sizes, available via modifier classes to be placed on a `.modal-dialog`. These sizes kick in at certain breakpoints to avoid horizontal scrollbars on narrower viewports.
-
-<BsTable>
-| Size | Class | Modal max-width
-| --- | --- | --- |
-| Small | `.modal-sm` | `300px` |
-| Default | <span class="text-body-secondary">None</span> | `500px` |
-| Large | `.modal-lg` | `800px` |
-| Extra large | `.modal-xl` | `1200px` |
-</BsTable>
-
-Our default modal without modifier class constitutes the “medium” size modal.
-
-<Example showMarkup={false} code={`<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalXl">Extra large modal</button>
-  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalLg">Large modal</button>
-  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalSm">Small modal</button>`} />
-
-```html
-<div class="modal-dialog modal-xl">...</div>
-<div class="modal-dialog modal-lg">...</div>
-<div class="modal-dialog modal-sm">...</div>
-```
-
-<div class="modal fade" id="exampleModalXl" tabindex="-1" aria-labelledby="exampleModalXlLabel" aria-hidden="true">
-  <div class="modal-dialog modal-xl">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-4" id="exampleModalXlLabel">Extra large modal</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="modal fade" id="exampleModalLg" tabindex="-1" aria-labelledby="exampleModalLgLabel" aria-hidden="true">
-  <div class="modal-dialog modal-lg">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-4" id="exampleModalLgLabel">Large modal</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="modal fade" id="exampleModalSm" tabindex="-1" aria-labelledby="exampleModalSmLabel" aria-hidden="true">
-  <div class="modal-dialog modal-sm">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-4" id="exampleModalSmLabel">Small modal</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-    </div>
-  </div>
-</div>
-
-## Fullscreen Modal
-
-Another override is the option to pop up a modal that covers the user viewport, available via modifier classes that are placed on a `.modal-dialog`.
-
-<BsTable>
-| Class | Availability |
-| --- | --- |
-| `.modal-fullscreen` | Always |
-| `.modal-fullscreen-sm-down` | `576px` |
-| `.modal-fullscreen-md-down` | `768px` |
-| `.modal-fullscreen-lg-down` | `1024px` |
-| `.modal-fullscreen-xl-down` | `1280px` |
-| `.modal-fullscreen-2xl-down` | `1536px` |
-</BsTable>
-
-<Example showMarkup={false} code={`<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalFullscreen">Full screen</button>
-  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalFullscreenSm">Full screen below sm</button>
-  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalFullscreenMd">Full screen below md</button>
-  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalFullscreenLg">Full screen below lg</button>
-  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalFullscreenXl">Full screen below xl</button>
-  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalFullscreen2xl">Full screen below 2xl</button>`} />
-
-```html
-<!-- Full screen modal -->
-<div class="modal-dialog modal-fullscreen-sm-down">
-  ...
-</div>
-```
-
-<div class="modal fade" id="exampleModalFullscreen" tabindex="-1" aria-labelledby="exampleModalFullscreenLabel" aria-hidden="true">
-  <div class="modal-dialog modal-fullscreen">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-4" id="exampleModalFullscreenLabel">Full screen modal</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="modal fade" id="exampleModalFullscreenSm" tabindex="-1" aria-labelledby="exampleModalFullscreenSmLabel" aria-hidden="true">
-  <div class="modal-dialog modal-fullscreen-sm-down">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-4" id="exampleModalFullscreenSmLabel">Full screen below sm</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="modal fade" id="exampleModalFullscreenMd" tabindex="-1" aria-labelledby="exampleModalFullscreenMdLabel" aria-hidden="true">
-  <div class="modal-dialog modal-fullscreen-md-down">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-4" id="exampleModalFullscreenMdLabel">Full screen below md</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="modal fade" id="exampleModalFullscreenLg" tabindex="-1" aria-labelledby="exampleModalFullscreenLgLabel" aria-hidden="true">
-  <div class="modal-dialog modal-fullscreen-lg-down">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-4" id="exampleModalFullscreenLgLabel">Full screen below lg</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="modal fade" id="exampleModalFullscreenXl" tabindex="-1" aria-labelledby="exampleModalFullscreenXlLabel" aria-hidden="true">
-  <div class="modal-dialog modal-fullscreen-xl-down">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-4" id="exampleModalFullscreenXlLabel">Full screen below xl</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="modal fade" id="exampleModalFullscreen2xl" tabindex="-1" aria-labelledby="exampleModalFullscreen2xlLabel" aria-hidden="true">
-  <div class="modal-dialog modal-fullscreen-2xl-down">
-    <div class="modal-content">
-      <div class="modal-header">
-        <h1 class="modal-title fs-4" id="exampleModalFullscreen2xlLabel">Full screen below 2xl</h1>
-        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
-      </div>
-      <div class="modal-body">
-        ...
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
-      </div>
-    </div>
-  </div>
-</div>
-
-## CSS
-
-### Variables
-
-<CSSVariables component="Modals" className="modal" />
-
-<ScssDocs name="modal-css-vars" file="scss/_modal.scss" />
-
-<ScssDocs name="modal-backdrop-css-vars" file="scss/_modal.scss" />
-
-### Sass variables
-
-<ScssDocs name="modal-variables" file="scss/_variables.scss" />
-
-### Sass loops
-
-[Responsive fullscreen modals](#fullscreen-modal) are generated via the `$breakpoints` map and a loop in `scss/_modal.scss`.
-
-<ScssDocs name="modal-fullscreen-loop" file="scss/_modal.scss" />
-
-## Usage
-
-The modal plugin toggles your hidden content on demand, via data attributes or JavaScript. It also overrides default scrolling behavior and generates a `.modal-backdrop` to provide a click area for dismissing shown modals when clicking outside the modal.
-
-### Via data attributes
-
-#### Toggle
-
-Activate a modal without writing JavaScript. Set `data-bs-toggle="modal"` on a controller element, like a button, along with a `data-bs-target="#foo"` or `href="#foo"` to target a specific modal to toggle.
-
-```html
-<button type="button" data-bs-toggle="modal" data-bs-target="#myModal">Launch modal</button>
-```
-
-#### Dismiss
-
-<JsDismiss name="modal" />
-
-<Callout type="warning">
-While both ways to dismiss a modal are supported, keep in mind that dismissing from outside a modal does not match the [ARIA Authoring Practices Guide dialog (modal) pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/). Do this at your own risk.
-</Callout>
-
-### Via JavaScript
-
-Create a modal with a single line of JavaScript:
-
-```js
-const myModal = new bootstrap.Modal(document.getElementById('myModal'), options)
-// or
-const myModalAlternative = new bootstrap.Modal('#myModal', options)
-```
-
-### Options
-
-<JsDataAttributes />
-
-<BsTable>
-| Name | Type | Default | Description |
-| --- | --- | --- | --- |
-| `backdrop` | boolean, `’static'` | `true` | Includes a modal-backdrop element. Alternatively, specify `static` for a backdrop which doesn’t close the modal when clicked. |
-| `focus` | boolean | `true` | Puts the focus on the modal when initialized. |
-| `keyboard` | boolean | `true` | Closes the modal when escape key is pressed. |
-</BsTable>
-
-### Methods
-
-<Callout name="danger-async-methods" type="danger" />
-
-#### Passing options
-
-Activates your content as a modal. Accepts an optional options `object`.
-
-```js
-const myModal = new bootstrap.Modal('#myModal', {
-  keyboard: false
-})
-```
-
-<BsTable>
-| Method | Description |
-| --- | --- |
-| `dispose` | Destroys an element’s modal. (Removes stored data on the DOM element) |
-| `getInstance` | _Static_ method which allows you to get the modal instance associated with a DOM element. |
-| `getOrCreateInstance` | _Static_ method which allows you to get the modal instance associated with a DOM element, or create a new one in case it wasn’t initialized. |
-| `handleUpdate` | Manually readjust the modal’s position if the height of a modal changes while it is open (i.e. in case a scrollbar appears). |
-| `hide` | Manually hides a modal. **Returns to the caller before the modal has actually been hidden** (i.e. before the `hidden.bs.modal` event occurs). |
-| `show` | Manually opens a modal. **Returns to the caller before the modal has actually been shown** (i.e. before the `shown.bs.modal` event occurs). Also, you can pass a DOM element as an argument that can be received in the modal events (as the `relatedTarget` property). (i.e. `const modalToggle = document.getElementById('toggleMyModal'); myModal.show(modalToggle)`. |
-| `toggle` | Manually toggles a modal. **Returns to the caller before the modal has actually been shown or hidden** (i.e. before the `shown.bs.modal` or `hidden.bs.modal` event occurs). |
-</BsTable>
-
-### Events
-
-Bootstrap’s modal class exposes a few events for hooking into modal functionality. All modal events are fired at the modal itself (i.e. at the `<div class="modal">`).
-
-<BsTable>
-| Event | Description |
-| --- | --- |
-| `hide.bs.modal` | This event is fired immediately when the `hide` instance method has been called. Can be prevented by calling `event.preventDefault()`. See [JavaScript events documentation]([[docsref:/getting-started/javascript#events]]) for more details on event prevention. |
-| `hidden.bs.modal` | This event is fired when the modal has finished being hidden from the user (will wait for CSS transitions to complete). |
-| `hidePrevented.bs.modal` | This event is fired when the modal is shown, its backdrop is `static` and a click outside of the modal is performed. The event is also fired when the escape key is pressed and the `keyboard` option is set to `false`. |
-| `show.bs.modal` | This event fires immediately when the `show` instance method is called. If caused by a click, the clicked element is available as the `relatedTarget` property of the event. |
-| `shown.bs.modal` | This event is fired when the modal has been made visible to the user (will wait for CSS transitions to complete). If caused by a click, the clicked element is available as the `relatedTarget` property of the event. |
-</BsTable>
-
-```js
-const myModalEl = document.getElementById('myModal')
-myModalEl.addEventListener('hidden.bs.modal', event => {
-  // do something...
-})
-```
index 7ff1aec54c4478a2da230397b00060555166b285..f20873c0e3402f654dcc58bf7571610c3a41d7b4 100644 (file)
@@ -8,10 +8,10 @@ toc: true
 
 Offcanvas is a sidebar component that can be toggled via JavaScript to appear from the left, right, top, or bottom edge of the viewport. Buttons or anchors are used as triggers that are attached to specific elements you toggle, and `data` attributes are used to invoke our JavaScript.
 
-- Offcanvas shares some of the same JavaScript code as modals. Conceptually, they are quite similar, but they are separate plugins.
+- Offcanvas shares some of the same JavaScript code as dialogs. Conceptually, they are quite similar, but they are separate plugins.
 - Similarly, some [source Sass](#sass-variables) variables for offcanvas’s styles and dimensions are inherited from the modal’s variables.
 - When shown, offcanvas includes a default backdrop that can be clicked to hide the offcanvas.
-- Similar to modals, only one offcanvas can be shown at a time.
+- Similar to dialogs, only one offcanvas can be shown at a time.
 
 **Heads up!** Given how CSS handles animations, you cannot use `margin` or `translate` on an `.offcanvas` element. Instead, use the class as an independent wrapping element.
 
index f4430b2c496f025557a00540f5d137a19bb3e80c..8c5b5acbec5737c797f869a949f92c87fb9f89aa 100644 (file)
@@ -71,11 +71,11 @@ const popover = new bootstrap.Popover('.example-popover', {
 })
 ```
 
-Another situation where you’ll want to set an explicit custom `container` are popovers inside a [modal dialog]([[docsref:/components/modal]]), to make sure that the popover itself is appended to the modal. This is particularly important for popovers that contain interactive elements – modal dialogs will trap focus, so unless the popover is a child element of the modal, users won’t be able to focus or activate these interactive elements.
+Another situation where you’ll want to set an explicit custom `container` are popovers inside a [dialog]([[docsref:/components/dialog]]), to make sure that the popover itself is appended to the dialog. This is particularly important for popovers that contain interactive elements – dialogs will trap focus, so unless the popover is a child element of the dialog, users won’t be able to focus or activate these interactive elements.
 
 ```js
 const popover = new bootstrap.Popover('.example-popover', {
-  container: '.modal-body'
+  container: '.dialog-body'
 })
 ```
 
@@ -145,7 +145,7 @@ const popover = new bootstrap.Popover(exampleEl, options)
 
 Avoid adding an excessive amount of content in popovers with the `html` option. Once popovers are displayed, their content is tied to the trigger element with the `aria-describedby` attribute, causing all of the popover’s content to be announced to assistive technology users as one long, uninterrupted stream.
 
-Popovers do not manage keyboard focus order, and their placement can be random in the DOM, so be careful when adding interactive elements (like forms or links), as it may lead to an illogical focus order or make the popover content itself completely unreachable for keyboard users. In cases where you must use these elements, consider using a modal dialog instead.
+Popovers do not manage keyboard focus order, and their placement can be random in the DOM, so be careful when adding interactive elements (like forms or links), as it may lead to an illogical focus order or make the popover content itself completely unreachable for keyboard users. In cases where you must use these elements, consider using a dialog instead.
 </Callout>
 
 ### Options
index 5d89b9045a7294caa87e29e4fde042f8f4396039..b660a6569ef9ea18c57419b7d1fe2da3017610ce 100644 (file)
@@ -16,7 +16,7 @@ If you’re not using a component, comment it out or delete it entirely. For exa
 
 Bootstrap’s JavaScript includes every component in our primary dist files (`bootstrap.js` and `bootstrap.min.js`), and even our primary dependency (Popper) with our bundle files (`bootstrap.bundle.js` and `bootstrap.bundle.min.js`). While you’re customizing via Sass, be sure to remove related JavaScript.
 
-For instance, assuming you’re using your own JavaScript bundler like Webpack, Parcel, or Vite, you’d only import the JavaScript you plan on using. In the example below, we show how to just include our modal JavaScript:
+For instance, assuming you’re using your own JavaScript bundler like Webpack, Parcel, or Vite, you’d only import the JavaScript you plan on using. In the example below, we show how to just include our dialog JavaScript:
 
 ```js
 // Import just what we need
@@ -25,8 +25,8 @@ For instance, assuming you’re using your own JavaScript bundler like Webpack,
 // import 'bootstrap/js/dist/button';
 // import 'bootstrap/js/dist/carousel';
 // import 'bootstrap/js/dist/collapse';
+import 'bootstrap/js/dist/dialog';
 // import 'bootstrap/js/dist/dropdown';
-import 'bootstrap/js/dist/modal';
 // import 'bootstrap/js/dist/offcanvas';
 // import 'bootstrap/js/dist/popover';
 // import 'bootstrap/js/dist/scrollspy';
@@ -41,8 +41,8 @@ This way, you’re not including any JavaScript you don’t intend to use for co
 **Heads up!** Files in `bootstrap/js/dist` use the **default export**. To use them, do the following:
 
 ```js
-import Modal from 'bootstrap/js/dist/modal'
-const modal = new Modal(document.getElementById('myModal'))
+import Dialog from 'bootstrap/js/dist/dialog'
+const dialog = new Dialog(document.getElementById('myDialog'))
 ```
 </Callout>
 
index 3dc6f2cf90f232392732670001d7c5f73ef7bb08..59f08110f98218a82a2b2134a1c0c531dcb27c17 100644 (file)
@@ -112,7 +112,7 @@ Our dropdowns, popovers, and tooltips also depend on [Popper](https://popper.js.
 
 ## Data attributes
 
-Nearly all Bootstrap plugins can be enabled and configured through HTML alone with data attributes (our preferred way of using JavaScript functionality). Be sure to **only use one set of data attributes on a single element** (e.g., you cannot trigger a tooltip and modal from the same button.)
+Nearly all Bootstrap plugins can be enabled and configured through HTML alone with data attributes (our preferred way of using JavaScript functionality). Be sure to **only use one set of data attributes on a single element** (e.g., you cannot trigger a tooltip and dialog from the same button.)
 
 <JsDataAttributes />
 
@@ -127,10 +127,10 @@ Bootstrap provides custom events for most plugins’ unique actions. Generally,
 All infinitive events provide [`preventDefault()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault) functionality. This provides the ability to stop the execution of an action before it starts. Returning false from an event handler will also automatically call `preventDefault()`.
 
 ```js
-const myModal = document.querySelector('#myModal')
+const myDialog = document.querySelector('#myDialog')
 
-myModal.addEventListener('show.bs.modal', event => {
-  return event.preventDefault() // stops modal from being shown
+myDialog.addEventListener('show.bs.dialog', event => {
+  return event.preventDefault() // stops dialog from being shown
 })
 ```
 
@@ -139,11 +139,11 @@ myModal.addEventListener('show.bs.modal', event => {
 All constructors accept an optional options object or nothing (which initiates a plugin with its default behavior):
 
 ```js
-const myModalEl = document.querySelector('#myModal')
-const modal = new bootstrap.Modal(myModalEl) // initialized with defaults
+const myDialogEl = document.querySelector('#myDialog')
+const dialog = new bootstrap.Dialog(myDialogEl) // initialized with defaults
 
 const configObject = { keyboard: false }
-const modal1 = new bootstrap.Modal(myModalEl, configObject) // initialized with no keyboard
+const dialog1 = new bootstrap.Dialog(myDialogEl, configObject) // initialized with no keyboard
 ```
 
 If you’d like to get a particular plugin instance, each plugin exposes a `getInstance` method. For example, to retrieve an instance directly from an element:
@@ -167,7 +167,7 @@ In case an instance wasn’t initialized, it may accept and use an optional conf
 In addition to the `getInstance` and `getOrCreateInstance` methods, all plugin constructors can accept a DOM element or a valid [CSS selector](#selectors) as the first argument. Plugin elements are found with the `querySelector` method since our plugins only support a single element.
 
 ```js
-const modal = new bootstrap.Modal('#myModal')
+const dialog = new bootstrap.Dialog('#myDialog')
 const dropdown = new bootstrap.Dropdown('[data-bs-toggle="dropdown"]')
 const offcanvas = bootstrap.Offcanvas.getInstance('#myOffcanvas')
 const alert = bootstrap.Alert.getOrCreateInstance('#myAlert')
@@ -204,11 +204,12 @@ carousel.to('2') // !! Will be ignored, as the transition to the slide 1 is not
 While it may seem correct to use the `dispose` method immediately after `hide()`, it will lead to incorrect results. Here’s an example of the problem use:
 
 ```js
-const myModal = document.querySelector('#myModal')
-myModal.hide() // it is asynchronous
+const myToast = document.querySelector('#myToast')
+const toast = bootstrap.Toast.getInstance(myToast)
+toast.hide() // it is asynchronous
 
-myModal.addEventListener('shown.bs.hidden', event => {
-  myModal.dispose()
+myToast.addEventListener('hidden.bs.toast', event => {
+  toast.dispose()
 })
 ```
 
@@ -217,8 +218,8 @@ myModal.addEventListener('shown.bs.hidden', event => {
 You can change the default settings for a plugin by modifying the plugin’s `Constructor.Default` object:
 
 ```js
-// changes default for the modal plugin’s `keyboard` option to false
-bootstrap.Modal.Default.keyboard = false
+// changes default for the toast plugin’s `autohide` option to false
+bootstrap.Toast.Default.autohide = false
 ```
 
 ## Methods and properties
@@ -228,9 +229,9 @@ Every Bootstrap plugin exposes the following methods and static properties.
 <BsTable class="table">
 | Method | Description |
 | --- | --- |
-| `dispose` | Destroys an element’s modal. (Removes stored data on the DOM element) |
-| `getInstance` | *Static* method which allows you to get the modal instance associated with a DOM element. |
-| `getOrCreateInstance` | *Static* method which allows you to get the modal instance associated with a DOM element, or create a new one in case it wasn’t initialized. |
+| `dispose` | Destroys an element's plugin instance. (Removes stored data on the DOM element) |
+| `getInstance` | *Static* method which allows you to get the plugin instance associated with a DOM element. |
+| `getOrCreateInstance` | *Static* method which allows you to get the plugin instance associated with a DOM element, or create a new one in case it wasn’t initialized. |
 </BsTable>
 
 <BsTable class="table">
index 1be84f7700a1989cfde2fdcc432884b63bdb7d24..8e902ef6fa625f2238b26fc4de2cd8f0f0c4c72d 100644 (file)
@@ -22,7 +22,7 @@ We call these “low-level” `z-index` utilities because of their default value
 
 ## Overlays
 
-Bootstrap overlay components—dropdown, modal, offcanvas, popover, toast, and tooltip—all have their own `z-index` values to ensure a usable experience with competing “layers” of an interface.
+Bootstrap overlay components—dropdown, dialog, offcanvas, popover, toast, and tooltip—all have their own `z-index` values to ensure a usable experience with competing “layers” of an interface.
 
 Read about them in the [`z-index` layout page]([[docsref:/layout/z-index]]).