|
@@ -21,47 +21,47 @@
|
|
</button>
|
|
</button>
|
|
</template>
|
|
</template>
|
|
<script lang="ts">
|
|
<script lang="ts">
|
|
-import {defineComponent, ref,watch,onMounted} from 'vue';
|
|
|
|
|
|
+import {defineComponent, ref, watch, onMounted} from 'vue';
|
|
import {SwitchProps} from "./attribute.ts";
|
|
import {SwitchProps} from "./attribute.ts";
|
|
export default defineComponent({
|
|
export default defineComponent({
|
|
- name:"CptSwitch",
|
|
|
|
- props:SwitchProps,
|
|
|
|
- emits:['update:modelValue'],
|
|
|
|
- setup(props,{emit:e}){
|
|
|
|
|
|
+ name: "CptSwitch",
|
|
|
|
+ props: SwitchProps,
|
|
|
|
+ emits: ['update:modelValue'],
|
|
|
|
+ setup(props, {emit: e}) {
|
|
const switchs = ref();
|
|
const switchs = ref();
|
|
|
|
|
|
const click = () => {
|
|
const click = () => {
|
|
- if(props.loading) return;
|
|
|
|
- if(!props.modelValue){
|
|
|
|
- e('update:modelValue',true)
|
|
|
|
- }else{
|
|
|
|
- e('update:modelValue',false)
|
|
|
|
|
|
+ if (props.loading) return;
|
|
|
|
+ if (!props.modelValue) {
|
|
|
|
+ e('update:modelValue', true)
|
|
|
|
+ } else {
|
|
|
|
+ e('update:modelValue', false)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- const initSwitch = (val:boolean) => {
|
|
|
|
|
|
+ const initSwitch = (val: boolean) => {
|
|
val ? switchs.value.classList.add("cpt-switch-checked") : switchs.value.classList.remove("cpt-switch-checked");
|
|
val ? switchs.value.classList.add("cpt-switch-checked") : switchs.value.classList.remove("cpt-switch-checked");
|
|
}
|
|
}
|
|
- const switchLoading = (val:boolean) => {
|
|
|
|
- if(val){
|
|
|
|
|
|
+ const switchLoading = (val: boolean) => {
|
|
|
|
+ if (val) {
|
|
switchs.value.classList.add("cpt-switch-disabled");
|
|
switchs.value.classList.add("cpt-switch-disabled");
|
|
switchs.value.children[0].classList.add("cpt-switch-loading");
|
|
switchs.value.children[0].classList.add("cpt-switch-loading");
|
|
- }else{
|
|
|
|
|
|
+ } else {
|
|
switchs.value.classList.remove("cpt-switch-disabled");
|
|
switchs.value.classList.remove("cpt-switch-disabled");
|
|
switchs.value.children[0].classList.remove("cpt-switch-loading");
|
|
switchs.value.children[0].classList.remove("cpt-switch-loading");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
initSwitch(props.modelValue);
|
|
initSwitch(props.modelValue);
|
|
- if(!props.disabled){
|
|
|
|
|
|
+ if (!props.disabled) {
|
|
switchLoading(props.loading);
|
|
switchLoading(props.loading);
|
|
}
|
|
}
|
|
})
|
|
})
|
|
- watch(() => props.modelValue,(newV) => {
|
|
|
|
- if(!props.loading){
|
|
|
|
|
|
+ watch(() => props.modelValue, (newV) => {
|
|
|
|
+ if (!props.loading) {
|
|
initSwitch(newV)
|
|
initSwitch(newV)
|
|
}
|
|
}
|
|
})
|
|
})
|
|
- watch(() => props.loading,(newV) => {
|
|
|
|
|
|
+ watch(() => props.loading, (newV) => {
|
|
switchLoading(newV)
|
|
switchLoading(newV)
|
|
})
|
|
})
|
|
|
|
|
|
@@ -73,6 +73,150 @@ export default defineComponent({
|
|
}
|
|
}
|
|
})
|
|
})
|
|
</script>
|
|
</script>
|
|
-<style>
|
|
|
|
-@import url("./switch.css");
|
|
|
|
|
|
+<style lang="css" scoped>
|
|
|
|
+:root {
|
|
|
|
+ --transition: all .2s;
|
|
|
|
+}
|
|
|
|
+.cpt-switch {
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ margin: 0;
|
|
|
|
+ padding: 0;
|
|
|
|
+ color: rgba(0, 0, 0, 0.88);
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ line-height: 22px;
|
|
|
|
+ list-style: none;
|
|
|
|
+ position: relative;
|
|
|
|
+ display: inline-block;
|
|
|
|
+ min-width: 44px;
|
|
|
|
+ height: 22px;
|
|
|
|
+ vertical-align: middle;
|
|
|
|
+ background: rgba(0, 0, 0, 0.25);
|
|
|
|
+ border: 0;
|
|
|
|
+ border-radius: 100px;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ transition: var(--transition);
|
|
|
|
+ user-select: none;
|
|
|
|
+ /* outline: #f00; */
|
|
|
|
+}
|
|
|
|
+.cpt-switch-small {
|
|
|
|
+ width: 28px !important;
|
|
|
|
+ height: 16px !important;
|
|
|
|
+}
|
|
|
|
+.cpt-switch .inner {
|
|
|
|
+ display: block;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ height: 100%;
|
|
|
|
+ padding-inline-start: 24px;
|
|
|
|
+ padding-inline-end: 9px;
|
|
|
|
+ border-radius: 100px;
|
|
|
|
+ font-size: 12px;
|
|
|
|
+ color: #fff;
|
|
|
|
+ transition: var(--transition);
|
|
|
|
+}
|
|
|
|
+.cpt-switch .inner span {
|
|
|
|
+ display: block;
|
|
|
|
+ transition: var(--transition);
|
|
|
|
+}
|
|
|
|
+.cpt-switch .handle {
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 2px;
|
|
|
|
+ inset-inline-start: 2px;
|
|
|
|
+ width: 18px;
|
|
|
|
+ transition: var(--transition);
|
|
|
|
+ height: 18px;
|
|
|
|
+}
|
|
|
|
+.cpt-switch .handle:before {
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 0;
|
|
|
|
+ inset-inline-end: 0;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ inset-inline-start: 0;
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ border-radius: 9px;
|
|
|
|
+ box-shadow: 0 2px 4px 0 rgba(0, 35, 11, 0.2);
|
|
|
|
+ content: "";
|
|
|
|
+}
|
|
|
|
+.cpt-switch .inner span:first-of-type {
|
|
|
|
+ margin-inline-start: calc(-100% + 22px - 48px);
|
|
|
|
+ margin-inline-end: calc(100% - 22px + 48px);
|
|
|
|
+}
|
|
|
|
+.cpt-switch .inner span:last-of-type {
|
|
|
|
+ margin-inline-start: 0;
|
|
|
|
+ margin-inline-end: 0;
|
|
|
|
+ margin-top: -22px;
|
|
|
|
+}
|
|
|
|
+.cpt-switch:active .handle {
|
|
|
|
+ width: 23px;
|
|
|
|
+}
|
|
|
|
+.cpt-switch:active .inner span:last-of-type {
|
|
|
|
+ margin-inline-end: -3px;
|
|
|
|
+ margin-inline-start: 3px;
|
|
|
|
+}
|
|
|
|
+.cpt-switch-checked {
|
|
|
|
+ background-color: #eb5a10;
|
|
|
|
+}
|
|
|
|
+.cpt-switch-checked .handle {
|
|
|
|
+ inset-inline-start: calc(100% - 20px);
|
|
|
|
+}
|
|
|
|
+.cpt-switch-checked:active .handle {
|
|
|
|
+ inset-inline-start: calc(100% - 23px - 2px);
|
|
|
|
+}
|
|
|
|
+.cpt-switch-checked .inner {
|
|
|
|
+ padding-inline-start: 9px;
|
|
|
|
+ padding-inline-end: 24px;
|
|
|
|
+ display: block;
|
|
|
|
+}
|
|
|
|
+.cpt-switch-checked .inner span:first-of-type {
|
|
|
|
+ margin-inline-start: 0;
|
|
|
|
+ margin-inline-end: 0;
|
|
|
|
+}
|
|
|
|
+.cpt-switch-checked .inner span:last-of-type {
|
|
|
|
+ margin-inline-start: calc(100% - 22px + 48px);
|
|
|
|
+ margin-inline-end: calc(-100% + 22px - 48px);
|
|
|
|
+}
|
|
|
|
+.cpt-switch-checked:active .inner span:first-of-type {
|
|
|
|
+ margin-inline-end: 3px;
|
|
|
|
+ margin-inline-start: -3px;
|
|
|
|
+}
|
|
|
|
+.cpt-switch-checked:active .inner span:last-of-type {
|
|
|
|
+ margin-inline-start: calc(100% - 22px + 48px);
|
|
|
|
+ margin-inline-end: calc(-100% + 22px - 48px);
|
|
|
|
+}
|
|
|
|
+.cpt-switch-disabled {
|
|
|
|
+ cursor: not-allowed;
|
|
|
|
+ opacity: 0.5;
|
|
|
|
+}
|
|
|
|
+.cpt-switch-loading {
|
|
|
|
+ pointer-events: none;
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 18px;
|
|
|
|
+ height: 18px;
|
|
|
|
+ left: -1px;
|
|
|
|
+ top: -1px;
|
|
|
|
+ z-index: 10;
|
|
|
|
+ cursor: no-drop;
|
|
|
|
+}
|
|
|
|
+.cpt-switch-loading::after {
|
|
|
|
+ position: absolute;
|
|
|
|
+ content: '';
|
|
|
|
+ width: calc(18px - 4px);
|
|
|
|
+ height: calc(18px - 4px);
|
|
|
|
+ right: 2px;
|
|
|
|
+ top: 2px;
|
|
|
|
+ border: 1px solid #000;
|
|
|
|
+ border-top: transparent;
|
|
|
|
+ border-right: transparent;
|
|
|
|
+ border-bottom: transparent;
|
|
|
|
+ border-radius: 50%;
|
|
|
|
+ animation: cpt-switch-loading 1s infinite linear;
|
|
|
|
+}
|
|
|
|
+@keyframes cpt-switch-loading {
|
|
|
|
+ 0% {
|
|
|
|
+ transform: rotate(360deg);
|
|
|
|
+ }
|
|
|
|
+ 100% {
|
|
|
|
+ transform: rotate(0deg);
|
|
|
|
+ }
|
|
|
|
+}
|
|
</style>
|
|
</style>
|