Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Modal closes when using 1Password browser extension #107

Closed
maelp opened this issue Oct 8, 2023 · 7 comments
Closed

[Bug]: Modal closes when using 1Password browser extension #107

maelp opened this issue Oct 8, 2023 · 7 comments
Labels
bug Something isn't working

Comments

@maelp
Copy link

maelp commented Oct 8, 2023

Environment

Developement/Production OS: Windows 10 19043.1110
Node version: 16.0.0
Package manager: pnpm@8.6.0
Radix Vue version: 1.0.0
Shadcn Vue version: 1.0.0
Vue version: 3.0.0
Nuxt version: 3.0.0
Nuxt mode: universal
Nuxt target: server
CSS framework: tailwindcss@3.3.3
Client OS: Windows 10 19043.1110
Browser: Chrome 90.0.4430.212

Link to minimal reproduction

None

Steps to reproduce

Not sure where the bug comes from, but when I have a form in a modal (I'm using something similar as the Dialog example on shadcn-vue), when I click on the 1Password icon, it closes the modal

Describe the bug

It should keep the modal open

Expected behavior

No response

Conext & Screenshots (if applicable)

No response

@maelp maelp added the bug Something isn't working label Oct 8, 2023
@romansp
Copy link

romansp commented Oct 11, 2023

@maelp 1Password button is placed inside shadow DOM attached to body and rendered as position: fixed on top of the <input>. So clicks on that button are considered to be outside of the modal thus modal attempts to close.

I'm afraid that for now you'll have to provide custom @pointerDownOutside or @interactOutside handlers to detect such click and event.preventDefault() it.

Also check out these threads for possible workarounds:

@maelp
Copy link
Author

maelp commented Oct 11, 2023

Thank you!

Adding this to the Dialog works, perhaps we can integrate it in radix-vue/shadcn-vue?

        @pointer-down-outside="
          (event) => {
            event.preventDefault();
          }
        "
        @interact-outside="
          (event) => {
            // @ts-ignore
            if (event.currentTarget?.contains(event.target)) {
              event.stopPropagation();
            }
          }

@romansp
Copy link

romansp commented Oct 11, 2023

@maelp this will deny all click outside events and keep Dialog around which isn't desirable for the most of use cases. Maybe you wanted AlertDialog behavior in the first place?

@maelp
Copy link
Author

maelp commented Oct 11, 2023

hmmm you're right.. is there a workaround which still allows to close the modal by clicking outside?

@romansp
Copy link

romansp commented Oct 11, 2023

@maelp I'd say you'd want to carefully inspect event in @interact-outside handler, check if event's target is 1Password button based on your requirements and preventDefault() only in that case.

FYI you don't need pointer-down-outside as interact-outside covers both pointerdown and focus outside events.

This should work:

// ...
<DialogContent @interact-outside="handleInteractOutside"></DialogContent>
// ...
function handleInteractOutside(event: Event) {
  const is1PasswordButtonClick = /* check event.target.tagName maybe? */
  if (is1PasswordButtonClick) {
    event.preventDefault();
  } 
}

@maelp
Copy link
Author

maelp commented Oct 11, 2023

Thanks I'll try that!

@maelp maelp closed this as completed Oct 11, 2023
@linkb15
Copy link

linkb15 commented Mar 5, 2024

I am from ReactJS world!

Thanks for the advise! Managed to solve it because of this comment as well.

<DialogContent
  onInteractOutside={e => {
    const target = e.target as HTMLElement;
    const isGrammarly =
      target && target.hasAttribute('data-grammarly-shadow-root');

    const is1Password = target.tagName === 'COM-1PASSWORD-BUTTON';

    if (isGrammarly || is1Password) {
      e.preventDefault();
    }
  }}
>
...

@maelp I'd say you'd want to carefully inspect event in @interact-outside handler, check if event's target is 1Password button based on your requirements and preventDefault() only in that case.

FYI you don't need pointer-down-outside as interact-outside covers both pointerdown and focus outside events.

This should work:

// ...
<DialogContent @interact-outside="handleInteractOutside"></DialogContent>
// ...
function handleInteractOutside(event: Event) {
  const is1PasswordButtonClick = /* check event.target.tagName maybe? */
  if (is1PasswordButtonClick) {
    event.preventDefault();
  } 
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants