Skip to content

Popover: Clicking outside does not close popover if element stops propagation #8147

@mathildebm

Description

@mathildebm

Describe the bug

This PR addresses an issue where a popover remains open when clicking outside, if the click event originates from an element (or one of its ancestors) inside the popover that has stopPropagation applied. This prevents the document from detecting the outside click, causing the popover to stay open when it should close.
This issue was previously fixed in an earlier PR (f6293cf), but that fix was later reverted (e8b896f) because it required two clicks to close the popover when no element had stopped propagation.

Background
The popover uses a selfClick flag to determine whether the most recent click happened inside the popover. This is how the logic used to work:

Original Behavior:
Click inside the popover:

  1. mousedown on content → selfClick = true
  2. click (bubble) on content → selfClick = true
  3. click (bubble) on document → selfClick = false

Then, click outside the popover:

  1. click (bubble) on document → selfClick === false, so the popover hides

Problem: If an element inside the popover stops propagation, the click event never reaches the document, so the popover never hides.

Previous Fix:
To address that, we added a click capture listener on the document.

Click inside the popover:

  1. mousedown on content → selfClick = true
  2. click (capture) on document → selfClick = false
  3. click (bubble) on content → selfClick = true (if not stopped)

Then, click outside the popover:

  1. Click bubbles on document → selfClick === true, so popover does not hide (bug)

This approach failed when no element would stop the click propagation, requiring two clicks to close the popover.

Proposed Fix:
This PR removes the click listener on the popover content and restores the document click listener in the capture phase.

  • mousedown on content→ sets selfClick = true
  • click (capture) on document → resets selfClick = false

So:

Click inside the popover:

  1. mousedown → selfClick = true
  2. click (capture) on document → selfClick = false

Click outside the popover:

  1. click (capture) on document → selfClick === false, so popover hides

It would work correctly regardless of whether elements stop event propagation

Pull Request Link

#8148

Reason for not contributing a PR

  • Lack of time
  • Unsure how to implement the fix/feature
  • Difficulty understanding the codebase
  • Other

Other Reason

No response

Reproducer

https://stackblitz.com/edit/primevue-4-vite-issue-template-5klfzna7

Environment

Any environment

Vue version

3.5.22

PrimeVue version

4.3.9

Node version

No response

Browser(s)

No response

Steps to reproduce the behavior

  1. Click the "Share" button
  2. InputText is shown in a Popover
  3. Click inside the input
  4. Click outside the the Popover
  5. Popover is not hidden

Expected behavior

Popover should hide on click outside

Metadata

Metadata

Assignees

No one assigned

    Labels

    Status: Needs TriageIssue will be reviewed by Core Team and a relevant label will be added as soon as possible

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions