On this page
ToggleSwitch
An animated toggle switch (InputSwitch) for boolean values with label, three sizes, and validation support.
uwc-toggleswitch is an animated toggle switch for selecting boolean values. It supports a
label, three sizes (small, medium, large), and fires
uwc-change with { checked } on every toggle.
Import
All components
import '@uwc/components';
Selected component (Lit / Angular / Vue)
import { UwcToggleSwitch } from '@uwc/components/toggleswitch';
customElements.define('uwc-toggleswitch', UwcToggleSwitch);
React
import { UwcToggleSwitch } from '@uwc/components/react';
Usage
Lit
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('app-demo')
export class AppDemo extends LitElement {
render() {
return html`
<uwc-toggleswitch
label="Notifications"
@uwc-change=${(e) => console.log(e.detail.checked)}>
</uwc-toggleswitch>
`;
}
}
React
import React from 'react';
import { UwcToggleSwitch } from '@uwc/components/react';
export default function App() {
return (
<UwcToggleSwitch
label="Notifications"
onUwcChange={(e) => console.log(e.detail.checked)}
/>
);
}
Angular
import { Component } from '@angular/core';
import '@uwc/toggleswitch';
@Component({
selector: 'app-root',
standalone: true,
template: `
<uwc-toggleswitch
label="Notifications"
(uwc-change)="onToggle($event)">
</uwc-toggleswitch>
`,
})
export class AppComponent {
onToggle(e: CustomEvent) { console.log(e.detail.checked); }
}
Vue
import '@uwc/toggleswitch';
export default {
template: `
<uwc-toggleswitch
label="Notifications"
@uwc-change="onToggle">
</uwc-toggleswitch>
`,
methods: {
onToggle(e) { console.log(e.detail.checked); },
},
};
Basic Usage
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('app-demo')
export class AppDemo extends LitElement {
render() {
return html`
<div style="display:flex;gap:1.5rem;flex-wrap:wrap;align-items:center;">
<uwc-toggleswitch label="Off"></uwc-toggleswitch>
<uwc-toggleswitch label="On" checked></uwc-toggleswitch>
<uwc-toggleswitch label="Disabled" disabled></uwc-toggleswitch>
</div>
`;
}
}
import React from 'react';
import { UwcToggleSwitch } from '@uwc/components/react';
export default function App() {
return (
<div style={{ display: 'flex', gap: '1.5rem', flexWrap: 'wrap', alignItems: 'center' }}>
<UwcToggleSwitch label="Off" />
<UwcToggleSwitch label="On" checked />
<UwcToggleSwitch label="Disabled" disabled />
</div>
);
}
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<div style="display:flex;gap:1.5rem;flex-wrap:wrap;align-items:center;">
<uwc-toggleswitch label="Off"></uwc-toggleswitch>
<uwc-toggleswitch label="On" checked></uwc-toggleswitch>
<uwc-toggleswitch label="Disabled" disabled></uwc-toggleswitch>
</div>
`
})
export class AppComponent {}
export default {
template: `
<div style="display:flex;gap:1.5rem;flex-wrap:wrap;align-items:center;">
<uwc-toggleswitch label="Off"></uwc-toggleswitch>
<uwc-toggleswitch label="On" checked></uwc-toggleswitch>
<uwc-toggleswitch label="Disabled" disabled></uwc-toggleswitch>
</div>
`
};
Basic
Toggle the switch to flip the boolean state. Listen to uwc-change for
{ checked }.
import { LitElement, html, css } from 'lit';
import { customElement, state } from 'lit/decorators.js';
@customElement('toggleswitch-basic-demo')
export class AppDemo extends LitElement {
static styles = css`
:host { display: block; }
p { margin: .75rem 0 0; font-size: .875rem; color: #374151; }
strong { color: #6366f1; }
`;
@state() checked = false;
render() {
return html`
<uwc-toggleswitch
label="Notifications"
?checked=${this.checked}
@uwc-change=${(e) => { this.checked = e.detail.checked; }}>
</uwc-toggleswitch>
<p>State: <strong>${this.checked ? 'on' : 'off'}</strong></p>
`;
}
}
import React, { useState } from 'react';
import { UwcToggleSwitch } from '@uwc/components/react';
export default function App() {
const [checked, setChecked] = useState(false);
return (
<>
<UwcToggleSwitch
label="Notifications"
checked={checked}
onUwcChange={(e) => setChecked(e.detail.checked)}
/>
<p style={{ marginTop: '.75rem', fontSize: '.875rem', color: '#374151' }}>
State: <strong style={{ color: '#6366f1' }}>{checked ? 'on' : 'off'}</strong>
</p>
</>
);
}
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<uwc-toggleswitch
label="Notifications"
[checked]="checked()"
(uwc-change)="checked.set($event.detail.checked)">
</uwc-toggleswitch>
<p style="margin:.75rem 0 0;font-size:.875rem;color:#374151">
State: <strong style="color:#6366f1">{{ checked() ? 'on' : 'off' }}</strong>
</p>
`
})
export class AppComponent {
readonly checked = signal(false);
}
export default {
data() {
return { checked: false };
},
template: `
<uwc-toggleswitch
label="Notifications"
:checked="checked"
@uwc-change="checked = $event.detail.checked">
</uwc-toggleswitch>
<p style="margin:.75rem 0 0;font-size:.875rem;color:#374151">
State: <strong style="color:#6366f1">{{ checked ? 'on' : 'off' }}</strong>
</p>
`
};
Sizes
Use size for small, medium (default), or
large variants.
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('toggleswitch-sizes-demo')
export class AppDemo extends LitElement {
render() {
return html`
<div style="display:flex;gap:1.5rem;align-items:center;flex-wrap:wrap;">
<uwc-toggleswitch size="small" label="Small" checked></uwc-toggleswitch>
<uwc-toggleswitch size="medium" label="Medium" checked></uwc-toggleswitch>
<uwc-toggleswitch size="large" label="Large" checked></uwc-toggleswitch>
</div>
`;
}
}
import React from 'react';
import { UwcToggleSwitch } from '@uwc/components/react';
export default function App() {
return (
<div style={{ display: 'flex', gap: '1.5rem', alignItems: 'center', flexWrap: 'wrap' }}>
<UwcToggleSwitch size="small" label="Small" checked />
<UwcToggleSwitch size="medium" label="Medium" checked />
<UwcToggleSwitch size="large" label="Large" checked />
</div>
);
}
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<div style="display:flex;gap:1.5rem;align-items:center;flex-wrap:wrap;">
<uwc-toggleswitch size="small" label="Small" checked></uwc-toggleswitch>
<uwc-toggleswitch size="medium" label="Medium" checked></uwc-toggleswitch>
<uwc-toggleswitch size="large" label="Large" checked></uwc-toggleswitch>
</div>
`
})
export class AppComponent {}
export default {
template: `
<div style="display:flex;gap:1.5rem;align-items:center;flex-wrap:wrap;">
<uwc-toggleswitch size="small" label="Small" checked></uwc-toggleswitch>
<uwc-toggleswitch size="medium" label="Medium" checked></uwc-toggleswitch>
<uwc-toggleswitch size="large" label="Large" checked></uwc-toggleswitch>
</div>
`
};
Settings panel
Combine multiple switches to build a real-world settings form.
import { LitElement, html, css } from 'lit';
import { customElement, state } from 'lit/decorators.js';
@customElement('toggleswitch-settings-demo')
export class AppDemo extends LitElement {
static styles = css`
:host { display: block; max-width: 320px; }
.row { display: flex; justify-content: space-between; align-items: center; padding: .75rem 0; border-bottom: 1px solid #e5e7eb; }
.row:last-child { border-bottom: none; }
.label { font-size: .875rem; color: #374151; }
.sublabel { font-size: .75rem; color: #9ca3af; margin-top: .125rem; }
`;
@state() settings = { email: true, push: false, sms: false };
render() {
return html`
<div class="row">
<div><div class="label">Email notifications</div><div class="sublabel">Daily digest</div></div>
<uwc-toggleswitch ?checked=${this.settings.email} @uwc-change=${(e) => { this.settings = {...this.settings, email: e.detail.checked}; }}></uwc-toggleswitch>
</div>
<div class="row">
<div><div class="label">Push notifications</div><div class="sublabel">Real-time alerts</div></div>
<uwc-toggleswitch ?checked=${this.settings.push} @uwc-change=${(e) => { this.settings = {...this.settings, push: e.detail.checked}; }}></uwc-toggleswitch>
</div>
<div class="row">
<div><div class="label">SMS notifications</div><div class="sublabel">Text messages</div></div>
<uwc-toggleswitch ?checked=${this.settings.sms} @uwc-change=${(e) => { this.settings = {...this.settings, sms: e.detail.checked}; }}></uwc-toggleswitch>
</div>
`;
}
}
import React, { useState } from 'react';
import { UwcToggleSwitch } from '@uwc/components/react';
export default function App() {
const [settings, setSettings] = useState({ email: true, push: false, sms: false });
const toggle = (key) => (e) => setSettings(s => ({ ...s, [key]: e.detail.checked }));
const rowStyle = { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '.75rem 0', borderBottom: '1px solid #e5e7eb' };
return (
<div style={{ maxWidth: '320px' }}>
{[
{ key: 'email', label: 'Email notifications', sub: 'Daily digest' },
{ key: 'push', label: 'Push notifications', sub: 'Real-time alerts' },
{ key: 'sms', label: 'SMS notifications', sub: 'Text messages' },
].map(({ key, label, sub }, i, arr) => (
<div key={key} style={{ ...rowStyle, borderBottom: i < arr.length - 1 ? '1px solid #e5e7eb' : 'none' }}>
<div>
<div style={{ fontSize: '.875rem', color: '#374151' }}>{label}</div>
<div style={{ fontSize: '.75rem', color: '#9ca3af', marginTop: '.125rem' }}>{sub}</div>
</div>
<UwcToggleSwitch checked={settings[key]} onUwcChange={toggle(key)} />
</div>
))}
</div>
);
}
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<div style="max-width:320px;">
@for (item of items; track item.key; let last = $last) {
<div style="display:flex;justify-content:space-between;align-items:center;padding:.75rem 0;"
[style.border-bottom]="last ? 'none' : '1px solid #e5e7eb'">
<div>
<div style="font-size:.875rem;color:#374151">{{ item.label }}</div>
<div style="font-size:.75rem;color:#9ca3af;margin-top:.125rem">{{ item.sub }}</div>
</div>
<uwc-toggleswitch [checked]="settings()[item.key]"
(uwc-change)="toggle(item.key, $event.detail.checked)">
</uwc-toggleswitch>
</div>
}
</div>
`
})
export class AppComponent {
readonly settings = signal<Record<string, boolean>>({ email: true, push: false, sms: false });
items = [
{ key: 'email', label: 'Email notifications', sub: 'Daily digest' },
{ key: 'push', label: 'Push notifications', sub: 'Real-time alerts' },
{ key: 'sms', label: 'SMS notifications', sub: 'Text messages' },
];
toggle(key: string, value: boolean) {
this.settings.set({ ...this.settings(), [key]: value });
}
}
export default {
data() {
return {
settings: { email: true, push: false, sms: false },
items: [
{ key: 'email', label: 'Email notifications', sub: 'Daily digest' },
{ key: 'push', label: 'Push notifications', sub: 'Real-time alerts' },
{ key: 'sms', label: 'SMS notifications', sub: 'Text messages' },
],
};
},
methods: {
toggle(key, e) { this.settings[key] = e.detail.checked; },
},
template: `
<div style="max-width:320px;">
<div v-for="(item, i) in items" :key="item.key"
style="display:flex;justify-content:space-between;align-items:center;padding:.75rem 0;"
:style="{ borderBottom: i < items.length - 1 ? '1px solid #e5e7eb' : 'none' }">
<div>
<div style="font-size:.875rem;color:#374151">{{ item.label }}</div>
<div style="font-size:.75rem;color:#9ca3af;margin-top:.125rem">{{ item.sub }}</div>
</div>
<uwc-toggleswitch :checked="settings[item.key]"
@uwc-change="toggle(item.key, $event)">
</uwc-toggleswitch>
</div>
</div>
`
};
Disabled
Set disabled to block interaction.
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('toggleswitch-disabled-demo')
export class AppDemo extends LitElement {
render() {
return html`
<div style="display:flex;gap:1.5rem;align-items:center;flex-wrap:wrap;">
<uwc-toggleswitch label="Disabled off" disabled></uwc-toggleswitch>
<uwc-toggleswitch label="Disabled on" checked disabled></uwc-toggleswitch>
</div>
`;
}
}
import React from 'react';
import { UwcToggleSwitch } from '@uwc/components/react';
export default function App() {
return (
<div style={{ display: 'flex', gap: '1.5rem', alignItems: 'center', flexWrap: 'wrap' }}>
<UwcToggleSwitch label="Disabled off" disabled />
<UwcToggleSwitch label="Disabled on" checked disabled />
</div>
);
}
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<div style="display:flex;gap:1.5rem;align-items:center;flex-wrap:wrap;">
<uwc-toggleswitch label="Disabled off" disabled></uwc-toggleswitch>
<uwc-toggleswitch label="Disabled on" checked disabled></uwc-toggleswitch>
</div>
`
})
export class AppComponent {}
export default {
template: `
<div style="display:flex;gap:1.5rem;align-items:center;flex-wrap:wrap;">
<uwc-toggleswitch label="Disabled off" disabled></uwc-toggleswitch>
<uwc-toggleswitch label="Disabled on" checked disabled></uwc-toggleswitch>
</div>
`
};
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
checked |
— |
— |
Whether the switch is on. |
label |
— |
— |
Label text rendered beside the switch. |
size |
— |
— |
small | medium | large. Default: medium. |
disabled |
— |
— |
Disable the switch. |
invalid |
— |
— |
Mark as invalid. |
name |
— |
— |
Name for form submission. |
Properties
| Name | Type | Default | Description |
|---|---|---|---|
styles |
CSSResultGroup |
[styles] |
— |
checked |
boolean |
false |
— |
label |
string | undefined |
— |
— |
name |
string | undefined |
— |
— |
size |
ToggleSwitchSize |
'medium' |
— |
disabled |
boolean |
false |
— |
invalid |
boolean |
false |
— |
Slots
| Name | Description |
|---|---|
default |
Custom label content (overrides label attr). |
Events
| Name | Type | Description |
|---|---|---|
uwc-change |
CustomEvent |
Fired when the switch is toggled. Detail: { checked }. |
CSS Custom Properties
| Name | Default | Description |
|---|---|---|
--uwc-switch-width |
— |
Track width. Default: 2.75rem. |
--uwc-switch-height |
— |
Track height. Default: 1.5rem. |
--uwc-switch-bg-off |
— |
Track color when off. Default: #d1d5db. |
--uwc-switch-bg-on |
— |
Track color when on. Default: primary. |
--uwc-switch-radius |
— |
Track border radius. Default: full pill. |
CSS Parts
| Name | Description |
|---|---|
track |
The switch track. |
dot |
The sliding thumb. |
label |
The label element. |