From 688bce4fa695cc360a0d084e34f029b0c192b223 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 22 Jun 2021 21:29:16 +0300 Subject: Release v5.0.2 (#34276) * Bump version to v5.0.2. * Dist --- js/src/modal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/modal.js') diff --git a/js/src/modal.js b/js/src/modal.js index 1d23b3d89..8dac75265 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -1,6 +1,6 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.1): modal.js + * Bootstrap (v5.0.2): modal.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ -- cgit v1.2.3 From dfafb9a60c5f15d341fc8992542aead014114058 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Mon, 19 Jul 2021 16:56:05 +0300 Subject: modal: change `data-dismiss` so that it can be outside of a modal using `bs-target` (#33403) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * change data-dismiss, so can be outside modal, using a bs-target * Update site/content/docs/5.0/components/modal.md Co-authored-by: Gaƫl Poupard --- js/src/modal.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'js/src/modal.js') diff --git a/js/src/modal.js b/js/src/modal.js index 8dac75265..0e8346d6f 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -62,6 +62,7 @@ const CLASS_NAME_FADE = 'fade' const CLASS_NAME_SHOW = 'show' const CLASS_NAME_STATIC = 'modal-static' +const SELECTOR = '.modal' const SELECTOR_DIALOG = '.modal-dialog' const SELECTOR_MODAL_BODY = '.modal-body' const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]' @@ -130,8 +131,6 @@ class Modal extends BaseComponent { this._setEscapeEvent() this._setResizeEvent() - EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, event => this.hide(event)) - EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => { EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, event => { if (event.target === this._element) { @@ -436,6 +435,13 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( data.toggle(this) }) +EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_DISMISS, function (event) { + const target = getElementFromSelector(this) || this.closest(SELECTOR) + const modal = Modal.getOrCreateInstance(target) + + modal.hide(event) +}) + /** * ------------------------------------------------------------------------ * jQuery -- cgit v1.2.3 From 7646f6bd33a03132e446fb060880bbf051a1639f Mon Sep 17 00:00:00 2001 From: Ryan Berliner <22206986+RyanBerliner@users.noreply.github.com> Date: Tue, 27 Jul 2021 01:01:04 -0400 Subject: Add shift-tab keyboard support for dialogs (modal & Offcanvas components) (#33865) * consolidate dialog focus trap logic * add shift-tab support to focustrap * remove redundant null check of trap element Co-authored-by: GeoSot * remove area support forom focusableChildren * fix no expectations warning in focustrap tests Co-authored-by: GeoSot Co-authored-by: XhmikosR --- js/src/modal.js | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) (limited to 'js/src/modal.js') diff --git a/js/src/modal.js b/js/src/modal.js index 0e8346d6f..53a3ccfd1 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -19,6 +19,7 @@ import SelectorEngine from './dom/selector-engine' import ScrollBarHelper from './util/scrollbar' import BaseComponent from './base-component' import Backdrop from './util/backdrop' +import FocusTrap from './util/focustrap' /** * ------------------------------------------------------------------------ @@ -49,7 +50,6 @@ 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_FOCUSIN = `focusin${EVENT_KEY}` const EVENT_RESIZE = `resize${EVENT_KEY}` const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}` const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}` @@ -81,6 +81,7 @@ class Modal extends BaseComponent { this._config = this._getConfig(config) this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element) this._backdrop = this._initializeBackDrop() + this._focustrap = this._initializeFocusTrap() this._isShown = false this._ignoreBackdropClick = false this._isTransitioning = false @@ -167,7 +168,7 @@ class Modal extends BaseComponent { this._setEscapeEvent() this._setResizeEvent() - EventHandler.off(document, EVENT_FOCUSIN) + this._focustrap.deactivate() this._element.classList.remove(CLASS_NAME_SHOW) @@ -182,14 +183,8 @@ class Modal extends BaseComponent { .forEach(htmlElement => EventHandler.off(htmlElement, EVENT_KEY)) this._backdrop.dispose() + this._focustrap.deactivate() super.dispose() - - /** - * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API` - * Do not move `document` in `htmlElements` array - * It will remove `EVENT_CLICK_DATA_API` event that should remain - */ - EventHandler.off(document, EVENT_FOCUSIN) } handleUpdate() { @@ -205,6 +200,12 @@ class Modal extends BaseComponent { }) } + _initializeFocusTrap() { + return new FocusTrap({ + trapElement: this._element + }) + } + _getConfig(config) { config = { ...Default, @@ -240,13 +241,9 @@ class Modal extends BaseComponent { this._element.classList.add(CLASS_NAME_SHOW) - if (this._config.focus) { - this._enforceFocus() - } - const transitionComplete = () => { if (this._config.focus) { - this._element.focus() + this._focustrap.activate() } this._isTransitioning = false @@ -258,17 +255,6 @@ class Modal extends BaseComponent { this._queueCallback(transitionComplete, this._dialog, isAnimated) } - _enforceFocus() { - EventHandler.off(document, EVENT_FOCUSIN) // guard against infinite focus loop - EventHandler.on(document, EVENT_FOCUSIN, event => { - if (document !== event.target && - this._element !== event.target && - !this._element.contains(event.target)) { - this._element.focus() - } - }) - } - _setEscapeEvent() { if (this._isShown) { EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => { -- cgit v1.2.3 From 4bfd8a2cbcb10610b4078cefa45756b4a96301a0 Mon Sep 17 00:00:00 2001 From: GeoSot Date: Wed, 28 Jul 2021 17:39:32 +0300 Subject: Use a streamlined way to trigger component dismiss (#34170) * use a streamlined way to trigger component dismiss * add documentation Co-authored-by: XhmikosR --- js/src/modal.js | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'js/src/modal.js') diff --git a/js/src/modal.js b/js/src/modal.js index 53a3ccfd1..bb8d97e48 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -20,6 +20,7 @@ import ScrollBarHelper from './util/scrollbar' import BaseComponent from './base-component' import Backdrop from './util/backdrop' import FocusTrap from './util/focustrap' +import { enableDismissTrigger } from './util/component-functions' /** * ------------------------------------------------------------------------ @@ -62,11 +63,9 @@ const CLASS_NAME_FADE = 'fade' const CLASS_NAME_SHOW = 'show' const CLASS_NAME_STATIC = 'modal-static' -const SELECTOR = '.modal' const SELECTOR_DIALOG = '.modal-dialog' const SELECTOR_MODAL_BODY = '.modal-body' const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]' -const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="modal"]' /** * ------------------------------------------------------------------------ @@ -143,11 +142,7 @@ class Modal extends BaseComponent { this._showBackdrop(() => this._showElement(relatedTarget)) } - hide(event) { - if (event && ['A', 'AREA'].includes(event.target.tagName)) { - event.preventDefault() - } - + hide() { if (!this._isShown || this._isTransitioning) { return } @@ -421,12 +416,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( data.toggle(this) }) -EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_DISMISS, function (event) { - const target = getElementFromSelector(this) || this.closest(SELECTOR) - const modal = Modal.getOrCreateInstance(target) - - modal.hide(event) -}) +enableDismissTrigger(Modal) /** * ------------------------------------------------------------------------ -- cgit v1.2.3