11ty / webc

Single File Web Components
MIT License
1.31k stars 38 forks source link

<script webc:setup> Expose JS defined in <script> tags to component's template #109

Closed georgedoescode closed 1 year ago

georgedoescode commented 1 year ago

It would be great if variables, functions, etc, that are defined in a .webc component's <script> tag could be referenced within that component's template. Similar to Vue's <script setup> Something like this:

<script>
const pageTitle = "Home";

function renderText() {
  return true;
}
</script>

<main>
  <h1 @text="pageTitle"></h1>
  <div webc:if="renderText()"></div>
</main>

It would also be great if we could reference global Eleventy data here, something like:

<script>
const blogPosts = data.blogPosts;
</script>

It could also be really interesting if the functions, variables, etc, defined in the <script> tag could be used both at build time, but also be carried over to the client for use with is-land and other interactive elements. I feel like this could be really powerful!

zachleat commented 1 year ago

Related https://github.com/11ty/webc/issues/87

zachleat commented 1 year ago

<script webc:setup> will ship with WebC v0.9.0.

Has access to the standard stuff from the WebC data cascade: global data (Eleventy’s data cascade), helper functions, etc.

A few test cases here: https://github.com/11ty/webc/blob/efe23f6c12ac8505c52f9cfedc0bce6f4d0ad750/test/stubs/setup-script/test.js

zachleat commented 1 year ago

cc @mayank99 who might be interested in this

mayank99 commented 1 year ago

This is amazing!

Couple questions:

  1. What would be the main difference between webc:setup and the older webc:type="js"?
  2. How does it get access to global 11ty data? Asking because it would be useful to provide it global data in my vite plugin.
zachleat commented 1 year ago

This may feel like whiplash but personally I don’t think we need webc:type="js" or webc:type="render" with webc:setup around.

That said,

On data scoping

On rendering:

Using webc:setup to render will look something like this (although I kinda wish we had an @outerhtml at this point):

<script webc:setup>
let myHtml = "<my-webc-component>";
</script>
<template @html="myHtml" webc:nokeep></template>

On data access:

georgedoescode commented 1 year ago

This is fantastic! Thank you so much for taking the time to implement this Zach ❤️ I can't wait to have a play!

Paul-Hebert commented 1 year ago

This is awesome! This is exactly what I needed for a project today. I'm excited to play with this. Thanks Zach!