refactor: extract debounce logic into shared composable
- Create useDebounce composable to avoid code duplication - Apply debounce to TextSettings margin/padding inputs - Harmonize debounce delay to 500ms across all components - Fix input lag when typing values like "30mm" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
35c9ab1d3b
commit
681517db21
5 changed files with 40 additions and 29 deletions
|
|
@ -274,6 +274,7 @@
|
|||
import { ref, computed, watch } from 'vue';
|
||||
import { useStylesheetStore } from '../stores/stylesheet';
|
||||
import { usePopupPosition } from '../composables/usePopupPosition';
|
||||
import { useDebounce } from '../composables/useDebounce';
|
||||
import NumberInput from './ui/NumberInput.vue';
|
||||
import Coloris from '@melloware/coloris';
|
||||
import '@melloware/coloris/dist/coloris.css';
|
||||
|
|
@ -307,7 +308,7 @@ const colorInput = ref(null);
|
|||
const backgroundInput = ref(null);
|
||||
|
||||
let isUpdatingFromStore = false;
|
||||
let updateTimer = null;
|
||||
const { debouncedUpdate } = useDebounce(500);
|
||||
|
||||
// Style properties
|
||||
const fontFamily = ref({ value: 'Alegreya Sans' });
|
||||
|
|
@ -320,11 +321,6 @@ const background = ref({ value: 'transparent' });
|
|||
const marginOuter = ref({ value: 0, unit: 'mm' });
|
||||
const paddingInner = ref({ value: 0, unit: 'mm' });
|
||||
|
||||
const debouncedUpdate = (callback) => {
|
||||
clearTimeout(updateTimer);
|
||||
updateTimer = setTimeout(callback, 1000);
|
||||
};
|
||||
|
||||
const immediateUpdate = (callback) => {
|
||||
callback();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@
|
|||
import { ref, computed, watch, onMounted } from 'vue';
|
||||
import { useStylesheetStore } from '../stores/stylesheet';
|
||||
import { usePopupPosition } from '../composables/usePopupPosition';
|
||||
import { useDebounce } from '../composables/useDebounce';
|
||||
import NumberInput from './ui/NumberInput.vue';
|
||||
import Coloris from '@melloware/coloris';
|
||||
import '@melloware/coloris/dist/coloris.css';
|
||||
|
|
@ -312,7 +313,7 @@ const inheritanceLocked = ref(true);
|
|||
const backgroundColorInput = ref(null);
|
||||
|
||||
let isUpdatingFromStore = false;
|
||||
let updateTimer = null;
|
||||
const { debouncedUpdate } = useDebounce(500);
|
||||
|
||||
const margins = ref({
|
||||
top: { value: 0, unit: 'mm' },
|
||||
|
|
@ -328,11 +329,6 @@ const background = ref({
|
|||
|
||||
const pattern = ref('');
|
||||
|
||||
const debouncedUpdate = (callback) => {
|
||||
clearTimeout(updateTimer);
|
||||
updateTimer = setTimeout(callback, 1000);
|
||||
};
|
||||
|
||||
const immediateUpdate = (callback) => {
|
||||
callback();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -288,16 +288,17 @@
|
|||
<script setup>
|
||||
import { ref, computed, watch, onMounted, inject } from 'vue';
|
||||
import { useStylesheetStore } from '../../stores/stylesheet';
|
||||
import { useDebounce } from '../../composables/useDebounce';
|
||||
import Coloris from '@melloware/coloris';
|
||||
import NumberInput from '../ui/NumberInput.vue';
|
||||
import '@melloware/coloris/dist/coloris.css';
|
||||
|
||||
const stylesheetStore = useStylesheetStore();
|
||||
const { debouncedUpdate } = useDebounce(500);
|
||||
const backgroundColorInput = ref(null);
|
||||
const activeTab = inject('activeTab', ref('document'));
|
||||
|
||||
let isUpdatingFromStore = false;
|
||||
let updateTimer = null;
|
||||
|
||||
const pageFormat = ref('A4');
|
||||
|
||||
|
|
@ -328,11 +329,6 @@ const pattern = ref('');
|
|||
const pageNumbers = ref(false);
|
||||
const runningTitle = ref(false);
|
||||
|
||||
const debouncedUpdate = (callback) => {
|
||||
clearTimeout(updateTimer);
|
||||
updateTimer = setTimeout(callback, 1000);
|
||||
};
|
||||
|
||||
const immediateUpdate = (callback) => {
|
||||
callback();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -130,9 +130,11 @@ import InputWithUnit from '../ui/InputWithUnit.vue';
|
|||
import MarginEditor from '../ui/MarginEditor.vue';
|
||||
import { useCssUpdater } from '../../composables/useCssUpdater';
|
||||
import { useCssSync } from '../../composables/useCssSync';
|
||||
import { useDebounce } from '../../composables/useDebounce';
|
||||
|
||||
const { updateStyle, setMargin, setDetailedMargins, setPadding, setDetailedPadding } = useCssUpdater();
|
||||
const { extractValue, extractNumericValue, extractSpacing } = useCssSync();
|
||||
const { debouncedUpdate } = useDebounce(500);
|
||||
|
||||
// Constants
|
||||
const fonts = ['Alegreya Sans', 'Arial', 'Georgia', 'Helvetica', 'Times New Roman'];
|
||||
|
|
@ -203,26 +205,32 @@ watch(weight, (val) => {
|
|||
|
||||
watch(fontSize, (val) => {
|
||||
if (isUpdatingFromStore) return;
|
||||
updateStyle('p', 'font-size', `${val.value}${val.unit}`);
|
||||
debouncedUpdate(() => {
|
||||
updateStyle('p', 'font-size', `${val.value}${val.unit}`);
|
||||
});
|
||||
}, { deep: true });
|
||||
|
||||
// Margin/Padding handlers
|
||||
const handleMarginOuterChange = ({ type, simple, detailed }) => {
|
||||
if (isUpdatingFromStore) return;
|
||||
if (type === 'simple') {
|
||||
setMargin('p', simple.value, simple.unit);
|
||||
} else {
|
||||
setDetailedMargins('p', detailed.top, detailed.right, detailed.bottom, detailed.left);
|
||||
}
|
||||
debouncedUpdate(() => {
|
||||
if (type === 'simple') {
|
||||
setMargin('p', simple.value, simple.unit);
|
||||
} else {
|
||||
setDetailedMargins('p', detailed.top, detailed.right, detailed.bottom, detailed.left);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleMarginInnerChange = ({ type, simple, detailed }) => {
|
||||
if (isUpdatingFromStore) return;
|
||||
if (type === 'simple') {
|
||||
setPadding('p', simple.value, simple.unit);
|
||||
} else {
|
||||
setDetailedPadding('p', detailed.top, detailed.right, detailed.bottom, detailed.left);
|
||||
}
|
||||
debouncedUpdate(() => {
|
||||
if (type === 'simple') {
|
||||
setPadding('p', simple.value, simple.unit);
|
||||
} else {
|
||||
setDetailedPadding('p', detailed.top, detailed.right, detailed.bottom, detailed.left);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Sync from store
|
||||
|
|
|
|||
15
src/composables/useDebounce.js
Normal file
15
src/composables/useDebounce.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Composable for debounced updates
|
||||
* @param {number} delay - Debounce delay in milliseconds (default: 500ms)
|
||||
* @returns {Function} debouncedUpdate function
|
||||
*/
|
||||
export function useDebounce(delay = 500) {
|
||||
let timer = null;
|
||||
|
||||
const debouncedUpdate = (callback) => {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(callback, delay);
|
||||
};
|
||||
|
||||
return { debouncedUpdate };
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue