@floegence/floe-webapp-core 0.70.0 → 0.72.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.
- package/dist/components/layout/AppViewport.d.ts +9 -0
- package/dist/components/layout/AppViewport.js +31 -0
- package/dist/components/layout/BottomBarCompanion.js +168 -154
- package/dist/components/layout/MobileTabBar.d.ts +1 -0
- package/dist/components/layout/MobileTabBar.js +42 -41
- package/dist/components/layout/Shell.d.ts +6 -0
- package/dist/components/layout/Shell.js +158 -141
- package/dist/components/layout/index.d.ts +1 -0
- package/dist/components/ui/SurfaceFloatingLayer.js +35 -26
- package/dist/components/ui/surfaceFloatingBoundary.js +31 -40
- package/dist/floe.css +6 -4
- package/dist/full.js +598 -596
- package/dist/layout.js +36 -34
- package/dist/remote-input.css +22 -0
- package/dist/remote-input.d.ts +38 -0
- package/dist/remote-input.js +145 -0
- package/dist/styles.css +1 -1
- package/dist/viewport.d.ts +54 -0
- package/dist/viewport.js +90 -0
- package/package.json +10 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Framework-independent visible bounds, in getBoundingClientRect CSS pixels. */
|
|
2
|
+
export interface ViewportRect {
|
|
3
|
+
left: number;
|
|
4
|
+
top: number;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
right: number;
|
|
8
|
+
bottom: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ViewportInsets {
|
|
11
|
+
top: number;
|
|
12
|
+
right: number;
|
|
13
|
+
bottom: number;
|
|
14
|
+
left: number;
|
|
15
|
+
}
|
|
16
|
+
export interface ViewportSnapshot {
|
|
17
|
+
visible: ViewportRect;
|
|
18
|
+
/** Dynamic browser content size before soft-keyboard occlusion. */
|
|
19
|
+
layout: {
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
};
|
|
23
|
+
safeArea: ViewportInsets;
|
|
24
|
+
keyboardOpen: boolean;
|
|
25
|
+
/** Add to client coordinates when positioning a document-level fixed element. */
|
|
26
|
+
fixedOffset: {
|
|
27
|
+
left: number;
|
|
28
|
+
top: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface ViewportSource {
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
fixedOrigin?: {
|
|
35
|
+
left: number;
|
|
36
|
+
top: number;
|
|
37
|
+
};
|
|
38
|
+
visualViewport?: {
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
offsetLeft: number;
|
|
42
|
+
offsetTop: number;
|
|
43
|
+
scale?: number;
|
|
44
|
+
} | null;
|
|
45
|
+
safeArea: ViewportInsets;
|
|
46
|
+
editing: boolean;
|
|
47
|
+
touch: boolean;
|
|
48
|
+
}
|
|
49
|
+
export declare function resolveViewportSnapshot(source: ViewportSource): ViewportSnapshot;
|
|
50
|
+
export declare function readViewportSnapshot(view: Window): ViewportSnapshot;
|
|
51
|
+
/** One event-driven measurement owner per Window; releasing the last subscription removes it. */
|
|
52
|
+
export declare function observeViewport(view: Window, listener: (snapshot: ViewportSnapshot) => void): () => void;
|
|
53
|
+
/** Apply to one top-level application container, not nested content surfaces. */
|
|
54
|
+
export declare function viewportStyle(snapshot: ViewportSnapshot): Record<string, string>;
|
package/dist/viewport.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const u = (t, e) => Number.isFinite(t) && Number(t) > 0 ? Number(t) : Math.max(0, e);
|
|
2
|
+
function g(t) {
|
|
3
|
+
const e = t.visualViewport, n = u(e?.width, t.width), i = u(e?.height, t.height), o = t.fixedOrigin ?? { left: 0, top: 0 }, s = Math.max(0, e?.offsetLeft || 0) + o.left, a = Math.max(0, e?.offsetTop || 0) + o.top, r = t.touch && t.editing && Math.abs((e?.scale ?? 1) - 1) < 0.01 && t.height - i > 100;
|
|
4
|
+
return {
|
|
5
|
+
visible: { left: s, top: a, width: n, height: i, right: s + n, bottom: a + i },
|
|
6
|
+
layout: { width: t.width, height: t.height },
|
|
7
|
+
safeArea: { ...t.safeArea, bottom: r ? 0 : t.safeArea.bottom },
|
|
8
|
+
keyboardOpen: r,
|
|
9
|
+
fixedOffset: { left: -o.left, top: -o.top }
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function b(t) {
|
|
13
|
+
let e = t.activeElement;
|
|
14
|
+
for (; e?.shadowRoot?.activeElement; ) e = e.shadowRoot.activeElement;
|
|
15
|
+
return !e || e.matches('[disabled], [readonly], [inputmode="none"]') ? !1 : e.matches('textarea, input:not([type]), input[type="text"], input[type="search"], input[type="email"], input[type="url"], input[type="tel"], input[type="password"], input[type="number"], [contenteditable=""], [contenteditable="true"], [contenteditable="plaintext-only"]');
|
|
16
|
+
}
|
|
17
|
+
function m(t) {
|
|
18
|
+
const e = t.document.createElement("div");
|
|
19
|
+
return e.setAttribute("aria-hidden", "true"), e.style.cssText = "position:fixed;top:0;left:0;width:100%;height:100dvh;visibility:hidden;pointer-events:none;box-sizing:border-box;padding:env(safe-area-inset-top,0px) env(safe-area-inset-right,0px) env(safe-area-inset-bottom,0px) env(safe-area-inset-left,0px)", t.document.documentElement.append(e), e;
|
|
20
|
+
}
|
|
21
|
+
function l(t, e) {
|
|
22
|
+
const n = e.getBoundingClientRect(), i = t.getComputedStyle(e), o = (s) => Math.max(0, Number.parseFloat(s) || 0);
|
|
23
|
+
return g({
|
|
24
|
+
width: n.width || t.innerWidth,
|
|
25
|
+
height: n.height || t.innerHeight,
|
|
26
|
+
visualViewport: t.visualViewport,
|
|
27
|
+
fixedOrigin: { left: n.left, top: n.top },
|
|
28
|
+
safeArea: { top: o(i.paddingTop), right: o(i.paddingRight), bottom: o(i.paddingBottom), left: o(i.paddingLeft) },
|
|
29
|
+
editing: b(t.document),
|
|
30
|
+
touch: t.matchMedia?.("(any-pointer: coarse)").matches ?? !1
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const d = /* @__PURE__ */ new WeakMap();
|
|
34
|
+
function x(t) {
|
|
35
|
+
const e = d.get(t);
|
|
36
|
+
if (e) return e.snapshot;
|
|
37
|
+
const n = m(t);
|
|
38
|
+
try {
|
|
39
|
+
return l(t, n);
|
|
40
|
+
} finally {
|
|
41
|
+
n.remove();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function y(t, e) {
|
|
45
|
+
let n = d.get(t);
|
|
46
|
+
if (!n) {
|
|
47
|
+
const o = m(t);
|
|
48
|
+
let s = 0;
|
|
49
|
+
const a = /* @__PURE__ */ new Set(), r = { snapshot: l(t, o), listeners: a, dispose: () => {
|
|
50
|
+
} }, c = () => {
|
|
51
|
+
s || (s = t.requestAnimationFrame(() => {
|
|
52
|
+
s = 0, r.snapshot = l(t, o);
|
|
53
|
+
for (const p of a) p(r.snapshot);
|
|
54
|
+
}));
|
|
55
|
+
}, f = [
|
|
56
|
+
[t, "resize"],
|
|
57
|
+
[t, "scroll"],
|
|
58
|
+
[t, "orientationchange"],
|
|
59
|
+
[t.document, "focusin"],
|
|
60
|
+
[t.document, "focusout"]
|
|
61
|
+
];
|
|
62
|
+
t.visualViewport && f.push([t.visualViewport, "resize"], [t.visualViewport, "scroll"]);
|
|
63
|
+
for (const [p, h] of f) p.addEventListener(h, c);
|
|
64
|
+
r.dispose = () => {
|
|
65
|
+
for (const [p, h] of f) p.removeEventListener(h, c);
|
|
66
|
+
s && t.cancelAnimationFrame(s), o.remove(), d.delete(t);
|
|
67
|
+
}, d.set(t, r), n = r;
|
|
68
|
+
}
|
|
69
|
+
n.listeners.add(e), e(n.snapshot);
|
|
70
|
+
const i = n;
|
|
71
|
+
return () => {
|
|
72
|
+
i.listeners.delete(e), i.listeners.size === 0 && i.dispose();
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function V(t) {
|
|
76
|
+
const { visible: e } = t;
|
|
77
|
+
return {
|
|
78
|
+
position: "fixed",
|
|
79
|
+
left: `${e.left + t.fixedOffset.left}px`,
|
|
80
|
+
top: `${e.top + t.fixedOffset.top}px`,
|
|
81
|
+
width: `${e.width}px`,
|
|
82
|
+
height: `${e.height}px`
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
y as observeViewport,
|
|
87
|
+
x as readViewportSnapshot,
|
|
88
|
+
g as resolveViewportSnapshot,
|
|
89
|
+
V as viewportStyle
|
|
90
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@floegence/floe-webapp-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.72.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -108,6 +108,7 @@
|
|
|
108
108
|
},
|
|
109
109
|
"./progress-shimmer.css": "./dist/progress-shimmer.css",
|
|
110
110
|
"./window-status.css": "./dist/window-status.css",
|
|
111
|
+
"./remote-input.css": "./dist/remote-input.css",
|
|
111
112
|
"./window-status": {
|
|
112
113
|
"types": "./dist/window-status.d.ts",
|
|
113
114
|
"import": "./dist/window-status.js",
|
|
@@ -116,6 +117,14 @@
|
|
|
116
117
|
"./reload-placeholder": {
|
|
117
118
|
"types": "./dist/reload-placeholder.d.ts",
|
|
118
119
|
"import": "./dist/reload-placeholder.js"
|
|
120
|
+
},
|
|
121
|
+
"./remote-input": {
|
|
122
|
+
"types": "./dist/remote-input.d.ts",
|
|
123
|
+
"import": "./dist/remote-input.js"
|
|
124
|
+
},
|
|
125
|
+
"./viewport": {
|
|
126
|
+
"types": "./dist/viewport.d.ts",
|
|
127
|
+
"import": "./dist/viewport.js"
|
|
119
128
|
}
|
|
120
129
|
},
|
|
121
130
|
"files": [
|