|
| 1 | +<template> |
| 2 | + <div class="q-px-md q-pb-md"> |
| 3 | + <div class="row no-wrap items-center q-mb-md"> |
| 4 | + <div class="col"> |
| 5 | + <WidgetEditorColorPicker :initial-value="customColorValue" :label="$t('dashboard.widgetEditor.colors.customColor')" @change="customColorValue = $event" /> |
| 6 | + </div> |
| 7 | + <div class="col-auto q-pl-sm"> |
| 8 | + <q-btn flat round dense color="primary" icon="add" :disable="!customColorValue" @click="addColor"> |
| 9 | + <q-tooltip>{{ $t('common.add') }}</q-tooltip> |
| 10 | + </q-btn> |
| 11 | + </div> |
| 12 | + </div> |
| 13 | + |
| 14 | + <div v-if="colorsModel"> |
| 15 | + <div v-for="(color, index) in colorsModel" :key="index" class="color-row row no-wrap items-center q-mb-xs" :class="{ 'color-row--drag-over': activeDropzone === index }" @dragover.prevent="activeDropzone = index" @dragleave="activeDropzone = -1" @drop.prevent="onDropAtIndex(index)"> |
| 16 | + <div class="kn-drag-handle row items-center justify-center" draggable="true" @dragstart="onDragStart(index)" @dragend="activeDropzone = -1"> |
| 17 | + <q-icon name="drag_indicator" size="xs" class="text-grey-5" /> |
| 18 | + </div> |
| 19 | + <div class="color-text-input row items-center"> |
| 20 | + <q-input v-model="colorsModel[index]" dense borderless @update:model-value="colorsChanged" /> |
| 21 | + </div> |
| 22 | + <div class="color-swatch col cursor-pointer" :style="`background-color: ${color}`"> |
| 23 | + <q-menu touch-position> |
| 24 | + <q-color v-model="colorsModel[index]" format-model="hexa" @update:model-value="colorsChanged" /> |
| 25 | + </q-menu> |
| 26 | + </div> |
| 27 | + <div class="kn-action-handle row items-center justify-center"> |
| 28 | + <q-btn flat round dense size="sm" icon="delete" @click="deleteColor(index)" /> |
| 29 | + </div> |
| 30 | + </div> |
| 31 | + </div> |
| 32 | + </div> |
| 33 | +</template> |
| 34 | + |
| 35 | +<script lang="ts"> |
| 36 | +import { defineComponent, PropType } from 'vue' |
| 37 | +import deepcopy from 'deepcopy' |
| 38 | +import WidgetEditorColorPicker from '../../common/WidgetEditorColorPicker.vue' |
| 39 | +
|
| 40 | +export default defineComponent({ |
| 41 | + name: 'map-chart-color-picker', |
| 42 | + components: { WidgetEditorColorPicker }, |
| 43 | + props: { modelValue: { type: Array as PropType<string[]>, required: true } }, |
| 44 | + emits: ['update:modelValue'], |
| 45 | + data() { |
| 46 | + return { |
| 47 | + customColorValue: '#8D8D8D', |
| 48 | + colorsModel: null as string[] | null, |
| 49 | + dragIndex: -1, |
| 50 | + activeDropzone: -1 |
| 51 | + } |
| 52 | + }, |
| 53 | + watch: { |
| 54 | + modelValue() { |
| 55 | + this.colorsModel = deepcopy(this.modelValue) |
| 56 | + } |
| 57 | + }, |
| 58 | + created() { |
| 59 | + this.colorsModel = deepcopy(this.modelValue) |
| 60 | + }, |
| 61 | + methods: { |
| 62 | + onDragStart(index: number) { |
| 63 | + this.dragIndex = index |
| 64 | + }, |
| 65 | + onDropAtIndex(dropIndex: number) { |
| 66 | + if (!this.colorsModel || this.dragIndex === -1 || this.dragIndex === dropIndex) return |
| 67 | + const moved = this.colorsModel.splice(this.dragIndex, 1)[0] |
| 68 | + this.colorsModel.splice(dropIndex, 0, moved) |
| 69 | + this.dragIndex = -1 |
| 70 | + this.activeDropzone = -1 |
| 71 | + this.colorsChanged() |
| 72 | + }, |
| 73 | + addColor() { |
| 74 | + if (!this.colorsModel) return |
| 75 | + this.colorsModel.push(this.customColorValue) |
| 76 | + this.colorsChanged() |
| 77 | + }, |
| 78 | + deleteColor(index: number) { |
| 79 | + if (!this.colorsModel) return |
| 80 | + this.colorsModel.splice(index, 1) |
| 81 | + this.colorsChanged() |
| 82 | + }, |
| 83 | + colorsChanged() { |
| 84 | + this.$emit('update:modelValue', deepcopy(this.colorsModel)) |
| 85 | + } |
| 86 | + } |
| 87 | +}) |
| 88 | +</script> |
| 89 | + |
| 90 | +<style lang="scss" scoped> |
| 91 | +.color-row { |
| 92 | + border-radius: 4px; |
| 93 | + overflow: hidden; |
| 94 | + height: 32px; |
| 95 | + cursor: default; |
| 96 | + transition: box-shadow 0.15s; |
| 97 | + border: 1px solid #d0d0d0; |
| 98 | +
|
| 99 | + &--drag-over { |
| 100 | + box-shadow: 0 -2px 0 0 var(--q-primary); |
| 101 | + } |
| 102 | +
|
| 103 | + .kn-drag-handle { |
| 104 | + width: 28px; |
| 105 | + flex-shrink: 0; |
| 106 | + background-color: #f0f0f0; |
| 107 | + height: 100%; |
| 108 | + cursor: grab; |
| 109 | + } |
| 110 | +
|
| 111 | + .color-swatch { |
| 112 | + flex-shrink: 1; |
| 113 | + height: 100%; |
| 114 | + } |
| 115 | +
|
| 116 | + .color-text-input { |
| 117 | + width: 125px; |
| 118 | + flex-shrink: 0; |
| 119 | + background-color: #f0f0f0; |
| 120 | + padding: 0 4px; |
| 121 | + border: 1px solid #d0d0d0; |
| 122 | +
|
| 123 | + :deep(.q-field__native) { |
| 124 | + font-size: 0.75rem; |
| 125 | + font-family: monospace; |
| 126 | + } |
| 127 | + } |
| 128 | +
|
| 129 | + .kn-action-handle { |
| 130 | + width: 36px; |
| 131 | + flex-shrink: 0; |
| 132 | + background-color: #f0f0f0; |
| 133 | + height: 100%; |
| 134 | + } |
| 135 | +} |
| 136 | +</style> |
0 commit comments