feat: implement template-specific CSS inheritance in PagePopup
- Add templateName extracted from data-page-type attribute - When unlocked: edits create/update @page <templateName> block - When re-locked: remove template block, preview returns to @page - Fields retain their values when re-locking (for user convenience) - Display dynamic template name in popup header - Show template-specific CSS block when unlocked 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
ed856972bc
commit
30d1d26d15
1 changed files with 94 additions and 13 deletions
|
|
@ -7,7 +7,7 @@
|
|||
<div class="popup-header">
|
||||
<div class="header-left">
|
||||
<span class="page-label">@page</span>
|
||||
<span class="page-name">geoformat</span>
|
||||
<span class="page-name">{{ templateName || 'default' }}</span>
|
||||
<span class="page-count">{{ pageCount }} page{{ pageCount > 1 ? 's' : '' }}</span>
|
||||
</div>
|
||||
<button class="close-btn" @click="close">×</button>
|
||||
|
|
@ -304,6 +304,7 @@ const visible = ref(false);
|
|||
const position = ref({ x: 0, y: 0 });
|
||||
const selectedPageElement = ref(null);
|
||||
const pageCount = ref(0);
|
||||
const templateName = ref('');
|
||||
const isEditable = ref(false);
|
||||
const inheritanceLocked = ref(true);
|
||||
const backgroundColorInput = ref(null);
|
||||
|
|
@ -339,27 +340,89 @@ const POPUP_HEIGHT = 600;
|
|||
|
||||
const { calculatePosition } = usePopupPosition(POPUP_WIDTH, POPUP_HEIGHT);
|
||||
|
||||
// Get the selector for the current template's @page rule
|
||||
const getTemplateSelector = () => {
|
||||
return templateName.value ? `@page ${templateName.value}` : '@page';
|
||||
};
|
||||
|
||||
// Get or create the template-specific @page block
|
||||
const getOrCreateTemplateBlock = () => {
|
||||
const selector = getTemplateSelector();
|
||||
let block = stylesheetStore.extractBlock(selector);
|
||||
|
||||
if (!block && templateName.value) {
|
||||
// Create new block with current values from @page
|
||||
const baseBlock = stylesheetStore.extractBlock('@page');
|
||||
if (baseBlock) {
|
||||
// Insert the new template block after @page
|
||||
const marginValue = `${margins.value.top.value}${margins.value.top.unit} ${margins.value.right.value}${margins.value.right.unit} ${margins.value.bottom.value}${margins.value.bottom.unit} ${margins.value.left.value}${margins.value.left.unit}`;
|
||||
const newBlock = `\n@page ${templateName.value} {\n margin: ${marginValue};${background.value.value ? `\n background: ${background.value.value};` : ''}\n}\n`;
|
||||
|
||||
stylesheetStore.content = stylesheetStore.content.replace(
|
||||
baseBlock,
|
||||
baseBlock + newBlock
|
||||
);
|
||||
block = stylesheetStore.extractBlock(selector);
|
||||
}
|
||||
}
|
||||
|
||||
return block;
|
||||
};
|
||||
|
||||
// Remove the template-specific @page block
|
||||
const removeTemplateBlock = () => {
|
||||
if (!templateName.value) return;
|
||||
|
||||
const selector = `@page ${templateName.value}`;
|
||||
const block = stylesheetStore.extractBlock(selector);
|
||||
|
||||
if (block) {
|
||||
// Remove the block and any surrounding whitespace
|
||||
stylesheetStore.content = stylesheetStore.content.replace(
|
||||
new RegExp(`\\n?${selector.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*\\{[^}]*\\}\\n?`),
|
||||
'\n'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const updateMargins = () => {
|
||||
// Only update if inheritance is unlocked
|
||||
if (inheritanceLocked.value) return;
|
||||
|
||||
const marginValue = `${margins.value.top.value}${margins.value.top.unit} ${margins.value.right.value}${margins.value.right.unit} ${margins.value.bottom.value}${margins.value.bottom.unit} ${margins.value.left.value}${margins.value.left.unit}`;
|
||||
|
||||
const currentBlock = stylesheetStore.extractBlock('@page');
|
||||
const currentBlock = getOrCreateTemplateBlock();
|
||||
if (!currentBlock) return;
|
||||
|
||||
const updatedBlock = currentBlock.replace(
|
||||
/(margin:\s*)[^;]+/,
|
||||
`$1${marginValue}`
|
||||
);
|
||||
const selector = getTemplateSelector();
|
||||
|
||||
stylesheetStore.content = stylesheetStore.content.replace(
|
||||
currentBlock,
|
||||
updatedBlock
|
||||
);
|
||||
if (currentBlock.includes('margin:')) {
|
||||
const updatedBlock = currentBlock.replace(
|
||||
/(margin:\s*)[^;]+/,
|
||||
`$1${marginValue}`
|
||||
);
|
||||
stylesheetStore.content = stylesheetStore.content.replace(
|
||||
currentBlock,
|
||||
updatedBlock
|
||||
);
|
||||
} else {
|
||||
const updatedBlock = currentBlock.replace(
|
||||
/(\s*})$/,
|
||||
` margin: ${marginValue};\n$1`
|
||||
);
|
||||
stylesheetStore.content = stylesheetStore.content.replace(
|
||||
currentBlock,
|
||||
updatedBlock
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const updateBackground = () => {
|
||||
// Only update if inheritance is unlocked
|
||||
if (inheritanceLocked.value) return;
|
||||
if (!background.value.value) return;
|
||||
|
||||
const currentBlock = stylesheetStore.extractBlock('@page');
|
||||
const currentBlock = getOrCreateTemplateBlock();
|
||||
if (!currentBlock) return;
|
||||
|
||||
if (currentBlock.includes('background:')) {
|
||||
|
|
@ -468,7 +531,13 @@ const open = (pageElement, event, count = 1) => {
|
|||
pageCount.value = count;
|
||||
position.value = calculatePosition(event);
|
||||
|
||||
// Load values from stylesheet
|
||||
// Extract template name from data-page-type attribute
|
||||
templateName.value = pageElement.getAttribute('data-page-type') || '';
|
||||
|
||||
// Reset inheritance state when opening
|
||||
inheritanceLocked.value = true;
|
||||
|
||||
// Load values from stylesheet (@page block)
|
||||
loadValuesFromStylesheet();
|
||||
|
||||
visible.value = true;
|
||||
|
|
@ -513,11 +582,23 @@ const close = () => {
|
|||
};
|
||||
|
||||
const toggleInheritance = () => {
|
||||
const wasLocked = inheritanceLocked.value;
|
||||
inheritanceLocked.value = !inheritanceLocked.value;
|
||||
// TODO: Implement CSS priority logic when unlocked
|
||||
|
||||
if (inheritanceLocked.value && !wasLocked) {
|
||||
// Re-locking: remove the template-specific block
|
||||
// Fields keep their values, but preview returns to @page defaults
|
||||
removeTemplateBlock();
|
||||
}
|
||||
// When unlocking: fields already have values, block will be created on first edit
|
||||
};
|
||||
|
||||
const pageCss = computed(() => {
|
||||
// Show template-specific block if unlocked and exists, otherwise show @page
|
||||
if (!inheritanceLocked.value && templateName.value) {
|
||||
const templateBlock = stylesheetStore.extractBlock(`@page ${templateName.value}`);
|
||||
if (templateBlock) return templateBlock;
|
||||
}
|
||||
return stylesheetStore.extractBlock('@page') || '';
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue