diff --git a/js/src/collapse.js b/js/src/collapse.js index b308863f46..9b75ebc652 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -122,7 +122,7 @@ class Collapse extends BaseComponent { .map(element => Collapse.getOrCreateInstance(element, { toggle: false })) } - if (activeChildren.length && activeChildren[0]._isTransitioning) { + if (activeChildren.some(instance => instance._isTransitioning)) { return } @@ -137,7 +137,6 @@ class Collapse extends BaseComponent { const dimension = this._getDimension() - this._element.classList.remove(CLASS_NAME_COLLAPSE) this._element.classList.add(CLASS_NAME_COLLAPSING) this._element.style[dimension] = 0 @@ -149,7 +148,7 @@ class Collapse extends BaseComponent { this._isTransitioning = false this._element.classList.remove(CLASS_NAME_COLLAPSING) - this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW) + this._element.classList.add(CLASS_NAME_SHOW) this._element.style[dimension] = '' @@ -180,7 +179,7 @@ class Collapse extends BaseComponent { reflow(this._element) this._element.classList.add(CLASS_NAME_COLLAPSING) - this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW) + this._element.classList.remove(CLASS_NAME_SHOW) for (const trigger of this._triggerArray) { const element = SelectorEngine.getElementFromSelector(trigger) @@ -195,7 +194,6 @@ class Collapse extends BaseComponent { const complete = () => { this._isTransitioning = false this._element.classList.remove(CLASS_NAME_COLLAPSING) - this._element.classList.add(CLASS_NAME_COLLAPSE) EventHandler.trigger(this._element, EVENT_HIDDEN) } diff --git a/js/tests/unit/collapse.spec.js b/js/tests/unit/collapse.spec.js index 58c5367526..00e8e8510f 100644 --- a/js/tests/unit/collapse.spec.js +++ b/js/tests/unit/collapse.spec.js @@ -333,6 +333,51 @@ describe('Collapse', () => { }) }) + it('should be able to handle quick toggling between siblings', () => + new Promise(resolve => { + fixtureEl.innerHTML = [ + '
', + '
', + ' ', + '
', + '
', + '
', + '
', + ' ', + '
', + '
', + '
', + '
' + ].join('') + + const el = selector => fixtureEl.querySelector(selector) + + const btn1 = el('[data-bs-target="#collapseOne"]') + const btn2 = el('[data-bs-target="#collapseTwo"]') + + const collapseEl1 = el('#collapseOne') + const collapseEl2 = el('#collapseTwo') + + collapseEl2.addEventListener('shown.bs.collapse', () => { + throw new Error('should not fire shown event') + }) + + collapseEl1.addEventListener('shown.bs.collapse', () => { + setTimeout(() => { + expect(collapseEl2).not.toHaveClass('show') + resolve() + }, 1000) + }) + + btn1.click() + btn2.click() + }) + ) + it('should not change tab tabpanels descendants on accordion', () => { return new Promise(resolve => { fixtureEl.innerHTML = [ diff --git a/scss/_transitions.scss b/scss/_transitions.scss index bfb26aa8ac..ade2414fe2 100644 --- a/scss/_transitions.scss +++ b/scss/_transitions.scss @@ -8,7 +8,7 @@ // scss-docs-start collapse-classes .collapse { - &:not(.show) { + &:not(.show):not(.collapsing) { display: none; } }