refactor: extract shared patterns from popup/settings components

- Create useColoris composable (shared Coloris init across 4 files)
- Create useLinkedSpacing composable (linked margin/padding logic from TextSettings)
- Create BasePopup component (shared popup shell, CSS editor, inheritance button)
- Add watchProp helper in ElementPopup (12 watchers → 12 compact lines)
- Use extractSpacing for @page margin parsing in PagePopup and PageSettings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-02-26 15:35:45 +01:00
parent 0c682c78c0
commit 69d5ebe7ed
7 changed files with 816 additions and 1187 deletions

View file

@ -319,13 +319,14 @@
import { ref, computed, watch, onMounted, inject } from 'vue';
import { useStylesheetStore } from '../../stores/stylesheet';
import { useDebounce } from '../../composables/useDebounce';
import Coloris from '@melloware/coloris';
import { useCssSync } from '../../composables/useCssSync';
import { initColoris } from '../../composables/useColoris';
import NumberInput from '../ui/NumberInput.vue';
import { convertUnit } from '../../utils/unit-conversion';
import '@melloware/coloris/dist/coloris.css';
const stylesheetStore = useStylesheetStore();
const { debouncedUpdate } = useDebounce(500);
const { extractSpacing } = useCssSync();
const backgroundColorInput = ref(null);
const activeTab = inject('activeTab', ref('document'));
@ -621,26 +622,17 @@ const syncFromStore = () => {
}
}
const marginMatch = pageBlock.match(
/margin:\s*([0-9.]+)([a-z]+)\s+([0-9.]+)([a-z]+)\s+([0-9.]+)([a-z]+)\s+([0-9.]+)([a-z]+)/i
);
if (marginMatch) {
margins.value.top = {
value: parseFloat(marginMatch[1]),
unit: marginMatch[2],
};
margins.value.right = {
value: parseFloat(marginMatch[3]),
unit: marginMatch[4],
};
margins.value.bottom = {
value: parseFloat(marginMatch[5]),
unit: marginMatch[6],
};
margins.value.left = {
value: parseFloat(marginMatch[7]),
unit: marginMatch[8],
};
const spacing = extractSpacing('@page', 'margin');
if (spacing?.detailed) {
margins.value.top = spacing.detailed.top;
margins.value.right = spacing.detailed.right;
margins.value.bottom = spacing.detailed.bottom;
margins.value.left = spacing.detailed.left;
} else if (spacing?.simple) {
margins.value.top = { ...spacing.simple };
margins.value.right = { ...spacing.simple };
margins.value.bottom = { ...spacing.simple };
margins.value.left = { ...spacing.simple };
}
const bgMatch = pageBlock.match(/background:\s*([^;]+)/);
@ -705,34 +697,7 @@ watch(activeTab, (newTab, oldTab) => {
onMounted(() => {
syncFromStore();
// Initialize Coloris
Coloris.init();
Coloris({
el: '[data-coloris]',
theme: 'pill',
themeMode: 'dark',
formatToggle: true,
alpha: true,
closeButton: true,
closeLabel: 'Fermer',
clearButton: true,
clearLabel: 'Effacer',
swatchesOnly: false,
inline: false,
wrap: true,
swatches: [
'#264653',
'#2a9d8f',
'#e9c46a',
'#f4a261',
'#e76f51',
'#d62828',
'#023e8a',
'#0077b6',
'#ffffff',
'#000000',
],
});
initColoris();
// Initialize button color if value exists
if (background.value.value) {