2020-06-15 11:46:52 +02:00
|
|
|
<template>
|
|
|
|
<div class="color-picker-container">
|
2021-08-19 16:20:40 +02:00
|
|
|
<datalist :id="colorListID">
|
|
|
|
<option v-for="color in defaultColors" :key="color" :value="color" />
|
|
|
|
</datalist>
|
|
|
|
|
|
|
|
<div class="picker">
|
|
|
|
<input
|
|
|
|
class="picker__input"
|
|
|
|
type="color"
|
|
|
|
v-model="color"
|
|
|
|
:list="colorListID"
|
|
|
|
:class="{'is-empty': isEmpty}"
|
|
|
|
/>
|
|
|
|
<svg class="picker__pattern" v-show="isEmpty" viewBox="0 0 22 22" fill="fff">
|
|
|
|
<pattern id="checker" width="11" height="11" patternUnits="userSpaceOnUse" fill="FFF">
|
|
|
|
<rect fill="#cccccc" x="0" width="5.5" height="5.5" y="0"></rect>
|
|
|
|
<rect fill="#cccccc" x="5.5" width="5.5" height="5.5" y="5.5"></rect>
|
|
|
|
</pattern>
|
|
|
|
<rect width="22" height="22" fill="url(#checker)"></rect>
|
|
|
|
</svg>
|
|
|
|
</div>
|
|
|
|
|
2021-11-09 20:09:52 +01:00
|
|
|
<x-button
|
|
|
|
v-if="!isEmpty"
|
|
|
|
:disabled="isEmpty"
|
|
|
|
@click="reset"
|
|
|
|
class="is-small ml-2"
|
|
|
|
:shadow="false"
|
|
|
|
type="secondary"
|
|
|
|
>
|
2021-06-24 01:24:57 +02:00
|
|
|
{{ $t('input.resetColor') }}
|
2021-01-17 18:57:57 +01:00
|
|
|
</x-button>
|
2020-06-15 11:46:52 +02:00
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2021-10-04 14:20:29 +02:00
|
|
|
import {createRandomID} from '@/helpers/randomId'
|
|
|
|
|
2021-08-19 16:20:40 +02:00
|
|
|
const DEFAULT_COLORS = [
|
|
|
|
'#1973ff',
|
|
|
|
'#7F23FF',
|
|
|
|
'#ff4136',
|
|
|
|
'#ff851b',
|
|
|
|
'#ffeb10',
|
|
|
|
'#00db60',
|
|
|
|
]
|
|
|
|
|
2020-09-05 22:35:52 +02:00
|
|
|
export default {
|
|
|
|
name: 'colorPicker',
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
color: '',
|
|
|
|
lastChangeTimeout: null,
|
2021-08-19 16:20:40 +02:00
|
|
|
defaultColors: DEFAULT_COLORS,
|
|
|
|
colorListID: createRandomID(),
|
2020-09-05 22:35:52 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
props: {
|
2021-08-23 21:18:12 +02:00
|
|
|
modelValue: {
|
2020-09-05 22:35:52 +02:00
|
|
|
required: true,
|
2020-06-15 11:46:52 +02:00
|
|
|
},
|
2020-09-05 22:35:52 +02:00
|
|
|
menuPosition: {
|
|
|
|
type: String,
|
|
|
|
default: 'top',
|
2020-06-15 11:46:52 +02:00
|
|
|
},
|
2020-09-05 22:35:52 +02:00
|
|
|
},
|
2021-08-23 21:18:12 +02:00
|
|
|
emits: ['update:modelValue', 'change'],
|
2020-09-05 22:35:52 +02:00
|
|
|
watch: {
|
2021-08-23 21:18:12 +02:00
|
|
|
modelValue: {
|
|
|
|
handler(modelValue) {
|
|
|
|
this.color = modelValue
|
2021-09-08 11:59:38 +02:00
|
|
|
},
|
|
|
|
immediate: true,
|
2020-06-15 11:46:52 +02:00
|
|
|
},
|
2020-09-05 22:35:52 +02:00
|
|
|
color() {
|
|
|
|
this.update()
|
2020-06-15 11:46:52 +02:00
|
|
|
},
|
2020-09-05 22:35:52 +02:00
|
|
|
},
|
2021-01-23 18:41:13 +01:00
|
|
|
computed: {
|
2021-08-19 16:20:40 +02:00
|
|
|
isEmpty() {
|
2021-01-23 18:41:13 +01:00
|
|
|
return this.color === '#000000' || this.color === ''
|
|
|
|
},
|
|
|
|
},
|
2020-09-05 22:35:52 +02:00
|
|
|
methods: {
|
2021-01-31 12:19:34 +01:00
|
|
|
update(force = false) {
|
2020-06-21 20:27:39 +02:00
|
|
|
|
2021-08-19 16:20:40 +02:00
|
|
|
if(this.isEmpty && !force) {
|
2021-01-23 18:41:13 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-09-05 22:35:52 +02:00
|
|
|
if (this.lastChangeTimeout !== null) {
|
|
|
|
clearTimeout(this.lastChangeTimeout)
|
|
|
|
}
|
2020-06-21 20:27:39 +02:00
|
|
|
|
2020-09-05 22:35:52 +02:00
|
|
|
this.lastChangeTimeout = setTimeout(() => {
|
2021-08-23 21:18:12 +02:00
|
|
|
this.$emit('update:modelValue', this.color)
|
2020-09-05 22:35:52 +02:00
|
|
|
this.$emit('change')
|
|
|
|
}, 500)
|
|
|
|
},
|
|
|
|
reset() {
|
|
|
|
// FIXME: I havn't found a way to make it clear to the user the color war reset.
|
|
|
|
// Not sure if verte is capable of this - it does not show the change when setting this.color = ''
|
|
|
|
this.color = ''
|
2021-01-31 12:19:34 +01:00
|
|
|
this.update(true)
|
2020-06-15 11:46:52 +02:00
|
|
|
},
|
2020-09-05 22:35:52 +02:00
|
|
|
},
|
|
|
|
}
|
2021-10-18 14:51:57 +02:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.color-picker-container {
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
// reset / see https://stackoverflow.com/a/11471224/15522256
|
|
|
|
input[type="color"] {
|
|
|
|
-webkit-appearance: none;
|
|
|
|
border: none;
|
|
|
|
}
|
|
|
|
input[type="color"]::-webkit-color-swatch-wrapper {
|
|
|
|
padding: 0;
|
|
|
|
}
|
|
|
|
input[type="color"]::-webkit-color-swatch {
|
|
|
|
border: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
$PICKER_SIZE: 24px;
|
|
|
|
$BORDER_WIDTH: 1px;
|
|
|
|
.picker {
|
|
|
|
display: grid;
|
|
|
|
width: $PICKER_SIZE;
|
|
|
|
height: $PICKER_SIZE;
|
|
|
|
overflow: hidden;
|
|
|
|
border-radius: 100%;
|
2021-11-22 22:12:54 +01:00
|
|
|
border: $BORDER_WIDTH solid var(--grey-300);
|
2021-10-20 15:05:08 +02:00
|
|
|
box-shadow: $shadow;
|
2021-10-18 14:51:57 +02:00
|
|
|
|
|
|
|
& > * {
|
|
|
|
grid-row: 1;
|
|
|
|
grid-column: 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
input.picker__input {
|
|
|
|
padding: 0;
|
|
|
|
width: $PICKER_SIZE - 2 * $BORDER_WIDTH;
|
|
|
|
height: $PICKER_SIZE - 2 * $BORDER_WIDTH;
|
|
|
|
}
|
|
|
|
|
|
|
|
.picker__input.is-empty {
|
|
|
|
opacity: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.picker__pattern {
|
|
|
|
pointer-events: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|