Files
tehran_taj/apps/user-app/src/components/ui/ToggleSwitch.vue
T

60 lines
1.7 KiB
Vue
Raw Normal View History

<!--
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>