What is it

Switches are used to toggle application state between two mutually exclusive values.

When to use it

Use a switch when the user will see an immediate visible state change. Do not use a switch when the state change will affect future results. The user should not have to perform another action (search, save, etc) for the result to take affect. If the change in state does not take effect immediately, consider a checkbox.

How to use it

The switch label should describe what will happen when the switch is turned to the on state. Frontload labels with keywords.

Include the CSS and JavaScript. An additional handler will need to be created for the actual state change. The CSS implements the visual design of the switch, which is based on the accessibility properties, which are implemented by the JavaScript.

Example

span#example-id(role="switch")
[role=switch]{display:-ms-inline-grid;display:inline-grid;border:1px solid #2e51a1;background-color:#d8d8d8;border-radius:0.75rem;height:1.5rem;width:3rem;-webkit-transition:all 500ms;transition:all 500ms}[role=switch]>span{display:inline-block;background-color:white;border-radius:50%;margin:2%;width:calc(1.5rem - 2%);-webkit-transition:all 500ms;transition:all 500ms}[role=switch][aria-checked=true]{background-color:#2e51a1}[role=switch][aria-checked=true]>span{margin-left:calc(1.5rem - 5%)}
@import "scss/core/switch/_switch"; 
@include switch;
//-		DS2 core (c) 2024 Alexander McIlwraith 
//-		Licensed under CC BY-SA 4.0 

@use "sass:math";

$switch-accent: #2e51a1 !default;     // switch background when switched right (on/ true)
$switch-background: #d8d8d8 !default;   // switch background when switched left (off / false)
$switch-color: white !default;    // the colour of the switch
$switch-height: 1.5rem !default;

@mixin switch {  
	[role='switch'] {
		display: inline-grid;
		border: 1px solid $switch-accent;
		background-color: $switch-background;
		border-radius: math.div($switch-height, 2);
		height: $switch-height;
		width: #{$switch-height * 2};
		transition: all 500ms;
		> span {
			display: inline-block;
			background-color: white;
			border-radius: 50%;
			margin: 2%;
			width: calc(#{$switch-height} - 2%);
			transition: all 500ms;
		}
	
		&[aria-checked="true"] {
			background-color: $switch-accent;
			> span {
				margin-left: calc(#{$switch-height} - 5%);
			}
		}
	}
}
// Note that switch is a reserved word. 
import * as swtch from "./js/core/switch/_switch.js";
swtch.init();
//-		DS2 core (c) 2024 Alexander McIlwraith 
//-		Licensed under CC BY-SA 4.0 

function flip(e) {
	let sw = e.currentTarget;
	switch(sw.getAttribute("aria-checked")) {
		case "true": 
			sw.setAttribute("aria-checked", "false");
		break;
		case "false": 
			sw.setAttribute("aria-checked", "true");
		break;
	}
};

module.exports = {
	init: (p = document) => {
		try {
			p.querySelectorAll("[role='switch']").forEach((sw) => {
				sw.innerHTML = "";
				sw.setAttribute("aria-checked", "false");
				sw.setAttribute("tabindex", "0");
				sw.addEventListener("click", flip, false);
				sw.addEventListener("keypress", flip, false);
			})
		} catch (e) {
			console.warn("Cannot initialise switches.", e);
		}
	}
}