diff --git a/js/src/offcanvas.js b/js/src/offcanvas.js index 8d1feb13bb78..fb5f14c8b2d5 100644 --- a/js/src/offcanvas.js +++ b/js/src/offcanvas.js @@ -49,13 +49,15 @@ const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]' const Default = { backdrop: true, keyboard: true, - scroll: false + scroll: false, + focusAfterClose: true } const DefaultType = { backdrop: '(boolean|string)', keyboard: 'boolean', - scroll: 'boolean' + scroll: 'boolean', + focusAfterClose: 'boolean' } /** @@ -151,7 +153,9 @@ class Offcanvas extends BaseComponent { new ScrollBarHelper().reset() } - EventHandler.trigger(this._element, EVENT_HIDDEN) + EventHandler.trigger(this._element, EVENT_HIDDEN, { + focusAfterClose: this._config.focusAfterClose + }) } this._queueCallback(completeCallback, this._element, true) @@ -240,9 +244,9 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( return } - EventHandler.one(target, EVENT_HIDDEN, () => { + EventHandler.one(target, EVENT_HIDDEN, event => { // focus on trigger when it is closed - if (isVisible(this)) { + if (event.focusAfterClose && isVisible(this)) { this.focus() } }) diff --git a/js/tests/unit/offcanvas.spec.js b/js/tests/unit/offcanvas.spec.js index 3b6c98c1004c..0db3b8b08fdc 100644 --- a/js/tests/unit/offcanvas.spec.js +++ b/js/tests/unit/offcanvas.spec.js @@ -192,10 +192,11 @@ describe('Offcanvas', () => { expect(offCanvas._backdrop._config.isVisible).toBeTrue() expect(offCanvas._config.keyboard).toBeTrue() expect(offCanvas._config.scroll).toBeFalse() + expect(offCanvas._config.focusAfterClose).toBeTrue() }) it('should read data attributes and override default config', () => { - fixtureEl.innerHTML = '
' + fixtureEl.innerHTML = '' const offCanvasEl = fixtureEl.querySelector('.offcanvas') const offCanvas = new Offcanvas(offCanvasEl) @@ -204,20 +205,23 @@ describe('Offcanvas', () => { expect(offCanvas._backdrop._config.isVisible).toBeFalse() expect(offCanvas._config.keyboard).toBeFalse() expect(offCanvas._config.scroll).toBeTrue() + expect(offCanvas._config.focusAfterClose).toBeFalse() }) it('given a config object must override data attributes', () => { - fixtureEl.innerHTML = '' + fixtureEl.innerHTML = '' const offCanvasEl = fixtureEl.querySelector('.offcanvas') const offCanvas = new Offcanvas(offCanvasEl, { backdrop: true, keyboard: true, - scroll: false + scroll: false, + focusAfterClose: true }) expect(offCanvas._config.backdrop).toBeTrue() expect(offCanvas._config.keyboard).toBeTrue() expect(offCanvas._config.scroll).toBeFalse() + expect(offCanvas._config.focusAfterClose).toBeTrue() }) }) @@ -598,6 +602,28 @@ describe('Offcanvas', () => { offCanvas.hide() }) }) + + it('should not focus when focusAfterClose is disabled', () => { + return new Promise(resolve => { + fixtureEl.innerHTML = '' + + const offCanvasEl = fixtureEl.querySelector('div') + const offCanvas = new Offcanvas(offCanvasEl, { + focusAfterClose: false + }) + const spy = spyOn(offCanvas._focustrap, 'deactivate').and.callThrough() + offCanvas.show() + + offCanvasEl.addEventListener('hidden.bs.offcanvas', () => { + expect(spy).toHaveBeenCalled() + + // TODO HOW TO CHECK THAT THE TARGET-ELEMENT WAS NOT FOCUSED + resolve() + }) + + offCanvas.hide() + }) + }) }) describe('dispose', () => { diff --git a/site/content/docs/5.3/components/offcanvas.md b/site/content/docs/5.3/components/offcanvas.md index ac257df24226..458a70b1fc82 100644 --- a/site/content/docs/5.3/components/offcanvas.md +++ b/site/content/docs/5.3/components/offcanvas.md @@ -309,6 +309,7 @@ const offcanvasList = [...offcanvasElementList].map(offcanvasEl => new bootstrap | `backdrop` | boolean or the string `static` | `true` | Apply a backdrop on body while offcanvas is open. Alternatively, specify `static` for a backdrop which doesn't close the offcanvas when clicked. | | `keyboard` | boolean | `true` | Closes the offcanvas when escape key is pressed. | | `scroll` | boolean | `false` | Allow body scrolling while offcanvas is open. | +| `focusAfterClose` | boolean | `true` | Focus the offcanvas toggler after the offcanvas is closed. | {{< /bs-table >}} ### Methods