From 19077fb1330ebe3d523b01ff469a5475b130c3c2 Mon Sep 17 00:00:00 2001 From: isUnknown Date: Wed, 3 Dec 2025 16:57:11 +0100 Subject: [PATCH 1/4] refactor: migrate CSS to SCSS with compilation setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move all CSS files to public/assets/css/src/ as SCSS - Add public/assets/css/style.scss as main entry point - Compile SCSS to public/assets/css/style.css - Update src/style.css to import compiled CSS - Add .css.map for source maps 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../css/{editor-ui.css => src/editor-ui.scss} | 0 .../pagedjs-interface.scss} | 0 .../print-styles.scss} | 0 .../{stylesheet.css => src/stylesheet.scss} | 0 public/assets/css/style.css | 195 ++++++++++++++++++ public/assets/css/style.css.map | 1 + public/assets/css/style.scss | 4 + src/style.css | 3 +- 8 files changed, 201 insertions(+), 2 deletions(-) rename public/assets/css/{editor-ui.css => src/editor-ui.scss} (100%) rename public/assets/css/{pagedjs-interface.css => src/pagedjs-interface.scss} (100%) rename public/assets/css/{print-styles.css => src/print-styles.scss} (100%) rename public/assets/css/{stylesheet.css => src/stylesheet.scss} (100%) create mode 100644 public/assets/css/style.css create mode 100644 public/assets/css/style.css.map create mode 100644 public/assets/css/style.scss diff --git a/public/assets/css/editor-ui.css b/public/assets/css/src/editor-ui.scss similarity index 100% rename from public/assets/css/editor-ui.css rename to public/assets/css/src/editor-ui.scss diff --git a/public/assets/css/pagedjs-interface.css b/public/assets/css/src/pagedjs-interface.scss similarity index 100% rename from public/assets/css/pagedjs-interface.css rename to public/assets/css/src/pagedjs-interface.scss diff --git a/public/assets/css/print-styles.css b/public/assets/css/src/print-styles.scss similarity index 100% rename from public/assets/css/print-styles.css rename to public/assets/css/src/print-styles.scss diff --git a/public/assets/css/stylesheet.css b/public/assets/css/src/stylesheet.scss similarity index 100% rename from public/assets/css/stylesheet.css rename to public/assets/css/src/stylesheet.scss diff --git a/public/assets/css/style.css b/public/assets/css/style.css new file mode 100644 index 0000000..e647445 --- /dev/null +++ b/public/assets/css/style.css @@ -0,0 +1,195 @@ +@charset "UTF-8"; +/* CSS for Paged.js interface – v0.4 */ +/* Change the look */ +:root { + --color-background: whitesmoke; + --color-pageSheet: #cfcfcf; + --color-pageBox: violet; + --color-paper: white; + --color-marginBox: transparent; + --pagedjs-crop-color: black; + --pagedjs-crop-shadow: white; + --pagedjs-crop-stroke: 1px; +} + +/* To define how the book look on the screen: */ +@media screen, pagedjs-ignore { + body { + background-color: var(--color-background); + } + .pagedjs_pages { + display: flex; + width: calc(var(--pagedjs-width) * 2); + flex: 0; + flex-wrap: wrap; + margin: 0 auto; + } + .pagedjs_page { + background-color: var(--color-paper); + box-shadow: 0 0 0 1px var(--color-pageSheet); + margin: 0; + flex-shrink: 0; + flex-grow: 0; + margin-top: 10mm; + } + .pagedjs_first_page { + margin-left: var(--pagedjs-width); + } + .pagedjs_page:last-of-type { + margin-bottom: 10mm; + } + .pagedjs_pagebox { + box-shadow: 0 0 0 1px var(--color-pageBox); + } + .pagedjs_left_page { + z-index: 20; + width: calc(var(--pagedjs-bleed-left) + var(--pagedjs-pagebox-width)) !important; + } + .pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop { + border-color: transparent; + } + .pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-middle { + width: 0; + } + .pagedjs_right_page { + z-index: 10; + position: relative; + left: calc(var(--pagedjs-bleed-left) * -1); + } + /* show the margin-box */ + .pagedjs_margin-top-left-corner-holder, + .pagedjs_margin-top, + .pagedjs_margin-top-left, + .pagedjs_margin-top-center, + .pagedjs_margin-top-right, + .pagedjs_margin-top-right-corner-holder, + .pagedjs_margin-bottom-left-corner-holder, + .pagedjs_margin-bottom, + .pagedjs_margin-bottom-left, + .pagedjs_margin-bottom-center, + .pagedjs_margin-bottom-right, + .pagedjs_margin-bottom-right-corner-holder, + .pagedjs_margin-right, + .pagedjs_margin-right-top, + .pagedjs_margin-right-middle, + .pagedjs_margin-right-bottom, + .pagedjs_margin-left, + .pagedjs_margin-left-top, + .pagedjs_margin-left-middle, + .pagedjs_margin-left-bottom { + box-shadow: 0 0 0 1px inset var(--color-marginBox); + } + /* uncomment this part for recto/verso book : ------------------------------------ */ + /* + .pagedjs_pages { + flex-direction: column; + width: 100%; + } + + .pagedjs_first_page { + margin-left: 0; + } + + .pagedjs_page { + margin: 0 auto; + margin-top: 10mm; + } + + .pagedjs_left_page{ + width: calc(var(--pagedjs-bleed-left) + var(--pagedjs-pagebox-width) + var(--pagedjs-bleed-left))!important; + } + + .pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop{ + border-color: var(--pagedjs-crop-color); + } + + .pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-middle{ + width: var(--pagedjs-cross-size)!important; + } + + .pagedjs_right_page{ + left: 0; + } + */ + /*--------------------------------------------------------------------------------------*/ + /* uncomment this par to see the baseline : -------------------------------------------*/ + /* .pagedjs_pagebox { + --pagedjs-baseline: 22px; + --pagedjs-baseline-position: 5px; + --pagedjs-baseline-color: cyan; + background: linear-gradient(transparent 0%, transparent calc(var(--pagedjs-baseline) - 1px), var(--pagedjs-baseline-color) calc(var(--pagedjs-baseline) - 1px), var(--pagedjs-baseline-color) var(--pagedjs-baseline)), transparent; + background-size: 100% var(--pagedjs-baseline); + background-repeat: repeat-y; + background-position-y: var(--pagedjs-baseline-position); + } */ + /*--------------------------------------------------------------------------------------*/ +} +/* Marks (to delete when merge in paged.js) */ +.pagedjs_marks-crop { + z-index: 999999999999; +} + +.pagedjs_bleed-top .pagedjs_marks-crop, +.pagedjs_bleed-bottom .pagedjs_marks-crop { + box-shadow: 1px 0px 0px 0px var(--pagedjs-crop-shadow); +} + +.pagedjs_bleed-top .pagedjs_marks-crop:last-child, +.pagedjs_bleed-bottom .pagedjs_marks-crop:last-child { + box-shadow: -1px 0px 0px 0px var(--pagedjs-crop-shadow); +} + +.pagedjs_bleed-left .pagedjs_marks-crop, +.pagedjs_bleed-right .pagedjs_marks-crop { + box-shadow: 0px 1px 0px 0px var(--pagedjs-crop-shadow); +} + +.pagedjs_bleed-left .pagedjs_marks-crop:last-child, +.pagedjs_bleed-right .pagedjs_marks-crop:last-child { + box-shadow: 0px -1px 0px 0px var(--pagedjs-crop-shadow); +} + +/* PagedJS print styles */ +@page { + size: A4; + margin: 20mm 15mm 26mm 15mm; +} +h2 { + -moz-column-break-before: page; + break-before: page; +} + +@page { + @bottom-center { + content: string(title); + } +} +.chapter > h2 { + string-set: title content(text); +} + +@page { + size: A4; + margin: 20mm 15mm 26mm 15mm; +} +@page { + @bottom-center { + content: string(title); + } +} +h2 { + -moz-column-break-before: page; + break-before: page; +} + +.chapter > h2 { + string-set: title content(text); +} + +#chapter-2 { + font-size: 2rem; +} + +p { + font-size: 1rem; +}/*# sourceMappingURL=style.css.map */ \ No newline at end of file diff --git a/public/assets/css/style.css.map b/public/assets/css/style.css.map new file mode 100644 index 0000000..76d684b --- /dev/null +++ b/public/assets/css/style.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["style.css","src/pagedjs-interface.scss","src/print-styles.scss","src/stylesheet.scss"],"names":[],"mappings":"AAAA,gBAAgB;ACAhB,sCAAA;AAEA,oBAAA;AACA;EACE,8BAAA;EACA,0BAAA;EACA,uBAAA;EACA,oBAAA;EACA,8BAAA;EACA,2BAAA;EACA,4BAAA;EACA,0BAAA;ADCF;;ACEA,+CAAA;AACA;EACE;IACE,yCAAA;EDCF;ECEA;IACE,aAAA;IACA,qCAAA;IACA,OAAA;IACA,eAAA;IACA,cAAA;EDAF;ECGA;IACE,oCAAA;IACA,4CAAA;IACA,SAAA;IACA,cAAA;IACA,YAAA;IACA,gBAAA;EDDF;ECIA;IACE,iCAAA;EDFF;ECKA;IACE,mBAAA;EDHF;ECMA;IACE,0CAAA;EDJF;ECOA;IACE,WAAA;IACA,gFAAA;EDLF;ECUA;IACE,yBAAA;EDRF;ECWA;IACE,QAAA;EDTF;ECYA;IACE,WAAA;IACA,kBAAA;IACA,0CAAA;EDVF;ECaA,wBAAA;EAEA;;;;;;;;;;;;;;;;;;;;IAoBE,kDAAA;EDZF;ECeA,oFAAA;EAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAA;EAgCA,yFAAA;EAEA,wFAAA;EAEA;;;;;;;;MAAA;EAUA,yFAAA;ADlBF;ACqBA,6CAAA;AAEA;EACE,qBAAA;ADpBF;;ACuBA;;EAEE,sDAAA;ADpBF;;ACuBA;;EAEE,uDAAA;ADpBF;;ACuBA;;EAEE,sDAAA;ADpBF;;ACuBA;;EAEE,uDAAA;ADpBF;;AErJA,yBAAA;AACA;EACE,QAAA;EACA,2BAAA;AFwJF;AEtJA;EACE,8BAAA;OAAA,kBAAA;AFwJF;;AErJA;EACE;IACE,sBAAA;EFwJF;AACF;AEtJA;EACE,+BAAA;AFwJF;;AGvKA;EACE,QAAA;EACA,2BAAA;AH0KF;AGvKA;EACE;IAAiB,sBAAA;EH0KjB;AACF;AGxKA;EACE,8BAAA;OAAA,kBAAA;AH0KF;;AGvKA;EACE,+BAAA;AH0KF;;AGvKA;EACE,eAAA;AH0KF;;AGvKA;EACE,eAAA;AH0KF","file":"style.css"} \ No newline at end of file diff --git a/public/assets/css/style.scss b/public/assets/css/style.scss new file mode 100644 index 0000000..113c864 --- /dev/null +++ b/public/assets/css/style.scss @@ -0,0 +1,4 @@ +@import "src/editor-ui.scss"; +@import "src/pagedjs-interface.scss"; +@import "src/print-styles.scss"; +@import "src/stylesheet.scss"; diff --git a/src/style.css b/src/style.css index e25f678..699de50 100644 --- a/src/style.css +++ b/src/style.css @@ -1,2 +1 @@ -@import url('/assets/css/pagedjs-interface.css'); -@import url('/assets/css/editor-ui.css'); +@import url('/assets/css/style.css'); From 7ed57d000be299a191007cb34490d6846a3d4572 Mon Sep 17 00:00:00 2001 From: isUnknown Date: Thu, 4 Dec 2025 13:34:33 +0100 Subject: [PATCH 2/4] refactor: integrate StylesheetViewer into EditorPanel code tab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move StylesheetViewer from standalone fixed panel to integrated component within EditorPanel's "code" tab. Maintains full functionality including: - Bidirectional sync with Pinia store and PagedJS preview - Toggle between read/edit modes - CSS syntax highlighting - Debounced updates Changes: - EditorPanel.vue: Import and render StylesheetViewer in code tab - EditorPanel.vue: Add flexbox layout for proper height management - StylesheetViewer.vue: Convert from fixed positioning to flex container - App.vue: Remove standalone StylesheetViewer component 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/App.vue | 21 +++++----- src/components/StylesheetViewer.vue | 19 ++++----- src/components/editor/EditorPanel.vue | 55 +++++++++++++++------------ 3 files changed, 49 insertions(+), 46 deletions(-) diff --git a/src/App.vue b/src/App.vue index b5d616a..89efbfc 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,7 +1,6 @@ @@ -71,8 +76,6 @@ onMounted(() => renderPreview(true)); - - @@ -80,8 +83,8 @@ onMounted(() => renderPreview(true)); #preview-frame { position: fixed; top: 0; - left: 250px; - width: calc(100% - 600px); + left: 0; + width: 100vw; height: 100vh; border: none; } diff --git a/src/components/StylesheetViewer.vue b/src/components/StylesheetViewer.vue index 5782ddc..012f251 100644 --- a/src/components/StylesheetViewer.vue +++ b/src/components/StylesheetViewer.vue @@ -1,5 +1,5 @@ - From 467ae905bdeae7363c88a14dc4b9f1f2bd7dd859 Mon Sep 17 00:00:00 2001 From: isUnknown Date: Thu, 4 Dec 2025 14:03:40 +0100 Subject: [PATCH 3/4] refactor: optimize EditorPanel updates with selective debouncing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement immediate vs debounced updates based on input type to improve UX responsiveness while preventing excessive re-renders. Update strategy: - Immediate (0ms): select, buttons, checkboxes, color picker - Debounced (1s): text inputs, number inputs, range sliders Changes: - PageSettings.vue: Split watchers for margin values/units and background value/format. Extract update logic into reusable functions. - TextSettings.vue: Add comprehensive watcher system with selective debouncing for all settings (font, size, color, margins, etc.) This ensures button clicks (unit toggles, format switches) apply instantly while typed values (numbers, text) batch updates to reduce CSS re-parsing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/components/editor/PageSettings.vue | 309 +++++++++++++++---------- src/components/editor/TextSettings.vue | 265 ++++++++++++++++++--- 2 files changed, 417 insertions(+), 157 deletions(-) diff --git a/src/components/editor/PageSettings.vue b/src/components/editor/PageSettings.vue index 2bd7f21..9fdd04d 100644 --- a/src/components/editor/PageSettings.vue +++ b/src/components/editor/PageSettings.vue @@ -2,43 +2,37 @@

Réglage des pages

-
- - +
+
+ + +
-
- - +
+
+ + +
+ +
+ + +
-
- - -
- -
+

Marges

-
+
-
+
-
+
-
+
-
- -
- -
- - +
+
+ +
+ +
+ + +
-
- - +
+
+ + +
-
- - -
+
+
+ + +
-
- - +
+ + +
@@ -222,7 +210,7 @@ const pageFormats = { A5: { width: '148mm', height: '210mm' }, A3: { width: '297mm', height: '420mm' }, letter: { width: '8.5in', height: '11in' }, - legal: { width: '8.5in', height: '14in' } + legal: { width: '8.5in', height: '14in' }, }; const pageWidth = computed(() => pageFormats[pageFormat.value].width); @@ -232,12 +220,12 @@ const margins = ref({ top: { value: 20, unit: 'mm' }, bottom: { value: 20, unit: 'mm' }, left: { value: 20, unit: 'mm' }, - right: { value: 20, unit: 'mm' } + right: { value: 20, unit: 'mm' }, }); const background = ref({ value: '', - format: 'hex' + format: 'hex', }); const pattern = ref(''); @@ -249,57 +237,109 @@ const debouncedUpdate = (callback) => { updateTimer = setTimeout(callback, 1000); }; +const immediateUpdate = (callback) => { + callback(); +}; + watch(pageFormat, (newFormat) => { if (isUpdatingFromStore) return; - debouncedUpdate(() => { + immediateUpdate(() => { stylesheetStore.updateProperty('@page', 'size', newFormat, ''); }); }); -watch(margins, (newMargins) => { - if (isUpdatingFromStore) return; +const updateMargins = () => { + 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}`; - debouncedUpdate(() => { - const marginValue = `${newMargins.top.value}${newMargins.top.unit} ${newMargins.right.value}${newMargins.right.unit} ${newMargins.bottom.value}${newMargins.bottom.unit} ${newMargins.left.value}${newMargins.left.unit}`; + const currentBlock = stylesheetStore.extractBlock('@page'); + const updatedBlock = currentBlock.replace( + /(margin:\s*)[^;]+/, + `$1${marginValue}` + ); - const currentBlock = stylesheetStore.extractBlock('@page'); + stylesheetStore.content = stylesheetStore.content.replace( + currentBlock, + updatedBlock + ); +}; + +// Watch margin values (number inputs) with debounce +watch( + () => [ + margins.value.top.value, + margins.value.bottom.value, + margins.value.left.value, + margins.value.right.value, + ], + () => { + if (isUpdatingFromStore) return; + debouncedUpdate(updateMargins); + } +); + +// Watch margin units (button clicks) without debounce +watch( + () => [ + margins.value.top.unit, + margins.value.bottom.unit, + margins.value.left.unit, + margins.value.right.unit, + ], + () => { + if (isUpdatingFromStore) return; + immediateUpdate(updateMargins); + } +); + +const updateBackground = () => { + if (!background.value.value) return; + + const currentBlock = stylesheetStore.extractBlock('@page'); + + if (currentBlock.includes('background:')) { const updatedBlock = currentBlock.replace( - /(margin:\s*)[^;]+/, - `$1${marginValue}` + /(background:\s*)[^;]+/, + `$1${background.value.value}` ); + stylesheetStore.content = stylesheetStore.content.replace( + currentBlock, + updatedBlock + ); + } else { + const updatedBlock = currentBlock.replace( + /(\s*})$/, + ` background: ${background.value.value};\n$1` + ); + stylesheetStore.content = stylesheetStore.content.replace( + currentBlock, + updatedBlock + ); + } +}; - stylesheetStore.content = stylesheetStore.content.replace(currentBlock, updatedBlock); - }); -}, { deep: true }); +// Watch background value (text input) with debounce +watch( + () => background.value.value, + () => { + if (isUpdatingFromStore) return; + debouncedUpdate(updateBackground); + } +); -watch(background, (newBg) => { - if (!newBg.value) return; - if (isUpdatingFromStore) return; - - debouncedUpdate(() => { - const currentBlock = stylesheetStore.extractBlock('@page'); - - if (currentBlock.includes('background:')) { - const updatedBlock = currentBlock.replace( - /(background:\s*)[^;]+/, - `$1${newBg.value}` - ); - stylesheetStore.content = stylesheetStore.content.replace(currentBlock, updatedBlock); - } else { - const updatedBlock = currentBlock.replace( - /(\s*})$/, - ` background: ${newBg.value};\n$1` - ); - stylesheetStore.content = stylesheetStore.content.replace(currentBlock, updatedBlock); - } - }); -}, { deep: true }); +// Watch background format (button clicks) without debounce +watch( + () => background.value.format, + () => { + if (isUpdatingFromStore) return; + immediateUpdate(updateBackground); + } +); watch(pattern, (newPattern) => { if (!newPattern || isUpdatingFromStore) return; - debouncedUpdate(() => { + immediateUpdate(() => { // TODO: implement pattern application }); }); @@ -307,7 +347,7 @@ watch(pattern, (newPattern) => { watch(pageNumbers, (enabled) => { if (isUpdatingFromStore) return; - debouncedUpdate(() => { + immediateUpdate(() => { // TODO: implement page numbers toggle }); }); @@ -315,7 +355,7 @@ watch(pageNumbers, (enabled) => { watch(runningTitle, (enabled) => { if (isUpdatingFromStore) return; - debouncedUpdate(() => { + immediateUpdate(() => { // TODO: implement running title toggle }); }); @@ -331,12 +371,26 @@ const syncFromStore = () => { pageFormat.value = sizeMatch[1]; } - 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); + 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] }; + 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 bgMatch = pageBlock.match(/background:\s*([^;]+)/); @@ -348,11 +402,14 @@ const syncFromStore = () => { } }; -watch(() => stylesheetStore.content, () => { - if (!isUpdatingFromStore) { - syncFromStore(); +watch( + () => stylesheetStore.content, + () => { + if (!isUpdatingFromStore) { + syncFromStore(); + } } -}); +); onMounted(() => { syncFromStore(); diff --git a/src/components/editor/TextSettings.vue b/src/components/editor/TextSettings.vue index a72a39f..451b682 100644 --- a/src/components/editor/TextSettings.vue +++ b/src/components/editor/TextSettings.vue @@ -2,8 +2,8 @@

Réglage du texte

- Ces réglages s'appliquent à l'ensemble des éléments du document. - Vous pouvez modifier ensuite les éléments indépendamment. + Ces réglages s'appliquent à l'ensemble des éléments du document. Vous + pouvez modifier ensuite les éléments indépendamment.

@@ -17,11 +17,7 @@
- +
@@ -84,7 +80,7 @@
-
+
- + -
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
From 9af36fb4221c295e04ea381ba5a36b7be93e2aa1 Mon Sep 17 00:00:00 2001 From: isUnknown Date: Thu, 4 Dec 2025 15:03:29 +0100 Subject: [PATCH 4/4] feat: integrate Coloris color picker for background field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Coloris.js library for enhanced color selection in PageSettings with automatic button state sync across tab changes. Features: - Color picker with swatches, alpha support, and format toggle (hex/rgb/hsl) - Button positioned to the left of input field - Automatic sync when switching tabs (remembers selected color) - Close button and click-outside-to-close functionality - Dark theme with pill UI style Changes: - Install @melloware/coloris package - PageSettings.vue: Integrate Coloris with data-coloris attribute, add tab visibility detection via provide/inject, force button update when returning to document tab - EditorPanel.vue: Provide activeTab to child components, increase panel width to 30rem - _forms.scss: Add .input-with-color styles with custom Coloris button positioning (absolute positioned to left of input) - Temporarily comment out rgb/hex format buttons (replaced by Coloris format toggle) Technical details: - Uses provide/inject pattern to detect tab changes - Triggers synthetic input events to force Coloris button refresh - Custom CSS overrides to position swatch button correctly 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- package-lock.json | 7 + package.json | 1 + ...s-interface.scss => pagedjs-interface.css} | 0 public/assets/css/src/_buttons.scss | 21 ++ public/assets/css/src/_forms.scss | 72 +++++ .../{print-styles.scss => _print-styles.scss} | 0 public/assets/css/src/_reset.scss | 27 ++ public/assets/css/src/_text.scss | 15 + public/assets/css/src/_variables.scss | 8 + public/assets/css/src/editor-ui.scss | 1 - public/assets/css/style.css | 278 +++++++----------- public/assets/css/style.css.map | 2 +- public/assets/css/style.scss | 10 +- .../{src/stylesheet.scss => stylesheet.css} | 0 public/site/snippets/header.php | 4 +- src/components/editor/EditorPanel.vue | 7 +- src/components/editor/PageSettings.vue | 85 +++++- 17 files changed, 359 insertions(+), 179 deletions(-) rename public/assets/css/{src/pagedjs-interface.scss => pagedjs-interface.css} (100%) create mode 100644 public/assets/css/src/_buttons.scss create mode 100644 public/assets/css/src/_forms.scss rename public/assets/css/src/{print-styles.scss => _print-styles.scss} (100%) create mode 100644 public/assets/css/src/_reset.scss create mode 100644 public/assets/css/src/_text.scss create mode 100644 public/assets/css/src/_variables.scss delete mode 100644 public/assets/css/src/editor-ui.scss rename public/assets/css/{src/stylesheet.scss => stylesheet.css} (100%) diff --git a/package-lock.json b/package-lock.json index be5ff4b..a84d662 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "geoproject", "version": "0.0.0", "dependencies": { + "@melloware/coloris": "^0.25.0", "highlight.js": "^11.11.1", "pagedjs": "^0.4.3", "pinia": "^3.0.4", @@ -532,6 +533,12 @@ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, + "node_modules/@melloware/coloris": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@melloware/coloris/-/coloris-0.25.0.tgz", + "integrity": "sha512-RBWVFLjWbup7GRkOXb9g3+ZtR9AevFtJinrRz2cYPLjZ3TCkNRGMWuNbmQWbZ5cF3VU7aQDZwUsYgIY/bGrh2g==", + "license": "MIT" + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.50", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.50.tgz", diff --git a/package.json b/package.json index 03d6604..1b82269 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "preview": "vite preview" }, "dependencies": { + "@melloware/coloris": "^0.25.0", "highlight.js": "^11.11.1", "pagedjs": "^0.4.3", "pinia": "^3.0.4", diff --git a/public/assets/css/src/pagedjs-interface.scss b/public/assets/css/pagedjs-interface.css similarity index 100% rename from public/assets/css/src/pagedjs-interface.scss rename to public/assets/css/pagedjs-interface.css diff --git a/public/assets/css/src/_buttons.scss b/public/assets/css/src/_buttons.scss new file mode 100644 index 0000000..970b909 --- /dev/null +++ b/public/assets/css/src/_buttons.scss @@ -0,0 +1,21 @@ +button { + cursor: pointer; + + border: 1px solid var(--color-browngray-300); + color: var(--color-browngray-300); + border-radius: var(--border-radius); + padding: 0.1rem 0.3rem; + + &.active { + border: 1px solid #000; + color: #000; + } + + &.tab { + &.active { + background-color: #000; + color: #fff; + border: none; + } + } +} diff --git a/public/assets/css/src/_forms.scss b/public/assets/css/src/_forms.scss new file mode 100644 index 0000000..34ce9ce --- /dev/null +++ b/public/assets/css/src/_forms.scss @@ -0,0 +1,72 @@ +select, +input[type="text"], +input[type="number"] { + background-color: var(--color-browngray-300); +} + +.field--view-only { + opacity: 0.3; +} + +.settings-section { + h2 { + border-bottom: 1px solid #000; + } + .settings-subsection:not(:last-child) { + border-bottom: 1px solid var(--color-browngray-050); + } + + .settings-subsection { + padding: 0.5rem 0; + + .field { + display: flex; + label { + width: 50%; + } + + .input-with-unit { + display: flex; + } + + .input-with-color { + .clr-field { + display: flex; + button { + position: absolute; + transform: none; + height: 1rem; + top: auto; + right: auto; + cursor: pointer; + } + + input { + padding-left: 2.5rem; + } + } + } + } + + &.margins { + display: flex; + flex-wrap: wrap; + h3 { + width: 100%; + } + .field { + width: 50%; + + label { + width: 50%; + } + + .input-with-unit { + input { + width: 50%; + } + } + } + } + } +} diff --git a/public/assets/css/src/print-styles.scss b/public/assets/css/src/_print-styles.scss similarity index 100% rename from public/assets/css/src/print-styles.scss rename to public/assets/css/src/_print-styles.scss diff --git a/public/assets/css/src/_reset.scss b/public/assets/css/src/_reset.scss new file mode 100644 index 0000000..ed3fb95 --- /dev/null +++ b/public/assets/css/src/_reset.scss @@ -0,0 +1,27 @@ +body, +html { + padding: 0; + margin: 0; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0; +} + +input, +select { + border: none; + outline: none; + + border-radius: var(--border-radius); +} + +button { + background-color: transparent; + border: none; +} diff --git a/public/assets/css/src/_text.scss b/public/assets/css/src/_text.scss new file mode 100644 index 0000000..6c537a3 --- /dev/null +++ b/public/assets/css/src/_text.scss @@ -0,0 +1,15 @@ +body, +h1, +h2, +h3, +h4, +h5, +h6, +p, +a, +input, +select, +figcaption, +label { + font-family: sans-serif; +} diff --git a/public/assets/css/src/_variables.scss b/public/assets/css/src/_variables.scss new file mode 100644 index 0000000..b9a0427 --- /dev/null +++ b/public/assets/css/src/_variables.scss @@ -0,0 +1,8 @@ +:root { + --color-panel-bg: #e8e6e5; + --color-browngray-050: #f5f3f0; + --color-browngray-200: #d0c4ba; + --color-browngray-300: #b5a9a1; + + --border-radius: 0.2rem; +} diff --git a/public/assets/css/src/editor-ui.scss b/public/assets/css/src/editor-ui.scss deleted file mode 100644 index 8b13789..0000000 --- a/public/assets/css/src/editor-ui.scss +++ /dev/null @@ -1 +0,0 @@ - diff --git a/public/assets/css/style.css b/public/assets/css/style.css index e647445..4f98705 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -1,152 +1,52 @@ -@charset "UTF-8"; -/* CSS for Paged.js interface – v0.4 */ -/* Change the look */ +body, +html { + padding: 0; + margin: 0; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0; +} + +input, +select { + border: none; + outline: none; + border-radius: var(--border-radius); +} + +button { + background-color: transparent; + border: none; +} + :root { - --color-background: whitesmoke; - --color-pageSheet: #cfcfcf; - --color-pageBox: violet; - --color-paper: white; - --color-marginBox: transparent; - --pagedjs-crop-color: black; - --pagedjs-crop-shadow: white; - --pagedjs-crop-stroke: 1px; + --color-panel-bg: #e8e6e5; + --color-browngray-050: #f5f3f0; + --color-browngray-200: #d0c4ba; + --color-browngray-300: #b5a9a1; + --border-radius: 0.2rem; } -/* To define how the book look on the screen: */ -@media screen, pagedjs-ignore { - body { - background-color: var(--color-background); - } - .pagedjs_pages { - display: flex; - width: calc(var(--pagedjs-width) * 2); - flex: 0; - flex-wrap: wrap; - margin: 0 auto; - } - .pagedjs_page { - background-color: var(--color-paper); - box-shadow: 0 0 0 1px var(--color-pageSheet); - margin: 0; - flex-shrink: 0; - flex-grow: 0; - margin-top: 10mm; - } - .pagedjs_first_page { - margin-left: var(--pagedjs-width); - } - .pagedjs_page:last-of-type { - margin-bottom: 10mm; - } - .pagedjs_pagebox { - box-shadow: 0 0 0 1px var(--color-pageBox); - } - .pagedjs_left_page { - z-index: 20; - width: calc(var(--pagedjs-bleed-left) + var(--pagedjs-pagebox-width)) !important; - } - .pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop { - border-color: transparent; - } - .pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-middle { - width: 0; - } - .pagedjs_right_page { - z-index: 10; - position: relative; - left: calc(var(--pagedjs-bleed-left) * -1); - } - /* show the margin-box */ - .pagedjs_margin-top-left-corner-holder, - .pagedjs_margin-top, - .pagedjs_margin-top-left, - .pagedjs_margin-top-center, - .pagedjs_margin-top-right, - .pagedjs_margin-top-right-corner-holder, - .pagedjs_margin-bottom-left-corner-holder, - .pagedjs_margin-bottom, - .pagedjs_margin-bottom-left, - .pagedjs_margin-bottom-center, - .pagedjs_margin-bottom-right, - .pagedjs_margin-bottom-right-corner-holder, - .pagedjs_margin-right, - .pagedjs_margin-right-top, - .pagedjs_margin-right-middle, - .pagedjs_margin-right-bottom, - .pagedjs_margin-left, - .pagedjs_margin-left-top, - .pagedjs_margin-left-middle, - .pagedjs_margin-left-bottom { - box-shadow: 0 0 0 1px inset var(--color-marginBox); - } - /* uncomment this part for recto/verso book : ------------------------------------ */ - /* - .pagedjs_pages { - flex-direction: column; - width: 100%; - } - - .pagedjs_first_page { - margin-left: 0; - } - - .pagedjs_page { - margin: 0 auto; - margin-top: 10mm; - } - - .pagedjs_left_page{ - width: calc(var(--pagedjs-bleed-left) + var(--pagedjs-pagebox-width) + var(--pagedjs-bleed-left))!important; - } - - .pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-crop{ - border-color: var(--pagedjs-crop-color); - } - - .pagedjs_left_page .pagedjs_bleed-right .pagedjs_marks-middle{ - width: var(--pagedjs-cross-size)!important; - } - - .pagedjs_right_page{ - left: 0; - } - */ - /*--------------------------------------------------------------------------------------*/ - /* uncomment this par to see the baseline : -------------------------------------------*/ - /* .pagedjs_pagebox { - --pagedjs-baseline: 22px; - --pagedjs-baseline-position: 5px; - --pagedjs-baseline-color: cyan; - background: linear-gradient(transparent 0%, transparent calc(var(--pagedjs-baseline) - 1px), var(--pagedjs-baseline-color) calc(var(--pagedjs-baseline) - 1px), var(--pagedjs-baseline-color) var(--pagedjs-baseline)), transparent; - background-size: 100% var(--pagedjs-baseline); - background-repeat: repeat-y; - background-position-y: var(--pagedjs-baseline-position); - } */ - /*--------------------------------------------------------------------------------------*/ -} -/* Marks (to delete when merge in paged.js) */ -.pagedjs_marks-crop { - z-index: 999999999999; -} - -.pagedjs_bleed-top .pagedjs_marks-crop, -.pagedjs_bleed-bottom .pagedjs_marks-crop { - box-shadow: 1px 0px 0px 0px var(--pagedjs-crop-shadow); -} - -.pagedjs_bleed-top .pagedjs_marks-crop:last-child, -.pagedjs_bleed-bottom .pagedjs_marks-crop:last-child { - box-shadow: -1px 0px 0px 0px var(--pagedjs-crop-shadow); -} - -.pagedjs_bleed-left .pagedjs_marks-crop, -.pagedjs_bleed-right .pagedjs_marks-crop { - box-shadow: 0px 1px 0px 0px var(--pagedjs-crop-shadow); -} - -.pagedjs_bleed-left .pagedjs_marks-crop:last-child, -.pagedjs_bleed-right .pagedjs_marks-crop:last-child { - box-shadow: 0px -1px 0px 0px var(--pagedjs-crop-shadow); +body, +h1, +h2, +h3, +h4, +h5, +h6, +p, +a, +input, +select, +figcaption, +label { + font-family: sans-serif; } /* PagedJS print styles */ @@ -168,28 +68,78 @@ h2 { string-set: title content(text); } -@page { - size: A4; - margin: 20mm 15mm 26mm 15mm; -} -@page { - @bottom-center { - content: string(title); - } -} -h2 { - -moz-column-break-before: page; - break-before: page; +select, +input[type=text], +input[type=number] { + background-color: var(--color-browngray-300); } -.chapter > h2 { - string-set: title content(text); +.field--view-only { + opacity: 0.3; } -#chapter-2 { - font-size: 2rem; +.settings-section h2 { + border-bottom: 1px solid #000; +} +.settings-section .settings-subsection:not(:last-child) { + border-bottom: 1px solid var(--color-browngray-050); +} +.settings-section .settings-subsection { + padding: 0.5rem 0; +} +.settings-section .settings-subsection .field { + display: flex; +} +.settings-section .settings-subsection .field label { + width: 50%; +} +.settings-section .settings-subsection .field .input-with-unit { + display: flex; +} +.settings-section .settings-subsection .field .input-with-color .clr-field { + display: flex; +} +.settings-section .settings-subsection .field .input-with-color .clr-field button { + position: absolute; + transform: none; + height: 1rem; + top: auto; + right: auto; + cursor: pointer; +} +.settings-section .settings-subsection .field .input-with-color .clr-field input { + padding-left: 2.5rem; +} +.settings-section .settings-subsection.margins { + display: flex; + flex-wrap: wrap; +} +.settings-section .settings-subsection.margins h3 { + width: 100%; +} +.settings-section .settings-subsection.margins .field { + width: 50%; +} +.settings-section .settings-subsection.margins .field label { + width: 50%; +} +.settings-section .settings-subsection.margins .field .input-with-unit input { + width: 50%; } -p { - font-size: 1rem; +button { + cursor: pointer; + border: 1px solid var(--color-browngray-300); + color: var(--color-browngray-300); + border-radius: var(--border-radius); + padding: 0.1rem 0.3rem; +} +button.active { + border: 1px solid #000; + color: #000; +} +button.tab.active { + background-color: #000; + color: #fff; + border: none; }/*# sourceMappingURL=style.css.map */ \ No newline at end of file diff --git a/public/assets/css/style.css.map b/public/assets/css/style.css.map index 76d684b..3fafa0d 100644 --- a/public/assets/css/style.css.map +++ b/public/assets/css/style.css.map @@ -1 +1 @@ -{"version":3,"sources":["style.css","src/pagedjs-interface.scss","src/print-styles.scss","src/stylesheet.scss"],"names":[],"mappings":"AAAA,gBAAgB;ACAhB,sCAAA;AAEA,oBAAA;AACA;EACE,8BAAA;EACA,0BAAA;EACA,uBAAA;EACA,oBAAA;EACA,8BAAA;EACA,2BAAA;EACA,4BAAA;EACA,0BAAA;ADCF;;ACEA,+CAAA;AACA;EACE;IACE,yCAAA;EDCF;ECEA;IACE,aAAA;IACA,qCAAA;IACA,OAAA;IACA,eAAA;IACA,cAAA;EDAF;ECGA;IACE,oCAAA;IACA,4CAAA;IACA,SAAA;IACA,cAAA;IACA,YAAA;IACA,gBAAA;EDDF;ECIA;IACE,iCAAA;EDFF;ECKA;IACE,mBAAA;EDHF;ECMA;IACE,0CAAA;EDJF;ECOA;IACE,WAAA;IACA,gFAAA;EDLF;ECUA;IACE,yBAAA;EDRF;ECWA;IACE,QAAA;EDTF;ECYA;IACE,WAAA;IACA,kBAAA;IACA,0CAAA;EDVF;ECaA,wBAAA;EAEA;;;;;;;;;;;;;;;;;;;;IAoBE,kDAAA;EDZF;ECeA,oFAAA;EAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAA;EAgCA,yFAAA;EAEA,wFAAA;EAEA;;;;;;;;MAAA;EAUA,yFAAA;ADlBF;ACqBA,6CAAA;AAEA;EACE,qBAAA;ADpBF;;ACuBA;;EAEE,sDAAA;ADpBF;;ACuBA;;EAEE,uDAAA;ADpBF;;ACuBA;;EAEE,sDAAA;ADpBF;;ACuBA;;EAEE,uDAAA;ADpBF;;AErJA,yBAAA;AACA;EACE,QAAA;EACA,2BAAA;AFwJF;AEtJA;EACE,8BAAA;OAAA,kBAAA;AFwJF;;AErJA;EACE;IACE,sBAAA;EFwJF;AACF;AEtJA;EACE,+BAAA;AFwJF;;AGvKA;EACE,QAAA;EACA,2BAAA;AH0KF;AGvKA;EACE;IAAiB,sBAAA;EH0KjB;AACF;AGxKA;EACE,8BAAA;OAAA,kBAAA;AH0KF;;AGvKA;EACE,+BAAA;AH0KF;;AGvKA;EACE,eAAA;AH0KF;;AGvKA;EACE,eAAA;AH0KF","file":"style.css"} \ No newline at end of file +{"version":3,"sources":["src/_reset.scss","style.css","src/_variables.scss","src/_text.scss","src/_print-styles.scss","src/_forms.scss","src/_buttons.scss"],"names":[],"mappings":"AAAA;;EAEE,UAAA;EACA,SAAA;ACCF;;ADEA;;;;;;EAME,SAAA;ACCF;;ADEA;;EAEE,YAAA;EACA,aAAA;EAEA,mCAAA;ACAF;;ADGA;EACE,6BAAA;EACA,YAAA;ACAF;;ACzBA;EACE,yBAAA;EACA,8BAAA;EACA,8BAAA;EACA,8BAAA;EAEA,uBAAA;AD2BF;;AEjCA;;;;;;;;;;;;;EAaE,uBAAA;AFoCF;;AGjDA,yBAAA;AACA;EACE,QAAA;EACA,2BAAA;AHoDF;AGlDA;EACE,8BAAA;OAAA,kBAAA;AHoDF;;AGjDA;EACE;IACE,sBAAA;EHoDF;AACF;AGlDA;EACE,+BAAA;AHoDF;;AInEA;;;EAGE,4CAAA;AJsEF;;AInEA;EACE,YAAA;AJsEF;;AIlEE;EACE,6BAAA;AJqEJ;AInEE;EACE,mDAAA;AJqEJ;AIlEE;EACE,iBAAA;AJoEJ;AIlEI;EACE,aAAA;AJoEN;AInEM;EACE,UAAA;AJqER;AIlEM;EACE,aAAA;AJoER;AIhEQ;EACE,aAAA;AJkEV;AIjEU;EACE,kBAAA;EACA,eAAA;EACA,YAAA;EACA,SAAA;EACA,WAAA;EACA,eAAA;AJmEZ;AIhEU;EACE,oBAAA;AJkEZ;AI5DI;EACE,aAAA;EACA,eAAA;AJ8DN;AI7DM;EACE,WAAA;AJ+DR;AI7DM;EACE,UAAA;AJ+DR;AI7DQ;EACE,UAAA;AJ+DV;AI3DU;EACE,UAAA;AJ6DZ;;AK9HA;EACE,eAAA;EAEA,4CAAA;EACA,iCAAA;EACA,mCAAA;EACA,sBAAA;ALgIF;AK9HE;EACE,sBAAA;EACA,WAAA;ALgIJ;AK5HI;EACE,sBAAA;EACA,WAAA;EACA,YAAA;AL8HN","file":"style.css"} \ No newline at end of file diff --git a/public/assets/css/style.scss b/public/assets/css/style.scss index 113c864..3b96e2f 100644 --- a/public/assets/css/style.scss +++ b/public/assets/css/style.scss @@ -1,4 +1,6 @@ -@import "src/editor-ui.scss"; -@import "src/pagedjs-interface.scss"; -@import "src/print-styles.scss"; -@import "src/stylesheet.scss"; +@import "src/_reset.scss"; +@import "src/_variables.scss"; +@import "src/_text.scss"; +@import "src/_print-styles.scss"; +@import "src/_forms.scss"; +@import "src/_buttons.scss"; diff --git a/public/assets/css/src/stylesheet.scss b/public/assets/css/stylesheet.css similarity index 100% rename from public/assets/css/src/stylesheet.scss rename to public/assets/css/stylesheet.css diff --git a/public/site/snippets/header.php b/public/site/snippets/header.php index 8326578..75fd430 100644 --- a/public/site/snippets/header.php +++ b/public/site/snippets/header.php @@ -8,8 +8,8 @@ isHomePage() != true, $page->title() . ' - ') . $site->title() ?> - - + + diff --git a/src/components/editor/EditorPanel.vue b/src/components/editor/EditorPanel.vue index 76bd422..b87e98d 100644 --- a/src/components/editor/EditorPanel.vue +++ b/src/components/editor/EditorPanel.vue @@ -45,13 +45,16 @@