You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
2.3 KiB
124 lines
2.3 KiB
<script lang="ts" setup>
|
|
import { computed, ref } from 'vue'
|
|
|
|
defineOptions({
|
|
name: 'Switch'
|
|
})
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
size?: 'small' | 'medium' | 'large'
|
|
value?: boolean
|
|
loading?: boolean
|
|
defaultValue?: boolean
|
|
disabled?: boolean
|
|
bgActiveColor?: string
|
|
}>(),
|
|
{
|
|
size: 'medium',
|
|
defaultValue: false,
|
|
disabled: false,
|
|
bgActiveColor: '#0256FF'
|
|
}
|
|
)
|
|
|
|
|
|
const { _width } = formartSize(props.size)
|
|
const _bgActiveColor = computed(() => props.bgActiveColor)
|
|
const status = ref<boolean>()
|
|
status.value = props.value || props.defaultValue
|
|
|
|
|
|
|
|
|
|
const emits = defineEmits<{
|
|
(event: 'change', status: boolean): void
|
|
}>()
|
|
|
|
type tempObj = {
|
|
_width: string
|
|
_height: string
|
|
}
|
|
|
|
function formartSize(str: string): tempObj {
|
|
let _width = "", _height = ""
|
|
if (str === 'small') {
|
|
_width = "40px"
|
|
_height = "20px"
|
|
}
|
|
if (str === 'medium') {
|
|
_width = "40px"
|
|
_height = "20px"
|
|
}
|
|
if (str === 'large') {
|
|
_width = "40px"
|
|
_height = "20px"
|
|
}
|
|
|
|
return { _width, _height }
|
|
}
|
|
|
|
|
|
const handleClick = () => {
|
|
if (!props.disabled) {
|
|
status.value = !status.value
|
|
emits('change', status.value)
|
|
}
|
|
}
|
|
</script>
|
|
<template>
|
|
<div class="d-switch" :class="{ 'is-checked': status }">
|
|
<input
|
|
class="d-switch__input"
|
|
ref="input"
|
|
type="checkbox"
|
|
:checked="status"
|
|
@change="handleClick"
|
|
/>
|
|
<span class="d-switch_action"></span>
|
|
</div>
|
|
</template>
|
|
|
|
|
|
|
|
<style lang="less" scoped>
|
|
.d-switch {
|
|
position: relative;
|
|
height: 18px;
|
|
transition: #0256FF 0.2s;
|
|
width: v-bind(_width);
|
|
background: rgb(117, 117, 117);
|
|
border-radius: 10px;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
vertical-align: middle;
|
|
.d-switch__input {
|
|
position: relative;
|
|
z-index: 1;
|
|
margin: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
opacity: 0;
|
|
}
|
|
.d-switch_action {
|
|
position: absolute;
|
|
transition: 0.2s;
|
|
left: 2px;
|
|
top: 2px;
|
|
z-index: 0;
|
|
height: 14px;
|
|
width: 14px;
|
|
background: #fff;
|
|
border-radius: 50%;
|
|
}
|
|
&.is-checked {
|
|
background: v-bind(_bgActiveColor);
|
|
.d-switch_action {
|
|
left: 100%;
|
|
background: #fff;
|
|
margin-left: -18px;
|
|
}
|
|
}
|
|
}
|
|
|
|
</style>
|
|
|