mirror of https://github.com/nocodb/nocodb
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.
104 lines
2.1 KiB
104 lines
2.1 KiB
<script lang="ts" setup> |
|
const props = withDefaults( |
|
defineProps<{ |
|
checked: boolean |
|
disabled?: boolean |
|
size?: 'default' | 'small' | 'xsmall' |
|
placement?: 'left' | 'right' |
|
loading?: boolean |
|
contentWrapperClass?: string |
|
}>(), |
|
{ |
|
size: 'small', |
|
placement: 'left', |
|
loading: false, |
|
contentWrapperClass: '', |
|
}, |
|
) |
|
|
|
const emit = defineEmits(['change', 'update:checked']) |
|
|
|
const checked = useVModel(props, 'checked', emit) |
|
|
|
const { loading, disabled } = toRefs(props) |
|
|
|
const switchSize = computed(() => (['default', 'small'].includes(props.size) ? props.size : undefined)) |
|
|
|
const onChange = (e: boolean, updateValue = false) => { |
|
if (loading.value || disabled.value) return |
|
|
|
if (updateValue) { |
|
checked.value = e |
|
} |
|
|
|
emit('change', e) |
|
} |
|
</script> |
|
|
|
<template> |
|
<span |
|
v-if="placement === 'right' && $slots.default" |
|
class="pr-2" |
|
:class="[ |
|
contentWrapperClass, |
|
{ |
|
'cursor-not-allowed opacity-60': disabled, |
|
'cursor-pointer': !disabled, |
|
}, |
|
]" |
|
@click="onChange(!checked, true)" |
|
> |
|
<slot /> |
|
</span> |
|
<a-switch |
|
v-model:checked="checked" |
|
:disabled="disabled" |
|
class="nc-switch" |
|
:class="{ |
|
'size-xsmall': size === 'xsmall', |
|
}" |
|
:loading="loading" |
|
v-bind="$attrs" |
|
:size="switchSize" |
|
@change="onChange" |
|
> |
|
</a-switch> |
|
<span |
|
v-if="placement === 'left' && $slots.default" |
|
class="pl-2" |
|
:class="[ |
|
contentWrapperClass, |
|
{ |
|
'cursor-not-allowed opacity-60': disabled, |
|
'cursor-pointer': !disabled, |
|
}, |
|
]" |
|
@click="onChange(!checked, true)" |
|
> |
|
<slot /> |
|
</span> |
|
</template> |
|
|
|
<style lang="scss" scoped> |
|
.size-xsmall { |
|
@apply h-3.5 min-w-[26px] leading-[14px]; |
|
|
|
:deep(.ant-switch-handle) { |
|
@apply h-[10px] w-[10px] top-[2px] left-[calc(100%_-_24px)]; |
|
} |
|
|
|
:deep(.ant-switch-inner) { |
|
@apply !mr-[5px] !ml-[18px] !my-0; |
|
} |
|
|
|
&.ant-switch-checked { |
|
:deep(.ant-switch-handle) { |
|
@apply left-[calc(100%_-_12px)]; |
|
} |
|
|
|
:deep(.ant-switch-inner) { |
|
@apply !mr-[18px] !ml-[5px]; |
|
} |
|
} |
|
} |
|
</style>
|
|
|