Added color picker
This commit is contained in:
@@ -41,6 +41,7 @@
|
|||||||
import AbilityListTile from '/imports/ui/components/AbilityListTile.Story.vue';
|
import AbilityListTile from '/imports/ui/components/AbilityListTile.Story.vue';
|
||||||
import AttributeCard from '/imports/ui/components/AttributeCard.Story.vue';
|
import AttributeCard from '/imports/ui/components/AttributeCard.Story.vue';
|
||||||
import AttributeEdit from '/imports/ui/components/AttributeEdit.Story.vue';
|
import AttributeEdit from '/imports/ui/components/AttributeEdit.Story.vue';
|
||||||
|
import ColorPicker from '/imports/ui/components/ColorPicker.Story.vue';
|
||||||
import ColumnLayout from "/imports/ui/components/ColumnLayout.Story.vue";
|
import ColumnLayout from "/imports/ui/components/ColumnLayout.Story.vue";
|
||||||
import DialogStack from '/imports/ui/dialogStack/DialogStack.Story.vue';
|
import DialogStack from '/imports/ui/dialogStack/DialogStack.Story.vue';
|
||||||
import EffectEdit from '/imports/ui/components/EffectEdit.Story.vue';
|
import EffectEdit from '/imports/ui/components/EffectEdit.Story.vue';
|
||||||
@@ -55,6 +56,7 @@
|
|||||||
AbilityListTile,
|
AbilityListTile,
|
||||||
AttributeCard,
|
AttributeCard,
|
||||||
AttributeEdit,
|
AttributeEdit,
|
||||||
|
ColorPicker,
|
||||||
ColumnLayout,
|
ColumnLayout,
|
||||||
DialogStack,
|
DialogStack,
|
||||||
EffectEdit,
|
EffectEdit,
|
||||||
|
|||||||
26
app/imports/ui/components/ColorPicker.Story.vue
Normal file
26
app/imports/ui/components/ColorPicker.Story.vue
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<v-layout justify-center>
|
||||||
|
<color-picker v-model="color"/>
|
||||||
|
</v-layout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ColorPicker from '/imports/ui/components/ColorPicker.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data(){ return {
|
||||||
|
color: '#CE93D8',
|
||||||
|
}},
|
||||||
|
components: {
|
||||||
|
ColorPicker,
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
color(newColor){
|
||||||
|
console.log(`%c${newColor}`, `background: ${newColor};`);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
</style>
|
||||||
189
app/imports/ui/components/ColorPicker.vue
Normal file
189
app/imports/ui/components/ColorPicker.vue
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<v-menu
|
||||||
|
:close-on-content-click="false"
|
||||||
|
transition="slide-y-transition"
|
||||||
|
lazy
|
||||||
|
v-model="opened"
|
||||||
|
>
|
||||||
|
<v-btn
|
||||||
|
slot="activator"
|
||||||
|
icon
|
||||||
|
>
|
||||||
|
<v-icon>format_paint</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
<div class="white overflow-hidden">
|
||||||
|
<v-item-group v-model="color" mandatory>
|
||||||
|
<v-layout row wrap>
|
||||||
|
<v-item
|
||||||
|
v-for="kebabColorOption in colors"
|
||||||
|
:key="kebabColorOption"
|
||||||
|
:value="kebabToCamelCase(kebabColorOption)"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
slot-scope="{ active, toggle }"
|
||||||
|
:class="[kebabColorOption, kebabShade]"
|
||||||
|
class="color-swatch d-flex align-center"
|
||||||
|
@click="toggle"
|
||||||
|
>
|
||||||
|
<v-scroll-y-transition>
|
||||||
|
<v-icon
|
||||||
|
v-if="active"
|
||||||
|
:dark="isDark(kebabColorOption, kebabShade)"
|
||||||
|
>
|
||||||
|
check
|
||||||
|
</v-icon>
|
||||||
|
</v-scroll-y-transition>
|
||||||
|
</div>
|
||||||
|
</v-item>
|
||||||
|
<div class="spacer" v-for="i in 8"/>
|
||||||
|
</v-layout>
|
||||||
|
</v-item-group>
|
||||||
|
<v-item-group class="mt-2" v-model="shade" mandatory>
|
||||||
|
<v-layout wrap>
|
||||||
|
<v-item
|
||||||
|
v-for="kebabShadeOption in shades"
|
||||||
|
:key="kebabShadeOption"
|
||||||
|
:value="kebabToCamelCase(kebabShadeOption)"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
slot-scope="{ active, toggle }"
|
||||||
|
:class="[kebabColor, kebabShadeOption]"
|
||||||
|
class="shade-swatch d-flex align-center"
|
||||||
|
@click="toggle"
|
||||||
|
>
|
||||||
|
<v-scroll-y-transition>
|
||||||
|
<v-icon
|
||||||
|
v-if="active"
|
||||||
|
:dark="isDark(kebabColor, kebabShadeOption)"
|
||||||
|
>
|
||||||
|
check
|
||||||
|
</v-icon>
|
||||||
|
</v-scroll-y-transition>
|
||||||
|
</div>
|
||||||
|
</v-item>
|
||||||
|
<div class="spacer" v-for="i in 8"/>
|
||||||
|
</v-layout>
|
||||||
|
</v-item-group>
|
||||||
|
<v-layout row class="mt-2">
|
||||||
|
<v-spacer/>
|
||||||
|
<v-btn flat @click="opened = false">Done</v-btn>
|
||||||
|
</v-layout>
|
||||||
|
</div>
|
||||||
|
</v-menu>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import isDarkColor from '/imports/ui/utility/isDarkColor.js';
|
||||||
|
import vuetifyColors from 'vuetify/es5/util/colors';
|
||||||
|
import { kebabToCamelCase, camelToKebabCase } from '/imports/ui/utility/swapCase.js';
|
||||||
|
|
||||||
|
function colorToHex(color, shade = 'base'){
|
||||||
|
color = kebabToCamelCase(color);
|
||||||
|
shade = kebabToCamelCase(shade);
|
||||||
|
return vuetifyColors[color][shade];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create an index of hex colors and what color/shade combination makes them
|
||||||
|
let colorIndex = {};
|
||||||
|
for (let color in vuetifyColors){
|
||||||
|
for (let shade in vuetifyColors[color]){
|
||||||
|
colorIndex[vuetifyColors[color][shade]] = {color, shade};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function hexToColor(hex){
|
||||||
|
return colorIndex[hex.toLowerCase()];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
value: String, //hex string
|
||||||
|
},
|
||||||
|
data(){ return {
|
||||||
|
colors: [
|
||||||
|
'red',
|
||||||
|
'pink',
|
||||||
|
'purple',
|
||||||
|
'deep-purple',
|
||||||
|
'indigo',
|
||||||
|
'blue',
|
||||||
|
'light-blue',
|
||||||
|
'cyan',
|
||||||
|
'teal',
|
||||||
|
'green',
|
||||||
|
'light-green',
|
||||||
|
'lime',
|
||||||
|
'yellow',
|
||||||
|
'amber',
|
||||||
|
'orange',
|
||||||
|
'deep-orange',
|
||||||
|
'brown',
|
||||||
|
'grey',
|
||||||
|
],
|
||||||
|
shades: [
|
||||||
|
'lighten-4',
|
||||||
|
'lighten-3',
|
||||||
|
'lighten-2',
|
||||||
|
'lighten-1',
|
||||||
|
'base',
|
||||||
|
'darken-1',
|
||||||
|
'darken-2',
|
||||||
|
'darken-3',
|
||||||
|
'darken-4',
|
||||||
|
],
|
||||||
|
opened: false,
|
||||||
|
}},
|
||||||
|
methods: {
|
||||||
|
isDark(kebabColor, kebabShade){
|
||||||
|
color = colorToHex(kebabColor, kebabShade);
|
||||||
|
return isDarkColor(color);
|
||||||
|
},
|
||||||
|
kebabToCamelCase,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
combination (){
|
||||||
|
return hexToColor(this.value) || {};
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
get(){
|
||||||
|
return this.combination.color;
|
||||||
|
},
|
||||||
|
set(newColor){
|
||||||
|
this.$emit('input', colorToHex(newColor, this.shade));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
shade: {
|
||||||
|
get(){
|
||||||
|
return this.combination.shade;
|
||||||
|
},
|
||||||
|
set(newShade){
|
||||||
|
this.$emit('input', colorToHex(this.color, newShade));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
kebabColor(){
|
||||||
|
return camelToKebabCase(this.color);
|
||||||
|
},
|
||||||
|
kebabShade(){
|
||||||
|
return camelToKebabCase(this.shade);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.color-swatch, .shade-swatch {
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.v-icon {
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
.layout {
|
||||||
|
max-width: 270px;
|
||||||
|
}
|
||||||
|
.spacer {
|
||||||
|
width: 30px;
|
||||||
|
height: 0;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
7
app/imports/ui/utility/swapCase.js
Normal file
7
app/imports/ui/utility/swapCase.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function kebabToCamelCase(string){
|
||||||
|
return string.replace(/-([a-z0-9])/g, g => g[1].toUpperCase());
|
||||||
|
};
|
||||||
|
|
||||||
|
export function camelToKebabCase(string){
|
||||||
|
return string.replace(/([a-z][A-Z0-9])/g, g => g[0] + '-' + g[1].toLowerCase());
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user