The agnostic-astro package utilizes XElement under-the-hood in order to provide build-time Astro components. These build-time components will help your project get closer to realizing a mostly no client-side runtime…if you do it right, this should mean an all-green 100% Lighthouse performance score! Leverage the benefits of Islands architecture by sending mostly server built agnostic-astro components. Then, sprinkle client-hydrated ones only as needed.
Ensure you've installed and setup the AgnosticUI Astro integration
which will import the required common.min.css
onto your page:
npm i astro-agnosticui
Then add the integration to your astro.config.mjs
(you may need to run Astro with experimental integrations flag astro dev --experimental-integrations
):
import { defineConfig } from 'astro/config';
import agnosticAstro from 'astro-agnosticui';;
export default defineConfig({
integrations: [agnosticAstro()]
});
Then you can import Astro Progress component (agnostic-astro
ships with the astro-agnosticui
integration):
import AgProgress from 'agnostic-astro/Progress.astro';
Here's the agnostic-astro Progress component in use:
<AgProgress class="mbs24 progress-el" max={100} value={0} />
Here's how you might implement the above functionality using only platform JavaScript:
// This is just a demo of how you might control the progress
// with your own application code
const progressElement = document.querySelector('.progress-el');
const playButton = document.querySelector('.start');
const stopButton = document.querySelector('.stop');
let requestAnimationID;
let progress = 0;
// Increments progress by 1 unit then issues RAF request
const step = () => {
playButton.disabled = true;
stopButton.disabled = false;
progress += 1;
progressElement.setAttribute('value', progress.toString());
if (progress === 100) {
playButton.disabled = false;
stopButton.disabled = true;
} else if (progress < 100) {
requestAnimationID = requestAnimationFrame(step);
}
}
// Calls step and stores the RAF ID
requestAnimationID = requestAnimationFrame(step);
// Attaches the start aka play button click handler
playButton.addEventListener('click', () => {
// Circle back to zero if at end
if (progress >= 100) {
progress = 0;
}
requestAnimationID = requestAnimationFrame(step)
})
// Attaches the stop button click handler
stopButton.addEventListener('click', () => {
if (requestAnimationID) {
cancelAnimationFrame(requestAnimationID)
requestAnimationID = undefined
// Re-enable the Play button
playButton.disabled = false
stopButton.disabled = true
}
})