mirror of
https://github.com/twbs/bootstrap.git
synced 2025-08-10 23:54:08 +02:00
Handle disabled focused tabs with tab JavaScript plugin (#36169)
* Handle disabled tabs * Fix after feedback * Update js/src/tab.js Co-authored-by: GeoSot <geo.sotis@gmail.com> * Update js/src/tab.js Co-authored-by: GeoSot <geo.sotis@gmail.com> * Commit suggestions via GitHub broke the thing * Add some unit tests * Remove temp doc modification * Add tests for left arrow * Add disabled tabs in JavaScript Behavior section * Compact 4 tests to 2 tests * Compact 4 tests to 2 tests * Add 'disabled' attribute for all buttons * Change the disabled pane position only for the vertical version * Change ids for the confusing first example in JavaScript behavior * Use disabled attribute instead of the class for buttons in tabs Co-authored-by: GeoSot <geo.sotis@gmail.com>
This commit is contained in:
@@ -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
|
||||
|
@@ -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', () => {
|
||||
|
Reference in New Issue
Block a user