Skip to content

Progress Ring Children

Slotted content renders centered inside the ring, and elements without a data-* attribute are never overwritten. Here a valuechange listener maps each value range to a message, and data-value-text forwards that text to aria-valuetext.

Confidence Level

Very Low

Code

The following example assumes that you have imported the component and set up the theme.

Progress Ring
<div class="progress-container">
<h3 id="progress-ring-label">Confidence Level</h3>
<sv-progress-ring id="progress-ring" aria-labelledby="progress-ring-label" value="0">
<span class="confidence-message" data-value-text>Very Low</span>
</sv-progress-ring>
<button id="random-value-button" type="button" class="update-button">I'm Feeling Lucky</button>
</div>
<script>
29 collapsed lines
/** @type {HTMLButtonElement} */
const randomValueButton = document.querySelector("#random-value-button");
/** @type {ProgressRing} */
const progressRing = document.querySelector("#progress-ring");
/** @type {HTMLSpanElement} */
const confidenceMessage = document.querySelector(".confidence-message");
randomValueButton.addEventListener("click", () => {
progressRing.value = Math.floor(Math.random() * 100);
});
// Update the confidence message when the progress ring's value changes
progressRing.addEventListener("valuechange", () => {
const currentValue = progressRing.value;
if (currentValue <= 20) {
confidenceMessage.textContent = "Very Low";
} else if (currentValue >= 21 && currentValue <= 40) {
confidenceMessage.textContent = "Low";
} else if (currentValue >= 41 && currentValue <= 60) {
confidenceMessage.textContent = "Moderate";
} else if (currentValue >= 61 && currentValue <= 80) {
confidenceMessage.textContent = "High";
} else if (currentValue >= 81 && currentValue <= 100) {
confidenceMessage.textContent = "Very High";
}
});
</script>
<style>
34 collapsed lines
.progress-container {
display: flex;
flex-direction: column;
gap: 1em;
align-items: center;
}
sv-progress-ring {
--sv-track-thickness: 2px;
--sv-fill-thickness: 10px;
inline-size: 100%;
max-inline-size: 200px;
margin-block: 1em;
&::part(fill) {
filter: drop-shadow(0 0 0.5px rgb(0 0 0 / 50%));
}
.confidence-message {
font-weight: bold;
text-align: center;
}
}
.update-button {
padding: 0.5em 2em;
margin-inline: 0.5em;
color: var(--sv-accent-content);
cursor: pointer;
background-color: var(--sv-accent);
border: none;
border-radius: var(--sv-bdr-rad-md);
}
</style>