marc walter

Elm with custom elements (cheat sheet)

2020-09-27

When exploring custom elements (often called Web Components) in combination with Elm, the following techniques seemed to be very important to me, and I want to have them easily available for future reference:

Techniques

  1. Pass stringified data from Elm to the custom element as an HTML attribute (the custom element can watch on changes for these).
  2. Pass arbitrary JSON (also opaque objects like RTCPeerConnection) from Elm to the custom element
  3. Pass arbitrary JS data from the custom element to elm using DOM events

I use them also for the elm-conf example, but this post is easier to use as a cheat sheet.

1. Send strings from Elm and watch for changes

The official Elm guide also contains a section about this simple use case.
You need to set the HTML attribute names to watch for by adding a static get observedAttributes() { return ['abc']; } method in the custom element class.

And then every change by an Elm view function like Html.Attributes.attribute "abc" "def" will trigger the attributeChangedCallback method of the custom element.

2. Send arbitrary JS data from Elm

Elm can also set JS properties of a custom element, for example Html.Attributes.property "ghi" (Json.Encode.bool True) can be accessed inside the custom element class like this if (this.ghi === true) { .. }.

This does not trigger the onAttributeChanged callback, but if you set an attribute that signifies that a property has changed, you can have full two-way communication together with the third technique.

3. Send arbitrary data to Elm via a DOM event

The custom element can emit DOM events that Elm can listen to.

If you only need the event, but no additional data, you can even skip the decoder in the example below and shorten it to Html.Events.on "jkl" <| Json.Decode.succeed JklMsg.

Example

The following ellie example uses all these techniques (direct download) :