61c73f394d
Sidenav becomes a full-screen overlay on mobile with slide-in animation. Dialog goes full-screen on small screens. Settings dialog gets a mobile nav with hamburger menu. Touch targets and text sizes scaled up for mobile. Slider gets visual checked/unchecked colors. Sidebar auto-closes on mobile route navigation. Resize handle hidden on mobile.
42 lines
1.2 KiB
Vue
42 lines
1.2 KiB
Vue
<script setup>
|
|
const props = defineProps({
|
|
checked: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
id: {
|
|
type: String
|
|
},
|
|
label: {
|
|
type: String
|
|
},
|
|
disabled: {
|
|
type: Boolean
|
|
}
|
|
})
|
|
|
|
const emit = defineEmits(['click'])
|
|
|
|
const active = ref(props.checked);
|
|
|
|
watch(() => props.checked, (newValue) => {
|
|
active.value = newValue;
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<button :id="id" role="switch"
|
|
:class="{
|
|
'checked': active,
|
|
}"
|
|
class="vl-toggle-switch flex items-center w-[2.5em] h-[1.4em] rounded-[100px] bg-[var(--bg-container)] py-0.5 px-1 transition-[background-color] duration-300 ease-[cubic-bezier(0.5,_1,_0.89,_1)]"
|
|
:aria-disabled="(props.disabled === true) ? 'true' : 'false'" :aria-label="label" :aria-labelledby="id"
|
|
:tabindex="(disabled) ? '-1' : '0'" @click="(e) => $emit('click', e)" :aria-checked="active"
|
|
:data-state="(active) ? 'checked' : 'unchecked'">
|
|
<div
|
|
:class="active ? 'bg-gray-100' : 'bg-gray-500 dark:bg-gray-100'"
|
|
class="transform-origin-center-left [will-change:tranform] relative left-0 w-[1em] h-[1em] rounded-full pointer-events-none transition-all duration-300">
|
|
</div>
|
|
</button>
|
|
</template>
|