viewport-truth 1.0.0

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.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +251 -0
  3. package/banner.js +46 -0
  4. package/dist/angular.d.ts +28 -0
  5. package/dist/angular.d.ts.map +1 -0
  6. package/dist/angular.js +82 -0
  7. package/dist/angular.js.map +1 -0
  8. package/dist/core/engine.d.ts +3 -0
  9. package/dist/core/engine.d.ts.map +1 -0
  10. package/dist/core/engine.js +200 -0
  11. package/dist/core/engine.js.map +1 -0
  12. package/dist/core/env.d.ts +8 -0
  13. package/dist/core/env.d.ts.map +1 -0
  14. package/dist/core/env.js +38 -0
  15. package/dist/core/env.js.map +1 -0
  16. package/dist/core/index.d.ts +3 -0
  17. package/dist/core/index.d.ts.map +1 -0
  18. package/dist/core/index.js +2 -0
  19. package/dist/core/index.js.map +1 -0
  20. package/dist/core/scheduler.d.ts +7 -0
  21. package/dist/core/scheduler.d.ts.map +1 -0
  22. package/dist/core/scheduler.js +44 -0
  23. package/dist/core/scheduler.js.map +1 -0
  24. package/dist/core/types.d.ts +70 -0
  25. package/dist/core/types.d.ts.map +1 -0
  26. package/dist/core/types.js +2 -0
  27. package/dist/core/types.js.map +1 -0
  28. package/dist/index.d.ts +8 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +8 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/react.d.ts +4 -0
  33. package/dist/react.d.ts.map +1 -0
  34. package/dist/react.js +7 -0
  35. package/dist/react.js.map +1 -0
  36. package/dist/solid.d.ts +12 -0
  37. package/dist/solid.d.ts.map +1 -0
  38. package/dist/solid.js +26 -0
  39. package/dist/solid.js.map +1 -0
  40. package/dist/svelte.d.ts +15 -0
  41. package/dist/svelte.d.ts.map +1 -0
  42. package/dist/svelte.js +31 -0
  43. package/dist/svelte.js.map +1 -0
  44. package/dist/vanilla.d.ts +8 -0
  45. package/dist/vanilla.d.ts.map +1 -0
  46. package/dist/vanilla.js +16 -0
  47. package/dist/vanilla.js.map +1 -0
  48. package/dist/vue.d.ts +8 -0
  49. package/dist/vue.d.ts.map +1 -0
  50. package/dist/vue.js +32 -0
  51. package/dist/vue.js.map +1 -0
  52. package/package.json +120 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AntonVoronezh <anton.voronezh.1990@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,251 @@
1
+ # viewport-truth 🏆
2
+
3
+ [![npm version](https://img.shields.io/npm/v/viewport-truth.svg?style=flat-square)](https://www.npmjs.com/package/viewport-truth)
4
+ [![minzipped size](https://img.shields.io/bundlephobia/minzip/viewport-truth?style=flat-square)](https://bundlephobia.com/package/viewport-truth)
5
+ [![license](https://img.shields.io/npm/l/viewport-truth?style=flat-square)](https://github.com/your-org/viewport-truth/blob/main/LICENSE)
6
+ [![Boosty](https://img.shields.io/badge/Support-Boosty-orange?style=flat-square&logo=boosty)](https://boosty.to/antonvoronezh/donate)
7
+ [![Crypto](https://img.shields.io/badge/Donate-Crypto-2CA5E0?style=flat-square&logo=telegram&logoColor=white)](https://t.me/AntonVoronezhh/4)
8
+
9
+ > **Zero-config, tiny “real viewport” store.**
10
+ > Always returns the *visible* viewport size in **CSS px** (VisualViewport-first) and tells you when the **virtual keyboard** actually ate your UI.
11
+
12
+ ---
13
+
14
+ ## Why? 🤔
15
+
16
+ Mobile viewport is Geometry Hell. You write `100vh` and expect “screen height”. The browser replies: “adorable.”
17
+
18
+ You don’t want to:
19
+
20
+ - ❌ Build “fullscreen” layouts that jump on iOS Safari when the URL bar expands/collapses.
21
+ - ❌ Ship modals / sticky footers that slide under the virtual keyboard.
22
+ - ❌ Depend on `resize` events that jitter on scroll and lie across mobile browsers.
23
+ - ❌ Maintain hacks with `focusin/focusout`, timeouts, and fragile heuristics.
24
+
25
+ **viewport-truth** solves it by using the **Visual Viewport API** as the primary source of truth, stabilizing updates, and providing `isKeyboardOpen` based on geometry—without DOM polling.
26
+
27
+ - **Universal:** React, Vue, Svelte, Solid, Angular, Vanilla.
28
+ - **Tiny:** tree-shakeable, zero runtime deps.
29
+ - **Performant:** rAF throttling, microtask coalescing, idle stability work.
30
+
31
+ ---
32
+
33
+ ## Installation 📦
34
+
35
+ ```bash
36
+ npm install viewport-truth
37
+ # or
38
+ yarn add viewport-truth
39
+ # or
40
+ pnpm add viewport-truth
41
+ ```
42
+
43
+ ## Usage 🚀
44
+
45
+ ### React
46
+
47
+ Use the `useViewportTruth` hook.
48
+
49
+ ```tsx
50
+ import { useViewportTruth } from "viewport-truth/react";
51
+
52
+ export function DebugViewport() {
53
+ const v = useViewportTruth();
54
+
55
+ if (!v) return null; // SSR-safe
56
+
57
+ return (
58
+ <div style={{ padding: 12, border: "1px solid #ddd" }}>
59
+ <div>Visible: {v.width} Ă— {v.height} (CSS px)</div>
60
+ <div>Keyboard: {String(v.isKeyboardOpen)} · Stable: {String(v.isStable)}</div>
61
+ </div>
62
+ );
63
+ }
64
+
65
+ ```
66
+
67
+ ### Vue 3
68
+
69
+ Use the `useViewportTruth` composable.
70
+
71
+ ```html
72
+ <script setup lang="ts">
73
+ import { computed } from "vue";
74
+ import { useViewportTruth } from "viewport-truth/vue";
75
+
76
+ const v = useViewportTruth();
77
+ const label = computed(() =>
78
+ v.value
79
+ ? `Visible: ${v.value.width}×${v.value.height} · Keyboard: ${v.value.isKeyboardOpen}`
80
+ : "SSR…"
81
+ );
82
+ </script>
83
+
84
+ <template>
85
+ <div style="padding: 12px; border: 1px solid #ddd;">
86
+ {{ label }}
87
+ </div>
88
+ </template>
89
+
90
+
91
+ ```
92
+
93
+ ### Svelte
94
+
95
+ Use the `viewportTruth` store-like helper.
96
+
97
+ ```svelte
98
+ <script lang="ts">
99
+ import { viewportTruth } from "viewport-truth/svelte";
100
+ const v = viewportTruth();
101
+ </script>
102
+
103
+ <div style="padding:12px;border:1px solid #ddd">
104
+ {#if $v}
105
+ <div>Visible: {$v.width}Ă—{$v.height}</div>
106
+ <div>Keyboard: {$v.isKeyboardOpen} · Stable: {$v.isStable}</div>
107
+ {/if}
108
+ </div>
109
+
110
+ ```
111
+
112
+ ### SolidJS
113
+
114
+ Use the `createViewportTruth` primitive.
115
+
116
+ ```tsx
117
+ iimport { createViewportTruth } from "viewport-truth/solid";
118
+
119
+ export function DebugViewport() {
120
+ const v = createViewportTruth();
121
+
122
+ return (
123
+ <div style={{ padding: "12px", border: "1px solid #ddd" }}>
124
+ {v() ? (
125
+ <>
126
+ <div>Visible: {v()!.width}Ă—{v()!.height}</div>
127
+ <div>Keyboard: {String(v()!.isKeyboardOpen)} · Stable: {String(v()!.isStable)}</div>
128
+ </>
129
+ ) : null}
130
+ </div>
131
+ );
132
+ }
133
+ ```
134
+
135
+ ### Angular (17+)
136
+
137
+ Use the standalone `ViewportTruthDirective`.
138
+
139
+ ```typescript
140
+ import { Component } from "@angular/core";
141
+ import { CommonModule } from "@angular/common";
142
+ import { ViewportTruthDirective } from "viewport-truth/angular";
143
+
144
+ @Component({
145
+ selector: "app-viewport-debug",
146
+ standalone: true,
147
+ imports: [CommonModule, ViewportTruthDirective],
148
+ template: `
149
+ <div viewportTruth #vt="viewportTruth" style="padding:12px;border:1px solid #ddd;">
150
+ <ng-container *ngIf="vt.vt()() as v">
151
+ <div>Visible: {{ v.width }}Ă—{{ v.height }}</div>
152
+ <div>Keyboard: {{ v.isKeyboardOpen }} · Stable: {{ v.isStable }}</div>
153
+ </ng-container>
154
+ </div>
155
+ `,
156
+ })
157
+ export class ViewportDebugComponent {}
158
+
159
+ ```
160
+
161
+ ### Vanilla JS
162
+
163
+ ```js
164
+ import { createViewportTruth } from "viewport-truth/vanilla";
165
+
166
+ const el = document.getElementById("debug");
167
+
168
+ const vt = createViewportTruth();
169
+ const unsub = vt.subscribe((v) => {
170
+ el.textContent = `Visible: ${v.width}Ă—${v.height} | Keyboard: ${v.isKeyboardOpen} | Stable: ${v.isStable}`;
171
+ });
172
+
173
+ // Later:
174
+ // unsub();
175
+ // vt.destroy();
176
+
177
+ ```
178
+
179
+ ---
180
+
181
+ ## Configuration ⚙️
182
+
183
+ You can tune stability and keyboard detection without changing your app code.
184
+
185
+ ```ts
186
+ // React
187
+ useViewportTruth({
188
+ stableDelayMs: 150,
189
+ keyboardRatio: 0.75,
190
+ keyboardMinDeltaPx: 120,
191
+ });
192
+
193
+ // Vanilla
194
+ createViewportTruth({
195
+ trustVisualViewportUnderZoom: true,
196
+ minViewportPx: 1,
197
+ });
198
+
199
+ ```
200
+
201
+ | Option | Type | Default | Description |
202
+ |---|---|---:|---|
203
+ | `stableDelayMs` | `number` | `150` | `isStable` becomes `true` after this many ms without changes (end of URL bar/keyboard animation). |
204
+ | `keyboardRatio` | `number` | `0.75` | If `visibleHeight < layoutHeight * keyboardRatio`, keyboard is likely open. |
205
+ | `keyboardMinDeltaPx` | `number` | `120` | Minimum height loss (px) required to mark keyboard as open (prevents false positives). |
206
+ | `minViewportPx` | `number` | `1` | Clamps transient `0` / broken values during rotations and browser quirks. |
207
+ | `trustVisualViewportUnderZoom` | `boolean` | `true` | Keep using `visualViewport` even when pinch-zoom is active (`scale !== 1`). |
208
+ | `safeAreaInsets` | `{ top?: number; right?: number; bottom?: number; left?: number }` | `{}` | Optional safe-area compensation (core does not read CSS `env()` automatically). |
209
+
210
+
211
+ ## How it works 🛠️
212
+
213
+ The API looks simple, but it’s doing a few careful things to stay *correct* on mobile.
214
+
215
+ - **VisualViewport-first:** If `window.visualViewport` exists, we treat it as the source of truth for the **visible** viewport.
216
+ - We listen to `visualViewport.resize` **and** `visualViewport.scroll` (mobile browsers change viewport without a classic `window.resize`).
217
+ - **Fallback path:** If Visual Viewport API is unavailable, we fall back to `window.innerWidth/innerHeight`.
218
+ - **Coalesced updates:** Multiple events in a burst are merged into a single update (no “event spam”).
219
+ - **Frame throttling:** Updates are emitted **at most once per animation frame** (via `requestAnimationFrame`) to reduce layout thrash.
220
+ - **Stability flag:** `isStable` turns `true` only after `stableDelayMs` with no changes (useful during URL bar / keyboard animations).
221
+ - **Keyboard detection (geometry-based):** We infer `isKeyboardOpen` by comparing **visible** vs **layout** viewport:
222
+ - `visibleHeight < layoutHeight * keyboardRatio` and
223
+ - `(layoutHeight - visibleHeight) >= keyboardMinDeltaPx`
224
+ - **SSR-safe:** On the server, it returns `null` and attaches listeners only in the browser.
225
+ - **No DOM polling:** Core doesn’t query your layout or mutate styles; it only reads viewport metrics and emits snapshots.
226
+
227
+ ## Support the project ❤️
228
+
229
+ > “We ate the Geometry Hell for you: jumping `100vh`, jittery `resize`, modals under the keyboard.
230
+ > You saved hours (and sanity). A donation is a fair trade for a rock-solid UI and weekends free from debugging.”
231
+
232
+ If this library saved you time, please consider supporting the development:
233
+
234
+ 1. **Fiat (Cards/PayPal):** via **[Boosty](https://boosty.to/antonvoronezh/donate)** (one-time or monthly).
235
+ 2. **Crypto (USDT/TON/BTC/ETH):** view wallet addresses on **[Telegram](https://t.me/AntonVoronezhh/4)**.
236
+
237
+ <div style="display: flex; gap: 10px;">
238
+ <a href="https://boosty.to/antonvoronezh/donate">
239
+ <img src="https://img.shields.io/badge/Support_on-Boosty-orange?style=for-the-badge&logo=boosty" alt="Support on Boosty">
240
+ </a>
241
+ <a href="https://t.me/AntonVoronezhh/4">
242
+ <img src="https://img.shields.io/badge/Crypto_via-Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white" alt="Crypto via Telegram">
243
+ </a>
244
+ </div>
245
+
246
+ ## License
247
+
248
+ MIT
249
+
250
+ ## Keywords
251
+ `viewport`, `visualViewport`, `mobile viewport`, `iOS Safari`, `Android Chrome`, `100vh`, `dvh`, `svh`, `lvh`, `safe-area-inset`, `on-screen keyboard`, `virtual keyboard`, `resize`, `scroll`, `URL bar`, `address bar`, `layout viewport`, `visual viewport`, `responsive UI`, `modals`, `bottom sheet`, `fullscreen`, `PWA`, `SSR`, `requestAnimationFrame`, `debounce`, `throttling`, `webview`, `Capacitor`, `Cordova`, `React`, `Vue`, `Svelte`, `SolidJS`, `Angular`, `vanilla JS`
package/banner.js ADDED
@@ -0,0 +1,46 @@
1
+ try {
2
+ if (
3
+ process.env.CI ||
4
+ process.env.ADBLOCK ||
5
+ process.env.DISABLE_OPENCOLLECTIVE ||
6
+ process.env.npm_config_ignore_scripts === "true" ||
7
+ process.env.NODE_ENV === "test"
8
+ ) {
9
+ process.exit(0);
10
+ }
11
+
12
+ const loglevel = (process.env.npm_config_loglevel || "").toLowerCase();
13
+ if (loglevel === "silent") process.exit(0);
14
+
15
+ const reset = "\x1b[0m";
16
+ const cyan = "\x1b[36m";
17
+ const green = "\x1b[32m";
18
+ const yellow = "\x1b[33m";
19
+ const dim = "\x1b[2m";
20
+ const bold = "\x1b[1m";
21
+
22
+ const box = `${cyan}===============================================================${reset}`;
23
+
24
+ const msg = `
25
+ ${box}
26
+ ${green}${bold} Thanks for installing nope-click!${reset} ${green}🚀${reset}
27
+ ${box}
28
+
29
+ ${yellow}This project is community-supported.${reset}
30
+ If it saves you time, please consider supporting development:
31
+
32
+ ${green}Boosty (Cards/PayPal):${reset} https://boosty.to/antonvoronezh/donate
33
+ ${green}Crypto (Telegram):${reset} https://t.me/AntonVoronezhh/4
34
+
35
+ ${dim}Tip: hide install messages with --silent (or npm config set loglevel silent).${reset}
36
+ ${dim}Scripts can be disabled with --ignore-scripts (then this won’t run).${reset}
37
+ `;
38
+
39
+ process.stderr.write(msg);
40
+
41
+ process.stderr.write(
42
+ `${bold}Support:${reset} https://boosty.to/antonvoronezh/donate | https://t.me/AntonVoronezhh/4\n`
43
+ );
44
+ } catch (_) {
45
+ process.exit(0);
46
+ }
@@ -0,0 +1,28 @@
1
+ import { type Signal } from "@angular/core";
2
+ import type { ViewportTruthSnapshot } from "./core/types";
3
+ /**
4
+ * Usage:
5
+ * <div viewportTruth [vtOptions]="{...}" (vtChange)="onSnap($event)"></div>
6
+ *
7
+ * This directive exposes a Signal via `vt()` and also can emit changes through `vtChange`.
8
+ */
9
+ export declare class ViewportTruthDirective {
10
+ private destroyRef;
11
+ vtOptions: import("@angular/core").InputSignal<Readonly<{
12
+ stableDelayMs?: number;
13
+ keyboardRatio?: number;
14
+ keyboardMinDeltaPx?: number;
15
+ minViewportPx?: number;
16
+ trustVisualViewportUnderZoom?: boolean;
17
+ safeAreaInsets?: Partial<Readonly<{
18
+ top: number;
19
+ right: number;
20
+ bottom: number;
21
+ left: number;
22
+ }>>;
23
+ }> | undefined>;
24
+ private _vt;
25
+ vt(): Signal<ViewportTruthSnapshot | null>;
26
+ constructor();
27
+ }
28
+ //# sourceMappingURL=angular.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"angular.d.ts","sourceRoot":"","sources":["../src/angular.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwD,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,KAAK,EAAwB,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAGhF;;;;;GAKG;AACH,qBAKa,sBAAsB;IAC/B,OAAO,CAAC,UAAU,CAAsB;IAExC,SAAS;;;;;;;;;;;;oBAAsD;IAE/D,OAAO,CAAC,GAAG,CAA8C;IACzD,EAAE,IAAI,MAAM,CAAC,qBAAqB,GAAG,IAAI,CAAC;;CAkB7C"}
@@ -0,0 +1,82 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { Directive, DestroyRef, effect, inject, input, signal } from "@angular/core";
36
+ import { createViewportTruthStore } from "./core/engine";
37
+ /**
38
+ * Usage:
39
+ * <div viewportTruth [vtOptions]="{...}" (vtChange)="onSnap($event)"></div>
40
+ *
41
+ * This directive exposes a Signal via `vt()` and also can emit changes through `vtChange`.
42
+ */
43
+ let ViewportTruthDirective = (() => {
44
+ let _classDecorators = [Directive({
45
+ selector: "[viewportTruth]",
46
+ standalone: true,
47
+ exportAs: "viewportTruth",
48
+ })];
49
+ let _classDescriptor;
50
+ let _classExtraInitializers = [];
51
+ let _classThis;
52
+ var ViewportTruthDirective = class {
53
+ static { _classThis = this; }
54
+ static {
55
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
56
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
57
+ ViewportTruthDirective = _classThis = _classDescriptor.value;
58
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
59
+ __runInitializers(_classThis, _classExtraInitializers);
60
+ }
61
+ destroyRef = inject(DestroyRef);
62
+ vtOptions = input(undefined);
63
+ _vt = signal(null);
64
+ vt() {
65
+ return this._vt.asReadonly();
66
+ }
67
+ constructor() {
68
+ const store = createViewportTruthStore(this.vtOptions());
69
+ const unsub = store.subscribe(() => this._vt.set(store.getSnapshot()));
70
+ this.destroyRef.onDestroy(() => {
71
+ unsub();
72
+ store.destroy();
73
+ });
74
+ effect(() => {
75
+ void this._vt();
76
+ });
77
+ }
78
+ };
79
+ return ViewportTruthDirective = _classThis;
80
+ })();
81
+ export { ViewportTruthDirective };
82
+ //# sourceMappingURL=angular.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"angular.js","sourceRoot":"","sources":["../src/angular.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAe,MAAM,eAAe,CAAC;AAElG,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD;;;;;GAKG;IAMU,sBAAsB;4BALlC,SAAS,CAAC;YACP,QAAQ,EAAE,iBAAiB;YAC3B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,eAAe;SAC5B,CAAC;;;;;;;;YACF,6KAwBC;;;YAxBY,uDAAsB;;QACvB,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;QAExC,SAAS,GAAG,KAAK,CAAmC,SAAS,CAAC,CAAC;QAEvD,GAAG,GAAG,MAAM,CAA+B,IAAI,CAAC,CAAC;QACzD,EAAE;YACE,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;QACjC,CAAC;QAED;YACI,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YAEzD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YAEvE,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE;gBAC3B,KAAK,EAAE,CAAC;gBACR,KAAK,CAAC,OAAO,EAAE,CAAC;YACpB,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,GAAG,EAAE;gBACR,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;YACpB,CAAC,CAAC,CAAC;QACP,CAAC;;;;SAvBQ,sBAAsB"}
@@ -0,0 +1,3 @@
1
+ import type { ViewportTruthOptions, ViewportTruthStore } from "./types";
2
+ export declare const createViewportTruthStore: (options?: ViewportTruthOptions) => ViewportTruthStore;
3
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAyB,kBAAkB,EAAE,MAAM,SAAS,CAAC;AA2G/F,eAAO,MAAM,wBAAwB,GAAI,UAAU,oBAAoB,KAAG,kBAkIzE,CAAC"}
@@ -0,0 +1,200 @@
1
+ import { canUseDOM, now } from "./env";
2
+ import { createScheduler } from "./scheduler";
3
+ const clampMin = (n, min) => (Number.isFinite(n) ? Math.max(min, n) : min);
4
+ const round2 = (n) => Math.round(n * 100) / 100;
5
+ const getSafeArea = (opt) => {
6
+ const s = opt?.safeAreaInsets;
7
+ return {
8
+ top: s?.top ?? 0,
9
+ right: s?.right ?? 0,
10
+ bottom: s?.bottom ?? 0,
11
+ left: s?.left ?? 0,
12
+ };
13
+ };
14
+ const computeSnapshot = (opt) => {
15
+ const w = window;
16
+ const vv = w.visualViewport ?? null;
17
+ const layoutWidth = clampMin(w.innerWidth, opt.minViewportPx);
18
+ const layoutHeight = clampMin(w.innerHeight, opt.minViewportPx);
19
+ const hasVisualViewport = !!vv;
20
+ const scale = hasVisualViewport && typeof vv.scale === "number" ? clampMin(vv.scale, 0.01) : 1;
21
+ let visualWidth = hasVisualViewport && typeof vv.width === "number" ? vv.width : layoutWidth;
22
+ let visualHeight = hasVisualViewport && typeof vv.height === "number" ? vv.height : layoutHeight;
23
+ visualWidth = clampMin(visualWidth, opt.minViewportPx);
24
+ visualHeight = clampMin(visualHeight, opt.minViewportPx);
25
+ const offsetLeft = hasVisualViewport && typeof vv.offsetLeft === "number" ? vv.offsetLeft : 0;
26
+ const offsetTop = hasVisualViewport && typeof vv.offsetTop === "number" ? vv.offsetTop : 0;
27
+ const safe = getSafeArea(opt);
28
+ let height = visualHeight;
29
+ if (safe.bottom > 0) {
30
+ const delta = layoutHeight - visualHeight;
31
+ if (delta > safe.bottom * 0.8 && delta < safe.bottom * 2.5) {
32
+ height = visualHeight + safe.bottom;
33
+ }
34
+ }
35
+ let width = visualWidth;
36
+ if (safe.left > 0 || safe.right > 0) {
37
+ const delta = layoutWidth - visualWidth;
38
+ const sum = safe.left + safe.right;
39
+ if (sum > 0 && delta > sum * 0.8 && delta < sum * 2.5) {
40
+ width = visualWidth + sum;
41
+ }
42
+ }
43
+ const trustVV = opt.trustVisualViewportUnderZoom;
44
+ const effectiveWidth = hasVisualViewport && (trustVV || scale === 1) ? width : layoutWidth;
45
+ const effectiveHeight = hasVisualViewport && (trustVV || scale === 1) ? height : layoutHeight;
46
+ const deltaH = layoutHeight - effectiveHeight;
47
+ const ratioOk = effectiveHeight < layoutHeight * opt.keyboardRatio;
48
+ const deltaOk = deltaH > opt.keyboardMinDeltaPx;
49
+ const isKeyboardOpen = hasVisualViewport ? (ratioOk && deltaOk) : false;
50
+ return {
51
+ width: round2(effectiveWidth),
52
+ height: round2(effectiveHeight),
53
+ layoutWidth: round2(layoutWidth),
54
+ layoutHeight: round2(layoutHeight),
55
+ offsetLeft: round2(offsetLeft),
56
+ offsetTop: round2(offsetTop),
57
+ scale: round2(scale),
58
+ isKeyboardOpen,
59
+ isStable: true,
60
+ hasVisualViewport,
61
+ ts: now(),
62
+ };
63
+ };
64
+ const sameSnapshot = (a, b) => {
65
+ return (a.width === b.width &&
66
+ a.height === b.height &&
67
+ a.layoutWidth === b.layoutWidth &&
68
+ a.layoutHeight === b.layoutHeight &&
69
+ a.offsetLeft === b.offsetLeft &&
70
+ a.offsetTop === b.offsetTop &&
71
+ a.scale === b.scale &&
72
+ a.isKeyboardOpen === b.isKeyboardOpen &&
73
+ a.isStable === b.isStable &&
74
+ a.hasVisualViewport === b.hasVisualViewport);
75
+ };
76
+ const withDefaults = (options) => ({
77
+ stableDelayMs: options?.stableDelayMs ?? 150,
78
+ keyboardRatio: options?.keyboardRatio ?? 0.75,
79
+ keyboardMinDeltaPx: options?.keyboardMinDeltaPx ?? 120,
80
+ minViewportPx: options?.minViewportPx ?? 1,
81
+ trustVisualViewportUnderZoom: options?.trustVisualViewportUnderZoom ?? true,
82
+ safeAreaInsets: options?.safeAreaInsets ?? {},
83
+ });
84
+ export const createViewportTruthStore = (options) => {
85
+ const opt = withDefaults(options);
86
+ if (!canUseDOM()) {
87
+ return {
88
+ getSnapshot: () => {
89
+ throw new Error("viewport-truth: getSnapshot() called on the server. Use getServerSnapshot().");
90
+ },
91
+ getServerSnapshot: () => null,
92
+ subscribe: () => () => void 0,
93
+ destroy: () => void 0,
94
+ };
95
+ }
96
+ const scheduler = createScheduler();
97
+ let destroyed = false;
98
+ let snapshot = computeSnapshot(opt);
99
+ snapshot = { ...snapshot, isStable: true };
100
+ const listeners = new Set();
101
+ let stableTimer = null;
102
+ let lastChangeAt = snapshot.ts;
103
+ const setStable = (value) => {
104
+ if (destroyed)
105
+ return;
106
+ if (snapshot.isStable === value)
107
+ return;
108
+ snapshot = { ...snapshot, isStable: value, ts: now() };
109
+ listeners.forEach((l) => l());
110
+ };
111
+ const armStabilityTimer = () => {
112
+ if (stableTimer != null)
113
+ clearTimeout(stableTimer);
114
+ const delay = opt.stableDelayMs;
115
+ scheduler.scheduleIdle(() => {
116
+ if (destroyed)
117
+ return;
118
+ stableTimer = window.setTimeout(() => {
119
+ if (destroyed)
120
+ return;
121
+ const age = now() - lastChangeAt;
122
+ if (age >= delay)
123
+ setStable(true);
124
+ }, delay);
125
+ });
126
+ };
127
+ const recompute = () => {
128
+ if (destroyed)
129
+ return;
130
+ const nextBase = computeSnapshot(opt);
131
+ const next = { ...nextBase, isStable: false };
132
+ if (!sameSnapshot(snapshot, next)) {
133
+ snapshot = next;
134
+ lastChangeAt = snapshot.ts;
135
+ listeners.forEach((l) => l());
136
+ }
137
+ armStabilityTimer();
138
+ };
139
+ const onAnyViewportEvent = () => scheduler.scheduleFrame(recompute);
140
+ const vv = window.visualViewport ?? null;
141
+ let attached = false;
142
+ const attach = () => {
143
+ if (attached || destroyed)
144
+ return;
145
+ attached = true;
146
+ scheduler.scheduleFrame(recompute);
147
+ if (vv) {
148
+ vv.addEventListener("resize", onAnyViewportEvent, { passive: true });
149
+ vv.addEventListener("scroll", onAnyViewportEvent, { passive: true });
150
+ }
151
+ window.addEventListener("orientationchange", onAnyViewportEvent, { passive: true });
152
+ window.addEventListener("resize", onAnyViewportEvent, { passive: true });
153
+ window.addEventListener("pageshow", onAnyViewportEvent, { passive: true });
154
+ };
155
+ const detach = () => {
156
+ if (!attached)
157
+ return;
158
+ attached = false;
159
+ if (vv) {
160
+ vv.removeEventListener("resize", onAnyViewportEvent);
161
+ vv.removeEventListener("scroll", onAnyViewportEvent);
162
+ }
163
+ window.removeEventListener("orientationchange", onAnyViewportEvent);
164
+ window.removeEventListener("resize", onAnyViewportEvent);
165
+ window.removeEventListener("pageshow", onAnyViewportEvent);
166
+ };
167
+ const destroy = () => {
168
+ if (destroyed)
169
+ return;
170
+ destroyed = true;
171
+ detach();
172
+ scheduler.cancelAll();
173
+ if (stableTimer != null)
174
+ clearTimeout(stableTimer);
175
+ stableTimer = null;
176
+ listeners.clear();
177
+ };
178
+ return {
179
+ getSnapshot: () => snapshot,
180
+ getServerSnapshot: () => null,
181
+ subscribe: (listener) => {
182
+ if (destroyed)
183
+ return () => void 0;
184
+ listeners.add(listener);
185
+ if (listeners.size === 1)
186
+ attach();
187
+ scheduler.scheduleFrame(() => {
188
+ if (!destroyed && listeners.has(listener))
189
+ listener();
190
+ });
191
+ return () => {
192
+ listeners.delete(listener);
193
+ if (listeners.size === 0)
194
+ detach();
195
+ };
196
+ },
197
+ destroy,
198
+ };
199
+ };
200
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare const canUseDOM: () => boolean;
2
+ export declare const now: () => number;
3
+ export declare const raf: (cb: FrameRequestCallback) => number;
4
+ export declare const caf: (id: number) => void;
5
+ export declare const queueMicrotaskSafe: (cb: () => void) => void;
6
+ export declare const requestIdle: (cb: IdleRequestCallback, timeoutMs?: number) => number;
7
+ export declare const cancelIdle: (id: number) => void;
8
+ //# sourceMappingURL=env.d.ts.map