1
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-08-12 00:24:03 +02:00

Implement data-dismiss="toast" to allow user to interact itself with the component (#27155)

This commit is contained in:
Laussel Loïc
2018-08-31 09:18:28 +02:00
committed by XhmikosR
parent 2f81ab007c
commit 4cac833447
4 changed files with 117 additions and 32 deletions

View File

@@ -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) {

View File

@@ -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')
})
})

View File

@@ -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">&times;</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">&times;</span>
</button>
</div>
<div class="toast-body">
Heads up, toasts will stack automatically