Switch
An on-off switch for a setting that applies as soon as it is flipped.
Switch is a two-state control for a setting the user turns on and off. Useful
wherever the change should apply the moment it is made; for a choice that only
counts once a form is submitted, use Checkbox.
<template>
<div class="flex flex-col gap-3">
<Field.Root
v-for="setting in settings"
:key="setting.name"
class="flex items-center gap-3 data-[disabled=true]:cursor-not-allowed"
:options="{ disabled: setting.disabled, name: setting.name }"
>
<Switch.Root v-model="setting.enabled" :class="track">
<Switch.Thumb :class="thumb" />
</Switch.Root>
<Field.Label :class="label">{{ setting.label }}</Field.Label>
</Field.Root>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Field } from '@maas/mirror/vue/Field'
import { Switch } from '@maas/mirror/vue/Switch'
const track = [
'group/switch flex h-6 w-[2.625rem] items-center p-[0.0625rem]',
'rounded-component-round border-2 border-[transparent] bg-primary-subtle',
'transition-all duration-100 ease-[ease]',
'data-[disabled=true]:pointer-events-none',
'outline-4 outline-transparent focus-visible:focus-ring',
'not-data-[disabled=true]:active:bg-primary-subtle-active',
'data-[state=checked]:bg-accent-solid',
'not-data-[disabled=true]:data-[state=checked]:active:bg-accent-solid-active',
'data-[disabled=true]:bg-disabled-muted',
].join(' ')
const thumb = [
'rounded-component-round bg-primary-light block size-[1.125rem]',
'shadow-[0_0.0625rem_0.125rem_0_oklch(0%_0_none/0.24)]',
'transition-all duration-100 ease-[ease]',
'data-[state=checked]:translate-x-[1.125rem]',
'not-data-[disabled=true]:group-active/switch:w-[1.375rem]',
'not-data-[disabled=true]:group-active/switch:data-[state=checked]:translate-x-[0.875rem]',
'data-[disabled=true]:bg-disabled-light',
].join(' ')
const label = [
'type-component-xs text-surface [--mirror-label-cursor:pointer]',
'data-[disabled=true]:text-disabled-solid',
].join(' ')
const settings = ref([
{
name: 'notifications',
label: 'Email notifications',
enabled: true,
disabled: false,
},
{ name: 'digest', label: 'Weekly digest', enabled: false, disabled: false },
{ name: 'beta', label: 'Beta features', enabled: false, disabled: true },
])
</script>