Haunted: Hooks for Web Components
I was just chatting with Dave and he told me about Haunted. It’s hooks, but for native web components! Pretty cool. I think the existence of stuff like this makes using web components more and more palatable — particularly in that totally-native no-build-step-needed-at-all kinda way.
I get that there are all sorts of issues with web components, but the things that typically turn me away from them are a lack of nice templating and rerendering and no state management.
But we can knock those two out right quick these days…
First, making a component like is perfectly comfortable:
import { html } from "https://unpkg.com/lit-html/lit-html.js";
import { component } from "https://unpkg.com/haunted/haunted.js";
function App() {
return html`
<div class="module">
Hello, World!
</div>
`;
}
customElements.define("my-app", component(App));
Then we could add some state with hooks:
import { html } from "https://unpkg.com/lit-html/lit-html.js";
import { component, useState} from "https://unpkg.com/haunted/haunted.js";
function App() {
const [name, setName] = useState("Chris");
return html`
<div class="module">
Hello, ${name}!
</div>
`;
}
customElements.define("my-app", component(App));
The CodePen Challenge this week is using the Star Wars API, so let’s make a fetch request and use that to fill state. That’s a great use case for useEffect.
import { html } from "https://unpkg.com/lit-html/lit-html.js";
import { component, useState, useEffect } from "https://unpkg.com/haunted/haunted.js";
function App() {
const [planets, setPlanets] = useState([]);
useEffect(() => {
fetch('https://swapi.co/api/planets/?page=2')
.then(response => {
return response.json();
})
.then(data => {
let planets = data.results;
// remove ones with no diameters
planets = planets.filter(planet => planet.diameter !== "0");
setPlanets(planets);
});
}, []);
return html`
<style>
/* Shadow DOM styles */
</style>
<div class="all-planets">
${planets.map(planet => html`
<div class="planet" style="--dia: ${planet.diameter}px">
<span class="planet-name">
${planet.name}
</span>
</div>
`)}
</div>
`;
}
customElements.define("my-app", component(App));
That’s a proper little web component!
See the Pen
Star Wars API with Haunted.js by Chris Coyier (@chriscoyier)
on CodePen.
The post Haunted: Hooks for Web Components appeared first on CSS-Tricks.