A web component for visual progress of some sort.
npm i -S @substrate-system/progress-barUse a fetch call for progress events.
// fetch with body stream + Content-Length
import { signal, batch } from '@preact/signals'
const state = {
progress: signal(0),
fetchStatus: signal('')
}
async function runFetch () {
batch(() => {
state.progress.value = 0
state.fetchStatus.value = 'fetching...'
})
try {
const res = await fetch(IMG_URL)
if (!res.ok || !res.body) {
throw new Error('bad response: ' + res.status)
}
const total = Number(res.headers.get('Content-Length')) || 0
const reader = res.body.getReader()
let received = 0
while (true) {
const { done, value } = await reader.read()
if (done) break
received += value.byteLength
if (total > 0) {
state.progress.value = (received / total) * 100
}
}
batch(() => {
state.progress.value = 100
state.fetchStatus.value = `done (${received} bytes)`
})
} catch (err) {
state.fetchStatus.value = 'error: ' + (err as Error).message
}
}This exposes ESM and common JS via
package.json exports field.
import '@substrate-system/progress-bar'require('@substrate-system/progress-bar')A number from 0 to 100 that sets the fill width.
<progress-bar progress="42"></progress-bar>The value is parsed with Number() and written to the element's
--progress CSS variable as a percentage.
| Value | Result |
|---|---|
| missing | 0% |
42 |
42% |
99.5 |
99.5% |
150 |
100% |
-10 |
0% |
not-a-number |
0% |
Changing the attribute updates the CSS variable immediately.
const bar = document.querySelector('progress-bar')
bar?.setAttribute('progress', '73')This component does not dispatch custom events. Progress events come from the underlying operation.
import '@substrate-system/progress-bar/css'Or minified:
import '@substrate-system/progress-bar/min/css'These are the defaults:
progress-bar {
--progress-bar-color: #29d;
--progress: 0%;
--progress-height: 3px;
}This calls the global function customElements.define. Just import, then use
the tag in your HTML.
import '@substrate-system/progress-bar'<div>
<!-- progress attributes is percentage -->
<progress-bar progress="10"></progress-bar>
</div>This package exposes minified JS and CSS files too. Copy them to a location that is accessible to your web server, then link to them in HTML.
cp ./node_modules/@substrate-system/progress-bar/dist/index.min.js ./public/progress-bar.min.js
cp ./node_modules/@substrate-system/progress-bar/dist/style.min.css ./public/progress-bar.css<head>
<link rel="stylesheet" href="./progress-bar.css">
</head>
<body>
<!-- ... -->
<script type="module" src="./progress-bar.min.js"></script>
</body>