ProjectEvergreen / greenwood

Greenwood is your full-stack workbench for the web, focused on supporting modern web standards and development to help you create your next project.
https://www.greenwoodjs.io
MIT License
94 stars 9 forks source link

CSS Modules ™️ plugin #1233

Open thescientist13 opened 1 month ago

thescientist13 commented 1 month ago

Summary

The new Greenwood website is piloting a plugin for supporting a very basic implementation of CSS Modules ™️ optimized for providing a nice co-located CSS DX in particular for Light DOM Web Components used for static templating.

Like a footer, for example

.wrapper {
  text-align: center;
  border-radius: var(--radius-4);
  padding: var(--size-fluid-3);
  box-shadow: var(--shadow-4);
}
import styles from "./footer.module.css";

export default class Footer extends HTMLElement {
  connectedCallback() {
    const year = `${new Date().getFullYear()}`;

    this.innerHTML = `
      <footer class="${styles.wrapper}">
        <h4>GreenwoodJS &copy;${year}</h4>
      </footer>
    `;
  }
}

customElements.define("app-footer", Footer);

Would strip out the import statement and add the CSS as a <style> tag to the HTML page, including for SSR, leaving you with something like this in your final HTML

<html>
  <head>
   <style>
     .footer-aca12vdvv-wrapper {
      text-align: center;
      border-radius: var(--radius-4);
      padding: var(--size-fluid-3);
      box-shadow: var(--shadow-4);
    }
   </style>
  </head>
  <body>
    <app-footer>
      <footer class="footer-aca12vdvv-wrapper">
        <h4>GreenwoodJS &copy;2024</h4>
      </footer>
    </app-footer>
  </body>

There are some patches needed for this too, so we should try and vet those first against Greenwood's test cases.

Details

As CSS Modules are a spec and can get quite complex, this should definitely be marked as experimental and YMMV, but did want something nice to compliment a .css first authoring experience with minimal fuss / happy path only support. The below are probably a couple things we can handle for the PR

  1. documentation around only being useful for Light DOM use cases?
  2. should we shim / conform to Constructable Stylesheets API? This actually gets us the CSS rules 🤩 . Screenshot 2024-01-21 at 6 13 09 PM
  3. Any flexibility of the import usage API, e.g.

    // hardcoded import
    import styles from './something.module.css'
    
    // vs
    import myCss from './something.module.css'
  4. Any flexibility in the usage of the import?

     // needs to reference the import name
     <h1 class="${styles.heading}">Welcome to Greenwood!</h1>
    
     // as opposed to
     const { heading } = styles;
     <h1 class="${heading}">Welcome to Greenwood!</h1>

Discussions

And these are probably better left to putting into a discussion

  1. refactor to avoid having to use intermediate output file (I think this is needed for prerendering because things run in a Worker Thread? 🤔 )
  2. conform to icss specification (leverage postcss-modules package?)