98 lines
2.1 KiB
Vue
98 lines
2.1 KiB
Vue
<template>
|
|
<a-input-number
|
|
v-if="type === 'number'"
|
|
:default-value="(defaultValue as number)"
|
|
:style="{ width: '80px' }"
|
|
size="small"
|
|
@change="handleChange"
|
|
/>
|
|
<div v-else-if="type === 'color'" class="color-picker-wrapper">
|
|
<input
|
|
type="color"
|
|
:value="colorValue"
|
|
class="color-picker-input"
|
|
@input="handleColorInput"
|
|
/>
|
|
<a-input
|
|
:model-value="colorValue"
|
|
:style="{ width: '88px', marginLeft: '8px' }"
|
|
size="small"
|
|
@update:model-value="handleColorChange"
|
|
/>
|
|
</div>
|
|
<a-switch
|
|
v-else
|
|
:default-checked="(defaultValue as boolean)"
|
|
size="small"
|
|
@change="handleChange"
|
|
/>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { computed } from 'vue';
|
|
|
|
const props = defineProps({
|
|
type: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
name: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
defaultValue: {
|
|
type: [String, Boolean, Number],
|
|
default: '',
|
|
},
|
|
});
|
|
const emit = defineEmits(['inputChange']);
|
|
|
|
const colorValue = computed(() => {
|
|
const v = props.defaultValue as string;
|
|
if (!v || typeof v !== 'string') return '#007979';
|
|
return v.startsWith('#') ? v : `#${v}`;
|
|
});
|
|
|
|
const handleChange = (value: unknown) => {
|
|
emit('inputChange', {
|
|
value,
|
|
key: props.name,
|
|
});
|
|
};
|
|
|
|
const handleColorInput = (e: Event) => {
|
|
const value = (e.target as HTMLInputElement).value;
|
|
handleChange(value);
|
|
};
|
|
|
|
const handleColorChange = (value: string) => {
|
|
const hex = value.startsWith('#') ? value : `#${value}`;
|
|
if (/^#[0-9A-Fa-f]{6}$/.test(hex)) {
|
|
handleChange(hex);
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.color-picker-wrapper {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.color-picker-input {
|
|
width: 32px;
|
|
height: 28px;
|
|
padding: 2px;
|
|
border: 1px solid var(--color-border-2);
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
background: transparent;
|
|
&::-webkit-color-swatch-wrapper {
|
|
padding: 0;
|
|
}
|
|
&::-webkit-color-swatch {
|
|
border: none;
|
|
border-radius: 2px;
|
|
}
|
|
}
|
|
</style>
|