mayu-live / framework

Mayu is a live updating server-side component-based VDOM rendering framework written in Ruby
https://mayu.live
GNU Affero General Public License v3.0
130 stars 4 forks source link

Custom elements? #5

Open aalin opened 1 year ago

aalin commented 1 year ago

It would be interesting to support some sort of client side state via custom elements. I'm not sure how these would be defined. Maybe something like this?

  :typescript
    class extends HTMLButtonElement {
      connectedCallback() {}
      disconnectedCallback() {}
    }
%custom-element
  %p template contents

Could maybe use swc or esbuild for transforming typescript.


Or maybe something to deal with event handlers?

:ruby
  def handle_dragend(e)
    # do something with e
  end
:javascript
  export function handle_dragstart(e) {
    // do something with e..
  }
%img(ondragstart=handle_dragstart ondragend=handle_dragend){**props}

Handlers would be automatically bound to both the JS handler and the Ruby handler. Calling e.preventDefault() would make it so that it doesn't send the event to the server.

The module for each component would be loaded when the component gets mounted...


I'm not 100% sure though. Maybe it should be more difficult to write JS in Mayu.

It would be better to have good built-in abstractions for doing complex stuff like drag-and-drop or handling events, scrolling long lists etc..

aalin commented 3 months ago

This is how it should be done:

MyCustomElement.js

export default class MyCustomElement extends HTMLElement {
  static observedAttributes = ["color", "size"];

  constructor() {
    super();
  }

  connectedCallback() {
    console.log("Custom element added to page.");
  }

  disconnectedCallback() {
    console.log("Custom element removed from page.");
  }

  adoptedCallback() {
    console.log("Custom element moved to new page.");
  }

  attributeChangedCallback(name, oldValue, newValue) {
    console.log(`Attribute ${name} has changed.`);
  }
}

page.haml

:ruby
  MyCustomElement = import("./MyCustomElement.js")

%div
  %MyCustomElement(color="red" size=2)

And when the file loads, the browser runtime should do customElements.define("my-custom-element-abc123", mod.default);

aalin commented 2 months ago

https://github.com/mayu-live/mayu-swc