bug: custom events on non-stencil element not working
Prerequisites
- [x] I have read the Contributing Guidelines.
- [x] I agree to follow the Code of Conduct.
- [x] I have searched for existing issues that already report this problem, without success.
Stencil Version
4.22.2
Current Behavior
I am unable to listen to a custom event on a non-stencil element (f.e. a <div>) in JSX. Instead Stencil writes an attribute to DOM after stringifiying the passed function.
Expected Behavior
There should be a way to do this.
System Info
N/A
Steps to Reproduce
Put this component in a Stencil app.
import { Component, h, Prop } from '@stencil/core';
@Component({ tag: 'app-root', styleUrl: 'app-root.css', shadow: true })
export class AppRoot {
div!: HTMLElement;
componentDidLoad() {
this.div.dispatchEvent(new CustomEvent('customEvent')); // expect "customEvent" to be logged to console.
}
render() {
return (
<div
ref={el => (this.div = el)}
// @ts-ignore
oncustomEvent={() => console.log('customEvent')}
></div>
);
}
}
Instead of customEvent being logged, the DOM will have this in it (see element inspector):
Code Reproduction URL
...
Additional Information
Other JSX frameworks support this. For example,
- React 19 ->
onmYeVeNt={fn}listens for an event namedmYeVeNt(case sensitive) on any custom elements. - Similar with Preact.
- Solid.js and Pota both have explicit
on:wHaTeVeR={}prop syntax (case sensitive) which will always listen to the given event.
The reason it would be good to have this is then users do not need to do a dance with ref.
Having to escape out of one's favorite framework's template system is not desirable.
If I change it from <div to <foo-bar it will set the JS property instead of an attribute, but still not listen to a customEvent.
Based on this, it seems that if we use a <custom-element> from another framework (for example, Lit, Atomico, Enhance, Lume Element, etc) we won't be able to listen for events on those elements in JSX, and will have to undesirably escape out of Stencil's JSX into plain JS.
@trusktr what happens if you change the listener toonCustomEvent (with a capital 'C')?
I think stencil, rightly or wrongly, checks for on{UPPERCASELETTER}whatever for event handlers.
https://codesandbox.io/p/devbox/custom-event-listener-n33n9r
I think it's working?