Re: [WICG/webcomponents] [templates] A declarative JavaScript templating API (Issue #1069)

I have a concern, but I'm not sure _where_ it belongs -- but with reactive rendering w/ Signals -- and maybe this is something that a library/framework would use to solve my concern, but -- given this example:

```js
const count = new Signal.State(0);

document.body.render(HTMLElement.html`<p>count: ${count}</p>`);

count.set(count.get() + 1);
```
`count` is rendered reactively, inherently -- which is great! This isn't where my concern is tho. Say you have a situation like this:

```ts
class Animal {
  givenName = new Signal.State();
} 

class Cat {
  get name() {
    return `${this.givenName}, the cat`;
  }
}

class Dog {
  name() => {
    return `${this.givenName}, the dog`;
  }
}
```

Assuming we use the same rendering function from the example, we can't reliably or consistently render reactive data, unless we pass on the responsibility to handle all situations to the developer:
```js
let cat = new Cat();
let dog = new Dog();

document.body.render(HTMLElement.html`
  <details><summary>Your Cat</summary>
    ${() => cat.name}
    If we don't specify a function, ${cat.name} is burned in and non-reactive, 
    as the value of name is eagerly evaluated.
    This would require that the processing of HTMLElement.html call functions, 
    if encountered.
  </details>
  
   <details><summary>Your Dog</summary>
    ${dog.name()}
    Not everyone is on board with getters when it comes to reactivity, and that's fine,
    but the other way of accessing *maybe* reactive values is a function,
    this also burns in the value, and would require non-invocation, e.g.: 
    ${dog.name}.

    This reveals in an inconsistency and footgun between:
      burned in:
         ${cat.name}
         ${dog.name()}
      reactive, provided HTMLEelment.html calls all functions:
         ${() => cat.name}
         ${dog.name}
  </details>
`);

// some time later
cat.givenName = 'Alexander';
dog.givenName = 'Sir"
```

Now, what _I_ would prefer, is taking a templating system further, and _not_ using tagged template literals at all -- (though, I don't immediately see a reason why what I'm about to show _couldn't_ be implemented with the above).

```gjs
let cat = new Cat();
let dog = new Dog();

document.body.render(<template>
  <details><summary>Your Cat</summary>
    {{cat.name}}
  </details>
  
   <details><summary>Your Dog</summary>
    {{dog.name()}}
  </details>
</template>);

// some time later
cat.givenName = 'Alexander';
dog.givenName = 'Sir"
```

In this example, both ways you'd access the value in JS would inherently be reactive -- there is no need to know about any footguns, because there would be none (unless someone points out something to me haha). This removes the need to worry about what is reactive and what is not, no need to `${() => value}` everything due to _not knowing_ if something could be reactive (A library may always be able to make something reactive in the future, and you wouldn't know!)

This uses https://wycats.github.io/polaris-sketchwork/content-tag.html which is _very_ pre-proposal, but is a variant on something that the corner of the JS ecosystem I'm in has decided to use for its rendering.
(But again, I guess it _could_ be built on tagged-template-literals, and be more of a sugar)


anywho, my 2c

-- 
Reply to this email directly or view it on GitHub:
https://github.com/WICG/webcomponents/issues/1069#issuecomment-2295055999
You are receiving this because you are subscribed to this thread.

Message ID: <WICG/webcomponents/issues/1069/2295055999@github.com>

Received on Sunday, 18 August 2024 01:38:32 UTC