Edit panel > numberInput : fix decrement function
All checks were successful
Deploy / Build and Deploy to Production (push) Successful in 17s

This commit is contained in:
isUnknown 2026-01-09 10:14:45 +01:00
parent 18e4efc59d
commit ea0994ed45
3 changed files with 185 additions and 48 deletions

View file

@ -57,9 +57,10 @@
<div class="input-with-unit"> <div class="input-with-unit">
<NumberInput <NumberInput
id="margin-top" id="margin-top"
v-model="margins.top.value" :modelValue="margins.top.value"
:min="0" :min="0"
:step="1" :step="1"
@update:modelValue="(value) => margins.top.value = value"
/> />
<div class="unit-toggle"> <div class="unit-toggle">
<button <button
@ -97,9 +98,10 @@
<div class="input-with-unit"> <div class="input-with-unit">
<NumberInput <NumberInput
id="margin-bottom" id="margin-bottom"
v-model="margins.bottom.value" :modelValue="margins.bottom.value"
:min="0" :min="0"
:step="1" :step="1"
@update:modelValue="(value) => margins.bottom.value = value"
/> />
<div class="unit-toggle"> <div class="unit-toggle">
<button <button
@ -137,9 +139,10 @@
<div class="input-with-unit"> <div class="input-with-unit">
<NumberInput <NumberInput
id="margin-left" id="margin-left"
v-model="margins.left.value" :modelValue="margins.left.value"
:min="0" :min="0"
:step="1" :step="1"
@update:modelValue="(value) => margins.left.value = value"
/> />
<div class="unit-toggle"> <div class="unit-toggle">
<button <button
@ -177,9 +180,10 @@
<div class="input-with-unit"> <div class="input-with-unit">
<NumberInput <NumberInput
id="margin-right" id="margin-right"
v-model="margins.right.value" :modelValue="margins.right.value"
:min="0" :min="0"
:step="1" :step="1"
@update:modelValue="(value) => margins.right.value = value"
/> />
<div class="unit-toggle"> <div class="unit-toggle">
<button <button

View file

@ -111,7 +111,8 @@
<div class="input-with-unit"> <div class="input-with-unit">
<NumberInput <NumberInput
id="margin-outer-top" id="margin-outer-top"
v-model="marginOuterDetailed.top.value" :modelValue="marginOuterDetailed.top.value"
@update:modelValue="(value) => marginOuterDetailed.top.value = value"
:min="0" :min="0"
:step="1" :step="1"
/> />
@ -140,7 +141,8 @@
<div class="input-with-unit"> <div class="input-with-unit">
<NumberInput <NumberInput
id="margin-outer-bottom" id="margin-outer-bottom"
v-model="marginOuterDetailed.bottom.value" :modelValue="marginOuterDetailed.bottom.value"
@update:modelValue="(value) => marginOuterDetailed.bottom.value = value"
:min="0" :min="0"
:step="1" :step="1"
/> />
@ -169,7 +171,8 @@
<div class="input-with-unit"> <div class="input-with-unit">
<NumberInput <NumberInput
id="margin-outer-left" id="margin-outer-left"
v-model="marginOuterDetailed.left.value" :modelValue="marginOuterDetailed.left.value"
@update:modelValue="(value) => marginOuterDetailed.left.value = value"
:min="0" :min="0"
:step="1" :step="1"
/> />
@ -198,7 +201,8 @@
<div class="input-with-unit"> <div class="input-with-unit">
<NumberInput <NumberInput
id="margin-outer-right" id="margin-outer-right"
v-model="marginOuterDetailed.right.value" :modelValue="marginOuterDetailed.right.value"
@update:modelValue="(value) => marginOuterDetailed.right.value = value"
:min="0" :min="0"
:step="1" :step="1"
/> />
@ -244,7 +248,8 @@
<div class="input-with-unit"> <div class="input-with-unit">
<NumberInput <NumberInput
id="margin-inner-top" id="margin-inner-top"
v-model="marginInnerDetailed.top.value" :modelValue="marginInnerDetailed.top.value"
@update:modelValue="(value) => marginInnerDetailed.top.value = value"
:min="0" :min="0"
:step="1" :step="1"
/> />
@ -273,7 +278,8 @@
<div class="input-with-unit"> <div class="input-with-unit">
<NumberInput <NumberInput
id="margin-inner-bottom" id="margin-inner-bottom"
v-model="marginInnerDetailed.bottom.value" :modelValue="marginInnerDetailed.bottom.value"
@update:modelValue="(value) => marginInnerDetailed.bottom.value = value"
:min="0" :min="0"
:step="1" :step="1"
/> />
@ -302,7 +308,8 @@
<div class="input-with-unit"> <div class="input-with-unit">
<NumberInput <NumberInput
id="margin-inner-left" id="margin-inner-left"
v-model="marginInnerDetailed.left.value" :modelValue="marginInnerDetailed.left.value"
@update:modelValue="(value) => marginInnerDetailed.left.value = value"
:min="0" :min="0"
:step="1" :step="1"
/> />
@ -331,7 +338,8 @@
<div class="input-with-unit"> <div class="input-with-unit">
<NumberInput <NumberInput
id="margin-inner-right" id="margin-inner-right"
v-model="marginInnerDetailed.right.value" :modelValue="marginInnerDetailed.right.value"
@update:modelValue="(value) => marginInnerDetailed.right.value = value"
:min="0" :min="0"
:step="1" :step="1"
/> />
@ -410,6 +418,21 @@ const marginInnerDetailed = ref({
const marginOuterLinked = ref(false); const marginOuterLinked = ref(false);
const marginInnerLinked = ref(false); const marginInnerLinked = ref(false);
// Track previous values to detect which one changed
const prevMarginOuter = ref({
top: 0,
right: 0,
bottom: 24,
left: 0
});
const prevMarginInner = ref({
top: 0,
right: 0,
bottom: 0,
left: 0
});
let isUpdatingFromStore = false; let isUpdatingFromStore = false;
// Update margin outer unit for all sides // Update margin outer unit for all sides
@ -462,6 +485,47 @@ watch(fontSize, (val) => {
}); });
}, { deep: true }); }, { deep: true });
// Watch when link is toggled
watch(marginOuterLinked, (isLinked) => {
if (isLinked) {
// When linking, sync all to the first non-zero value or top value
const current = marginOuterDetailed.value;
const syncValue = current.top.value || current.bottom.value || current.left.value || current.right.value;
isUpdatingFromStore = true;
marginOuterDetailed.value.top.value = syncValue;
marginOuterDetailed.value.bottom.value = syncValue;
marginOuterDetailed.value.left.value = syncValue;
marginOuterDetailed.value.right.value = syncValue;
prevMarginOuter.value.top = syncValue;
prevMarginOuter.value.bottom = syncValue;
prevMarginOuter.value.left = syncValue;
prevMarginOuter.value.right = syncValue;
isUpdatingFromStore = false;
}
});
watch(marginInnerLinked, (isLinked) => {
if (isLinked) {
// When linking, sync all to the first non-zero value or top value
const current = marginInnerDetailed.value;
const syncValue = current.top.value || current.bottom.value || current.left.value || current.right.value;
isUpdatingFromStore = true;
marginInnerDetailed.value.top.value = syncValue;
marginInnerDetailed.value.bottom.value = syncValue;
marginInnerDetailed.value.left.value = syncValue;
marginInnerDetailed.value.right.value = syncValue;
prevMarginInner.value.top = syncValue;
prevMarginInner.value.bottom = syncValue;
prevMarginInner.value.left = syncValue;
prevMarginInner.value.right = syncValue;
isUpdatingFromStore = false;
}
});
// Watch margin outer values // Watch margin outer values
watch(() => [ watch(() => [
marginOuterDetailed.value.top.value, marginOuterDetailed.value.top.value,
@ -473,21 +537,41 @@ watch(() => [
// If linked, sync all values to the one that changed // If linked, sync all values to the one that changed
if (marginOuterLinked.value) { if (marginOuterLinked.value) {
// Find which value changed and sync others to it const current = {
const top = marginOuterDetailed.value.top.value; top: marginOuterDetailed.value.top.value,
const bottom = marginOuterDetailed.value.bottom.value; bottom: marginOuterDetailed.value.bottom.value,
const left = marginOuterDetailed.value.left.value; left: marginOuterDetailed.value.left.value,
const right = marginOuterDetailed.value.right.value; right: marginOuterDetailed.value.right.value,
};
// Use the max value to determine which one changed (simple heuristic) // Find which value actually changed by comparing with previous
const maxValue = Math.max(top, bottom, left, right); let changedValue = null;
if (current.top !== prevMarginOuter.value.top) changedValue = current.top;
else if (current.bottom !== prevMarginOuter.value.bottom) changedValue = current.bottom;
else if (current.left !== prevMarginOuter.value.left) changedValue = current.left;
else if (current.right !== prevMarginOuter.value.right) changedValue = current.right;
if (changedValue !== null) {
isUpdatingFromStore = true; isUpdatingFromStore = true;
marginOuterDetailed.value.top.value = maxValue; marginOuterDetailed.value.top.value = changedValue;
marginOuterDetailed.value.bottom.value = maxValue; marginOuterDetailed.value.bottom.value = changedValue;
marginOuterDetailed.value.left.value = maxValue; marginOuterDetailed.value.left.value = changedValue;
marginOuterDetailed.value.right.value = maxValue; marginOuterDetailed.value.right.value = changedValue;
// Update previous values
prevMarginOuter.value.top = changedValue;
prevMarginOuter.value.bottom = changedValue;
prevMarginOuter.value.left = changedValue;
prevMarginOuter.value.right = changedValue;
isUpdatingFromStore = false; isUpdatingFromStore = false;
} }
} else {
// Update previous values even when not linked
prevMarginOuter.value.top = marginOuterDetailed.value.top.value;
prevMarginOuter.value.bottom = marginOuterDetailed.value.bottom.value;
prevMarginOuter.value.left = marginOuterDetailed.value.left.value;
prevMarginOuter.value.right = marginOuterDetailed.value.right.value;
}
debouncedUpdate(() => { debouncedUpdate(() => {
setDetailedMargins('p', setDetailedMargins('p',
@ -510,19 +594,41 @@ watch(() => [
// If linked, sync all values to the one that changed // If linked, sync all values to the one that changed
if (marginInnerLinked.value) { if (marginInnerLinked.value) {
const top = marginInnerDetailed.value.top.value; const current = {
const bottom = marginInnerDetailed.value.bottom.value; top: marginInnerDetailed.value.top.value,
const left = marginInnerDetailed.value.left.value; bottom: marginInnerDetailed.value.bottom.value,
const right = marginInnerDetailed.value.right.value; left: marginInnerDetailed.value.left.value,
right: marginInnerDetailed.value.right.value,
};
const maxValue = Math.max(top, bottom, left, right); // Find which value actually changed by comparing with previous
let changedValue = null;
if (current.top !== prevMarginInner.value.top) changedValue = current.top;
else if (current.bottom !== prevMarginInner.value.bottom) changedValue = current.bottom;
else if (current.left !== prevMarginInner.value.left) changedValue = current.left;
else if (current.right !== prevMarginInner.value.right) changedValue = current.right;
if (changedValue !== null) {
isUpdatingFromStore = true; isUpdatingFromStore = true;
marginInnerDetailed.value.top.value = maxValue; marginInnerDetailed.value.top.value = changedValue;
marginInnerDetailed.value.bottom.value = maxValue; marginInnerDetailed.value.bottom.value = changedValue;
marginInnerDetailed.value.left.value = maxValue; marginInnerDetailed.value.left.value = changedValue;
marginInnerDetailed.value.right.value = maxValue; marginInnerDetailed.value.right.value = changedValue;
// Update previous values
prevMarginInner.value.top = changedValue;
prevMarginInner.value.bottom = changedValue;
prevMarginInner.value.left = changedValue;
prevMarginInner.value.right = changedValue;
isUpdatingFromStore = false; isUpdatingFromStore = false;
} }
} else {
// Update previous values even when not linked
prevMarginInner.value.top = marginInnerDetailed.value.top.value;
prevMarginInner.value.bottom = marginInnerDetailed.value.bottom.value;
prevMarginInner.value.left = marginInnerDetailed.value.left.value;
prevMarginInner.value.right = marginInnerDetailed.value.right.value;
}
debouncedUpdate(() => { debouncedUpdate(() => {
setDetailedPadding('p', setDetailedPadding('p',
@ -610,6 +716,21 @@ const syncFromStore = () => {
} }
} }
// Update previous values to match current state
prevMarginOuter.value = {
top: marginOuterDetailed.value.top.value,
right: marginOuterDetailed.value.right.value,
bottom: marginOuterDetailed.value.bottom.value,
left: marginOuterDetailed.value.left.value
};
prevMarginInner.value = {
top: marginInnerDetailed.value.top.value,
right: marginInnerDetailed.value.right.value,
bottom: marginInnerDetailed.value.bottom.value,
left: marginInnerDetailed.value.left.value
};
isUpdatingFromStore = false; isUpdatingFromStore = false;
}; };

View file

@ -19,8 +19,14 @@
:disabled="disabled || (max !== undefined && modelValue >= max)" :disabled="disabled || (max !== undefined && modelValue >= max)"
tabindex="-1" tabindex="-1"
> >
<svg width="8" height="6" viewBox="0 0 8 6" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg
<path d="M4 0L7.4641 6H0.535898L4 0Z" fill="currentColor"/> width="8"
height="6"
viewBox="0 0 8 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M4 0L7.4641 6H0.535898L4 0Z" fill="currentColor" />
</svg> </svg>
</button> </button>
<button <button
@ -30,8 +36,14 @@
:disabled="disabled || (min !== undefined && modelValue <= min)" :disabled="disabled || (min !== undefined && modelValue <= min)"
tabindex="-1" tabindex="-1"
> >
<svg width="8" height="6" viewBox="0 0 8 6" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg
<path d="M4 6L0.535898 0H7.4641L4 6Z" fill="currentColor"/> width="8"
height="6"
viewBox="0 0 8 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M4 6L0.535898 0H7.4641L4 6Z" fill="currentColor" />
</svg> </svg>
</button> </button>
</div> </div>
@ -42,32 +54,32 @@
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
type: Number, type: Number,
required: true required: true,
}, },
min: { min: {
type: Number, type: Number,
default: undefined default: undefined,
}, },
max: { max: {
type: Number, type: Number,
default: undefined default: undefined,
}, },
step: { step: {
type: Number, type: Number,
default: 1 default: 1,
}, },
id: { id: {
type: String, type: String,
default: undefined default: undefined,
}, },
inputClass: { inputClass: {
type: String, type: String,
default: '' default: '',
}, },
disabled: { disabled: {
type: Boolean, type: Boolean,
default: false default: false,
} },
}); });
const emit = defineEmits(['update:modelValue']); const emit = defineEmits(['update:modelValue']);