svelte icon indicating copy to clipboard operation
svelte copied to clipboard

onclick seems to not be working on web components

Open GCastilho opened this issue 1 year ago • 4 comments

Describe the bug

Using onclick on a web-component (ApplePay button, on this case) is not working. The handler function is not being called. If I change to Svelte's 4 on:click the handler function is called normally

As far as I understand the apple-pay-button web-component fires a click event

Reproduction

https://github.com/GCastilho/svelte-5-onclick-bug-reproduction

(Note the usage of 'vite-plugin-mkcert' to use https on localhost. HTTPS is required for the ApplePay button to be displayed)

Logs

No response

System Info

System:
    OS: Windows 11 10.0.26100
    CPU: (8) x64 Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz
    Memory: 3.05 GB / 15.77 GB
  Binaries:
    Node: 20.16.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.8.1 - C:\Program Files\nodejs\npm.CMD
    pnpm: 9.7.0 - C:\Program Files\nodejs\pnpm.CMD
  Browsers:
    Edge: Chromium (131.0.2903.86)
    Internet Explorer: 11.0.26100.1882
  npmPackages:
    svelte: ^5.2.7 => 5.11.2

Severity

blocking an upgrade

GCastilho avatar Dec 13 '24 14:12 GCastilho

From what I know, onclick uses event delegation in Svelte, while on:click is effectively the same as addEventListener. I don't know enough about the Apple Pay web components to know if they have a Shadow DOM, because that influences how events work as well. I'm not sure if/how event delegation works with custom elements either.

Ocean-OS avatar Dec 13 '24 19:12 Ocean-OS

@Ocean-OS Apple pay does use Shadow DOM

image

GCastilho avatar Dec 19 '24 20:12 GCastilho

This is a combination of several things:

  1. The custom element does stop the propagation of the click event. That means the event is only available on the custom element itself and does not bubble beyond it
  2. We're assuming that the delegateable events (such as click from a button) from within custom elements bubble and are composed, i.e. they bubble beyond the shadow root. It's debateable whether or not we should assume that; given that everything can happen within custom elements (as shown here) I would be in favor of never delegating events on custom elements
  3. Within events.js#create_event we're checking if the event has cancelBubble set to true, in which case we don't invoke the passed handler. That is wrong, because the custom element did call stopPropagation, so it's already true, but we're a listener on the last element that still receives the event.

dummdidumm avatar Jan 06 '25 12:01 dummdidumm

Temporary fix

Wrap it with other buttons

<button onclick={onApplePayButtonClicked}> <apple-pay-button buttonstyle="black" type="plain" locale="en"></apple-pay-button> </button>

rakanus avatar May 29 '25 16:05 rakanus