components/switch/switch.ts
45 lines and 9 functions in DrDustinEdwards/capsomer, at commit d3966cc on 2026-10-24. This file on GitHub.
Functions
| Function | Lines | Complexity | Covered | CRAP | Mutation |
|---|---|---|---|---|---|
| stateWord | 4 to 6 | 2 | 33% | OkCRAP 3.2 | No data: mutation testing has not run on this repo yet |
| syncWord | 9 to 14 | 3 | 17% | WatchCRAP 8.2 | No data: mutation testing has not run on this repo yet |
| setSwitch | 18 to 23 | 2 | 17% | OkCRAP 4.3 | No data: mutation testing has not run on this repo yet |
| setBusy | 28 to 33 | 3 | 17% | WatchCRAP 8.2 | No data: mutation testing has not run on this repo yet |
| enhance | 37 to 50 | 2 | 13% | OkCRAP 4.7 | No data: mutation testing has not run on this repo yet |
| onChange | 42 to 42 | 1 | 0% | OkCRAP 2 | No data: mutation testing has not run on this repo yet |
| <anonymous:44> | 44 to 47 | 1 | 0% | OkCRAP 2 | No data: mutation testing has not run on this repo yet |
| <anonymous:49> | 49 to 49 | 1 | 0% | OkCRAP 2 | No data: mutation testing has not run on this repo yet |
| <anonymous:49> | 49 to 49 | 1 | 100% | OkCRAP 1 | No data: mutation testing has not run on this repo yet |
Imports
It imports no other module of this repo. Imported by components/authorship/authorship.ts, components/switch-reason/switch-reason.react.tsx, components/switch-reason/switch-reason.ts, components/switch/switch.react.tsx.
Source
// The switch's behaviour: keeps the state word beside it true. The word is "On" and "Off"
// unless the .cap-switch-state element sets its own in data-on and data-off.
export function stateWord(checked: boolean, on = "On", off = "Off"): string {
return checked ? on : off;
}
// Writes the word for one switch's current state.
export function syncWord(label: Element): void {
const input = label.querySelector<HTMLInputElement>("input[role='switch']");
const word = label.querySelector<HTMLElement>(".cap-switch-state");
if (!input || !word) return;
word.textContent = stateWord(input.checked, word.dataset.on, word.dataset.off);
}
// Moves a switch from code (an Undo, a value from the server) and keeps its word true.
// Fires no change event, so it cannot loop back into the app's own handler.
export function setSwitch(label: Element, checked: boolean): void {
const input = label.querySelector<HTMLInputElement>("input[role='switch']");
if (!input) return;
input.checked = checked;
syncWord(label);
}
// Marks a switch pending while a request for its change runs (aria-busy, drawn as a dashed
// outline), and clears it when the request has answered. The switch is not disabled, so
// focus stays where it is.
export function setBusy(label: Element, busy: boolean): void {
const input = label.querySelector<HTMLInputElement>("input[role='switch']");
if (!input) return;
if (busy) input.setAttribute("aria-busy", "true");
else input.removeAttribute("aria-busy");
}
// Attaches to every [data-cap="switch"] under root that is not attached yet. Returns a
// function that detaches them all.
export function enhance(root: ParentNode = document): () => void {
const undo: Array<() => void> = [];
for (const label of root.querySelectorAll<HTMLElement>("[data-cap='switch']:not([data-cap-ready])")) {
label.dataset.capReady = "";
syncWord(label);
const onChange = () => syncWord(label);
label.addEventListener("change", onChange);
undo.push(() => {
label.removeEventListener("change", onChange);
delete label.dataset.capReady;
});
}
return () => undo.forEach((f) => f());
}