mirror of
https://github.com/twbs/bootstrap.git
synced 2025-02-17 14:54:30 +01:00
backport #29516: added animation when modal backdrop is static
This commit is contained in:
parent
29f585365f
commit
dd96b832f7
@ -38,6 +38,7 @@ const DefaultType = {
|
||||
|
||||
const Event = {
|
||||
HIDE : `hide${EVENT_KEY}`,
|
||||
HIDE_PREVENTED : `hidePrevented${EVENT_KEY}`,
|
||||
HIDDEN : `hidden${EVENT_KEY}`,
|
||||
SHOW : `show${EVENT_KEY}`,
|
||||
SHOWN : `shown${EVENT_KEY}`,
|
||||
@ -56,7 +57,8 @@ const ClassName = {
|
||||
BACKDROP : 'modal-backdrop',
|
||||
OPEN : 'modal-open',
|
||||
FADE : 'fade',
|
||||
SHOW : 'show'
|
||||
SHOW : 'show',
|
||||
STATIC : 'modal-static'
|
||||
}
|
||||
|
||||
const Selector = {
|
||||
@ -234,6 +236,29 @@ class Modal {
|
||||
return config
|
||||
}
|
||||
|
||||
_triggerBackdropTransition() {
|
||||
if (this._config.backdrop === 'static') {
|
||||
const hideEventPrevented = $.Event(Event.HIDE_PREVENTED)
|
||||
|
||||
$(this._element).trigger(hideEventPrevented)
|
||||
if (hideEventPrevented.defaultPrevented) {
|
||||
return
|
||||
}
|
||||
|
||||
this._element.classList.add(ClassName.STATIC)
|
||||
|
||||
const modalTransitionDuration = Util.getTransitionDurationFromElement(this._element)
|
||||
|
||||
$(this._element).one(Util.TRANSITION_END, () => {
|
||||
this._element.classList.remove(ClassName.STATIC)
|
||||
})
|
||||
.emulateTransitionEnd(modalTransitionDuration)
|
||||
this._element.focus()
|
||||
} else {
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
|
||||
_showElement(relatedTarget) {
|
||||
const transition = $(this._element).hasClass(ClassName.FADE)
|
||||
const modalBody = this._dialog ? this._dialog.querySelector(Selector.MODAL_BODY) : null
|
||||
@ -303,8 +328,7 @@ class Modal {
|
||||
if (this._isShown && this._config.keyboard) {
|
||||
$(this._element).on(Event.KEYDOWN_DISMISS, (event) => {
|
||||
if (event.which === ESCAPE_KEYCODE) {
|
||||
event.preventDefault()
|
||||
this.hide()
|
||||
this._triggerBackdropTransition()
|
||||
}
|
||||
})
|
||||
} else if (!this._isShown) {
|
||||
@ -362,11 +386,8 @@ class Modal {
|
||||
if (event.target !== event.currentTarget) {
|
||||
return
|
||||
}
|
||||
if (this._config.backdrop === 'static') {
|
||||
this._element.focus()
|
||||
} else {
|
||||
this.hide()
|
||||
}
|
||||
|
||||
this._triggerBackdropTransition()
|
||||
})
|
||||
|
||||
if (animate) {
|
||||
|
@ -833,4 +833,26 @@ $(function () {
|
||||
})
|
||||
.bootstrapModal('show')
|
||||
})
|
||||
|
||||
QUnit.test('should not close modal when clicking outside of modal-content if backdrop = static', function (assert) {
|
||||
assert.expect(1)
|
||||
var done = assert.async()
|
||||
var $modal = $('<div class="modal" data-backdrop="static"><div class="modal-dialog" /></div>').appendTo('#qunit-fixture')
|
||||
|
||||
$modal.on('shown.bs.modal', function () {
|
||||
$modal.trigger('click')
|
||||
setTimeout(function () {
|
||||
var modal = $modal.data('bs.modal')
|
||||
|
||||
assert.strictEqual(modal._isShown, true)
|
||||
done()
|
||||
}, 10)
|
||||
})
|
||||
.on('hidden.bs.modal', function () {
|
||||
assert.strictEqual(true, false, 'should not hide the modal')
|
||||
})
|
||||
.bootstrapModal({
|
||||
backdrop: 'static'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -48,6 +48,11 @@
|
||||
.modal.show & {
|
||||
transform: $modal-show-transform;
|
||||
}
|
||||
|
||||
// When trying to close, animate focus to scale
|
||||
.modal.modal-static & {
|
||||
transform: $modal-scale-transform;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-dialog-scrollable {
|
||||
|
@ -976,6 +976,7 @@ $modal-sm: 300px !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;
|
||||
|
||||
|
||||
// Alerts
|
||||
|
@ -135,6 +135,65 @@ Toggle a working modal demo by clicking the button below. It will slide down and
|
||||
</div>
|
||||
{% endhighlight %}
|
||||
|
||||
### Static backdrop
|
||||
|
||||
When backdrop is set to static, the modal will not close when clicking outside it. Click the button below to try it.
|
||||
|
||||
<div id="staticBackdropLive" class="modal fade" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="staticBackdropLiveLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="staticBackdropLiveLabel">Modal title</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</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-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary">Understood</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bd-example">
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#staticBackdropLive">
|
||||
Launch static backdrop modal
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{% highlight html %}
|
||||
<!-- Button trigger modal -->
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#staticBackdrop">
|
||||
Launch static backdrop modal
|
||||
</button>
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="staticBackdrop" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="staticBackdropLabel">Modal title</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
...
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary">Understood</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
### 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.
|
||||
@ -743,7 +802,7 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
|
||||
<td>backdrop</td>
|
||||
<td>boolean or the string <code>'static'</code></td>
|
||||
<td>true</td>
|
||||
<td>Includes a modal-backdrop element. Alternatively, specify <code>static</code> for a backdrop which doesn't close the modal on click.</td>
|
||||
<td>Includes a modal-backdrop element. Alternatively, specify <code>static</code> for a backdrop which doesn't close the modal on click or on escape key press.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>keyboard</td>
|
||||
@ -836,6 +895,10 @@ Bootstrap's modal class exposes a few events for hooking into modal functionalit
|
||||
<td>hidden.bs.modal</td>
|
||||
<td>This event is fired when the modal has finished being hidden from the user (will wait for CSS transitions to complete).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>hidePrevented.bs.modal</td>
|
||||
<td>This event is fired when the modal is shown, its backdrop is <code>static</code> and a click outside the modal or a scape key press is performed.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user