fable-compiler / Fable.Lit

Write Fable Elmish apps with Lit
https://fable.io/Fable.Lit/
MIT License
91 stars 13 forks source link

Dispatch events #14

Closed AngelMunoz closed 2 years ago

AngelMunoz commented 2 years ago

I think we're missing an integral part of Lit I don't remember adding (and it flew over my head sorry) anythign related to dispatching events from the LitElement

class MyEventSource extends LitElement {

  raiseEvent() {
    const evt = new Event('my-event', { bubbles: true, cancelable: true, composed: true });
    this.dispatchEvent(evt)
  }

  render() {
     html`
       <button @click=${this.raiseEvent}>I will send an Event</button>
     `;
  }
}

in F# we would need to do something like this

[<Emit("new Event($0, $1)")>]
let createEvent name opts = jsNative

[<LitElement("my-event-source")>]
let private MyEventSource () =
  LitElement.init()
  let raiseEvent ev =
    let evt = createEvent "go-back" {| bubbles = true; composed = true; cancelable = true |}
    (ev.target :?> HTMLElement).dispatchEvent evt

  html
    $"""
       <button @click={raiseEvent}>I will send an Event</button>
  """

Which I guess it's fine, but the target of the event won't be the web component itself (as in Lit) but the button that is dispatching the event

I think if we add a helper function in the LitElement class defined here

type LitElement() = 
   (* ... other members ... *)
   static member inline dispatchEvent (event: Event) =
       // I'm not sure if this is really the HTMLElement but my intuition tells me so
       jsThis<HTMLElement>.dispatchEvent(event)

could fix the dispatch target.

[<Emit("new Event($0, $1)")>]
let createEvent name opts = jsNative

[<LitElement("my-event-source")>]
let private MyEventSource () =
  LitElement.init()
  let raiseEvent ev =
    let evt = createEvent "go-back" {| bubbles = true; composed = true; cancelable = true |}
    LitElement.dispatchEvent evt

  html
    $"""
       <button @click={raiseEvent}>I will send an Event</button>
  """

The creation of events can be worked in the fable-browser repo because I think we've (mostly I, plead guilty) been recently adding helpers in many of the samples and I think that should belong there to be honest 😀

Reference: https://lit.dev/docs/components/events/#dispatching-events

alfonsogarciacaro commented 2 years ago

Yes, we should add a helper to dispatch custom events, thanks for the reminder :+1: And we should also make it easier to get a reference to the this instance. Maybe returning it together with the props in the LitElement.init function?

About fable-browser, right now is what we call a "pure binding" meaning the package only contains metadata and no actual code. So we only need to reference the .dll so the F#/Fable compiler doesn't need to parse the sources. Because of this, it's better not to add helpers for now. Having them in Fable.Lit should work 👍