From d5200bc7a0e45da33c708c054dca0671cc578da0 Mon Sep 17 00:00:00 2001 From: Xcreen Date: Wed, 12 Jun 2024 15:06:48 +0200 Subject: [PATCH 1/6] Added option to disable scrolling after closing the offcanvas --- js/src/offcanvas.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/js/src/offcanvas.js b/js/src/offcanvas.js index 8d1feb13bb78..0369ab657a35 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, + scrollAfterClose: true } const DefaultType = { backdrop: '(boolean|string)', keyboard: 'boolean', - scroll: 'boolean' + scroll: 'boolean', + scrollAfterClose: 'boolean' } /** @@ -151,7 +153,9 @@ class Offcanvas extends BaseComponent { new ScrollBarHelper().reset() } - EventHandler.trigger(this._element, EVENT_HIDDEN) + if (this._config.scrollAfterClose) { + EventHandler.trigger(this._element, EVENT_HIDDEN) + } } this._queueCallback(completeCallback, this._element, true) From 3f39532629ffef2142e521e20d403e122acbc2d9 Mon Sep 17 00:00:00 2001 From: Xcreen Date: Wed, 12 Jun 2024 15:14:30 +0200 Subject: [PATCH 2/6] Added new scrollAfterClose-Option to the documentation --- site/content/docs/5.3/components/offcanvas.md | 1 + 1 file changed, 1 insertion(+) diff --git a/site/content/docs/5.3/components/offcanvas.md b/site/content/docs/5.3/components/offcanvas.md index ac257df24226..96ec5d160f39 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. | +| `scrollAfterClose` | boolean | `true` | Scroll to the offcanvas toggler after the offcanvas is closed. | {{< /bs-table >}} ### Methods From a311f09d2d54d39a8a30ec90845cf0fa53eede04 Mon Sep 17 00:00:00 2001 From: Xcreen Date: Mon, 17 Jun 2024 17:11:29 +0200 Subject: [PATCH 3/6] Renamed option scrollAfterClose to focusAfterClose --- js/src/offcanvas.js | 6 +++--- site/content/docs/5.3/components/offcanvas.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/js/src/offcanvas.js b/js/src/offcanvas.js index 0369ab657a35..0c37dd75ba77 100644 --- a/js/src/offcanvas.js +++ b/js/src/offcanvas.js @@ -50,14 +50,14 @@ const Default = { backdrop: true, keyboard: true, scroll: false, - scrollAfterClose: true + focusAfterClose: true } const DefaultType = { backdrop: '(boolean|string)', keyboard: 'boolean', scroll: 'boolean', - scrollAfterClose: 'boolean' + focusAfterClose: 'boolean' } /** @@ -153,7 +153,7 @@ class Offcanvas extends BaseComponent { new ScrollBarHelper().reset() } - if (this._config.scrollAfterClose) { + if (this._config.focusAfterClose) { EventHandler.trigger(this._element, EVENT_HIDDEN) } } diff --git a/site/content/docs/5.3/components/offcanvas.md b/site/content/docs/5.3/components/offcanvas.md index 96ec5d160f39..458a70b1fc82 100644 --- a/site/content/docs/5.3/components/offcanvas.md +++ b/site/content/docs/5.3/components/offcanvas.md @@ -309,7 +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. | -| `scrollAfterClose` | boolean | `true` | Scroll to the offcanvas toggler after the offcanvas is closed. | +| `focusAfterClose` | boolean | `true` | Focus the offcanvas toggler after the offcanvas is closed. | {{< /bs-table >}} ### Methods From 30e264015dcadac5efbababd5d3c755f7e2d572b Mon Sep 17 00:00:00 2001 From: Xcreen Date: Tue, 16 Jul 2024 16:14:34 +0200 Subject: [PATCH 4/6] Make sure that the hidden-event always gets triggered --- js/src/offcanvas.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/js/src/offcanvas.js b/js/src/offcanvas.js index 0c37dd75ba77..6fbd1cb1018b 100644 --- a/js/src/offcanvas.js +++ b/js/src/offcanvas.js @@ -153,9 +153,9 @@ class Offcanvas extends BaseComponent { new ScrollBarHelper().reset() } - if (this._config.focusAfterClose) { - EventHandler.trigger(this._element, EVENT_HIDDEN) - } + EventHandler.trigger(this._element, EVENT_HIDDEN, { + focusAfterClose: this._config.focusAfterClose + }) } this._queueCallback(completeCallback, this._element, true) @@ -244,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, evt => { // focus on trigger when it is closed - if (isVisible(this)) { + if (evt.focusAfterClose && isVisible(this)) { this.focus() } }) From 62cc2e6c84c977781b3dd79cde681ae6e6f8fb42 Mon Sep 17 00:00:00 2001 From: Xcreen Date: Tue, 16 Jul 2024 16:20:33 +0200 Subject: [PATCH 5/6] Added Tests --- js/tests/unit/offcanvas.spec.js | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) 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', () => { From a18c976b2224c4a5ccbdf25388acad080c4cbe4e Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Sat, 27 Jul 2024 07:18:41 +0300 Subject: [PATCH 6/6] Update offcanvas.js --- js/src/offcanvas.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/src/offcanvas.js b/js/src/offcanvas.js index 6fbd1cb1018b..fb5f14c8b2d5 100644 --- a/js/src/offcanvas.js +++ b/js/src/offcanvas.js @@ -244,9 +244,9 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( return } - EventHandler.one(target, EVENT_HIDDEN, evt => { + EventHandler.one(target, EVENT_HIDDEN, event => { // focus on trigger when it is closed - if (evt.focusAfterClose && isVisible(this)) { + if (event.focusAfterClose && isVisible(this)) { this.focus() } })