Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support named export (top-level binding) #63

Open
Tracked by #10
DrSensor opened this issue Feb 15, 2023 · 2 comments
Open
Tracked by #10

Support named export (top-level binding) #63

DrSensor opened this issue Feb 15, 2023 · 2 comments
Labels
enhancement New feature or request experimental Breaking changes can happen at any time

Comments

@DrSensor
Copy link
Owner

DrSensor commented Feb 15, 2023

Warning: this pattern is highly experimental

<render-scope>
  <link top-level href=module.js>
  <template shadowrootmode=closed>
    <button :=counter>0</button>
    <span :: text:=set:total>0</span>
  </template>
</render-scope>
function increment() { this.value++ }

export function counter(element) {
  element ??= this ?? <button/>
  element.addEventListener("click",  increment)
  return element
}

👣 Footgun: how do you bind variable (i.e total)?

export let total
// total += 1
// require compiler
// (maybe compile to class
//  with @bind accessor
//  for the sake of performance
//  😂)

export const total = {}
// total.value += 1
// works without compiler but weird

The reason I'm interested in named export is because of handleEvent() pattern in class1

<render-scope>
  <link top-level href=module.js>
  <template shadowrootmode=closed>
    <button :=Counter>0</button>
  </template>
</render-scope>
export class Counter {
  value = 0
  constructor(element = <button/>) {
    element.addEventListener("click",  this)
    return Object.setPrototypeOf(element, new.target.prototype)
  }
  handleEvent(event) {
    switch (event.type) {
      case "click":
        this.increment()
        break
      default:
        this.value = +event.currentTarget.value
    }
  }
  increment() { this.value++ }
}

use module in other area or projects

import { Counter } from "./module.js"
for (const input of document.querySelectorAll("input.counter")) {
  const counter = new Counter()
  input.after(counter)
  input.addEventListener("change", counter)
}

Footnotes

  1. DOM handleEvent: a cross-platform standard since year 2000

@DrSensor DrSensor added enhancement New feature or request experimental Breaking changes can happen at any time data binding Everything related to data binding labels Feb 15, 2023
@DrSensor
Copy link
Owner Author

DrSensor commented Feb 15, 2023

Seems the only compromise for avoiding data-binding footgun is to only allow named exports for handling ref Element #9. Basically named export must be a function or class. With this limitation, top-level attribute is not necessary.

@DrSensor DrSensor removed the data binding Everything related to data binding label Feb 15, 2023
@DrSensor
Copy link
Owner Author

DrSensor commented Feb 20, 2023

I think I will go with ! prefix and only limit named/top-level export function for ref element, event handler, and setter/getter (choose one). Would be nice if I can support this context too.

@DrSensor DrSensor changed the title Support named/top-level export Support named export (top-level binding) Mar 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request experimental Breaking changes can happen at any time
Projects
None yet
Development

No branches or pull requests

1 participant