wip bsky client for the web & android bbell.vt3e.cat
at main 123 lines 2.2 kB view raw
1<script setup lang="ts"> 2import { useId } from 'vue' 3 4defineProps<{ 5 label?: string 6}>() 7 8const model = defineModel<boolean>() 9const id = useId() 10 11const toggle = (e: MouseEvent) => { 12 model.value = !model.value 13} 14</script> 15 16<template> 17 <div class="toggle-wrapper" @click.stop="toggle"> 18 <div class="label" v-if="label" :id="`${id}-label`">{{ label }}</div> 19 <button 20 type="button" 21 role="switch" 22 :aria-checked="model" 23 :aria-labelledby="label ? `${id}-label` : undefined" 24 class="toggle-track" 25 :class="{ 'is-checked': model }" 26 > 27 <span class="toggle-thumb"></span> 28 </button> 29 </div> 30</template> 31 32<style scoped lang="scss"> 33@use '@/assets/variables' as *; 34 35.toggle-wrapper { 36 display: flex; 37 align-items: center; 38 justify-content: space-between; 39 gap: 0.75rem; 40 cursor: pointer; 41} 42 43.label { 44 color: hsl(var(--text)); 45 font-weight: 500; 46} 47 48.toggle-track { 49 display: inline-flex; 50 width: 3rem; 51 height: 1.75rem; 52 background-color: hsla(var(--surface1) / 0.85); 53 border-radius: 1rem; 54 border: none; 55 position: relative; 56 cursor: pointer; 57 flex-shrink: 0; 58 59 box-sizing: unset; 60 61 transition-timing-function: $ease-spring; 62 transition-duration: 0.3s; 63 outline-width: 4px; 64 outline-offset: -1px; 65 66 &:active, 67 &:focus-visible { 68 .toggle-thumb { 69 transform: translateX(0.1rem); 70 background-color: hsl(var(--base) / 0.8); 71 } 72 } 73 74 &:focus-visible { 75 outline-color: hsl(var(--accent)); 76 outline-offset: -1px; 77 } 78 79 &:hover { 80 background-color: hsla(var(--surface1) / 1); 81 } 82 83 &:active { 84 .toggle-thumb { 85 width: calc(var(--width) + var(--pressed-grow)); 86 } 87 } 88 89 &.is-checked { 90 background: hsl(var(--accent)); 91 92 .toggle-thumb { 93 transform: translateX(1.25rem); 94 } 95 .toggle-label { 96 color: hsl(var(--text)); 97 } 98 99 &:active { 100 .toggle-thumb { 101 transform: translateX(calc(1.15rem - (var(--pressed-grow)))); 102 } 103 } 104 } 105} 106 107.toggle-thumb { 108 --width: 1.35rem; 109 --pressed-grow: 0.4rem; 110 111 position: absolute; 112 top: 0.2rem; 113 left: 0.2rem; 114 width: var(--width); 115 height: 1.35rem; 116 background: hsl(var(--base)); 117 border-radius: 2rem; 118 119 transition-timing-function: $ease-spring; 120 transition-duration: 0.3s; 121 transition-property: $transition-properties, width; 122} 123</style>