Skip to content

Toggle Checkbox Task List

A checklist that strikes through completed items and counts them. The strikethrough is pure CSS through :has(sv-toggle-checkbox:state(--checked)), so only the counter needs a script.

Release checklist

1 of 4 done

Code

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

Task List
<div class="task-list">
34 collapsed lines
<div class="head">
<h3>Release checklist</h3>
<span class="progress">1 of 4 done</span>
</div>
<ul>
<li>
<label>
<sv-toggle-checkbox checked></sv-toggle-checkbox>
Bump the version
</label>
</li>
<li>
<label>
<sv-toggle-checkbox></sv-toggle-checkbox>
Update the changelog
</label>
</li>
<li>
<label>
<sv-toggle-checkbox></sv-toggle-checkbox>
Run the test suite
</label>
</li>
<li>
<label>
<sv-toggle-checkbox></sv-toggle-checkbox>
Publish the package
</label>
</li>
</ul>
</div>
<script type="application/x-typescript" module>
12 collapsed lines
const list = document.querySelector(".task-list")!;
const tasks = list.querySelectorAll<ToggleCheckbox>("sv-toggle-checkbox");
const progress = list.querySelector(".progress")!;
const update = () => {
const done = [...tasks].filter(task => task.checked).length;
progress.textContent = `${done} of ${tasks.length} done`;
};
for (const task of tasks) {
task.addEventListener("checkedchange", update);
}
</script>
<style>
46 collapsed lines
.task-list {
max-inline-size: 22rem;
padding: 1.25em;
margin-inline: auto;
background-color: var(--sv-gray-7);
border: 1px solid var(--sv-gray-5);
border-radius: var(--sv-bdr-rad-lg);
.head {
display: flex;
gap: 1em;
align-items: baseline;
justify-content: space-between;
h3 {
margin: 0;
font-size: 1em;
}
.progress {
font-size: 0.85em;
color: var(--sv-gray-3);
}
}
ul {
display: grid;
gap: 0.6em;
padding: 0;
margin: 1em 0 0;
list-style: none;
}
label {
display: flex;
gap: 0.6em;
align-items: center;
cursor: pointer;
transition: color 300ms;
&:has(sv-toggle-checkbox:state(--checked)) {
color: var(--sv-gray-3);
text-decoration: line-through;
}
}
}
</style>