feat: add automatic CSS formatting with Prettier

Integrates Prettier into the stylesheet store for automatic CSS formatting:
- Installs prettier v3.7.4 with postcss plugin
- Implements formatContent() function using Prettier API
- Auto-formats CSS after 500ms of inactivity (debounced)
- Prevents infinite loops with isFormatting flag
- Ensures consistent indentation and line breaks
- Cleans up extra blank lines and formatting issues

This ensures the CSS in the Code tab stays clean and properly formatted
after reactive edits from TextSettings and PageSettings panels.

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
isUnknown 2025-12-05 16:23:42 +01:00
parent 628f666d6a
commit 94112ab1a8
3 changed files with 55 additions and 2 deletions

16
package-lock.json generated
View file

@ -12,6 +12,7 @@
"highlight.js": "^11.11.1", "highlight.js": "^11.11.1",
"pagedjs": "^0.4.3", "pagedjs": "^0.4.3",
"pinia": "^3.0.4", "pinia": "^3.0.4",
"prettier": "^3.7.4",
"vue": "^3.5.24" "vue": "^3.5.24"
}, },
"devDependencies": { "devDependencies": {
@ -1888,6 +1889,21 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/prettier": {
"version": "3.7.4",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz",
"integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==",
"license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/readdirp": { "node_modules/readdirp": {
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",

View file

@ -13,6 +13,7 @@
"highlight.js": "^11.11.1", "highlight.js": "^11.11.1",
"pagedjs": "^0.4.3", "pagedjs": "^0.4.3",
"pinia": "^3.0.4", "pinia": "^3.0.4",
"prettier": "^3.7.4",
"vue": "^3.5.24" "vue": "^3.5.24"
}, },
"devDependencies": { "devDependencies": {

View file

@ -1,9 +1,44 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { ref } from 'vue'; import { ref, watch } from 'vue';
import cssParsingUtils from '../utils/css-parsing'; import cssParsingUtils from '../utils/css-parsing';
import prettier from 'prettier/standalone';
import parserPostcss from 'prettier/plugins/postcss';
export const useStylesheetStore = defineStore('stylesheet', () => { export const useStylesheetStore = defineStore('stylesheet', () => {
const content = ref(''); const content = ref('');
let formatTimer = null;
let isFormatting = false;
// Format CSS with Prettier
const formatContent = async () => {
if (isFormatting || !content.value) return;
try {
isFormatting = true;
const formatted = await prettier.format(content.value, {
parser: 'css',
plugins: [parserPostcss],
printWidth: 80,
tabWidth: 2,
useTabs: false,
});
content.value = formatted;
} catch (error) {
console.error('CSS formatting error:', error);
} finally {
isFormatting = false;
}
};
// Watch content and format after 500ms of inactivity
watch(content, () => {
if (isFormatting) return;
clearTimeout(formatTimer);
formatTimer = setTimeout(() => {
formatContent();
}, 500);
});
const loadStylesheet = async () => { const loadStylesheet = async () => {
const response = await fetch('/assets/css/stylesheet.css'); const response = await fetch('/assets/css/stylesheet.css');
@ -33,6 +68,7 @@ export const useStylesheetStore = defineStore('stylesheet', () => {
loadStylesheet, loadStylesheet,
updateProperty, updateProperty,
extractValue, extractValue,
extractBlock extractBlock,
formatContent
}; };
}); });