diff options
author | Laussel Loïc <loic.laussel@orange.com> | 2018-08-31 10:18:28 +0300 |
---|---|---|
committer | XhmikosR <xhmikosr@gmail.com> | 2018-11-13 09:47:32 +0300 |
commit | 4cac833447c53ec7f140c26260ddf36d78ff298f (patch) | |
tree | 7c7b0631c775c79a39949c10d7d9d0bea5761219 /js | |
parent | 2f81ab007cad06dd333a7431a3a653f812bbf246 (diff) |
Implement `data-dismiss="toast"` to allow user to interact itself with the component (#27155)
Diffstat (limited to 'js')
-rw-r--r-- | js/src/toast.js | 66 | ||||
-rw-r--r-- | js/tests/unit/toast.js | 29 | ||||
-rw-r--r-- | js/tests/visual/toast.html | 10 |
3 files changed, 82 insertions, 23 deletions
diff --git a/js/src/toast.js b/js/src/toast.js index cb6de974b5..1e70e091f2 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -22,10 +22,11 @@ const Toast = (($) => { const JQUERY_NO_CONFLICT = $.fn[NAME] const Event = { - HIDE : `hide${EVENT_KEY}`, - HIDDEN : `hidden${EVENT_KEY}`, - SHOW : `show${EVENT_KEY}`, - SHOWN : `shown${EVENT_KEY}` + CLICK_DISMISS : `click.dismiss${EVENT_KEY}`, + HIDE : `hide${EVENT_KEY}`, + HIDDEN : `hidden${EVENT_KEY}`, + SHOW : `show${EVENT_KEY}`, + SHOWN : `shown${EVENT_KEY}` } const ClassName = { @@ -49,6 +50,10 @@ const Toast = (($) => { } } + const Selector = { + DATA_DISMISS : '[data-dismiss="toast"]' + } + /** * ------------------------------------------------------------------------ * Class Definition @@ -60,6 +65,7 @@ const Toast = (($) => { this._element = element this._config = this._getConfig(config) this._timeout = null + this._setListeners() } // Getters @@ -104,30 +110,20 @@ const Toast = (($) => { }, this._config.delay.show) } - hide() { + hide(withoutTimeout) { if (!this._element.classList.contains(ClassName.SHOW)) { return } $(this._element).trigger(Event.HIDE) - const complete = () => { - $(this._element).trigger(Event.HIDDEN) + if (withoutTimeout) { + this._close() + } else { + this._timeout = setTimeout(() => { + this._close() + }, this._config.delay.hide) } - - this._timeout = setTimeout(() => { - this._element.classList.remove(ClassName.SHOW) - - if (this._config.animation) { - const transitionDuration = Util.getTransitionDurationFromElement(this._element) - - $(this._element) - .one(Util.TRANSITION_END, complete) - .emulateTransitionEnd(transitionDuration) - } else { - complete() - } - }, this._config.delay.hide) } dispose() { @@ -138,6 +134,8 @@ const Toast = (($) => { this._element.classList.remove(ClassName.SHOW) } + $(this._element).off(Event.CLICK_DISMISS) + $.removeData(this._element, DATA_KEY) this._element = null this._config = null @@ -168,6 +166,32 @@ const Toast = (($) => { return config } + _setListeners() { + $(this._element).on( + Event.CLICK_DISMISS, + Selector.DATA_DISMISS, + () => this.hide(true) + ) + } + + _close() { + const complete = () => { + $(this._element).trigger(Event.HIDDEN) + } + + this._element.classList.remove(ClassName.SHOW) + + if (this._config.animation) { + const transitionDuration = Util.getTransitionDurationFromElement(this._element) + + $(this._element) + .one(Util.TRANSITION_END, complete) + .emulateTransitionEnd(transitionDuration) + } else { + complete() + } + } + // Static static _jQueryInterface(config) { diff --git a/js/tests/unit/toast.js b/js/tests/unit/toast.js index 873661c76f..d9c5e1fb6e 100644 --- a/js/tests/unit/toast.js +++ b/js/tests/unit/toast.js @@ -232,4 +232,33 @@ $(function () { }) .bootstrapToast('show') }) + + + QUnit.test('should close toast when close element with data-dismiss attribute is set', function (assert) { + assert.expect(2) + var done = assert.async() + + var toastHtml = + '<div class="toast" data-delay="1" data-autohide="false" data-animation="false">' + + '<button type="button" class="ml-2 mb-1 close" data-dismiss="toast">' + + 'close' + + '</button>' + + '</div>' + + var $toast = $(toastHtml) + .bootstrapToast() + .appendTo($('#qunit-fixture')) + + $toast + .on('shown.bs.toast', function () { + assert.strictEqual($toast.hasClass('show'), true) + var button = $toast.find('.close') + button.trigger('click') + }) + .on('hidden.bs.toast', function () { + assert.strictEqual($toast.hasClass('show'), false) + done() + }) + .bootstrapToast('show') + }) }) diff --git a/js/tests/visual/toast.html b/js/tests/visual/toast.html index 6897022c06..902194617b 100644 --- a/js/tests/visual/toast.html +++ b/js/tests/visual/toast.html @@ -26,22 +26,28 @@ </div> <div class="notifications"> - <div id="toastAutoHide" class="toast"> + <div id="toastAutoHide" class="toast" role="alert" aria-live="assertive" aria-atomic="true"> <div class="toast-header"> <img class="rounded mr-2" data-src="holder.js/20x20?size=1&text=.&bg=#007aff" alt=""> <strong class="mr-auto">Bootstrap</strong> <small>11 mins ago</small> + <button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> </div> <div class="toast-body"> Hello, world! This is a toast message with <strong>autohide</strong> in 2 seconds </div> </div> - <div class="toast" data-autohide="false"> + <div class="toast" data-autohide="false" role="alert" aria-live="assertive" aria-atomic="true"> <div class="toast-header"> <img class="rounded mr-2" data-src="holder.js/20x20?size=1&text=.&bg=#007aff" alt=""> <strong class="mr-auto">Bootstrap</strong> <small class="text-muted">2 seconds ago</small> + <button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> </div> <div class="toast-body"> Heads up, toasts will stack automatically |