Crank: Subscribing for events on custom elements not working

Created on 4 Aug 2020  路  5Comments  路  Source: bikeshaving/crank

Please have a look at the following Preact demo:
https://codesandbox.io/s/aged-silence-1dqjd?file=/src/index.js

The demo tries to listen to certain events on a custom element.
Everything is working fine in Preact.
Now switch to Crank (changing the imports etc.) and you'll see that not a single event registration is working.
Seems like a bug.

All 5 comments

From my code spelunking, I know that preact uses addEventListener/removeEventListener to deal with onevent props. Crank uses the onevent props API provided by the DOM; in other words, when elements are rendered we assign el.onclick = props.onclick and so on. I鈥檓 not sure how web components deal with event handling, but for the above code to work, you might need to define a custom getter/setter for the onevent props that you want to listen to. The fact of the matter is, people who consume your web components directly may expect the relevant onevent properties to work anyways.

Alternatively, you can use Crank鈥檚 addEventListener API, which uses the actual EventTarget methods under the hood, although this method means you have to worry about event delegation and the shadow DOM not propagating events or whatever.

Thanks for the information.
Seems that a proper custom element should implement both kinds of event subscription, shouldn't it?
Good to know.
I've tested with UI5 and MWC custom element buttons. Both were working perfectly fine.
So I'll close this issue.

Sorry, I have to reopen the issue.

Seems that a proper custom element should implement both kinds of event subscription, shouldn't it?

Turned out that not for all web components "both kind of event subscriptions" are implemented.
My simple test with a UI5 web component button was successful the other day.
But for example for ui5 dialogs the same is NOT working.
Please check the following demo. Before the dialog is shown an alert should be open and say "Dialog is opening....".
This is working for Dyo and Preact but not for Crank.

https://codesandbox.io/s/upbeat-dream-xkxxq

Shouldn't the algorithm be something like:
If you have something like <fancy-button onfancyclick={...}/> first check whether the custom element has a property called 'onfancyclick' (via 'onfancyclick' in elem). If yes, perform elem.onfancyclick = ...., otherwise perform elem.addEventListener('fancyclick', ...)?

@mcjazzyfunky

Shouldn't the algorithm be something like...

Maybe. I鈥檓 hesitant to implement custom logic here because any logic like that has to run for every prop for every host element for every update. It鈥檚 hot code, so much so that you鈥檒l see the other frameworks write stuff like if (name[0] === "o" && name[1] === "n") instead of if (name.startsWith("on")) to check if a prop is like an event handler. My inclination is to tell the UI5 people to implement the onafteropen prop. Alternatively, you can use this.addEventListener and have your example work.

  this.addEventListener("afterOpen", () => {
    alert('Dialog is opening...')
  });

I鈥檓 open to suggestions for algorithms here, and the relevant code is in the DOM renderer. This is just not something I鈥檓 keen on doing because JSX elements are the perfect use-case for onevent props, and any web component library that doesn鈥檛 implement them really should do so if only for consistency with the DOM APIs.

Hmm, okay, understandable ... the problem is a bit, that as there are (of course) no Crank component suites and Crank router package etc. out there yet, one fun way to use Crank is to use third-party custom elements (e.g. Vaadin web components, vmware's clarity web components, Salesforce's lightning web components or whatever) and maybe 'vaadin-router' and stuff like that. With using web compent technology it may be possible to implement a nice UI frontend with Crank in a reasonable time.
But it's necessary that Crank really supports those popular web compents libraries nicely, otherwise things will not really be fun.
Okay, but to end here: I personally do not use UI5 web components in real applications, I just used it here for the demo.
Just let's say maybe the "you ain't gonna need it" principle is best here, and we can handle this question as soon as it really turns out a problem, not earlier.
So I will close this issue for now.
Thanks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brainkim picture brainkim  路  5Comments

xkxx picture xkxx  路  7Comments

workingjubilee picture workingjubilee  路  6Comments

spiffytech picture spiffytech  路  6Comments

virtualfunction picture virtualfunction  路  5Comments