mirror of https://github.com/twbs/bootstrap.git
Merge 9ee6617dfe
into 4c98145482
This commit is contained in:
commit
66f9445ed2
|
@ -34,7 +34,7 @@
|
|||
},
|
||||
{
|
||||
"path": "./dist/js/bootstrap.bundle.js",
|
||||
"maxSize": "43.0 kB"
|
||||
"maxSize": "43.25 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/bootstrap.bundle.min.js",
|
||||
|
|
|
@ -174,6 +174,12 @@ class Offcanvas extends BaseComponent {
|
|||
this.hide()
|
||||
}
|
||||
|
||||
const keydownCallback = event => {
|
||||
if (event.key === ESCAPE_KEY) {
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
|
||||
// 'static' option will be translated to true, and booleans will keep their value
|
||||
const isVisible = Boolean(this._config.backdrop)
|
||||
|
||||
|
@ -182,7 +188,8 @@ class Offcanvas extends BaseComponent {
|
|||
isVisible,
|
||||
isAnimated: true,
|
||||
rootElement: this._element.parentNode,
|
||||
clickCallback: isVisible ? clickCallback : null
|
||||
clickCallback: isVisible ? clickCallback : null,
|
||||
keydownCallback: this._config.keyboard ? keydownCallback : null
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ import {
|
|||
const NAME = 'backdrop'
|
||||
const CLASS_NAME_FADE = 'fade'
|
||||
const CLASS_NAME_SHOW = 'show'
|
||||
const EVENT_KEY = `.bs.${NAME}`
|
||||
const EVENT_KEYDOWN = `keydown.bs.${NAME}`
|
||||
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME}`
|
||||
|
||||
const Default = {
|
||||
|
@ -25,6 +27,7 @@ const Default = {
|
|||
clickCallback: null,
|
||||
isAnimated: false,
|
||||
isVisible: true, // if false, we use the backdrop helper without adding any element to the dom
|
||||
keydownCallback: null,
|
||||
rootElement: 'body' // give the choice to place backdrop under different elements
|
||||
}
|
||||
|
||||
|
@ -33,6 +36,7 @@ const DefaultType = {
|
|||
clickCallback: '(function|null)',
|
||||
isAnimated: 'boolean',
|
||||
isVisible: 'boolean',
|
||||
keydownCallback: '(function|null)',
|
||||
rootElement: '(element|string)'
|
||||
}
|
||||
|
||||
|
@ -101,7 +105,7 @@ class Backdrop extends Config {
|
|||
return
|
||||
}
|
||||
|
||||
EventHandler.off(this._element, EVENT_MOUSEDOWN)
|
||||
EventHandler.off(this._element, EVENT_KEY)
|
||||
|
||||
this._element.remove()
|
||||
this._isAppended = false
|
||||
|
@ -140,6 +144,12 @@ class Backdrop extends Config {
|
|||
execute(this._config.clickCallback)
|
||||
})
|
||||
|
||||
if (this._config.keydownCallback) {
|
||||
EventHandler.on(document, EVENT_KEYDOWN, event => {
|
||||
execute(this._config.keydownCallback, [event])
|
||||
})
|
||||
}
|
||||
|
||||
this._isAppended = true
|
||||
}
|
||||
|
||||
|
|
|
@ -158,6 +158,74 @@ describe('Offcanvas', () => {
|
|||
})
|
||||
})
|
||||
|
||||
it('should hide if backdrop is static and esc key is pressed on document', () => {
|
||||
return new Promise(resolve => {
|
||||
fixtureEl.innerHTML = '<div class="offcanvas"></div>'
|
||||
|
||||
const offCanvasEl = fixtureEl.querySelector('div')
|
||||
const offCanvas = new Offcanvas(offCanvasEl, { backdrop: 'static' })
|
||||
|
||||
const keydownEscEvent = createEvent('keydown')
|
||||
keydownEscEvent.key = 'Escape'
|
||||
|
||||
const spyHide = spyOn(offCanvas, 'hide')
|
||||
|
||||
offCanvasEl.addEventListener('shown.bs.offcanvas', () => {
|
||||
document.dispatchEvent(keydownEscEvent)
|
||||
expect(spyHide).toHaveBeenCalled()
|
||||
resolve()
|
||||
})
|
||||
|
||||
offCanvas.show()
|
||||
})
|
||||
})
|
||||
|
||||
it('should not hide if backdrop is static and esc key is pressed on document but keyboard = false', () => {
|
||||
return new Promise(resolve => {
|
||||
fixtureEl.innerHTML = '<div class="offcanvas"></div>'
|
||||
|
||||
const offCanvasEl = fixtureEl.querySelector('div')
|
||||
const offCanvas = new Offcanvas(offCanvasEl, { backdrop: 'static', keyboard: false })
|
||||
|
||||
const keydownEscEvent = createEvent('keydown')
|
||||
keydownEscEvent.key = 'Escape'
|
||||
|
||||
const spyHide = spyOn(offCanvas, 'hide')
|
||||
|
||||
offCanvasEl.addEventListener('shown.bs.offcanvas', () => {
|
||||
expect(offCanvas._config.keyboard).toBeFalse()
|
||||
|
||||
document.dispatchEvent(keydownEscEvent)
|
||||
expect(spyHide).not.toHaveBeenCalled()
|
||||
resolve()
|
||||
})
|
||||
|
||||
offCanvas.show()
|
||||
})
|
||||
})
|
||||
|
||||
it('should not hide if backdrop is static but key other than esc is pressed on document', () => {
|
||||
return new Promise(resolve => {
|
||||
fixtureEl.innerHTML = '<div class="offcanvas"></div>'
|
||||
|
||||
const offCanvasEl = fixtureEl.querySelector('div')
|
||||
const offCanvas = new Offcanvas(offCanvasEl, { backdrop: 'static' })
|
||||
|
||||
const keydownEvent = createEvent('keydown')
|
||||
keydownEvent.key = 'Tab'
|
||||
|
||||
const spyHide = spyOn(offCanvas, 'hide')
|
||||
|
||||
offCanvasEl.addEventListener('shown.bs.offcanvas', () => {
|
||||
document.dispatchEvent(keydownEvent)
|
||||
expect(spyHide).not.toHaveBeenCalled()
|
||||
resolve()
|
||||
})
|
||||
|
||||
offCanvas.show()
|
||||
})
|
||||
})
|
||||
|
||||
it('should call `hide` on resize, if element\'s position is not fixed any more', () => {
|
||||
return new Promise(resolve => {
|
||||
fixtureEl.innerHTML = '<div class="offcanvas-lg"></div>'
|
||||
|
|
|
@ -191,6 +191,32 @@ describe('Backdrop', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('keydown callback', () => {
|
||||
it('should execute keydown callback on keydown event', () => {
|
||||
return new Promise(resolve => {
|
||||
const spy = jasmine.createSpy('spy')
|
||||
|
||||
const instance = new Backdrop({
|
||||
isVisible: true,
|
||||
isAnimated: false,
|
||||
keydownCallback: () => spy()
|
||||
})
|
||||
const endTest = () => {
|
||||
setTimeout(() => {
|
||||
expect(spy).toHaveBeenCalled()
|
||||
resolve()
|
||||
}, 10)
|
||||
}
|
||||
|
||||
instance.show(() => {
|
||||
const keydownEvent = new Event('keydown', { bubbles: true, cancelable: true })
|
||||
document.querySelector(CLASS_BACKDROP).dispatchEvent(keydownEvent)
|
||||
endTest()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('animation callbacks', () => {
|
||||
it('should show and hide backdrop after counting transition duration if it is animated', () => {
|
||||
return new Promise(resolve => {
|
||||
|
|
Loading…
Reference in New Issue