ad87fee15001

fix bottom-sheet positioning + Settings unreachable: render mobile vault sheet via Solid Portal at document root (was inside .peach-shell whose CSS animations apply transform, trapping position:fixed); add chrome.runtime.getManifest() stub to chrome shim (Settings.tsx calls it at module init, throwing TypeError that left Suspense fallback hung forever); sheet now hidden off-screen at rest

time
2026-05-07 04:35 UTC · 5 months ago
machine
koh2
parent
264e3339f4cd
1 file src/popup/App.tsx+36 −33
src/popup/App.tsx+36 −33
@@ -1,4 +1,5 @@11 import { createEffect, createMemo, createSignal, lazy, onCleanup, onMount, Show, Suspense } from "solid-js";2+import { Portal } from "solid-js/web";23 import { storageGet, storageSet } from "../shared/storage";34 import { sendMessage } from "../shared/bridge";45 import { ACCENT_COLORS } from "../shared/types";@@ -559,10 +560,10 @@559560           captured = true;560561         }561562 562-        // Translate the sheet by dy from its rest position. Clamp so the563-        // sheet can't be dragged above its open position or below its peek.563+        // Translate the sheet by dy from its rest position. At rest the sheet564+        // is fully off-screen (translateY = viewport height). Open is 0.564565         const v = view();565-        const restClosed = window.innerHeight - 60; // peek height566+        const restClosed = window.innerHeight;566567         const baseTranslate = v === "list" ? 0 : restClosed;567568         const next = Math.max(0, Math.min(restClosed, baseTranslate + dy));568569         setSheetTranslate(next);@@ -585,7 +586,7 @@585586           return;586587         }587588 588-        const restClosed = window.innerHeight - 60;589+        const restClosed = window.innerHeight;589590         const current = sheetTranslate() ?? restClosed;590591         const v = view();591592 @@ -1309,35 +1310,9 @@13091310               </section>13101311             </div>13111312 1312-            {/* Native: vault list lives in an always-mounted bottom sheet1313-                that peeks at the bottom (search-bar handle) and drags up to1314-                fill the screen. Desktop: shown on demand via Show. */}1315-            <Show when={isNativePlatform()}>1316-              <div1317-                class="peach-vault-sheet"1318-                classList={{ "is-open": view() === "list", "is-dragging": sheetTranslate() !== null }}1319-                style={(() => {1320-                  const live = sheetTranslate();1321-                  if (live === null) return undefined;1322-                  return { transform: `translateY(${live}px)` };1323-                })()}1324-              >1325-                <VaultView1326-                  entries={entries()}1327-                  selectedEntryId={selectedEntry()?.id}1328-                  currentTabDomain={currentTabDomain()}1329-                  sortOrder={sortOrder()}1330-                  searchSeed={listSearchSeed()}1331-                  searchSeedNonce={listSearchSeedNonce()}1332-                  onSelectEntry={handleSelectEntry}1333-                  onSortOrderChange={setSortOrder}1334-                  onAdd={handleAdd}1335-                  onClose={() => setView("entry")}1336-                  onOpenTrash={() => setView("trash")}1337-                  onDeleteMany={handleDeleteMany}1338-                />1339-              </div>1340-            </Show>1313+            {/* Desktop: shown on demand via Show. Native sheet is rendered1314+                via Portal below at the document root so its position:fixed1315+                isn't trapped by .peach-shell's transform-based animations. */}13411316             <Show when={!isNativePlatform() && view() === "list"}>13421317               <VaultView13431318                 entries={entries()}@@ -1353,6 +1328,34 @@13531328                 onOpenTrash={() => setView("trash")}13541329                 onDeleteMany={handleDeleteMany}13551330               />1331+            </Show>1332+            <Show when={isNativePlatform() && hasVault()}>1333+              <Portal>1334+                <div1335+                  class="peach-vault-sheet"1336+                  classList={{ "is-open": view() === "list", "is-dragging": sheetTranslate() !== null }}1337+                  style={(() => {1338+                    const live = sheetTranslate();1339+                    if (live === null) return undefined;1340+                    return { transform: `translateY(${live}px)` };1341+                  })()}1342+                >1343+                  <VaultView1344+                    entries={entries()}1345+                    selectedEntryId={selectedEntry()?.id}1346+                    currentTabDomain={currentTabDomain()}1347+                    sortOrder={sortOrder()}1348+                    searchSeed={listSearchSeed()}1349+                    searchSeedNonce={listSearchSeedNonce()}1350+                    onSelectEntry={handleSelectEntry}1351+                    onSortOrderChange={setSortOrder}1352+                    onAdd={handleAdd}1353+                    onClose={() => setView("entry")}1354+                    onOpenTrash={() => setView("trash")}1355+                    onDeleteMany={handleDeleteMany}1356+                  />1357+                </div>1358+              </Portal>13561359             </Show>13571360             <Show when={view() === "settings"}>13581361               <Suspense fallback={<div class="peach-loading"><PeachWordmark /></div>}>

view file