Settings Panel with Switches
Problem
You need a settings panel where each toggle takes effect immediately. The switch state must stay in sync with a reactive data model across React, Vue, and Svelte.
Solution
Bind checked to your component's state and listen to the change event. Toggle switches are perfect for settings that take effect immediately.
tsx
import '@vielzeug/sigil/switch';
import { useState } from 'react';
function SettingsPanel() {
const [settings, setSettings] = useState({
notifications: true,
darkMode: false,
autoSave: true,
analytics: false,
});
const handleToggle = (key: keyof typeof settings) => {
setSettings((prev) => ({ ...prev, [key]: !prev[key] }));
};
return (
<div className="settings-panel">
<h3>Application Settings</h3>
<div className="setting-item">
<sg-switch checked={settings.notifications} onChange={() => handleToggle('notifications')} color="primary">
Enable notifications
</sg-switch>
</div>
<div className="setting-item">
<sg-switch checked={settings.darkMode} onChange={() => handleToggle('darkMode')} color="secondary">
Dark mode
</sg-switch>
</div>
<div className="setting-item">
<sg-switch checked={settings.autoSave} onChange={() => handleToggle('autoSave')} color="success">
Auto-save documents
</sg-switch>
</div>
<div className="setting-item">
<sg-switch checked={settings.analytics} onChange={() => handleToggle('analytics')} color="warning">
Share analytics data
</sg-switch>
</div>
</div>
);
}vue
<template>
<div class="settings-panel">
<h3>Application Settings</h3>
<div class="setting-item">
<sg-switch :checked="settings.notifications" @change="handleToggle('notifications')" color="primary">
Enable notifications
</sg-switch>
</div>
<div class="setting-item">
<sg-switch :checked="settings.darkMode" @change="handleToggle('darkMode')" color="secondary">
Dark mode
</sg-switch>
</div>
<div class="setting-item">
<sg-switch :checked="settings.autoSave" @change="handleToggle('autoSave')" color="success">
Auto-save documents
</sg-switch>
</div>
<div class="setting-item">
<sg-switch :checked="settings.analytics" @change="handleToggle('analytics')" color="warning">
Share analytics data
</sg-switch>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
import '@vielzeug/sigil/switch';
const settings = reactive({
notifications: true,
darkMode: false,
autoSave: true,
analytics: false,
});
const handleToggle = (key: keyof typeof settings) => {
settings[key] = !settings[key];
};
</script>svelte
<script>
import '@vielzeug/sigil/switch';
let settings = {
notifications: true,
darkMode: false,
autoSave: true,
analytics: false,
};
function handleToggle(key) {
settings = {
...settings,
[key]: !settings[key],
};
}
</script>
<div class="settings-panel">
<h3>Application Settings</h3>
<div class="setting-item">
<sg-switch
checked={settings.notifications}
on:change={() => handleToggle('notifications')}
color="primary">
Enable notifications
</sg-switch>
</div>
<div class="setting-item">
<sg-switch
checked={settings.darkMode}
on:change={() => handleToggle('darkMode')}
color="secondary">
Dark mode
</sg-switch>
</div>
<div class="setting-item">
<sg-switch
checked={settings.autoSave}
on:change={() => handleToggle('autoSave')}
color="success">
Auto-save documents
</sg-switch>
</div>
<div class="setting-item">
<sg-switch
checked={settings.analytics}
on:change={() => handleToggle('analytics')}
color="warning">
Share analytics data
</sg-switch>
</div>
</div>
<style>
.settings-panel {
max-width: 400px;
padding: 1.5rem;
background: var(--color-canvas);
border-radius: 0.5rem;
box-shadow: var(--shadow-md);
}
.setting-item {
padding: 1rem 0;
border-bottom: 1px solid var(--color-backdrop);
}
.setting-item:last-child {
border-bottom: none;
}
</style>Pitfalls
- Read
e.detail.checkedfrom thechangeevent to get the new state — do not rely on thecheckedattribute value, which may not have updated yet. <sg-switch>emitschange, notinput. Listening forinputwill never fire.- In Vue, use
:checked(property binding), notchecked(attribute), to pass a reactive boolean; attribute binding coerces to a string.