Meter And Progress HTML Elements Demo Using SolidJS

2023-01-06
HTML
Javascript
Frontend
SolidJS
TIL
programming

Why

As someone who started dealing with HTML since it was (IIRC) version 3.2, much of my knowledge and usage of the HTML tags dates back if not to 1998 then to 2004 for sure - like, it's still easier for me to think page structure in tables than in grid and flex.

Nonetheless, when I encounter a new tag, it's always fascinating to gie it a try - even if it's not immediately useful. So when I read about <meter> and <progress> tags, I decided to do a little interactive demo out of those. I originally wanted to use Svelte, but since this blog is essentially Markdown rendered by 11ty, that would require changing template engine for one page, so maybe some other day. Instead, I remembered about SolidJS and it seemed like a good option so here we are.

There's deliberately very little styling involved, the only thing that's applied is

    meter, progress {
        width: 500px;
        height: 50px;
    }

Meter

<meter> is intended for a metric-like information display, a number that could go up and down and have a different states (high/low).

The thresholds are specified with min, max, low, optimum and high parameters, like e.g.

    <meter value="20" min="0" max="100" low="25" optimum="50" high="75" id="metric-display" title="Meter Demo"/>

To quickly see the different states, you could or or .

Progress

<progress> element is intended for displaying the state of some process as it progresses from start to end, like a loading or saving status indicator.

However, it could also display a general "in progress" state when no parameter provided:

    <progress max="100"></progress>

When it's more parameterized, it looks different:

(press "Reset" to put it back to 0).

SolidJS

And what about SolidJS? It proved to be a useful and simple way to add reactivity to the page - for example, meter part looks like this inside the <script> tag:

    import { createSignal } from "https://cdn.skypack.dev/solid-js";
    import { render } from "https://cdn.skypack.dev/solid-js/web";
    import html from "https://cdn.skypack.dev/solid-js/html";

    const [metric, setMetric] = createSignal(20);

    const MeterApp = () => {
    
        const metricFromEvent = (event) => {
            setMetric(parseInt(event.target.value));
        };
    
        return html`
            <label for="metric-input">Metric value: </label>
            <input type="number" id="metric-input" min="0" max="100" value="${metric}" step="1" onchange="${metricFromEvent}"/>
            <br/>
            <meter value="${metric}" min="0" max="100" low="25" optimum="50" high="75" id="metric-display" title="Meter Demo"/>
        `;
    };
    render(MeterApp, document.getElementById("meter-demo"));