diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/src/tab.js | 7 | ||||
-rw-r--r-- | js/tests/unit/tab.spec.js | 66 |
2 files changed, 71 insertions, 2 deletions
diff --git a/js/src/tab.js b/js/src/tab.js index 135e929dda..3fa5e4c9e9 100644 --- a/js/src/tab.js +++ b/js/src/tab.js @@ -168,8 +168,11 @@ class Tab extends BaseComponent { event.stopPropagation()// stopPropagation/preventDefault both added to support up/down keys without scrolling the page event.preventDefault() const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key) - const nextActiveElement = getNextActiveElement(this._getChildren(), event.target, isNext, true) - Tab.getOrCreateInstance(nextActiveElement).show() + const nextActiveElement = getNextActiveElement(this._getChildren().filter(element => !isDisabled(element)), event.target, isNext, true) + + if (nextActiveElement) { + Tab.getOrCreateInstance(nextActiveElement).show() + } } _getChildren() { // collection of inner elements diff --git a/js/tests/unit/tab.spec.js b/js/tests/unit/tab.spec.js index 4b8fb62de6..e6225b23db 100644 --- a/js/tests/unit/tab.spec.js +++ b/js/tests/unit/tab.spec.js @@ -548,6 +548,72 @@ describe('Tab', () => { expect(Event.prototype.stopPropagation).toHaveBeenCalledTimes(2) expect(Event.prototype.preventDefault).toHaveBeenCalledTimes(2) }) + + it('if keydown event is right arrow and next element is disabled', () => { + fixtureEl.innerHTML = [ + '<div class="nav">', + ' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>', + ' <span id="tab2" class="nav-link" data-bs-toggle="tab" disabled></span>', + ' <span id="tab3" class="nav-link disabled" data-bs-toggle="tab"></span>', + ' <span id="tab4" class="nav-link" data-bs-toggle="tab"></span>', + '</div>' + ].join('') + + const tabEl = fixtureEl.querySelector('#tab1') + const tabEl2 = fixtureEl.querySelector('#tab2') + const tabEl3 = fixtureEl.querySelector('#tab3') + const tabEl4 = fixtureEl.querySelector('#tab4') + const tab = new Tab(tabEl) + const tab2 = new Tab(tabEl2) + const tab3 = new Tab(tabEl3) + const tab4 = new Tab(tabEl4) + spyOn(tab, 'show').and.callThrough() + spyOn(tab2, 'show').and.callThrough() + spyOn(tab3, 'show').and.callThrough() + spyOn(tab4, 'show').and.callThrough() + + const keydown = createEvent('keydown') + keydown.key = 'ArrowRight' + + tabEl.dispatchEvent(keydown) + expect(tab.show).not.toHaveBeenCalled() + expect(tab2.show).not.toHaveBeenCalled() + expect(tab3.show).not.toHaveBeenCalled() + expect(tab4.show).toHaveBeenCalledTimes(1) + }) + + it('if keydown event is left arrow and next element is disabled', () => { + fixtureEl.innerHTML = [ + '<div class="nav">', + ' <span id="tab1" class="nav-link" data-bs-toggle="tab"></span>', + ' <span id="tab2" class="nav-link" data-bs-toggle="tab" disabled></span>', + ' <span id="tab3" class="nav-link disabled" data-bs-toggle="tab"></span>', + ' <span id="tab4" class="nav-link" data-bs-toggle="tab"></span>', + '</div>' + ].join('') + + const tabEl = fixtureEl.querySelector('#tab1') + const tabEl2 = fixtureEl.querySelector('#tab2') + const tabEl3 = fixtureEl.querySelector('#tab3') + const tabEl4 = fixtureEl.querySelector('#tab4') + const tab = new Tab(tabEl) + const tab2 = new Tab(tabEl2) + const tab3 = new Tab(tabEl3) + const tab4 = new Tab(tabEl4) + spyOn(tab, 'show').and.callThrough() + spyOn(tab2, 'show').and.callThrough() + spyOn(tab3, 'show').and.callThrough() + spyOn(tab4, 'show').and.callThrough() + + const keydown = createEvent('keydown') + keydown.key = 'ArrowLeft' + + tabEl4.dispatchEvent(keydown) + expect(tab4.show).not.toHaveBeenCalled() + expect(tab3.show).not.toHaveBeenCalled() + expect(tab2.show).not.toHaveBeenCalled() + expect(tab.show).toHaveBeenCalledTimes(1) + }) }) describe('jQueryInterface', () => { |