gaoluyang
2 天以前 b64a0deae5b5d33f9e20671a68936b27f0b9b00b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
<script lang="ts" setup>
import { computed } from 'vue';
 
/** 甘特图颜色选择器(ant-design-vue 4.x 暂未提供 ColorPicker,封装原生 input[type=color]) */
defineOptions({ name: 'RouteColorPicker' });
 
const props = withDefaults(
  defineProps<{
    disabled?: boolean;
    modelValue?: string;
  }>(),
  {
    disabled: false,
    modelValue: '',
  },
);
 
const emit = defineEmits<{
  change: [value: string];
  'update:modelValue': [value: string];
}>();
 
/** 用于 input[type=color] 的展示值,必须是合法 hex;非法时回退到 #000000 但不修改 modelValue */
const swatchValue = computed(() =>
  /^#[0-9a-f]{6}$/i.test(props.modelValue ?? '')
    ? (props.modelValue as string)
    : '#000000',
);
 
/** 颜色变化时同步 modelValue */
function handleColorChange(event: Event) {
  const value = (event.target as HTMLInputElement).value;
  emit('update:modelValue', value);
  emit('change', value);
}
</script>
 
<template>
  <div class="flex items-center gap-2">
    <input
      class="route-color-picker__swatch"
      :disabled="disabled"
      type="color"
      :value="swatchValue"
      @change="handleColorChange"
      @input="handleColorChange"
    />
    <span v-if="modelValue">{{ modelValue }}</span>
  </div>
</template>
 
<style scoped>
.route-color-picker__swatch {
  inline-size: 36px;
  block-size: 28px;
  padding: 2px;
  cursor: pointer;
  border: 1px solid var(--ant-color-border, #d9d9d9);
  border-radius: 4px;
}
 
.route-color-picker__swatch:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}
</style>