Skip to content

Commit

Permalink
backport #29516: added animation when modal backdrop is static
Browse files Browse the repository at this point in the history
  • Loading branch information
Johann-S authored and XhmikosR committed Nov 2, 2019
1 parent 29f5853 commit dd96b83
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 9 deletions.
37 changes: 29 additions & 8 deletions js/src/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}`,
Expand All @@ -56,7 +57,8 @@ const ClassName = {
BACKDROP : 'modal-backdrop',
OPEN : 'modal-open',
FADE : 'fade',
SHOW : 'show'
SHOW : 'show',
STATIC : 'modal-static'
}

const Selector = {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
22 changes: 22 additions & 0 deletions js/tests/unit/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
})
})
})
5 changes: 5 additions & 0 deletions scss/_modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions scss/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
65 changes: 64 additions & 1 deletion site/docs/4.3/components/modal.md
Original file line number Diff line number Diff line change
Expand Up @@ -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">&times;</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">&times;</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.
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>

Expand Down

0 comments on commit dd96b83

Please sign in to comment.