Skip to content

Conversation

@mironovsergey
Copy link

Description

Fixes a race condition in the Collapse component that can cause multiple accordion panels to open simultaneously when rapidly clicking different triggers in sequence. Accordion behavior should ensure that opening one panel closes any other open panel within the same parent.

Problem

When rapidly clicking different accordion triggers in sequence, multiple panels can remain open.

Steps to reproduce:

  1. Open accordion example (e.g., https://getbootstrap.com/docs/5.3/components/accordion/#example).
  2. Rapidly click on several accordion buttons in sequence.
  3. Observe that multiple panels remain open.

Root causes identified:

  1. Incorrect SELECTOR_ACTIVES - the selector .collapse.show, .collapse.collapsing is incorrect because .collapse.collapsing never matches: when .collapsing is added, .collapse is removed (and vice versa). As a result, elements in transition were not reliably detected.
  2. Incorrect transition check - the check activeChildren.length && activeChildren[0]._isTransitioning only inspected the first active element and did not distinguish between opening vs closing transitions, causing improper blocking logic.

During the investigation, I also discovered a test case should allow accordion to target multiple elements, which verifies that a single trigger can control multiple targets. The same race condition bug affects this scenario as well - when rapidly switching between triggers, all corresponding panels open.

Solution

  1. Fix SELECTOR_ACTIVES to .collapse.show, .collapsing to properly match elements during transition.
  2. Add _isShowing flag to track the opening animation direction.
  3. Filter activeChildren by shared triggers - elements controlled by the same trigger should not block each other (this enables proper handling of multiple targets per trigger).
  4. Change the blocking condition to check _isShowing flag across all active elements instead of checking _isTransitioning on the first one only.

Type of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Refactoring (non-breaking change)
  • Breaking change (fix or feature that would change existing functionality)

Checklist

  • I have read the contributing guidelines
  • My code follows the code style of the project (using npm run lint)
  • My change introduces changes to the documentation
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed

Related issues

Fixes #41883

- Match active selector during transition (handle .collapsing without .collapse)
- Track opening direction with _isShowing flag
- Filter active children by shared triggers to support multiple targets per trigger
- Only block when sibling elements are opening, not when they're closing

Fixes twbs#41883
@mironovsergey mironovsergey requested a review from a team as a code owner November 27, 2025 20:13
@mironovsergey
Copy link
Author

I've added a test to cover the race condition scenario. The test rapidly clicks three accordion triggers in sequence and verifies that only the first panel remains open.

@DenisLopatin
Copy link

Hi. You beat me to it. I checked your solution manually, it works.

That's how it was before:

before.mp4

And so now:

after.mp4

@DenisLopatin
Copy link

The test is working, all karma tests are also completed with the new change

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Accordion BUG clicking two elements fast enough they both opens

3 participants