Toggle Checkbox Filter Panel
A faceted filter sidebar where each group header uses controls to select its own options. Clearing the filters sets checked on every checkbox, which the group headers follow automatically.
Code
The following example assumes that you have imported the component and set up the theme.
<aside class="filter-panel">54 collapsed lines
<div class="head"> <h3>Filters</h3> <button type="button" class="clear">Clear</button> </div>
<fieldset> <legend> <label> <sv-toggle-checkbox controls="brand-acme brand-globex brand-initech"></sv-toggle-checkbox> Brand </label> </legend>
<label> <sv-toggle-checkbox id="brand-acme"></sv-toggle-checkbox> Acme <span class="count">128</span> </label>
<label> <sv-toggle-checkbox id="brand-globex"></sv-toggle-checkbox> Globex <span class="count">64</span> </label>
<label> <sv-toggle-checkbox id="brand-initech"></sv-toggle-checkbox> Initech <span class="count">17</span> </label> </fieldset>
<fieldset> <legend> <label> <sv-toggle-checkbox controls="ship-free ship-next-day"></sv-toggle-checkbox> Shipping </label> </legend>
<label> <sv-toggle-checkbox id="ship-free"></sv-toggle-checkbox> Free shipping <span class="count">92</span> </label>
<label> <sv-toggle-checkbox id="ship-next-day"></sv-toggle-checkbox> Next day <span class="count">31</span> </label> </fieldset>
<p class="summary">No filters applied</p></aside>
<script type="application/x-typescript" module>22 collapsed lines
const panel = document.querySelector(".filter-panel")!; const options = panel.querySelectorAll<ToggleCheckbox>("fieldset > label sv-toggle-checkbox"); const summary = panel.querySelector(".summary")!;
const update = () => { const active = [...options].filter(option => option.checked); summary.textContent = active.length === 0 ? "No filters applied" : `${active.length} filters applied`; };
const allCheckboxes = panel.querySelectorAll<ToggleCheckbox>("sv-toggle-checkbox");
for (const checkbox of allCheckboxes) { checkbox.addEventListener("checkedchange", update); }
panel.querySelector(".clear")?.addEventListener("click", () => { for (const checkbox of allCheckboxes) { checkbox.checked = false; }
update(); });</script>
<style>68 collapsed lines
.filter-panel { display: grid; gap: 1.25em; max-inline-size: 18rem; 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; align-items: center; justify-content: space-between;
h3 { margin: 0; font-size: 1em; }
.clear { padding: 0; font: inherit; font-size: 0.85em; color: var(--sv-accent); cursor: pointer; background: none; border: none; } }
label { display: flex; gap: 0.6em; align-items: center; cursor: pointer; }
fieldset { display: grid; gap: 0.6em; padding: 0; border: none;
legend { padding: 0; margin-block-end: 0.6em; font-weight: 600; }
> label { padding-inline-start: 1.25em; } }
.count { margin-inline-start: auto; font-size: 0.85em; font-variant-numeric: tabular-nums; color: var(--sv-gray-3); }
.summary { margin: 0; font-size: 0.85em; color: var(--sv-gray-3); } }</style>