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