Material Design 3 Switch web component — framework-agnostic, built with Lit.
An accessible M3 Switch web component following the Material Design 3 switch specifications. A switch allows users to toggle between on and off states. Works in Angular, React, Vue, Svelte, or plain HTML — no build step required.
- On/off toggle with expressive M3 animation
- Disabled state support
- Form integration (name, value, form attributes)
- Accessible with ARIA
switchrole - Keyboard navigation (Space and Enter keys)
- Framework-agnostic custom element
npm install @banegasn/m3-switch
# or
pnpm add @banegasn/m3-switch
# or
yarn add @banegasn/m3-switch<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>M3 Switch Demo</title>
<script type="module" src="https://cdn.jsdelivr.net/npm/@banegasn/m3-switch/+esm"></script>
<style>
body { font-family: Roboto, sans-serif; padding: 32px; background: #fef7ff; }
.row { display: flex; align-items: center; gap: 16px; margin-bottom: 16px; }
label { font-size: 16px; color: #1d1b20; }
</style>
</head>
<body>
<div class="row">
<m3-switch id="notifications"></m3-switch>
<label>Enable notifications</label>
</div>
<div class="row">
<m3-switch checked></m3-switch>
<label>Dark mode (on)</label>
</div>
<div class="row">
<m3-switch disabled></m3-switch>
<label>Disabled</label>
</div>
<script>
document.getElementById('notifications').addEventListener('switch-change', (e) => {
console.log('Notifications:', e.detail.checked ? 'enabled' : 'disabled');
});
</script>
</body>
</html>import '@banegasn/m3-switch';<m3-switch></m3-switch>
<m3-switch checked></m3-switch>
<m3-switch disabled></m3-switch>import '@banegasn/m3-switch';
const switchElement = document.querySelector('m3-switch');
switchElement.addEventListener('switch-change', (e) => {
console.log('Switch is now:', e.detail.checked);
});import '@banegasn/m3-switch';
function App() {
const [checked, setChecked] = useState(false);
return (
<m3-switch
checked={checked}
onSwitchChange={(e) => setChecked(e.detail.checked)}
/>
);
}import '@banegasn/m3-switch';
@Component({
template: `
<m3-switch
[checked]="isChecked"
(switch-change)="onSwitchChange($event)"
></m3-switch>
`
})
export class MyComponent {
isChecked = false;
onSwitchChange(event: CustomEvent) {
this.isChecked = event.detail.checked;
}
}<template>
<m3-switch
:checked="isChecked"
@switch-change="onSwitchChange"
/>
</template>
<script setup>
import '@banegasn/m3-switch';
import { ref } from 'vue';
const isChecked = ref(false);
const onSwitchChange = (event) => {
isChecked.value = event.detail.checked;
};
</script>| Property | Type | Default | Description |
|---|---|---|---|
checked |
boolean |
false |
Whether the switch is checked (on) |
disabled |
boolean |
false |
Disables the switch |
name |
string |
null |
Name attribute for form submission |
value |
string |
null |
Value attribute for form submission |
form |
string |
null |
Form attribute to associate switch with a form |
aria-label |
string |
null |
ARIA label for accessibility |
aria-labelledby |
string |
null |
ARIA labelled by for accessibility |
| Event | Detail | Description |
|---|---|---|
switch-change |
{ checked: boolean, name: string | null, value: string | null } |
Fired when the switch state changes |
| Method | Description |
|---|---|
focus() |
Focuses the switch |
blur() |
Removes focus from the switch |
You can customize the switch appearance using CSS custom properties:
m3-switch {
--md-switch-track-width: 52px;
--md-switch-track-height: 32px;
--md-switch-thumb-size: 24px;
--md-switch-track-shape: 16px;
--md-switch-thumb-shape: 12px;
--md-sys-color-primary: #6750a4;
--md-sys-color-on-primary: #ffffff;
--md-sys-color-on-surface: #1d1b20;
--md-sys-color-surface-container-highest: #e6e0e9;
}The switch component follows Material Design 3 accessibility guidelines:
- Uses proper ARIA attributes (
role="switch",aria-checked,aria-disabled) - Supports keyboard navigation (Space and Enter keys)
- Provides focus indicators
- Supports screen readers with
aria-labelandaria-labelledby
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- All modern browsers that support Web Components
MIT
