geoproject-app/src/composables/useCssUpdater.js
isUnknown c4d2015a69 refactor: extract reusable UI components and composables from TextSettings
Major refactoring to improve code quality and reduce duplication:

TextSettings.vue: 1127 → 269 lines (-76%)

New composables:
- useCssUpdater.js: generic CSS update/remove functions
- useCssSync.js: CSS parsing to form fields

New UI components:
- UnitToggle.vue: reusable unit selector buttons
- InputWithUnit.vue: number input with unit toggle
- MarginEditor.vue: simple/detailed margin editor with sync

Benefits:
- Reusable components for other settings panels
- Centralized CSS manipulation logic
- Better separation of concerns
- Easier to test and maintain

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 16:30:44 +01:00

120 lines
3.6 KiB
JavaScript

import { useStylesheetStore } from '../stores/stylesheet';
export function useCssUpdater() {
const store = useStylesheetStore();
/**
* Update or add a CSS property for a given selector
*/
const updateStyle = (selector, property, value) => {
const currentBlock = store.extractBlock(selector) || createRule(selector);
if (currentBlock.includes(`${property}:`)) {
const updatedBlock = currentBlock.replace(
new RegExp(`(${property}:\\s*)[^;]+`, 'i'),
`$1${value}`
);
store.content = store.content.replace(currentBlock, updatedBlock);
} else {
const updatedBlock = currentBlock.replace(
/(\s*})$/,
` ${property}: ${value};\n$1`
);
store.content = store.content.replace(currentBlock, updatedBlock);
}
};
/**
* Remove a CSS property from a selector
*/
const removeProperty = (selector, property) => {
const currentBlock = store.extractBlock(selector);
if (!currentBlock) return;
const updatedBlock = currentBlock.replace(
new RegExp(`\\s*${property}:\\s*[^;]+;\\n?`, 'gi'),
''
);
if (updatedBlock !== currentBlock) {
store.content = store.content.replace(currentBlock, updatedBlock);
}
};
/**
* Remove multiple CSS properties from a selector
*/
const removeProperties = (selector, properties) => {
let currentBlock = store.extractBlock(selector);
if (!currentBlock) return;
let updatedBlock = currentBlock;
for (const property of properties) {
updatedBlock = updatedBlock.replace(
new RegExp(`\\s*${property}:\\s*[^;]+;\\n?`, 'gi'),
''
);
}
if (updatedBlock !== currentBlock) {
store.content = store.content.replace(currentBlock, updatedBlock);
}
};
/**
* Create a new CSS rule for a selector
*/
const createRule = (selector) => {
store.content += `\n\n${selector} {\n}\n`;
return `${selector} {\n}`;
};
/**
* Remove detailed margin properties and set shorthand
*/
const setMargin = (selector, value, unit) => {
removeProperties(selector, ['margin-top', 'margin-right', 'margin-bottom', 'margin-left']);
updateStyle(selector, 'margin', `${value}${unit}`);
};
/**
* Remove shorthand margin and set detailed margins
*/
const setDetailedMargins = (selector, top, right, bottom, left) => {
removeProperty(selector, 'margin');
updateStyle(selector, 'margin-top', `${top.value}${top.unit}`);
updateStyle(selector, 'margin-right', `${right.value}${right.unit}`);
updateStyle(selector, 'margin-bottom', `${bottom.value}${bottom.unit}`);
updateStyle(selector, 'margin-left', `${left.value}${left.unit}`);
};
/**
* Remove detailed padding properties and set shorthand
*/
const setPadding = (selector, value, unit) => {
removeProperties(selector, ['padding-top', 'padding-right', 'padding-bottom', 'padding-left']);
updateStyle(selector, 'padding', `${value}${unit}`);
};
/**
* Remove shorthand padding and set detailed padding
*/
const setDetailedPadding = (selector, top, right, bottom, left) => {
removeProperty(selector, 'padding');
updateStyle(selector, 'padding-top', `${top.value}${top.unit}`);
updateStyle(selector, 'padding-right', `${right.value}${right.unit}`);
updateStyle(selector, 'padding-bottom', `${bottom.value}${bottom.unit}`);
updateStyle(selector, 'padding-left', `${left.value}${left.unit}`);
};
return {
updateStyle,
removeProperty,
removeProperties,
createRule,
setMargin,
setDetailedMargins,
setPadding,
setDetailedPadding,
};
}