Skip to content

Commit

Permalink
Fix color lock feature (#21)
Browse files Browse the repository at this point in the history
* add lock/unlock feature | Fix Bootstrap53Dto

* Auto stash before rebase of "main"

* update fe input types

* add js to preview

* add js to preview

* Add uuid to InputDto | Add isLocked to inputDto | fix input issues

* fix cs
  • Loading branch information
Kerrialn authored Nov 8, 2024
1 parent fb33c5c commit f82c34a
Show file tree
Hide file tree
Showing 10 changed files with 406 additions and 128 deletions.
28 changes: 5 additions & 23 deletions assets/vue/Store/store.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { reactive } from 'vue';
import {reactive} from 'vue';

const state = reactive({
variables: {},
css: null,
isLoading: true,
lockedColors: {},
});

export const store = {
Expand Down Expand Up @@ -34,29 +33,12 @@ export const store = {
state.isLoading = value;
},

// Method to update locked state for specific keys
updateLock(id, locked) {
state.lockedColors[id] = locked;
},

// Function to set random color values, excluding locked colors
setRandomColorVariables() {
Object.keys(state.variables.colors).forEach((key) => {
const colorItem = state.variables.colors[key];
if (!state.lockedColors[key] && colorItem.type === 'color') {
colorItem.value = `#${Math.floor(Math.random() * 16777215)
.toString(16)
.padStart(6, '0')}`;
const color = state.variables.colors[key];
if (!color.isLocked && color.type === 'color') {
color.value = `#${Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0')}`;
}
});
},

resetDefaults(sectionKey) {
if (state.variables[sectionKey]) {
Object.keys(state.variables[sectionKey]).forEach((key) => {
const item = state.variables[sectionKey][key];
item.value = item.default;
});
}
},
}
};
77 changes: 44 additions & 33 deletions assets/vue/controllers/Input/ColorPickerInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
<span>{{ modelValue.label }}</span>
<!-- Lock icon toggle -->
<i
:class="locked ? 'bi bi-lock-fill' : 'bi bi-unlock-fill'"
:class="modelValue.isLocked ? 'bi bi-lock-fill' : 'bi bi-unlock-fill'"
@click="toggleLock"
style="cursor: pointer; margin-left: 0.5rem;"
></i>
</label>
<div class="d-flex justify-content-between align-items-center position-relative">
<!-- Text input for color hex value or SCSS variable -->
<!-- Text input for color hex value, rgb, rgba, or SCSS variable -->
<input
type="text"
:id="modelValue.label"
Expand All @@ -19,15 +19,25 @@
@input="onInput"
@focus="showSuggestions = true"
class="form-control w-75"
:disabled="modelValue.isLocked"
/>

<!-- Color input picker for hex color selection -->
<input
type="color"
:value="currentColor"
@input="updateColorPicker"
class="form-control color-picker"
/>
<!-- Conditionally show color picker or icon for SCSS variable -->
<template v-if="isHexColor(inputValue)">
<input
type="color"
:value="currentColor"
@input="updateColorPicker"
class="form-control color-picker"
:disabled="modelValue.isLocked"
/>
</template>
<template v-else-if="isRgbColor(inputValue)">
<div class="color-preview" :style="{ backgroundColor: inputValue }"></div>
</template>
<template v-else>
<i class="bi bi-currency-dollar fs-4 text-muted"></i> <!-- Icon for SCSS variables -->
</template>

<!-- Suggestions dropdown for SCSS color variables -->
<ul
Expand All @@ -51,82 +61,77 @@

<script>
export default {
name: 'ColorPickerInput',
name: "ColorPickerInput",
props: {
modelValue: {
type: Object,
required: true,
},
colorMap: {
type: Object,
default: () => ({}), // Map of SCSS variable names to hex values
default: () => ({}),
},
},
data() {
return {
inputValue: this.modelValue.value || this.modelValue.default || '#000000',
locked: false, // Track locked state
showSuggestions: false, // Control visibility of autocomplete dropdown
inputValue: this.modelValue.value || this.modelValue.default || "#000000",
showSuggestions: false,
};
},
computed: {
// Filtered suggestions based on the user's input
filteredSuggestions() {
return Object.keys(this.colorMap).filter((variable) =>
variable.toLowerCase().includes(this.inputValue.toLowerCase())
);
},
// Computed color value for the color picker, using `value` if set, otherwise falling back to `default`
currentColor() {
return this.isHexColor(this.modelValue.value) ? this.modelValue.value : this.modelValue.default || '#000000';
if (this.isHexColor(this.inputValue)) return this.inputValue;
if (this.colorMap[this.inputValue]) return this.colorMap[this.inputValue];
return this.modelValue.default || "#000000";
},
},
watch: {
// Watch for changes in modelValue and update inputValue accordingly
modelValue: {
deep: true,
handler(newValue) {
this.inputValue = newValue.value || newValue.default || '#000000';
this.inputValue = newValue.value || newValue.default || "#000000";
},
},
},
methods: {
onInput() {
// Show suggestions when typing in the text input
this.showSuggestions = true;
this.updateModelWithInput(this.inputValue);
},
selectSuggestion(variable) {
// Update input with hex value of selected SCSS variable and close dropdown
const hex = this.colorMap[variable]?.default;
if (hex && this.isHexColor(hex)) {
this.inputValue = hex;
this.updateModelWithInput(hex);
const hex = this.colorMap[variable];
if (hex) {
this.inputValue = variable;
this.updateModelWithInput(variable);
}
this.showSuggestions = false;
},
updateColorPicker(event) {
// Only update the input and model if it's a valid hex color
const color = event.target.value;
if (this.isHexColor(color)) {
this.inputValue = color;
this.updateModelWithInput(color);
}
},
updateModelWithInput(value) {
// Update modelValue.value with the provided value (either hex or SCSS variable)
this.modelValue.value = value;
this.$emit('update:modelValue', this.modelValue);
this.$emit("update:modelValue", this.modelValue);
},
toggleLock() {
// Toggle lock and emit lock state to parent
this.locked = !this.locked;
this.$emit('update-lock', { id: this.id, locked: this.locked });
this.modelValue.isLocked = !this.modelValue.isLocked;
this.$emit("update:modelValue", this.modelValue);
},
isHexColor(value) {
// Check if the value is a valid hex color
return /^#[0-9A-Fa-f]{6}$|^#[0-9A-Fa-f]{3}$/.test(value);
},
isRgbColor(value) {
return /^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+(\s*,\s*[\d.]+)?\)$/.test(value);
},
},
};
</script>
Expand Down Expand Up @@ -158,4 +163,10 @@ export default {
max-height: 150px;
overflow-y: auto;
}
</style>
.color-preview {
width: 30px;
height: 30px;
border-radius: 50%;
}
</style>
Loading

0 comments on commit f82c34a

Please sign in to comment.