Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/bootstrap.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Berliner <22206986+RyanBerliner@users.noreply.github.com>2021-05-11 08:37:57 +0300
committerGitHub <noreply@github.com>2021-05-11 08:37:57 +0300
commit9c3ab6557ec89ae11cc27da1b4680b3e69381edf (patch)
treef311d6d71a6729bc29137d25b55f30853f17cde4 /js/src/toast.js
parentc3ad760cd7f7d8c5be80ec067338a9c526679604 (diff)
Prevent toast autohiding if focusing or hovering (#33221)
Diffstat (limited to 'js/src/toast.js')
-rw-r--r--js/src/toast.js57
1 files changed, 52 insertions, 5 deletions
diff --git a/js/src/toast.js b/js/src/toast.js
index c8539b3a96..94a9084ce5 100644
--- a/js/src/toast.js
+++ b/js/src/toast.js
@@ -26,6 +26,10 @@ const DATA_KEY = 'bs.toast'
const EVENT_KEY = `.${DATA_KEY}`
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`
+const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`
+const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`
+const EVENT_FOCUSIN = `focusin${EVENT_KEY}`
+const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`
const EVENT_HIDE = `hide${EVENT_KEY}`
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
const EVENT_SHOW = `show${EVENT_KEY}`
@@ -62,6 +66,8 @@ class Toast extends BaseComponent {
this._config = this._getConfig(config)
this._timeout = null
+ this._hasMouseInteraction = false
+ this._hasKeyboardInteraction = false
this._setListeners()
}
@@ -100,11 +106,7 @@ class Toast extends BaseComponent {
EventHandler.trigger(this._element, EVENT_SHOWN)
- if (this._config.autohide) {
- this._timeout = setTimeout(() => {
- this.hide()
- }, this._config.delay)
- }
+ this._maybeScheduleHide()
}
this._element.classList.remove(CLASS_NAME_HIDE)
@@ -159,8 +161,53 @@ class Toast extends BaseComponent {
return config
}
+ _maybeScheduleHide() {
+ if (!this._config.autohide) {
+ return
+ }
+
+ if (this._hasMouseInteraction || this._hasKeyboardInteraction) {
+ return
+ }
+
+ this._timeout = setTimeout(() => {
+ this.hide()
+ }, this._config.delay)
+ }
+
+ _onInteraction(event, isInteracting) {
+ switch (event.type) {
+ case 'mouseover':
+ case 'mouseout':
+ this._hasMouseInteraction = isInteracting
+ break
+ case 'focusin':
+ case 'focusout':
+ this._hasKeyboardInteraction = isInteracting
+ break
+ default:
+ break
+ }
+
+ if (isInteracting) {
+ this._clearTimeout()
+ return
+ }
+
+ const nextElement = event.relatedTarget
+ if (this._element === nextElement || this._element.contains(nextElement)) {
+ return
+ }
+
+ this._maybeScheduleHide()
+ }
+
_setListeners() {
EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide())
+ EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true))
+ EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false))
+ EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true))
+ EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false))
}
_clearTimeout() {