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 doneCode
The following example assumes that you have imported the component and set up the theme.
<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>