60 lines
1.7 KiB
Vue
60 lines
1.7 KiB
Vue
<!--
|
|||
|
|
The visual half of an on/off switch: a track and a knob. Deliberately not a
|
||
|
|
control on its own — the row that holds it is the <button role="switch">,
|
||
|
|
so the whole row is one tap target and screen readers announce one switch
|
||
|
|
(see views/user/AppearanceView.vue).
|
||
|
|
|
||
|
|
STRUCTURE IS SHARED, LOOK IS NOT: identical markup and script in user-app
|
||
|
|
and user-app-v2; only the "Look" block differs, per app.
|
||
|
|
-->
|
||
|
|
<template>
|
||
|
|
<span class="tsw" :class="{ 'is-on': on }" aria-hidden="true">
|
||
|
|
<span class="tsw__knob"></span>
|
||
|
|
</span>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
defineProps<{ on: boolean }>()
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped lang="less">
|
||
|
|
/* ── Mechanics (same in both apps) ──────────────────────────── */
|
||
|
|
.tsw {
|
||
|
|
position: relative;
|
||
|
|
flex: 0 0 auto;
|
||
|
|
display: inline-block;
|
||
|
|
width: 46px;
|
||
|
|
height: 28px;
|
||
|
|
border-radius: 999px;
|
||
|
|
transition: background-color 0.22s ease;
|
||
|
|
}
|
||
|
|
|
||
|
|
.tsw__knob {
|
||
|
|
position: absolute;
|
||
|
|
top: 3px;
|
||
|
|
// RTL page: "off" sits on the right (start), "on" slides to the left (end).
|
||
|
|
inset-inline-start: 3px;
|
||
|
|
width: 22px;
|
||
|
|
height: 22px;
|
||
|
|
border-radius: 50%;
|
||
|
|
box-shadow: 0 2px 6px -1px rgba(20, 22, 26, 0.35);
|
||
|
|
transition: transform 0.26s cubic-bezier(0.32, 0.72, 0, 1), background-color 0.22s ease;
|
||
|
|
}
|
||
|
|
|
||
|
|
.tsw.is-on .tsw__knob {
|
||
|
|
transform: translateX(-18px);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ── Look: user-app ─────────────────────────────────────────── */
|
||
|
|
// The app's chosen state is brand green (@primary, as on chips and CTAs).
|
||
|
|
.tsw {
|
||
|
|
background: @lightGray1;
|
||
|
|
}
|
||
|
|
.tsw__knob {
|
||
|
|
background: #fff;
|
||
|
|
}
|
||
|
|
.tsw.is-on {
|
||
|
|
background: @primary;
|
||
|
|
}
|
||
|
|
</style>
|