bd35b3ff296d

adaptive layout: layout-compact/medium/expanded body class on resize, breakpoints for two-pane + landscape + narrow split

time
2026-05-01 04:08 UTC · 5 months ago
machine
koh2
parent
a145a1c8e968
2 files src/popup/App.tsx+14 −0src/popup/styles/popup.css+71 −0
src/popup/App.tsx+14 −0
@@ -367,6 +367,19 @@367367       document.documentElement.classList.add("peach-mobile-root");368368       void applyMobileStatusBar(theme());369369 370+      // Window Size Class detection — compact/medium/expanded matches Android's371+      // breakpoints. Drives two-pane layout on Z Fold inner display + tablets.372+      const updateLayoutClass = () => {373+        const w = window.innerWidth;374+        const cls = document.body.classList;375+        cls.remove("layout-compact", "layout-medium", "layout-expanded");376+        if (w >= 840) cls.add("layout-expanded");377+        else if (w >= 600) cls.add("layout-medium");378+        else cls.add("layout-compact");379+      };380+      updateLayoutClass();381+      window.addEventListener("resize", updateLayoutClass);382+370383       const keyboardShow = await Keyboard.addListener("keyboardWillShow", (info) => {371384         document.body.style.paddingBottom = `${info.keyboardHeight}px`;372385       });@@ -401,6 +414,7 @@401414         void keyboardShow.remove();402415         void keyboardHide.remove();403416         void backButton.remove();417+        window.removeEventListener("resize", updateLayoutClass);404418         document.removeEventListener("touchstart", handleTouchStart);405419         document.removeEventListener("touchend", handleTouchEnd);406420         document.body.style.paddingBottom = "0";

view file

src/popup/styles/popup.css+71 −0
@@ -7033,3 +7033,74 @@70337033   margin: 0;70347034   padding: 2px 0 0;70357035 }7036+7037+/* ── Adaptive layout — Window Size Classes ───────────────────────────7038+   Compact  (< 600dp)  — phone, foldable cover, narrow split-screen7039+   Medium   (600–839)  — Z Fold inner display, small tablet7040+   Expanded (840+)     — tablet, DeX window, desktop7041+   Body class is set from App.tsx onMount + window resize. */7042+7043+/* Compact stays edge-to-edge (existing behavior). */7044+7045+body.peach-mobile.layout-medium .popup-root,7046+body.peach-mobile.layout-expanded .popup-root {7047+  max-width: 840px;7048+  margin: 0 auto;7049+}7050+7051+body.peach-mobile.layout-medium .peach-shell[data-surface="extension"],7052+body.peach-mobile.layout-expanded .peach-shell[data-surface="extension"] {7053+  max-width: 840px;7054+  margin: 0 auto;7055+}7056+7057+/* Two-pane: vault list on the left, entry detail on the right.7058+   Activates on medium+ when both are present. App-side wires the7059+   .peach-vault-twopane wrapper class on these widths. */7060+body.peach-mobile.layout-medium .peach-vault-twopane,7061+body.peach-mobile.layout-expanded .peach-vault-twopane {7062+  display: grid;7063+  grid-template-columns: 320px minmax(0, 1fr);7064+  gap: 0;7065+  height: 100%;7066+}7067+7068+body.peach-mobile.layout-medium .peach-vault-twopane > .peach-vault-list-pane,7069+body.peach-mobile.layout-expanded .peach-vault-twopane > .peach-vault-list-pane {7070+  border-right: 1px solid var(--peach-border, var(--peach-t3));7071+  overflow-y: auto;7072+  scrollbar-width: none;7073+}7074+7075+body.peach-mobile.layout-medium .peach-vault-twopane > .peach-vault-detail-pane,7076+body.peach-mobile.layout-expanded .peach-vault-twopane > .peach-vault-detail-pane {7077+  overflow-y: auto;7078+  scrollbar-width: none;7079+}7080+7081+/* Tabletop posture — pad content away from the hinge crease. */7082+body.peach-mobile[data-posture="tabletop"] .peach-vault-twopane,7083+body.peach-mobile[data-posture="tabletop"] .peach-stage,7084+body.peach-mobile[data-posture="tabletop"] .peach-overlay-view {7085+  padding-bottom: var(--peach-hinge-height, 0px);7086+}7087+7088+/* Landscape phone — short viewport, reduce vertical padding so content fits. */7089+@media (orientation: landscape) and (max-height: 500px) {7090+  body.peach-mobile .popup-root {7091+    padding-top: env(safe-area-inset-top);7092+  }7093+  body.peach-mobile .peach-shell[data-surface="extension"] {7094+    grid-template-rows: auto minmax(0, 1fr);7095+  }7096+}7097+7098+/* Narrow split-screen (down to 280dp) — keep content readable. */7099+@media (max-width: 320px) {7100+  body.peach-mobile .peach-chrome,7101+  body.peach-mobile .peach-stage,7102+  body.peach-mobile .peach-overlay-view {7103+    padding-left: 8px;7104+    padding-right: 8px;7105+  }7106+}

view file