Skip to content

WC Counter: Solid

SolidCounter.astro
<my-counter></my-counter>
<script>
import "./wc-counter-solid";
</script>

(source)

wc-counter-solid.ts
import { liftHtml } from "@lift-html/core";
import html from "solid-js/html";
import { createSignal } from "solid-js";
import { render } from "solid-js/web";
const css = /*css*/ `
* { font-size: 200%; }
span {
width: 4rem;
display: inline-block;
text-align: center;
}
button {
width: 4rem; height: 4rem;
border: none;
border-radius: 10px;
background-color: seagreen;
color: white;
outline: none;
cursor: pointer;
}
`;
export const solidCounter = liftHtml("my-counter", {
init() {
const [count, setCount] = createSignal(0);
const App = () =>
html`
<style>
${css}
</style>
<button onClick=${() => setCount(count() - 1)}>-</button>
<span>${count}</span>
<button onClick=${() => setCount(count() + 1)}>+</button>
`;
render(App, this.shadowRoot || this.attachShadow({ mode: "open" }));
},
});

(source)

While I personally dont’t use Shadow DOM you are welcome to do so. In this example you can see that CSS is scoped to the component and even rules like * { font-size: 200%; } do not leak outside of the component.

You can also see that the markup that server returns is initially empty that causes a layout shift when the page is (re)loaded.