Nice just saw this post (you mentioned on Better interop with Javascript libraries (React, Svelte, etc.))
Anyway I agree with all your points, though I don’t even think you’d need point 3) about functional wrappers if this was done correctly.
Bullet points 1) and 2) are the important ones though.
Here’s some thoughts I had which may or may not be feasible but I’d love to see something like this:
Currently in HEEX you can do
<my-element some-prop={@some_prop} />
but not much else I think, and @some_prop gets converted into an HTML safe string.
I think if HEEX introduced
- some delimiter syntax that basically means “don’t turn this into a string but rather assign as an object (string, number, boolean, array or object, i.e. JSON-stringifiable data)”, such as
some-prop=(@some_prop)
(note the round brackets, but could be anything that’s different from={@some_prop}
, e.g.:={@some_prop}
,=[@some_prop]
,~{@some_prop}
, etc.) - an easy way of doing the equivalent of
element.addEventListener("some-event", ...)
Then that’s really all you’d need.
A few examples of what it might look like, with
- an array prop
[1,2,3]
- listening to a CustomEvent
"appendNumber"
, withevent.detail
as a new number, which calls back tohandle_event("append", num, socket)
:
All of these examples effectively do the equivalent of
const element = document.createElement("my-element"); element.numbers = [1,2,3]; element.addEventListener("appendNumber", (event) => lv.pushEvent("append", event.detail);
Different ideas…
# Assumes you always send event.detail <my-element numbers=([1,2,3]) @appendNumber="append" /> # Specifies exactly what from the event object to take <my-element numbers=([1,2,3]) @appendNumber=({"append", "&1.detail"}) /> # side-note: that would also allow for more general events like clicks <div @click=({"click", "&1.clientX"}) /> # Use phx-xxx attributes like other functionality, also just sends all of event.detail <my-element numbers=([1,2,3]) phx-custom-event="appendNumber:append" /> # Use JS module <my-element numbers=([1,2,3]) phx-on-appendNumber={JS.push_event("append")} /> # As above but specifying what to take from event <my-element numbers=([1,2,3]) phx-on-appendNumber={JS.push_event("append", "&1.detail")} />
Anyway just throwing out a few ideas.
If that were possible, then:
- Svelte, Vue, Angular, Solid can all easily compile to web components
- Lit, Stencil etc. compile to web components
- React components could be easily wrapped on a per-component basis (because mapping function callbacks → custom events would need to be done per-component)
and therefore would be even easier to integrate into a liveview app.
I don’t know how the HEEX compiler works (though am interested to look into it), so don’t know how feasible this would be, but I imagine it would mean the need for a Javascript script to be added after the whole page or something, and possibly the need for ids for that JS code to target the correct elements