@pablozaiden/webapp 0.6.6 → 0.6.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,7 +29,7 @@ twice without a distinct user-facing reason.
29
29
 
30
30
  The framework owns the mobile shell breakpoint. `MOBILE_BREAKPOINT_PX` and `MOBILE_MEDIA_QUERY` are exported from `@pablozaiden/webapp/web` for application JavaScript that needs to coordinate with the shell; do not add an independent `innerWidth` threshold for shell behavior. The generated document initializes the `data-wapp-mobile` marker on the root element before the client and styles load, and `WebAppRoot` keeps it synchronized with media-query changes. Custom CSS that follows the framework mobile mode should use that marker rather than repeating a numeric media query.
31
31
 
32
- `WebAppRoot` follows `visualViewport` resize/scroll, window resize, orientation changes, focus boundaries, and mobile media-query changes. It schedules an immediate animation-frame sync first. Two named, bounded retries remain for mobile Safari/WebKit and Chromium behavior where focus/blur or orientation notifications can arrive before the final `visualViewport` geometry is available while the keyboard, browser chrome, or rotation is settling. The first retry catches the post-event layout pass; the final retry catches the end of that transition when no further geometry event is emitted. These retries are implementation fallbacks, not general synchronization primitives, and are cancelled with the associated animation frame and listeners when the root is unmounted.
32
+ `WebAppRoot` follows `visualViewport` resize/scroll, window resize, orientation changes, focus boundaries, and mobile media-query changes. CSS `100dvh` is the authoritative height when the browser supports dynamic viewport units; the hook removes its inline override in that case so a temporarily limited `visualViewport` cannot pin the shell after a rotation or keyboard transition. The visual-viewport pixel value and two named, bounded retries remain only as a fallback for browsers without `100dvh`. The first retry catches the post-event layout pass; the final retry catches the end of that transition when no further geometry event is emitted. These retries are implementation fallbacks, not general synchronization primitives, and are cancelled with the associated animation frame and listeners when the root is unmounted.
33
33
 
34
34
  The framework mobile mode is separate from the narrower `640px` settings-layout rules. Do not add global touch handlers or arbitrary sleeps to reproduce either behavior; use the framework drawer controls and the existing event-driven viewport lifecycle.
35
35
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pablozaiden/webapp",
3
- "version": "0.6.6",
3
+ "version": "0.6.8",
4
4
  "description": "Opinionated Bun + React webapp framework for single-server apps",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -41,6 +41,8 @@ export function useMobileViewportHeight(isMobile: boolean): void {
41
41
 
42
42
  const root = document.documentElement;
43
43
  const viewport = window.visualViewport;
44
+ const usesDynamicViewportUnit = typeof window.CSS?.supports === "function"
45
+ && window.CSS.supports("height", "100dvh");
44
46
  const timers = new Set<number>();
45
47
  let frame = 0;
46
48
 
@@ -55,9 +57,13 @@ export function useMobileViewportHeight(isMobile: boolean): void {
55
57
  return;
56
58
  }
57
59
 
58
- const height = Math.round(viewport?.height ?? window.innerHeight);
59
- if (height > 0) {
60
- root.style.setProperty("--wapp-viewport-height", `${height}px`);
60
+ if (usesDynamicViewportUnit) {
61
+ clearViewportHeight();
62
+ } else {
63
+ const height = Math.round(viewport?.height ?? window.innerHeight);
64
+ if (height > 0) {
65
+ root.style.setProperty("--wapp-viewport-height", `${height}px`);
66
+ }
61
67
  }
62
68
 
63
69
  const scrollingElement = document.scrollingElement;
@@ -83,7 +89,7 @@ export function useMobileViewportHeight(isMobile: boolean): void {
83
89
 
84
90
  const handleViewportTransition = () => {
85
91
  scheduleSync();
86
- if (isMobile) {
92
+ if (isMobile && !usesDynamicViewportUnit) {
87
93
  scheduleViewportRetry(MOBILE_VIEWPORT_FIRST_SETTLE_DELAY_MS);
88
94
  scheduleViewportRetry(MOBILE_VIEWPORT_FINAL_SETTLE_DELAY_MS);
89
95
  }
package/src/web/mobile.ts CHANGED
@@ -3,9 +3,10 @@ export const MOBILE_MEDIA_QUERY = `(max-width: ${MOBILE_BREAKPOINT_PX}px)`;
3
3
  export const MOBILE_STATE_ATTRIBUTE = "data-wapp-mobile";
4
4
 
5
5
  /*
6
- * Mobile Safari/WebKit and Chromium can report focus or orientation changes
7
- * before visualViewport reaches its final geometry. The first retry catches
8
- * the post-event layout pass; the final retry catches the end of the keyboard,
6
+ * These bounded retries are only used by browsers without 100dvh. Mobile
7
+ * Safari/WebKit and Chromium can report focus or orientation changes before
8
+ * visualViewport reaches its final geometry. The first retry catches the
9
+ * post-event layout pass; the final retry catches the end of the keyboard,
9
10
  * browser-chrome, or rotation transition when no further event is emitted.
10
11
  */
11
12
  export const MOBILE_VIEWPORT_FIRST_SETTLE_DELAY_MS = 120;
@@ -85,7 +85,7 @@ html,
85
85
  body,
86
86
  #root {
87
87
  height: 100%;
88
- min-height: 100%;
88
+ min-height: var(--wapp-viewport-height);
89
89
  }
90
90
 
91
91
  body {
@@ -899,7 +899,7 @@ textarea::placeholder {
899
899
  }
900
900
 
901
901
  .wapp-auth-screen {
902
- min-height: 100vh;
902
+ min-height: var(--wapp-viewport-height);
903
903
  display: flex;
904
904
  align-items: center;
905
905
  justify-content: center;
@@ -908,7 +908,7 @@ textarea::placeholder {
908
908
  }
909
909
 
910
910
  .wapp-device-screen {
911
- min-height: 100vh;
911
+ min-height: var(--wapp-viewport-height);
912
912
  display: flex;
913
913
  align-items: center;
914
914
  justify-content: center;