mirror of https://github.com/twbs/bootstrap.git
Added animation when modal backdrop is static (#29516)
This commit is contained in:
parent
9ee9b8a1e8
commit
46912797b2
|
@ -50,6 +50,7 @@ const DefaultType = {
|
||||||
|
|
||||||
const Event = {
|
const Event = {
|
||||||
HIDE: `hide${EVENT_KEY}`,
|
HIDE: `hide${EVENT_KEY}`,
|
||||||
|
HIDE_PREVENTED: `hidePrevented${EVENT_KEY}`,
|
||||||
HIDDEN: `hidden${EVENT_KEY}`,
|
HIDDEN: `hidden${EVENT_KEY}`,
|
||||||
SHOW: `show${EVENT_KEY}`,
|
SHOW: `show${EVENT_KEY}`,
|
||||||
SHOWN: `shown${EVENT_KEY}`,
|
SHOWN: `shown${EVENT_KEY}`,
|
||||||
|
@ -68,7 +69,8 @@ const ClassName = {
|
||||||
BACKDROP: 'modal-backdrop',
|
BACKDROP: 'modal-backdrop',
|
||||||
OPEN: 'modal-open',
|
OPEN: 'modal-open',
|
||||||
FADE: 'fade',
|
FADE: 'fade',
|
||||||
SHOW: 'show'
|
SHOW: 'show',
|
||||||
|
STATIC: 'modal-static'
|
||||||
}
|
}
|
||||||
|
|
||||||
const Selector = {
|
const Selector = {
|
||||||
|
@ -307,8 +309,7 @@ class Modal {
|
||||||
if (this._isShown && this._config.keyboard) {
|
if (this._isShown && this._config.keyboard) {
|
||||||
EventHandler.on(this._element, Event.KEYDOWN_DISMISS, event => {
|
EventHandler.on(this._element, Event.KEYDOWN_DISMISS, event => {
|
||||||
if (event.which === ESCAPE_KEYCODE) {
|
if (event.which === ESCAPE_KEYCODE) {
|
||||||
event.preventDefault()
|
this._triggerBackdropTransition()
|
||||||
this.hide()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -367,11 +368,7 @@ class Modal {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._config.backdrop === 'static') {
|
this._triggerBackdropTransition()
|
||||||
this._element.focus()
|
|
||||||
} else {
|
|
||||||
this.hide()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (animate) {
|
if (animate) {
|
||||||
|
@ -409,6 +406,25 @@ class Modal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_triggerBackdropTransition() {
|
||||||
|
if (this._config.backdrop === 'static') {
|
||||||
|
const hideEvent = EventHandler.trigger(this._element, Event.HIDE_PREVENTED)
|
||||||
|
if (hideEvent.defaultPrevented) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this._element.classList.add(ClassName.STATIC)
|
||||||
|
const modalTransitionDuration = getTransitionDurationFromElement(this._element)
|
||||||
|
EventHandler.one(this._element, TRANSITION_END, () => {
|
||||||
|
this._element.classList.remove(ClassName.STATIC)
|
||||||
|
})
|
||||||
|
emulateTransitionEnd(this._element, modalTransitionDuration)
|
||||||
|
this._element.focus()
|
||||||
|
} else {
|
||||||
|
this.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// the following methods are used to handle overflowing modals
|
// the following methods are used to handle overflowing modals
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
|
@ -540,6 +540,33 @@ describe('Modal', () => {
|
||||||
modal.show()
|
modal.show()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should not close modal when clicking outside of modal-content if backdrop = static', done => {
|
||||||
|
fixtureEl.innerHTML = '<div class="modal" data-backdrop="static" ><div class="modal-dialog" /></div>'
|
||||||
|
|
||||||
|
const modalEl = fixtureEl.querySelector('.modal')
|
||||||
|
const modal = new Modal(modalEl, {
|
||||||
|
backdrop: 'static'
|
||||||
|
})
|
||||||
|
|
||||||
|
const shownCallback = () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(modal._isShown).toEqual(true)
|
||||||
|
done()
|
||||||
|
}, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
modalEl.addEventListener('shown.bs.modal', () => {
|
||||||
|
modalEl.click()
|
||||||
|
shownCallback()
|
||||||
|
})
|
||||||
|
|
||||||
|
modalEl.addEventListener('hidden.bs.modal', () => {
|
||||||
|
throw new Error('Should not hide a modal')
|
||||||
|
})
|
||||||
|
|
||||||
|
modal.show()
|
||||||
|
})
|
||||||
|
|
||||||
it('should not adjust the inline body padding when it does not overflow', done => {
|
it('should not adjust the inline body padding when it does not overflow', done => {
|
||||||
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog" /></div>'
|
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog" /></div>'
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,11 @@
|
||||||
.modal.show & {
|
.modal.show & {
|
||||||
transform: $modal-show-transform;
|
transform: $modal-show-transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When trying to close, animate focus to scale
|
||||||
|
.modal.modal-static & {
|
||||||
|
transform: $modal-scale-transform;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-dialog-scrollable {
|
.modal-dialog-scrollable {
|
||||||
|
|
|
@ -1073,6 +1073,7 @@ $modal-sm: 300px !default;
|
||||||
$modal-fade-transform: translate(0, -50px) !default;
|
$modal-fade-transform: translate(0, -50px) !default;
|
||||||
$modal-show-transform: none !default;
|
$modal-show-transform: none !default;
|
||||||
$modal-transition: transform .3s ease-out !default;
|
$modal-transition: transform .3s ease-out !default;
|
||||||
|
$modal-scale-transform: scale(1.02) !default;
|
||||||
|
|
||||||
|
|
||||||
// Alerts
|
// Alerts
|
||||||
|
|
|
@ -140,6 +140,65 @@ Toggle a working modal demo by clicking the button below. It will slide down and
|
||||||
</div>
|
</div>
|
||||||
{{< /highlight >}}
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
### 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>
|
||||||
|
{{< /highlight >}}
|
||||||
|
|
||||||
|
|
||||||
### Scrolling long content
|
### 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.
|
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.
|
||||||
|
@ -753,7 +812,7 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
|
||||||
<td>backdrop</td>
|
<td>backdrop</td>
|
||||||
<td>boolean or the string <code>'static'</code></td>
|
<td>boolean or the string <code>'static'</code></td>
|
||||||
<td>true</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>
|
||||||
<tr>
|
<tr>
|
||||||
<td>keyboard</td>
|
<td>keyboard</td>
|
||||||
|
@ -859,6 +918,10 @@ Bootstrap's modal class exposes a few events for hooking into modal functionalit
|
||||||
<td>hidden.bs.modal</td>
|
<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>
|
<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>
|
||||||
|
<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>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue