From b903c75f984eeda2951a4c1af26c594a5020d7e1 Mon Sep 17 00:00:00 2001 From: isUnknown Date: Mon, 8 Dec 2025 16:17:34 +0100 Subject: [PATCH] refactor: mutualize popup styles into shared SCSS file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract ~150 lines of identical CSS from ElementPopup and PagePopup into a new _settings-popup.scss partial: - Common popup structure (header, body, controls, CSS panel) - Shared components (tooltips, toggle switches, inheritance button) - CSS editor styling (readonly display, textarea) Component-specific styles retained: - ElementPopup: purple theme, button groups, checkboxes - PagePopup: orange theme, margin grid layout Reduces duplication and improves maintainability. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- public/assets/css/src/_settings-popup.scss | 214 +++++++++++++++++++++ public/assets/css/style.css | 200 +++++++++++++++++++ public/assets/css/style.css.map | 2 +- public/assets/css/style.scss | 1 + src/components/ElementPopup.vue | 208 +------------------- src/components/PagePopup.vue | 208 +------------------- 6 files changed, 420 insertions(+), 413 deletions(-) create mode 100644 public/assets/css/src/_settings-popup.scss diff --git a/public/assets/css/src/_settings-popup.scss b/public/assets/css/src/_settings-popup.scss new file mode 100644 index 0000000..797ecb3 --- /dev/null +++ b/public/assets/css/src/_settings-popup.scss @@ -0,0 +1,214 @@ +// Common styles for ElementPopup and PagePopup components + +.settings-popup { + position: fixed; + background: white; + border-radius: 8px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); + z-index: 10000; + width: 800px; + max-height: 600px; + display: flex; + flex-direction: column; +} + +.popup-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.75rem 1rem; + border-bottom: 1px solid #e0e0e0; + background: #f9f9f9; +} + +.header-left { + display: flex; + align-items: center; + gap: 0.5rem; +} + +.close-btn { + background: none; + border: none; + cursor: pointer; + font-size: 1.5rem; + line-height: 1; + padding: 0; + color: #666; +} + +.popup-body { + display: flex; + flex: 1; + overflow: hidden; +} + +.popup-controls { + flex: 1; + padding: 1rem; + overflow-y: auto; + background: white; + display: flex; + flex-direction: column; + gap: 1rem; +} + +.settings-subsection h4 { + margin: 0 0 0.5rem 0; + font-size: 0.875rem; + font-weight: 600; +} + +// Label with CSS tooltip +.label-with-tooltip { + text-decoration: underline dotted; + text-underline-offset: 2px; + cursor: help; + position: relative; + + &::after { + content: attr(data-css); + position: absolute; + bottom: 100%; + left: 0; + margin-bottom: 4px; + padding: 0.25rem 0.5rem; + background: var(--color-browngray-700, #3d3d3d); + color: var(--color-browngray-100, #f5f5f5); + font-family: "Courier New", Courier, monospace; + font-size: 0.75rem; + border-radius: 4px; + white-space: nowrap; + opacity: 0; + visibility: hidden; + transition: + opacity 0.15s ease, + visibility 0.15s ease; + z-index: 10; + } + + &:hover::after { + opacity: 1; + visibility: visible; + } +} + +// Inheritance lock/unlock button +.inheritance-btn { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0; + background: transparent; + border: none; + cursor: pointer; + font-size: 0.875rem; + color: #666; + transition: color 0.2s; + + &:hover { + color: #333; + } + + svg { + width: 1.25rem; + height: 1.25rem; + } +} + +// CSS Editor panel +.popup-css { + flex: 1; + background: #f5f5f5; + display: flex; + flex-direction: column; + border-left: 1px solid #e0e0e0; +} + +.css-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.5rem 0.75rem; + background: #e8e8e8; + border-bottom: 1px solid #d0d0d0; + font-size: 0.875rem; + font-weight: 600; +} + +// Toggle switch for edit mode +.toggle { + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; + font-size: 0.75rem; + font-weight: normal; + color: #666; + + input[type="checkbox"] { + position: absolute; + opacity: 0; + width: 0; + height: 0; + } +} + +.toggle-switch { + position: relative; + display: inline-block; + width: 36px; + height: 18px; + background: #ccc; + border-radius: 18px; + transition: background 0.2s ease; + + &::after { + content: ""; + position: absolute; + top: 2px; + left: 2px; + width: 14px; + height: 14px; + background: white; + border-radius: 50%; + transition: transform 0.2s ease; + } +} + +.toggle input[type="checkbox"]:checked + .toggle-switch { + background: #61afef; + + &::after { + transform: translateX(18px); + } +} + +// CSS readonly display +.readonly { + flex: 1; + margin: 0; + padding: 0.75rem; + background: #1e1e1e; + color: #abb2bf; + font-family: "Courier New", Courier, monospace; + font-size: 0.75rem; + line-height: 1.5; + overflow-y: auto; + white-space: pre-wrap; +} + +// CSS textarea editor +.popup-css textarea { + flex: 1; + width: 100%; + background: #1e1e1e; + color: #abb2bf; + border: none; + padding: 0.75rem; + font-family: "Courier New", Courier, monospace; + font-size: 0.75rem; + line-height: 1.5; + resize: none; + outline: none; +} diff --git a/public/assets/css/style.css b/public/assets/css/style.css index ce20e3f..2d229d0 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -31,6 +31,7 @@ button { --color-browngray-200: #d0c4ba; --color-browngray-300: #b5a9a1; --color-page-highlight: #ff8a50; + --color-purple: #7136ff; --border-radius: 0.2rem; --space-xs: 0.5rem; --curve: cubic-bezier(0.86, 0, 0.07, 1); @@ -196,4 +197,203 @@ button.tab.active { background-color: #000; color: #fff; border: none; +} + +.settings-popup { + position: fixed; + background: white; + border-radius: 8px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); + z-index: 10000; + width: 800px; + max-height: 600px; + display: flex; + flex-direction: column; +} + +.popup-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.75rem 1rem; + border-bottom: 1px solid #e0e0e0; + background: #f9f9f9; +} + +.header-left { + display: flex; + align-items: center; + gap: 0.5rem; +} + +.close-btn { + background: none; + border: none; + cursor: pointer; + font-size: 1.5rem; + line-height: 1; + padding: 0; + color: #666; +} + +.popup-body { + display: flex; + flex: 1; + overflow: hidden; +} + +.popup-controls { + flex: 1; + padding: 1rem; + overflow-y: auto; + background: white; + display: flex; + flex-direction: column; + gap: 1rem; +} + +.settings-subsection h4 { + margin: 0 0 0.5rem 0; + font-size: 0.875rem; + font-weight: 600; +} + +.label-with-tooltip { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + text-underline-offset: 2px; + cursor: help; + position: relative; +} +.label-with-tooltip::after { + content: attr(data-css); + position: absolute; + bottom: 100%; + left: 0; + margin-bottom: 4px; + padding: 0.25rem 0.5rem; + background: var(--color-browngray-700, #3d3d3d); + color: var(--color-browngray-100, #f5f5f5); + font-family: "Courier New", Courier, monospace; + font-size: 0.75rem; + border-radius: 4px; + white-space: nowrap; + opacity: 0; + visibility: hidden; + transition: opacity 0.15s ease, visibility 0.15s ease; + z-index: 10; +} +.label-with-tooltip:hover::after { + opacity: 1; + visibility: visible; +} + +.inheritance-btn { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0; + background: transparent; + border: none; + cursor: pointer; + font-size: 0.875rem; + color: #666; + transition: color 0.2s; +} +.inheritance-btn:hover { + color: #333; +} +.inheritance-btn svg { + width: 1.25rem; + height: 1.25rem; +} + +.popup-css { + flex: 1; + background: #f5f5f5; + display: flex; + flex-direction: column; + border-left: 1px solid #e0e0e0; +} + +.css-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.5rem 0.75rem; + background: #e8e8e8; + border-bottom: 1px solid #d0d0d0; + font-size: 0.875rem; + font-weight: 600; +} + +.toggle { + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; + font-size: 0.75rem; + font-weight: normal; + color: #666; +} +.toggle input[type=checkbox] { + position: absolute; + opacity: 0; + width: 0; + height: 0; +} + +.toggle-switch { + position: relative; + display: inline-block; + width: 36px; + height: 18px; + background: #ccc; + border-radius: 18px; + transition: background 0.2s ease; +} +.toggle-switch::after { + content: ""; + position: absolute; + top: 2px; + left: 2px; + width: 14px; + height: 14px; + background: white; + border-radius: 50%; + transition: transform 0.2s ease; +} + +.toggle input[type=checkbox]:checked + .toggle-switch { + background: #61afef; +} +.toggle input[type=checkbox]:checked + .toggle-switch::after { + transform: translateX(18px); +} + +.readonly { + flex: 1; + margin: 0; + padding: 0.75rem; + background: #1e1e1e; + color: #abb2bf; + font-family: "Courier New", Courier, monospace; + font-size: 0.75rem; + line-height: 1.5; + overflow-y: auto; + white-space: pre-wrap; +} + +.popup-css textarea { + flex: 1; + width: 100%; + background: #1e1e1e; + color: #abb2bf; + border: none; + padding: 0.75rem; + font-family: "Courier New", Courier, monospace; + font-size: 0.75rem; + line-height: 1.5; + resize: none; + outline: 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 67cbf6d..498edd4 100644 --- a/public/assets/css/style.css.map +++ b/public/assets/css/style.css.map @@ -1 +1 @@ -{"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,+BAAA;EAEA,uBAAA;EAEA,kBAAA;EAEA,uCAAA;ADwBF;;AEpCA;;;;;;;;;;;;;EAaE,uBAAA;AFuCF;;AGpDA,yBAAA;AACA;EACE,QAAA;EACA,2BAAA;AHuDF;AGrDA;EACE,8BAAA;OAAA,kBAAA;AHuDF;;AGpDA;EACE;IACE,sBAAA;EHuDF;AACF;AGrDA;EACE,+BAAA;AHuDF;;AItEA;;;EAGE,4CAAA;AJyEF;;AItEA;EACE,YAAA;AJyEF;;AItEA,2BAAA;AACA;EACE,yCAAA;UAAA,iCAAA;EACA,iDAAA;EACA,0BAAA;EACA,YAAA;EACA,kBAAA;AJyEF;AIvEE;EACE,uBAAA;EACA,kBAAA;EACA,YAAA;EACA,OAAA;EACA,kBAAA;EACA,uBAAA;EACA,sCAAA;EACA,iCAAA;EACA,8CAAA;EACA,kBAAA;EACA,kBAAA;EACA,mBAAA;EACA,UAAA;EACA,kBAAA;EACA,qDACE;EAEF,WAAA;AJuEJ;AIpEE;EACE,UAAA;EACA,mBAAA;AJsEJ;;AIjEE;EACE,6BAAA;EACA,8BAAA;AJoEJ;AIlEE;EACE,mDAAA;AJoEJ;AIjEE;EACE,0BAAA;AJmEJ;AIjEI;EACE,8BAAA;AJmEN;AIhEI;EACE,aAAA;AJkEN;AIhEM;;EAEE,UAAA;AJkER;AI/DM;EACE,oCAAA;AJiER;AI9DM;EACE,aAAA;EACA,WAAA;AJgER;AI9DQ;EACE,aAAA;EACA,WAAA;AJgEV;AI5DM;EACE,UAAA;AJ8DR;AI7DQ;EACE,aAAA;AJ+DV;AI9DU;EACE,kBAAA;EACA,eAAA;EACA,cAAA;EACA,SAAA;EACA,WAAA;EACA,eAAA;AJgEZ;AI7DU;EACE,oBAAA;EACA,WAAA;AJ+DZ;AIzDI;EACE,aAAA;EACA,eAAA;EACA,wBAAA;AJ2DN;AIzDM;EACE,WAAA;AJ2DR;AIzDM;EACE,UAAA;AJ2DR;AIzDQ;EACE,UAAA;AJ2DV;AIvDU;EACE,UAAA;AJyDZ;;AKlLA;EACE,eAAA;EAEA,4CAAA;EACA,iCAAA;EACA,uCAAA;EACA,mCAAA;EACA,sBAAA;ALoLF;AKlLE;EACE,sBAAA;EACA,WAAA;ALoLJ;AKhLI;EACE,sBAAA;EACA,WAAA;EACA,YAAA;ALkLN","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","src/_settings-popup.scss"],"names":[],"mappings":"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","file":"style.css"} \ No newline at end of file diff --git a/public/assets/css/style.scss b/public/assets/css/style.scss index 3b96e2f..656ee33 100644 --- a/public/assets/css/style.scss +++ b/public/assets/css/style.scss @@ -4,3 +4,4 @@ @import "src/_print-styles.scss"; @import "src/_forms.scss"; @import "src/_buttons.scss"; +@import "src/_settings-popup.scss"; diff --git a/src/components/ElementPopup.vue b/src/components/ElementPopup.vue index dcf6c46..a6ebd79 100644 --- a/src/components/ElementPopup.vue +++ b/src/components/ElementPopup.vue @@ -2,6 +2,7 @@