Repeat Days
A weekday picker for a repeating schedule, the kind found in alarm and habit apps. Each day is a round toggle button whose single letter stays decorative: the aria-label carries the full day name.
The summary line is rebuilt from the group's value on every valuechange. The value comes back in DOM order, so the sentence always lists the days Monday first, no matter the order they were pressed in.
Repeat on M T W T F S S
Repeats every Monday, Wednesday, and Friday
Code
The following example assumes that you have imported the components and set up the theme.
<div class="repeat-days">13 collapsed lines
<span id="repeat-label">Repeat on</span>
<sv-toggle-group class="days" aria-labelledby="repeat-label" value="mon wed fri"> <sv-toggle aria-label="Monday" title="Monday" value="mon">M</sv-toggle> <sv-toggle aria-label="Tuesday" title="Tuesday" value="tue">T</sv-toggle> <sv-toggle aria-label="Wednesday" title="Wednesday" value="wed">W</sv-toggle> <sv-toggle aria-label="Thursday" title="Thursday" value="thu">T</sv-toggle> <sv-toggle aria-label="Friday" title="Friday" value="fri">F</sv-toggle> <sv-toggle aria-label="Saturday" title="Saturday" value="sat">S</sv-toggle> <sv-toggle aria-label="Sunday" title="Sunday" value="sun">S</sv-toggle> </sv-toggle-group>
<p class="summary" aria-live="polite">Repeats every Monday, Wednesday, and Friday</p></div>
<script type="application/x-typescript" module>19 collapsed lines
const DAY_NAMES = { mon: "Monday", tue: "Tuesday", wed: "Wednesday", thu: "Thursday", fri: "Friday", sat: "Saturday", sun: "Sunday", };
const listFormat = new Intl.ListFormat("en", { style: "long", type: "conjunction" });
const days = document.querySelector<ToggleGroup>(".days")!; const summary = document.querySelector(".summary")!;
days.addEventListener("valuechange", () => { const names = days.value.map(day => DAY_NAMES[day as keyof typeof DAY_NAMES]); summary.textContent = names.length > 0 ? `Repeats every ${listFormat.format(names)}` : "Does not repeat"; });</script>
<style>30 collapsed lines
.repeat-days { display: grid; gap: 0.75em; justify-items: center; padding-block: 1em;
> span { font-weight: 600; } }
.days { flex-wrap: wrap; gap: 0.4em; justify-content: center;
sv-toggle { inline-size: 2.2em; block-size: 2.2em; padding: 0; border-radius: 50%; } }
.summary { margin: 0; font-size: 0.85em; color: var(--sv-gray-3); text-align: center; }</style>