-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
content/issue 103 v0.30.0 release blog post (#118)
- Loading branch information
1 parent
0f6fdca
commit 3b0ec3e
Showing
4 changed files
with
185 additions
and
1 deletion.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
--- | ||
title: Release - v0.30.0 | ||
abstract: Import Attributes are here in Greenwood! Learn more about them and other key highlights from this release. | ||
published: 2024-11-02 | ||
coverImage: /assets/blog/acorn.webp | ||
layout: blog | ||
--- | ||
|
||
# Greenwood v0.30.0 | ||
|
||
**Published: Nov 2nd, 2024** | ||
|
||
## What's New | ||
|
||
<!-- <img src="/assets/blog/acorn.webp" style="display:inline-block; float: left; min-width: 100px; max-width: 10%; margin: 30px auto 10px; padding-right: 20px;" alt="Serverless function cloud"/> --> | ||
|
||
In support of this latest release the Greenwood team would like to share some highlights with you, and top of the list for us is Import Attributes. Import Attributes are a powerful new web standard for loading non JavaScript files like CSS and JSON just by extending the standard ESM syntax. They work great with Web Components, or standalone. In addition, we want to showcase the HTML Web Components pattern, as well as introduce a new plugin to support CSS Modules ™️. | ||
|
||
> Please refer to the [release notes](https://github.com/ProjectEvergreen/greenwood/releases/tag/v0.30.0) for a complete changelog and overview of breaking changes. | ||
## Import Attributes | ||
|
||
Although not implemented in [all browsers](https://github.com/web-platform-tests/interop/issues/733) (yet), **Import Attributes** are a [Stage 4 TC39 proposal](https://github.com/tc39/proposal-import-attributes) for extending ESM syntax to support additional module formats. [**CSS**](https://github.com/web-platform-tests/interop/issues/703) and [**JSON**](https://github.com/web-platform-tests/interop/issues/705) modules are already on the standards track, with [HTML Modules](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md) possible in the future. For Greenwood, we have made support for CSS and JSON possible out of the box, with a [polyfill config flag](/docs/reference/configuration/#polyfills) for providing fallback behavior in the interim. | ||
|
||
<!-- eslint-disable no-unused-vars --> | ||
|
||
```js | ||
// JSON is exported as an object | ||
import data from "./data.json" with { type: "json" }; | ||
|
||
// CSS is exported as a Constructable StyleSheet | ||
import sheet from "./styles" with { type: "css" }; | ||
``` | ||
|
||
<!-- eslint-enable no-unused-vars --> | ||
|
||
For CSS, this works especially well with Shadow DOM based custom elements, as you can now author component styles in vanilla CSS files, and "adopt" them right into your Shadow roots. This same adoption technique can also be used to include any global "light DOM" styles, as you can adopt those too! So now you can finally share a global CSS theme file across both Light and Shadow DOM. Web standards ftw! | ||
|
||
```js | ||
import themeSheet from "../theme.css" with { type: "css" }; | ||
import componentSheet from "./header.css" with { type: "css" }; | ||
|
||
const template = document.createElement("template"); | ||
|
||
template.innerHTML = ` | ||
<header><!-- content goes here --></header> | ||
`; | ||
|
||
export default class Header extends HTMLElement { | ||
connectedCallback() { | ||
if (!this.shadowRoot) { | ||
this.attachShadow({ mode: "open" }); | ||
this.shadowRoot.appendChild(template.content.cloneNode(true)); | ||
} | ||
|
||
this.shadowRoot.adoptedStyleSheets = [themeSheet, componentSheet]; | ||
} | ||
} | ||
|
||
customElements.define("x-header", Header); | ||
``` | ||
|
||
> In the case of CSS Module Scripts, Greenwood will handle linking any CSS files used in an Import Attribute and also used in a `<link>` tag in your HTML (like our _theme.css_ in the example above), ensuring a single source of truth for those contents across both your HTML and your JS. | ||
## HTML Web Components | ||
|
||
As detailed in this excellent [blog post](https://blog.jim-nielsen.com/2023/html-web-components/), HTML Web Components are a strategy for leaning more into a less JavaScript dependent flavor of custom elements. Instead of (or in addition to) setting attributes, which would require JavaScript to do anything meaningful with from a content perspective, this options favors nesting the content as HTML. In this way, the custom element can be a nice styling wrapper or progressively enhanced experience on top. This also provides the benefit of playing nicely with CSS, which is global by default, as styling is not restricted by the encapsulation of the Shadow DOM. (think of it as a Light DOM [`<slot>`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots), if you will.) | ||
|
||
So instead of setting attributes: | ||
|
||
```html | ||
<picture-frame url="/path/to/image.png" title="My Image"></picture-frame> | ||
``` | ||
|
||
You would want to "pass" HTML as children instead: | ||
|
||
```html | ||
<picture-frame> | ||
<h3>My Image<h3> | ||
<img src="/path/to/image.png" alt="My Image"> | ||
</picture-frame> | ||
``` | ||
|
||
With a custom element definition like so: | ||
|
||
```js | ||
// CSS can be referenced from HTML, utility libraries, etc | ||
export default class PictureFrame extends HTMLElement { | ||
connectedCallback() { | ||
this.innerHTML = ` | ||
<div class="picture-frame"> | ||
${this.innerHTML} | ||
</div> | ||
`; | ||
} | ||
} | ||
|
||
customElements.define("picture-frame", PictureFrame); | ||
``` | ||
|
||
> This pattern works great when combined with Greenwood's [**prerendering**](/docs/reference/configuration/#prerender) and [static optimization](/docs/reference/configuration/#optimization) settings for a no-runtime, JS based, SSG build pipeline. Or combine with our CSS Modules ™️ plugin. What's our CSS Modules plugin, you ask? Keep reading. 👇 | ||
## CSS Modules | ||
|
||
We are excited to share a [new plugin](/docs/plugins/css-modules/) we made to support [**CSS Modules ™️**](https://github.com/css-modules/css-modules). **_NOT_** to be confused with CSS Module _scripts_, which we covered at the start of this post, this plugin aims to be a modest implementation of [the specification](https://github.com/css-modules/icss). 🙂 | ||
|
||
With this plugin, create a standard CSS file that ends in _.module.css_: | ||
|
||
```css | ||
/* header.module.css */ | ||
.container { | ||
display: flex; | ||
justify-content: space-between; | ||
} | ||
|
||
.navBarMenu { | ||
border: 1px solid #020202; | ||
} | ||
|
||
.navBarMenuItem { | ||
& a { | ||
text-decoration: none; | ||
color: #020202; | ||
} | ||
} | ||
|
||
@media screen and (min-width: 768px) { | ||
.container { | ||
padding: 10px 20px; | ||
} | ||
} | ||
``` | ||
|
||
And reference that in your Light DOM based custom element: | ||
|
||
```js | ||
// header.js | ||
import styles from "./header.module.css"; | ||
|
||
export default class Header extends HTMLElement { | ||
connectedCallback() { | ||
this.innerHTML = ` | ||
<header class="${styles.container}"> | ||
<ul class="${styles.navBarMenu}"> | ||
<li class="${styles.navBarMenuItem}"> | ||
<a href="/about/" title="Documentation">About</a> | ||
</li> | ||
<li class="${styles.navBarMenuItem}"> | ||
<a href="/contact/" title="Guides">Contact</a> | ||
</li> | ||
</ul> | ||
</header> | ||
`; | ||
} | ||
} | ||
|
||
customElements.define("x-header", Header); | ||
``` | ||
|
||
From there, Greenwood will scope your CSS class names by prefixing them with the filename and a hash, and will then inline that content into a `<style>` tag in your HTML. It will also strip out the reference to the _module.css_ file from your calling file. | ||
|
||
> This plugin works great when combined with Greenwood's [**prerendering**](/docs/reference/configuration/#prerender) and [static optimization](/docs/reference/configuration/#optimization) settings for JS based static HTML generation featuring scoped styles with no JS overhead. | ||
## Honorable Mentions | ||
|
||
The above highlights are by no means the only features delivered in this release, and so let's take a moment to check out some of the other capabilities and enhancements included in this release. | ||
|
||
### Init Refresh | ||
|
||
We gave the initial scaffolding output when running our `@greenwood/init` command a refresh. It now comes with some useful starter code and links to the website for common documentation resources. Try it out today using `npx @greenwood/init@latest my-app`! | ||
|
||
![Greenwood Init Refresh](/assets/blog/greenwood-init-refresh.webp) | ||
|
||
### Lit SSR Enhancements | ||
|
||
In this release, we upgraded our Lit SSR plugin to support Lit v3 and addressed some bugs with our existing implementation. Checkout out the [plugin docs](/docs/plugins/lit-ssr/) for more info and check out our [demo repo](https://github.com/thescientist13/greenwood-lit-ssr) to see it all in action. | ||
|
||
### Content as Data | ||
|
||
We took on a pretty significant overhaul of the feature set related to leveraging the content of your Greenwood project programmatically as data, for creating things like navigation menus, content lists, and more. As of this release, we have deprecated our "menu" feature and replaced it with a more useful and general purpose "Collections" feature (that acts the same in principal), introduced a data client, and made enhancements to page data and frontmatter. Check out the [full docs](/docs/content-as-data/) to learn all about what's new. | ||
|
||
--- | ||
|
||
As always, we're excited to see where the community can take Greenwood and are always available to chat on [GitHub](https://github.com/ProjectEvergreen/greenwood) or [Discord](https://discord.gg/pFbynPar). See you for the next release! ✌️ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters