patx/projectpay

make sure new project button stays visible in mobile search ux/ui

Commit 1dd0104 · patx · 2026-07-06T23:55:36-04:00

Changeset
1dd0104519734cc6cd117272e4ab7c48a03117c2
Parents
a0db436d4b417888322d35f005c7d3eb1465276a

View source at this commit

Comments

No comments yet.

Log in to comment

Diff

diff --git a/templates/base.html b/templates/base.html
index 5d23804..960c784 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -445,7 +445,7 @@
         align-items: center;
         justify-content: center;
         right: max(20px, calc((100vw - 1080px) / 2));
-        bottom: 75px;
+        bottom: calc(75px + var(--keyboard-offset, 0px));
         z-index: 11;
         width: 56px;
         height: 56px;
@@ -489,7 +489,7 @@
           box-shadow: 0 8px 18px var(--shadow-color);
         }
         .has-sticky-index.index-search-active .floating-new-project {
-          display: none;
+          bottom: calc(16px + env(safe-area-inset-bottom, 0px) + var(--keyboard-offset, 0px));
         }
       }
         @media print {
diff --git a/templates/index.html b/templates/index.html
index b01bf09..82abedd 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -35,6 +35,16 @@
     let activeRequest = 0;
     let blurTimer = null;
 
+    function updateKeyboardOffset() {
+      if (!mobileSearchQuery.matches || document.activeElement !== searchInput || !window.visualViewport) {
+        document.documentElement.style.setProperty("--keyboard-offset", "0px");
+        return;
+      }
+      const viewportBottom = window.visualViewport.height + window.visualViewport.offsetTop;
+      const keyboardOffset = Math.max(0, Math.round(window.innerHeight - viewportBottom));
+      document.documentElement.style.setProperty("--keyboard-offset", `${keyboardOffset}px`);
+    }
+
     function keepSearchResultsVisible() {
       if (!mobileSearchQuery.matches) return;
       requestAnimationFrame(() => {
@@ -47,6 +57,7 @@
       clearTimeout(blurTimer);
       if (!page) return;
       page.classList.toggle("index-search-active", active && mobileSearchQuery.matches);
+      updateKeyboardOffset();
       if (active) keepSearchResultsVisible();
     }
 
@@ -120,8 +131,12 @@
     }
     if (window.visualViewport) {
       window.visualViewport.addEventListener("resize", () => {
+        updateKeyboardOffset();
         if (document.activeElement === searchInput) keepSearchResultsVisible();
       });
+      window.visualViewport.addEventListener("scroll", () => {
+        updateKeyboardOffset();
+      });
     }
 
     if ("IntersectionObserver" in window) {