diff --git a/js/src/dropdown.js b/js/src/dropdown.js
index 590c748012c9d134a3be426510e7d785f25132ac..bbae240fc8d633f19c9f65f34599e44c64235d9e 100644
--- a/js/src/dropdown.js
+++ b/js/src/dropdown.js
@@ -255,7 +255,6 @@ class Dropdown extends BaseComponent {
   _addEventListeners() {
     EventHandler.on(this._element, EVENT_CLICK, event => {
       event.preventDefault()
-      event.stopPropagation()
       this.toggle()
     })
   }
@@ -518,12 +517,15 @@ class Dropdown extends BaseComponent {
 
 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler)
 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler)
-EventHandler.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus)
+EventHandler.on(document, EVENT_CLICK_DATA_API, event => {
+  if (!event.target.matches(SELECTOR_DATA_TOGGLE) && !SelectorEngine.parents(event.target, SELECTOR_DATA_TOGGLE)[0]) {
+    Dropdown.clearMenus()
+  }
+})
 EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus)
 EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
   event.preventDefault()
-  event.stopPropagation()
-  Dropdown.dropdownInterface(this, 'toggle')
+  Dropdown.dropdownInterface(this)
 })
 EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => e.stopPropagation())
 
diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js
index 658cb65b04ad0697235fe7b337261d0f38bf54be..589cfd52647e0a0e074541d743e97473484a1be5 100644
--- a/js/tests/unit/dropdown.spec.js
+++ b/js/tests/unit/dropdown.spec.js
@@ -1765,4 +1765,66 @@ describe('Dropdown', () => {
 
     triggerDropdown.dispatchEvent(keydown)
   })
+
+  it('should bubble up the event from dropdown toggle to the parent elements', done => {
+    fixtureEl.innerHTML = [
+      '<div class="container">',
+      '  <div class="dropdown">',
+      '    <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+      '    <div class="dropdown-menu">',
+      '      <a class="dropdown-item" href="#subMenu">Sub menu</a>',
+      '    </div>',
+      '  </div>',
+      '</div>'
+    ].join('')
+
+    const container = fixtureEl.querySelector('.container')
+    const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+    const dropdown = new Dropdown(triggerDropdown)
+
+    spyOn(dropdown, 'show').and.callThrough()
+
+    container.addEventListener('click', event => {
+      expect(triggerDropdown.classList.contains('show')).toEqual(true)
+      expect(dropdown.show).toHaveBeenCalled()
+      expect(event.target).toEqual(triggerDropdown)
+      done()
+    })
+
+    triggerDropdown.click()
+  })
+
+  it('should open the dropdown when clicking the child element inside `data-bs-toggle="dropdown"`', done => {
+    fixtureEl.innerHTML = [
+      '<div class="container">',
+      '  <div class="dropdown">',
+      '    <button class="btn dropdown-toggle" data-bs-toggle="dropdown"><span id="childElement">Dropdown</span></button>',
+      '    <div class="dropdown-menu">',
+      '      <a class="dropdown-item" href="#subMenu">Sub menu</a>',
+      '    </div>',
+      '  </div>',
+      '</div>'
+    ].join('')
+
+    const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+    const childElement = fixtureEl.querySelector('#childElement')
+
+    spyOn(Dropdown, 'clearMenus').and.callThrough()
+    spyOn(triggerDropdown.classList, 'remove')
+
+    triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+      setTimeout(() => {
+        expect(Dropdown.clearMenus).toHaveBeenCalledTimes(1)
+        expect(triggerDropdown.classList.remove).not.toHaveBeenCalled()
+        expect(triggerDropdown.classList.contains('show')).toEqual(true)
+        done()
+      }, 20)
+    })
+
+    triggerDropdown.addEventListener('hidden.bs.dropdown', () => {
+      throw new Error('should not throw hidden.bs.dropdown event')
+    })
+
+    childElement.click()
+  })
 })