feat WSwitch.vue
parent
1edc1f4bd5
commit
09e7fc82de
@ -0,0 +1,136 @@
|
|||||||
|
<template>
|
||||||
|
<div class="w-switch" :class="{ 'w-switch-on': props.modelValue, 'disabled': props.disabled }" @click="handleChange">
|
||||||
|
<div>
|
||||||
|
<slot name="off">{{ props.offText }}</slot>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<slot name="on">{{ props.onText }}</slot>
|
||||||
|
</div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
onText: {
|
||||||
|
type: String,
|
||||||
|
default: 'ON'
|
||||||
|
},
|
||||||
|
offText: {
|
||||||
|
type: String,
|
||||||
|
default: "OFF"
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(["change", "update:modelValue"])
|
||||||
|
|
||||||
|
const handleChange = () => {
|
||||||
|
if (props.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let d = !props.modelValue;
|
||||||
|
emit("update:modelValue", d);
|
||||||
|
emit("change", d);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.w-switch {
|
||||||
|
position: relative;
|
||||||
|
min-width: 5em;
|
||||||
|
line-height: 1;
|
||||||
|
display: flex;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 2em;
|
||||||
|
height: 2em;
|
||||||
|
color: #FFF;
|
||||||
|
--off-color: #ccc;
|
||||||
|
--on-color: #13ce66;
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
filter: grayscale(.5);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&>div {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 2em;
|
||||||
|
background-color: var(--off-color);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 .5em;
|
||||||
|
transition: all .5s;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&:nth-child(1) {
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
background-color: var(--on-color);
|
||||||
|
padding-right: 2em;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
&:nth-child(3) {
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 2em;
|
||||||
|
height: 2em;
|
||||||
|
background-color: #FFF;
|
||||||
|
padding: .3em;
|
||||||
|
background-clip: content-box;
|
||||||
|
border-radius: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&.w-switch-on>div {
|
||||||
|
|
||||||
|
&:nth-child(1) {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
&:nth-child(3) {
|
||||||
|
left: calc(100% - 2em);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue