mirror of
https://github.com/twbs/bootstrap.git
synced 2025-08-14 17:44:15 +02:00
Add static backdrop to offcanvas (#35832)
* Add static backdrop option, to offcanvas * Trigger prevented event on esc with keyboard=false * Change offcanvas doc , moving backdrop examples to examples section
This commit is contained in:
@@ -39,6 +39,7 @@ const OPEN_SELECTOR = '.offcanvas.show'
|
||||
const EVENT_SHOW = `show${EVENT_KEY}`
|
||||
const EVENT_SHOWN = `shown${EVENT_KEY}`
|
||||
const EVENT_HIDE = `hide${EVENT_KEY}`
|
||||
const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`
|
||||
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
|
||||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
|
||||
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`
|
||||
@@ -52,7 +53,7 @@ const Default = {
|
||||
}
|
||||
|
||||
const DefaultType = {
|
||||
backdrop: 'boolean',
|
||||
backdrop: '(boolean|string)',
|
||||
keyboard: 'boolean',
|
||||
scroll: 'boolean'
|
||||
}
|
||||
@@ -164,12 +165,24 @@ class Offcanvas extends BaseComponent {
|
||||
|
||||
// Private
|
||||
_initializeBackDrop() {
|
||||
const clickCallback = () => {
|
||||
if (this._config.backdrop === 'static') {
|
||||
EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)
|
||||
return
|
||||
}
|
||||
|
||||
this.hide()
|
||||
}
|
||||
|
||||
// 'static' option will be translated to true, and booleans will keep their value
|
||||
const isVisible = Boolean(this._config.backdrop)
|
||||
|
||||
return new Backdrop({
|
||||
className: CLASS_NAME_BACKDROP,
|
||||
isVisible: this._config.backdrop,
|
||||
isVisible,
|
||||
isAnimated: true,
|
||||
rootElement: this._element.parentNode,
|
||||
clickCallback: () => this.hide()
|
||||
clickCallback: isVisible ? clickCallback : null
|
||||
})
|
||||
}
|
||||
|
||||
@@ -181,9 +194,16 @@ class Offcanvas extends BaseComponent {
|
||||
|
||||
_addEventListeners() {
|
||||
EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
|
||||
if (this._config.keyboard && event.key === ESCAPE_KEY) {
|
||||
this.hide()
|
||||
if (event.key !== ESCAPE_KEY) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!this._config.keyboard) {
|
||||
EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)
|
||||
return
|
||||
}
|
||||
|
||||
this.hide()
|
||||
})
|
||||
}
|
||||
|
||||
|
@@ -74,6 +74,21 @@ describe('Offcanvas', () => {
|
||||
expect(offCanvas.hide).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should hide if esc is pressed and backdrop is static', () => {
|
||||
fixtureEl.innerHTML = '<div class="offcanvas"></div>'
|
||||
|
||||
const offCanvasEl = fixtureEl.querySelector('.offcanvas')
|
||||
const offCanvas = new Offcanvas(offCanvasEl, { backdrop: 'static' })
|
||||
const keyDownEsc = createEvent('keydown')
|
||||
keyDownEsc.key = 'Escape'
|
||||
|
||||
spyOn(offCanvas, 'hide')
|
||||
|
||||
offCanvasEl.dispatchEvent(keyDownEsc)
|
||||
|
||||
expect(offCanvas.hide).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not hide if esc is not pressed', () => {
|
||||
fixtureEl.innerHTML = '<div class="offcanvas"></div>'
|
||||
|
||||
@@ -84,25 +99,61 @@ describe('Offcanvas', () => {
|
||||
|
||||
spyOn(offCanvas, 'hide')
|
||||
|
||||
document.dispatchEvent(keydownTab)
|
||||
offCanvasEl.dispatchEvent(keydownTab)
|
||||
|
||||
expect(offCanvas.hide).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not hide if esc is pressed but with keyboard = false', () => {
|
||||
fixtureEl.innerHTML = '<div class="offcanvas"></div>'
|
||||
return new Promise(resolve => {
|
||||
fixtureEl.innerHTML = '<div class="offcanvas"></div>'
|
||||
|
||||
const offCanvasEl = fixtureEl.querySelector('.offcanvas')
|
||||
const offCanvas = new Offcanvas(offCanvasEl, { keyboard: false })
|
||||
const keyDownEsc = createEvent('keydown')
|
||||
keyDownEsc.key = 'Escape'
|
||||
const offCanvasEl = fixtureEl.querySelector('.offcanvas')
|
||||
const offCanvas = new Offcanvas(offCanvasEl, { keyboard: false })
|
||||
const keyDownEsc = createEvent('keydown')
|
||||
keyDownEsc.key = 'Escape'
|
||||
|
||||
spyOn(offCanvas, 'hide')
|
||||
spyOn(offCanvas, 'hide')
|
||||
const hidePreventedSpy = jasmine.createSpy('hidePrevented')
|
||||
offCanvasEl.addEventListener('hidePrevented.bs.offcanvas', hidePreventedSpy)
|
||||
|
||||
document.dispatchEvent(keyDownEsc)
|
||||
offCanvasEl.addEventListener('shown.bs.offcanvas', () => {
|
||||
expect(offCanvas._config.keyboard).toBeFalse()
|
||||
offCanvasEl.dispatchEvent(keyDownEsc)
|
||||
|
||||
expect(offCanvas._config.keyboard).toBeFalse()
|
||||
expect(offCanvas.hide).not.toHaveBeenCalled()
|
||||
expect(hidePreventedSpy).toHaveBeenCalled()
|
||||
expect(offCanvas.hide).not.toHaveBeenCalled()
|
||||
resolve()
|
||||
})
|
||||
|
||||
offCanvas.show()
|
||||
})
|
||||
})
|
||||
|
||||
it('should not hide if user clicks on static backdrop', () => {
|
||||
return new Promise(resolve => {
|
||||
fixtureEl.innerHTML = '<div class="offcanvas"></div>'
|
||||
|
||||
const offCanvasEl = fixtureEl.querySelector('div')
|
||||
const offCanvas = new Offcanvas(offCanvasEl, { backdrop: 'static' })
|
||||
|
||||
const clickEvent = new Event('mousedown', { bubbles: true, cancelable: true })
|
||||
spyOn(offCanvas._backdrop._config, 'clickCallback').and.callThrough()
|
||||
spyOn(offCanvas._backdrop, 'hide').and.callThrough()
|
||||
const hidePreventedSpy = jasmine.createSpy('hidePrevented')
|
||||
offCanvasEl.addEventListener('hidePrevented.bs.offcanvas', hidePreventedSpy)
|
||||
|
||||
offCanvasEl.addEventListener('shown.bs.offcanvas', () => {
|
||||
expect(offCanvas._backdrop._config.clickCallback).toEqual(jasmine.any(Function))
|
||||
|
||||
offCanvas._backdrop._getElement().dispatchEvent(clickEvent)
|
||||
expect(hidePreventedSpy).toHaveBeenCalled()
|
||||
expect(offCanvas._backdrop.hide).not.toHaveBeenCalled()
|
||||
resolve()
|
||||
})
|
||||
|
||||
offCanvas.show()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
Reference in New Issue
Block a user