Newer
Older
<script setup lang="ts">
import { useVModel } from '@vueuse/core';
import { computed } from 'vue';
size?: 'small' | 'large';
theme?:
| 'white'
| 'slate'
| 'blue'
| 'sky'
| 'teal'
| 'lime'
| 'green'
| 'yellow'
| 'orange'
| 'pink'
| 'fuchsia'
| 'purple'
| 'indigo'
| 'rose'
| 'red';
}
const props = defineProps<Props>();
const emit = defineEmits(['update:isActive']);
const isActive = useVModel(props, 'isActive', emit);
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
const colorTheme = computed(() => {
switch (props.theme) {
case 'white':
return '#ffffff';
case 'slate':
return '#64748b';
case 'blue':
return '#3b82f6';
case 'sky':
return '#0ea5e9';
case 'teal':
return '#14b8a6';
case 'lime':
return '#84cc16';
case 'green':
return '#22c55e';
case 'yellow':
return '#eab308';
case 'orange':
return '#f97316';
case 'pink':
return '#ec4899';
case 'fuchsia':
return '#d946ef';
case 'purple':
return '#a855f7';
case 'indigo':
return '#6366f1';
case 'rose':
return '#f43f5e';
case 'red':
return '#ef4444';
}
return '#0ea5e9';
});
const sizes = computed(() => {
if (!props?.size)
return {
containerWidth: 35,
containerHeight: 21,
padding: 3,
borderRadius: 11,
circleSize: 15,
transformXCircle: 14
};
switch (props.size) {
case 'small':
return {
containerWidth: 30,
containerHeight: 18,
padding: 2,
borderRadius: 9,
circleSize: 14,
transformXCircle: 12
};
case 'large':
return {
containerWidth: 40,
containerHeight: 24,
padding: 3,
borderRadius: 12,
circleSize: 18,
transformXCircle: 14
};
}
return '';
});
:style="`min-width: ${sizes.containerWidth}px; min-height: ${sizes.containerHeight}px; border-radius: ${sizes.borderRadius}px; padding: ${sizes.padding}px;`"
class="switcher"
<span
:style="`background-color: ${colorTheme ?? '#0ea5e9'}; border-radius: ${sizes.borderRadius}px;`"
inactiveBackground: !isActive
></span>
<span
:style="`width: ${sizes.circleSize}px; height: ${sizes.circleSize}px; transform: translateX(${isActive ? sizes.transformXCircle : 0}px);`"
class="switcherCircle"
></span>
</button>
</template>
<style scoped>
.switcher {
.activeBackground {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: background-color 0.2s ease-in-out;
.inactiveBackground {
background-color: rgba(187, 197, 204, 0.66) !important;
transition: background-color 0.2s ease-in-out;
.switcher:hover .inactiveBackground {
filter: brightness(90%);
background-color: white;
border-radius: 50%;
transition: transform 0.2s ease-in-out;