@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
package/dist/layout.js
CHANGED
|
@@ -1,39 +1,41 @@
|
|
|
1
1
|
import { ActivityBar as r } from "./components/layout/ActivityBar.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
2
|
+
import { AppViewport as a } from "./components/layout/AppViewport.js";
|
|
3
|
+
import { BottomBar as i, BottomBarItem as m, StatusIndicator as n } from "./components/layout/BottomBar.js";
|
|
4
|
+
import { BottomBarCompanion as x } from "./components/layout/BottomBarCompanion.js";
|
|
5
|
+
import { DisplayModePageShell as d } from "./components/layout/DisplayModePageShell.js";
|
|
6
|
+
import { DisplayModeSwitcher as B, sanitizeDisplayMode as b } from "./components/layout/DisplayModeSwitcher.js";
|
|
7
|
+
import { KeepAliveStack as c } from "./components/layout/KeepAliveStack.js";
|
|
8
|
+
import { MobileTabBar as P } from "./components/layout/MobileTabBar.js";
|
|
9
|
+
import { Panel as M, PanelContent as h, PanelHeader as A } from "./components/layout/Panel.js";
|
|
10
|
+
import { ResizeHandle as D } from "./components/layout/ResizeHandle.js";
|
|
11
|
+
import { Shell as u } from "./components/layout/Shell.js";
|
|
12
|
+
import { Sidebar as w, SidebarContent as z, SidebarItem as H, SidebarItemList as g, SidebarSection as k } from "./components/layout/Sidebar.js";
|
|
13
|
+
import { SidebarPane as L } from "./components/layout/SidebarPane.js";
|
|
14
|
+
import { TopBar as V } from "./components/layout/TopBar.js";
|
|
15
|
+
import { TopBarIconButton as q } from "./components/layout/TopBarIconButton.js";
|
|
15
16
|
export {
|
|
16
17
|
r as ActivityBar,
|
|
17
|
-
a as
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
d as
|
|
22
|
-
|
|
23
|
-
c as
|
|
24
|
-
P as
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
a as AppViewport,
|
|
19
|
+
i as BottomBar,
|
|
20
|
+
x as BottomBarCompanion,
|
|
21
|
+
m as BottomBarItem,
|
|
22
|
+
d as DisplayModePageShell,
|
|
23
|
+
B as DisplayModeSwitcher,
|
|
24
|
+
c as KeepAliveStack,
|
|
25
|
+
P as MobileTabBar,
|
|
26
|
+
M as Panel,
|
|
27
|
+
h as PanelContent,
|
|
28
|
+
A as PanelHeader,
|
|
29
|
+
D as ResizeHandle,
|
|
30
|
+
u as Shell,
|
|
31
|
+
w as Sidebar,
|
|
30
32
|
z as SidebarContent,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
H as SidebarItem,
|
|
34
|
+
g as SidebarItemList,
|
|
35
|
+
L as SidebarPane,
|
|
36
|
+
k as SidebarSection,
|
|
37
|
+
n as StatusIndicator,
|
|
38
|
+
V as TopBar,
|
|
39
|
+
q as TopBarIconButton,
|
|
40
|
+
b as sanitizeDisplayMode
|
|
39
41
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* A real input anchors the operating system's IME without covering the surface. */
|
|
2
|
+
.floe-remote-input {
|
|
3
|
+
position: fixed;
|
|
4
|
+
z-index: 10;
|
|
5
|
+
width: 1px;
|
|
6
|
+
height: 1px;
|
|
7
|
+
padding: 0;
|
|
8
|
+
margin: 0;
|
|
9
|
+
border: 0;
|
|
10
|
+
opacity: 0;
|
|
11
|
+
pointer-events: none;
|
|
12
|
+
resize: none;
|
|
13
|
+
overflow: hidden;
|
|
14
|
+
font: 16px/1.5 sans-serif;
|
|
15
|
+
}
|
|
16
|
+
.floe-remote-input[data-composing] {
|
|
17
|
+
width: 20rem;
|
|
18
|
+
height: 1.5em;
|
|
19
|
+
opacity: 1;
|
|
20
|
+
color: var(--foreground, CanvasText);
|
|
21
|
+
background: var(--background, Canvas);
|
|
22
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Client-owned editing for a remote surface. No document contents are mirrored. */
|
|
2
|
+
export interface RemoteInputKey {
|
|
3
|
+
key: string;
|
|
4
|
+
code: string;
|
|
5
|
+
pressed: boolean;
|
|
6
|
+
repeat: boolean;
|
|
7
|
+
shiftKey: boolean;
|
|
8
|
+
ctrlKey: boolean;
|
|
9
|
+
altKey: boolean;
|
|
10
|
+
metaKey: boolean;
|
|
11
|
+
location: number;
|
|
12
|
+
}
|
|
13
|
+
export interface RemoteInputOptions<T> {
|
|
14
|
+
surface: HTMLElement;
|
|
15
|
+
label: string;
|
|
16
|
+
commitText(text: string, target: T): void;
|
|
17
|
+
sendKey(key: RemoteInputKey, target: T): void;
|
|
18
|
+
release(target: T): void;
|
|
19
|
+
/** Existing clipboard transport may own a shortcut; never submit it twice. */
|
|
20
|
+
clipboard?: (event: KeyboardEvent, target: T) => boolean;
|
|
21
|
+
onKeyboardVisibilityChange?: (visible: boolean) => void;
|
|
22
|
+
}
|
|
23
|
+
export interface RemoteInputController<T> {
|
|
24
|
+
readonly element: HTMLTextAreaElement;
|
|
25
|
+
bindTarget(target: T | null): void;
|
|
26
|
+
setAnchor(clientX: number, clientY: number): void;
|
|
27
|
+
focus(): void;
|
|
28
|
+
setKeyboardVisible(visible: boolean): void;
|
|
29
|
+
release(): void;
|
|
30
|
+
reset(): void;
|
|
31
|
+
dispose(): void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The caller gives this controller exclusive keyboard/editing ownership of its
|
|
35
|
+
* surface. Pointer transport and clipboard synchronization remain caller-owned.
|
|
36
|
+
* Targets are immutable identity tokens; bind a new token when ownership changes.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createRemoteInput<T>(options: RemoteInputOptions<T>): RemoteInputController<T>;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
function I(a) {
|
|
2
|
+
const { surface: M } = a, k = M.ownerDocument, c = k.defaultView;
|
|
3
|
+
if (!c) throw new Error("Remote input requires an attached document");
|
|
4
|
+
const t = k.createElement("textarea");
|
|
5
|
+
t.className = "floe-remote-input", t.setAttribute("aria-label", a.label), t.setAttribute("autocorrect", "off"), t.autocomplete = "off", t.autocapitalize = "off", t.spellcheck = !1, t.wrap = "off", t.disabled = !0, t.tabIndex = -1, k.body.append(t);
|
|
6
|
+
let l = null, y = 0, u = !1, V = !1, o = null, p = !1, s = null;
|
|
7
|
+
const h = /* @__PURE__ */ new Set(), w = /* @__PURE__ */ new Set();
|
|
8
|
+
let C = null;
|
|
9
|
+
const E = [];
|
|
10
|
+
function n(e, i, r) {
|
|
11
|
+
const g = r;
|
|
12
|
+
e.addEventListener(i, g), E.push(() => e.removeEventListener(i, g));
|
|
13
|
+
}
|
|
14
|
+
const b = (e) => e.code || e.key, x = (e, i) => ({
|
|
15
|
+
key: e.key,
|
|
16
|
+
code: e.code,
|
|
17
|
+
pressed: i,
|
|
18
|
+
repeat: e.repeat,
|
|
19
|
+
location: e.location,
|
|
20
|
+
shiftKey: e.shiftKey,
|
|
21
|
+
ctrlKey: e.ctrlKey,
|
|
22
|
+
altKey: e.altKey,
|
|
23
|
+
metaKey: e.metaKey
|
|
24
|
+
});
|
|
25
|
+
function K(e) {
|
|
26
|
+
V !== e && (V = e, a.onKeyboardVisibilityChange?.(e));
|
|
27
|
+
}
|
|
28
|
+
function f() {
|
|
29
|
+
const e = M.getBoundingClientRect(), i = c.visualViewport, r = Math.max(e.left, i?.offsetLeft ?? 0), g = Math.max(e.top, i?.offsetTop ?? 0), D = Math.min(e.right, (i?.offsetLeft ?? 0) + (i?.width ?? c.innerWidth)), F = Math.min(e.bottom, (i?.offsetTop ?? 0) + (i?.height ?? c.innerHeight)), L = Math.max(1, Math.min(320, D - r - 8));
|
|
30
|
+
t.style.maxWidth = `${L}px`;
|
|
31
|
+
const S = t.getBoundingClientRect(), P = C?.x ?? r + 12, R = C?.y ?? g + 12;
|
|
32
|
+
t.style.left = `${Math.max(r, Math.min(P, D - S.width - 4))}px`, t.style.top = `${Math.max(g, Math.min(R, F - S.height - 4))}px`;
|
|
33
|
+
}
|
|
34
|
+
function d() {
|
|
35
|
+
t.value = "", delete t.dataset.composing, s = null;
|
|
36
|
+
}
|
|
37
|
+
function B() {
|
|
38
|
+
const e = l, i = h.size > 0;
|
|
39
|
+
h.clear(), e !== null && i && a.release(e);
|
|
40
|
+
}
|
|
41
|
+
function m() {
|
|
42
|
+
y++, o && (o.cancelled = !0), p = !0, d(), B(), o && k.activeElement === t && t.blur();
|
|
43
|
+
}
|
|
44
|
+
function T(e) {
|
|
45
|
+
!e || l === null || u || a.commitText(e, l);
|
|
46
|
+
}
|
|
47
|
+
function z(e) {
|
|
48
|
+
if (l === null) return;
|
|
49
|
+
const i = { key: e, code: e, pressed: !0, repeat: !1, shiftKey: !1, ctrlKey: !1, altKey: !1, metaKey: !1, location: 0 }, r = l;
|
|
50
|
+
a.sendKey(i, r), l === r && a.sendKey({ ...i, pressed: !1 }, r);
|
|
51
|
+
}
|
|
52
|
+
function A(e) {
|
|
53
|
+
if (l === null || u) {
|
|
54
|
+
d();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (o?.cancelled || o && o.epoch !== y) {
|
|
58
|
+
d();
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (e.isComposing) {
|
|
62
|
+
o ??= { epoch: y, committed: !1, cancelled: !1 }, t.dataset.composing = "true", f();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (o) {
|
|
66
|
+
!o.committed && t.value && (o.committed = !0, T(t.value)), d();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (p || e.inputType === "insertFromComposition") {
|
|
70
|
+
p = !1, d();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const i = t.value;
|
|
74
|
+
if (s && i === s.key && !s.altKey && i.length === 1) {
|
|
75
|
+
const r = s;
|
|
76
|
+
h.add(r.code || r.key), a.sendKey(r, l);
|
|
77
|
+
} else T(i);
|
|
78
|
+
d();
|
|
79
|
+
}
|
|
80
|
+
return n(t, "keydown", (e) => {
|
|
81
|
+
if (!(l === null || u)) {
|
|
82
|
+
if (e.stopPropagation(), o?.cancelled && !e.isComposing && e.key !== "Process" && e.keyCode !== 229 && (o = null), e.isComposing || o || e.key === "Process" || e.keyCode === 229) {
|
|
83
|
+
w.add(b(e)), s = null;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (w.delete(b(e)), p = !1, a.clipboard?.(e, l)) {
|
|
87
|
+
s = null;
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (e.key === "Dead" || e.key === "Unidentified") {
|
|
91
|
+
s = null;
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (Array.from(e.key).length === 1 && !e.metaKey && (!e.ctrlKey || e.getModifierState("AltGraph"))) {
|
|
95
|
+
s = x(e, !0);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
e.preventDefault(), h.add(b(e)), a.sendKey(x(e, !0), l);
|
|
99
|
+
}
|
|
100
|
+
}), n(t, "keyup", (e) => {
|
|
101
|
+
e.stopPropagation(), s = null, !w.delete(b(e)) && l !== null && h.delete(b(e)) && a.sendKey(x(e, !1), l);
|
|
102
|
+
}), n(t, "beforeinput", (e) => {
|
|
103
|
+
if (l === null || u) {
|
|
104
|
+
e.preventDefault();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (e.isComposing || o || e.inputType === "insertCompositionText" || e.inputType === "deleteCompositionText" || e.inputType === "insertFromComposition") return;
|
|
108
|
+
p = !1;
|
|
109
|
+
const r = { deleteContentBackward: "Backspace", deleteContentForward: "Delete", insertLineBreak: "Enter", insertParagraph: "Enter" }[e.inputType];
|
|
110
|
+
r && (e.preventDefault(), d(), z(r));
|
|
111
|
+
}), n(t, "input", A), n(t, "compositionstart", () => {
|
|
112
|
+
o = { epoch: y, committed: !1, cancelled: l === null }, p = !1, s = null, t.dataset.composing = "true", f();
|
|
113
|
+
}), n(t, "compositionend", (e) => {
|
|
114
|
+
const i = o;
|
|
115
|
+
o = null, p = !0, d(), i && !i.cancelled && !i.committed && i.epoch === y && T(e.data);
|
|
116
|
+
}), n(t, "blur", () => {
|
|
117
|
+
m(), K(!1);
|
|
118
|
+
}), n(c, "blur", m), n(c, "pagehide", m), n(c, "resize", f), c.visualViewport && (n(c.visualViewport, "resize", f), n(c.visualViewport, "scroll", f)), f(), {
|
|
119
|
+
element: t,
|
|
120
|
+
bindTarget(e) {
|
|
121
|
+
u || Object.is(l, e) || (m(), l = e, t.disabled = e === null);
|
|
122
|
+
},
|
|
123
|
+
setAnchor(e, i) {
|
|
124
|
+
!Number.isFinite(e) || !Number.isFinite(i) || (C = { x: e, y: i }, f());
|
|
125
|
+
},
|
|
126
|
+
focus() {
|
|
127
|
+
l === null || u || (t.focus({ preventScroll: !0 }), f());
|
|
128
|
+
},
|
|
129
|
+
setKeyboardVisible(e) {
|
|
130
|
+
e && l !== null && !u ? (t.focus({ preventScroll: !0 }), K(!0), f()) : (t.blur(), K(!1));
|
|
131
|
+
},
|
|
132
|
+
release: B,
|
|
133
|
+
reset: m,
|
|
134
|
+
dispose() {
|
|
135
|
+
if (!u) {
|
|
136
|
+
m(), u = !0, l = null;
|
|
137
|
+
for (const e of E) e();
|
|
138
|
+
t.remove(), K(!1);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
export {
|
|
144
|
+
I as createRemoteInput
|
|
145
|
+
};
|