@floegence/floe-webapp-core 0.86.18 → 0.86.20
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/graph/GraphCanvas.d.ts +2 -3
- package/dist/components/graph/GraphCanvas.js +15 -12
- package/dist/components/graph/GraphMinimap.d.ts +8 -1
- package/dist/components/graph/GraphMinimap.js +110 -59
- package/dist/graph.css +12 -4
- package/dist/remote-input.d.ts +2 -2
- package/dist/remote-input.js +112 -94
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type JSX } from 'solid-js';
|
|
2
|
+
import { type GraphMinimapProps } from './GraphMinimap';
|
|
2
3
|
import type { GraphLayout, GraphLayoutNode, GraphObjectEvent, GraphObjectRef, GraphViewport } from './types';
|
|
3
4
|
export interface GraphNodeRenderContext {
|
|
4
5
|
selected: () => boolean;
|
|
@@ -22,9 +23,7 @@ export interface GraphCanvasProps {
|
|
|
22
23
|
/** Overlay content should use shared SurfaceFloatingLayer for point placement. */
|
|
23
24
|
overlay?: JSX.Element;
|
|
24
25
|
/** Optional interactive overview. Its geometry follows the same visible layout. */
|
|
25
|
-
minimap?:
|
|
26
|
-
ariaLabel: string;
|
|
27
|
-
};
|
|
26
|
+
minimap?: Pick<GraphMinimapProps, 'ariaLabel' | 'nodeStyle'>;
|
|
28
27
|
class?: string;
|
|
29
28
|
}
|
|
30
29
|
/** Controlled graph surface. Hosts own documents and selection; Floe owns geometry and input. */
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { insert as w, createComponent as x, setAttribute as l, effect as
|
|
1
|
+
import { insert as w, createComponent as x, setAttribute as l, effect as L, className as K, template as I, memo as ae, setStyleProperty as T, use as ie, delegateEvents as oe } from "solid-js/web";
|
|
2
2
|
import { createUniqueId as le, createSignal as O, createMemo as y, onMount as ce, For as j, Show as D, onCleanup as de } from "solid-js";
|
|
3
3
|
import { InfiniteCanvas as ue } from "../ui/InfiniteCanvas.js";
|
|
4
4
|
import { resolveSurfaceInteractionTargetRole as se } from "../ui/localInteractionSurface.js";
|
|
5
5
|
import { graphRelatedEdges as U, graphEdgeLabelPosition as he, graphSectionPath as ge } from "./geometry.js";
|
|
6
6
|
import { GraphMinimap as fe } from "./GraphMinimap.js";
|
|
7
7
|
var ve = /* @__PURE__ */ I("<div data-floe-canvas-pan-surface=true role=group tabindex=0>"), me = /* @__PURE__ */ I("<div role=region tabindex=0>"), be = /* @__PURE__ */ I('<svg class=floe-graph__edges width=1 height=1><defs><marker viewBox="0 0 8 8"refX=7 refY=4 markerWidth=7 markerHeight=7 orient=auto-start-reverse><path d="M1 1 L7 4 L1 7"fill=none stroke=context-stroke stroke-width=1.2>'), xe = /* @__PURE__ */ I("<svg><g><path class=floe-graph__edge></path><path class=floe-graph__edge-target tabindex=0 role=button data-floe-canvas-pan-surface=true></svg>", !1, !0, !1), ye = /* @__PURE__ */ I("<svg><text class=floe-graph__edge-label aria-hidden=true></svg>", !1, !0, !1);
|
|
8
|
-
function
|
|
8
|
+
function Ee(i) {
|
|
9
9
|
const H = `graph-arrow-${le()}`;
|
|
10
10
|
let g;
|
|
11
11
|
const [J, Q] = O(null), [V, Z] = O({
|
|
@@ -103,7 +103,7 @@ function Le(i) {
|
|
|
103
103
|
}, r.$$focusout = () => f(null), r.$$focusin = () => f(t), r.addEventListener("pointerleave", () => f(null)), r.addEventListener("pointerenter", () => f(t)), w(r, (() => {
|
|
104
104
|
var a = ae(() => !!(e.kind === "group" && i.renderGroup));
|
|
105
105
|
return () => a() ? i.renderGroup(e, n) : i.renderNode(e, n);
|
|
106
|
-
})()),
|
|
106
|
+
})()), L((a) => {
|
|
107
107
|
var m = e.kind === "group" ? "floe-graph__group" : "floe-graph__node", c = e.id, d = A(t), _ = `${e.x}px`, P = `${e.y}px`, $ = `${e.width}px`, u = `${e.height}px`, v = e.label;
|
|
108
108
|
return m !== a.e && K(r, a.e = m), c !== a.t && l(r, "data-graph-object", a.t = c), d !== a.a && l(r, "data-selected", a.a = d), _ !== a.o && T(r, "left", a.o = _), P !== a.i && T(r, "top", a.i = P), $ !== a.n && T(r, "width", a.n = $), u !== a.s && T(r, "height", a.s = u), v !== a.h && l(r, "aria-label", a.h = v), a;
|
|
109
109
|
}, {
|
|
@@ -179,9 +179,9 @@ function Le(i) {
|
|
|
179
179
|
},
|
|
180
180
|
children: (o) => (() => {
|
|
181
181
|
var b = ye();
|
|
182
|
-
return w(b, () => u.label),
|
|
183
|
-
var M = /^\d+$/.test(u.label),
|
|
184
|
-
return M !== h.e && l(b, "data-count", h.e = M),
|
|
182
|
+
return w(b, () => u.label), L((h) => {
|
|
183
|
+
var M = /^\d+$/.test(u.label), S = o().x, E = o().y - 6;
|
|
184
|
+
return M !== h.e && l(b, "data-count", h.e = M), S !== h.t && l(b, "x", h.t = S), E !== h.a && l(b, "y", h.a = E), h;
|
|
185
185
|
}, {
|
|
186
186
|
e: void 0,
|
|
187
187
|
t: void 0,
|
|
@@ -190,9 +190,9 @@ function Le(i) {
|
|
|
190
190
|
})()
|
|
191
191
|
}), s), s.$$keydown = (o) => G(v, o), s.$$contextmenu = (o) => z(v, o), s.$$click = (o) => {
|
|
192
192
|
o.stopPropagation(), i.onActivate?.(k(v, o.currentTarget, o));
|
|
193
|
-
}, s.addEventListener("blur", () => f(null)), s.addEventListener("focus", () => f(v)), s.addEventListener("pointerleave", () => f(null)), s.addEventListener("pointerenter", () => f(v)),
|
|
194
|
-
var b = u.id, h = ee().has(u.id), M = A(v),
|
|
195
|
-
return b !== o.e && l(C, "data-graph-object", o.e = b), h !== o.t && l(C, "data-emphasized", o.t = h), M !== o.a && l(C, "data-selected", o.a = M),
|
|
193
|
+
}, s.addEventListener("blur", () => f(null)), s.addEventListener("focus", () => f(v)), s.addEventListener("pointerleave", () => f(null)), s.addEventListener("pointerenter", () => f(v)), L((o) => {
|
|
194
|
+
var b = u.id, h = ee().has(u.id), M = A(v), S = W(), E = W(), q = u.label;
|
|
195
|
+
return b !== o.e && l(C, "data-graph-object", o.e = b), h !== o.t && l(C, "data-emphasized", o.t = h), M !== o.a && l(C, "data-selected", o.a = M), S !== o.o && l(R, "d", o.o = S), E !== o.i && l(s, "d", o.i = E), q !== o.n && l(s, "aria-label", o.n = q), o;
|
|
196
196
|
}, {
|
|
197
197
|
e: void 0,
|
|
198
198
|
t: void 0,
|
|
@@ -204,7 +204,7 @@ function Le(i) {
|
|
|
204
204
|
}
|
|
205
205
|
});
|
|
206
206
|
}
|
|
207
|
-
}), null),
|
|
207
|
+
}), null), L(() => l(d, "aria-label", i.ariaLabel)), d;
|
|
208
208
|
})(), x(j, {
|
|
209
209
|
get each() {
|
|
210
210
|
return m();
|
|
@@ -234,9 +234,12 @@ function Le(i) {
|
|
|
234
234
|
},
|
|
235
235
|
get ariaLabel() {
|
|
236
236
|
return n().ariaLabel;
|
|
237
|
+
},
|
|
238
|
+
get nodeStyle() {
|
|
239
|
+
return n().nodeStyle;
|
|
237
240
|
}
|
|
238
241
|
})
|
|
239
|
-
}), null), w(e, () => i.overlay, null),
|
|
242
|
+
}), null), w(e, () => i.overlay, null), L((n) => {
|
|
240
243
|
var r = `floe-graph ${i.class ?? ""}`, a = i.ariaLabel;
|
|
241
244
|
return r !== n.e && K(e, n.e = r), a !== n.t && l(e, "aria-label", n.t = a), n;
|
|
242
245
|
}, {
|
|
@@ -247,5 +250,5 @@ function Le(i) {
|
|
|
247
250
|
}
|
|
248
251
|
oe(["focusin", "focusout", "click", "contextmenu", "keydown"]);
|
|
249
252
|
export {
|
|
250
|
-
|
|
253
|
+
Ee as GraphCanvas
|
|
251
254
|
};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type { GraphLayout, GraphViewport } from './types';
|
|
1
|
+
import type { GraphLayout, GraphLayoutNode, GraphViewport } from './types';
|
|
2
|
+
export interface GraphMinimapNodeStyle {
|
|
3
|
+
/** CSS colors, including theme variables. Omitted colors retain the defaults. */
|
|
4
|
+
fill?: string;
|
|
5
|
+
stroke?: string;
|
|
6
|
+
}
|
|
2
7
|
export interface GraphMinimapProps {
|
|
3
8
|
layout: GraphLayout;
|
|
4
9
|
viewport: GraphViewport;
|
|
@@ -9,6 +14,8 @@ export interface GraphMinimapProps {
|
|
|
9
14
|
onViewportChange: (viewport: GraphViewport) => void;
|
|
10
15
|
onInteractionStart?: () => void;
|
|
11
16
|
ariaLabel: string;
|
|
17
|
+
/** Host appearance over the exact layout. Equal styles share one SVG path. */
|
|
18
|
+
nodeStyle?: (node: GraphLayoutNode) => GraphMinimapNodeStyle | undefined;
|
|
12
19
|
}
|
|
13
20
|
/** A lightweight navigator over the exact main-canvas geometry. No second layout. */
|
|
14
21
|
export declare function GraphMinimap(props: GraphMinimapProps): import("solid-js").JSX.Element;
|
|
@@ -1,74 +1,127 @@
|
|
|
1
|
-
import { effect as
|
|
2
|
-
import { createMemo as w } from "solid-js";
|
|
3
|
-
import { graphSectionPath as
|
|
4
|
-
var
|
|
5
|
-
function R(
|
|
6
|
-
let
|
|
7
|
-
const
|
|
1
|
+
import { insert as k, createComponent as _, effect as g, setAttribute as h, style as C, template as f, use as S, delegateEvents as z } from "solid-js/web";
|
|
2
|
+
import { createMemo as w, For as I } from "solid-js";
|
|
3
|
+
import { graphSectionPath as A, fitGraphViewport as D } from "./geometry.js";
|
|
4
|
+
var L = /* @__PURE__ */ f('<svg class=floe-graph__minimap role=region tabindex=0 preserveAspectRatio="xMidYMid meet"data-floe-canvas-interactive=true><path class=floe-graph__minimap-edges></path><rect class=floe-graph__minimap-viewport>'), V = /* @__PURE__ */ f("<svg><path class=floe-graph__minimap-groups></svg>", !1, !0, !1), E = /* @__PURE__ */ f("<svg><path class=floe-graph__minimap-nodes></svg>", !1, !0, !1);
|
|
5
|
+
function R(i) {
|
|
6
|
+
let v, s;
|
|
7
|
+
const u = w(() => {
|
|
8
8
|
const {
|
|
9
|
-
x:
|
|
10
|
-
y:
|
|
11
|
-
width:
|
|
12
|
-
height:
|
|
13
|
-
} =
|
|
9
|
+
x: e,
|
|
10
|
+
y: l,
|
|
11
|
+
width: d,
|
|
12
|
+
height: n
|
|
13
|
+
} = i.layout.bounds, t = Math.max(d, n, 1) * 0.04;
|
|
14
14
|
return {
|
|
15
|
-
x:
|
|
16
|
-
y:
|
|
17
|
-
width:
|
|
18
|
-
height:
|
|
15
|
+
x: e - t,
|
|
16
|
+
y: l - t,
|
|
17
|
+
width: d + t * 2,
|
|
18
|
+
height: n + t * 2
|
|
19
19
|
};
|
|
20
|
-
}),
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
}), m = w(() => {
|
|
21
|
+
const e = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map();
|
|
22
|
+
for (const n of i.layout.nodes) {
|
|
23
|
+
const t = i.nodeStyle?.(n) ?? {}, o = n.kind === "group" ? e : l, r = JSON.stringify([t.fill ?? null, t.stroke ?? null]);
|
|
24
|
+
let a = o.get(r);
|
|
25
|
+
a || (a = {
|
|
26
|
+
...t,
|
|
27
|
+
paths: []
|
|
28
|
+
}, o.set(r, a)), a.paths.push(`M${n.x},${n.y}h${n.width}v${n.height}h${-n.width}Z`);
|
|
29
|
+
}
|
|
30
|
+
const d = (n) => [...n.values()].map(({
|
|
31
|
+
paths: t,
|
|
32
|
+
...o
|
|
33
|
+
}) => ({
|
|
34
|
+
...o,
|
|
35
|
+
path: t.join("")
|
|
36
|
+
}));
|
|
37
|
+
return {
|
|
38
|
+
groups: d(e),
|
|
39
|
+
nodes: d(l)
|
|
40
|
+
};
|
|
41
|
+
}), p = (e) => ({
|
|
42
|
+
"--graph-minimap-fill": e.fill,
|
|
43
|
+
"--graph-minimap-stroke": e.stroke,
|
|
44
|
+
"--graph-minimap-opacity": e.fill || e.stroke ? "1" : void 0
|
|
45
|
+
}), P = w(() => i.layout.edges.flatMap((e) => e.sections.map(A)).join(" ")), y = (e) => {
|
|
46
|
+
const l = v?.getScreenCTM();
|
|
47
|
+
return l ? new DOMPoint(e.clientX, e.clientY).matrixTransform(l.inverse()) : void 0;
|
|
48
|
+
}, x = (e) => {
|
|
49
|
+
s?.id === e.pointerId && (s = void 0, v?.hasPointerCapture(e.pointerId) && v.releasePointerCapture(e.pointerId));
|
|
25
50
|
};
|
|
26
51
|
return (() => {
|
|
27
|
-
var
|
|
28
|
-
|
|
29
|
-
const
|
|
52
|
+
var e = L(), l = e.firstChild, d = l.nextSibling;
|
|
53
|
+
e.$$keydown = (t) => {
|
|
54
|
+
const r = {
|
|
30
55
|
ArrowLeft: [1, 0],
|
|
31
56
|
ArrowRight: [-1, 0],
|
|
32
57
|
ArrowUp: [0, 1],
|
|
33
58
|
ArrowDown: [0, -1]
|
|
34
59
|
}[t.key];
|
|
35
|
-
!
|
|
36
|
-
...
|
|
37
|
-
x:
|
|
38
|
-
y:
|
|
39
|
-
} :
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
}),
|
|
43
|
-
if (
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
...
|
|
47
|
-
x:
|
|
48
|
-
y:
|
|
60
|
+
!r && t.key !== "Home" || (t.preventDefault(), t.stopPropagation(), i.onInteractionStart?.(), i.onViewportChange(r ? {
|
|
61
|
+
...i.viewport,
|
|
62
|
+
x: i.viewport.x + r[0] * i.size.width * 0.2,
|
|
63
|
+
y: i.viewport.y + r[1] * i.size.height * 0.2
|
|
64
|
+
} : D(i.layout.bounds, i.size, 24)));
|
|
65
|
+
}, e.addEventListener("lostpointercapture", () => {
|
|
66
|
+
s = void 0;
|
|
67
|
+
}), e.addEventListener("pointercancel", x), e.$$pointerup = x, e.$$pointermove = (t) => {
|
|
68
|
+
if (s?.id !== t.pointerId) return;
|
|
69
|
+
const o = y(t);
|
|
70
|
+
o && i.onViewportChange({
|
|
71
|
+
...s.viewport,
|
|
72
|
+
x: s.viewport.x - (o.x - s.x) * s.viewport.scale,
|
|
73
|
+
y: s.viewport.y - (o.y - s.y) * s.viewport.scale
|
|
49
74
|
});
|
|
50
|
-
},
|
|
75
|
+
}, e.$$pointerdown = (t) => {
|
|
51
76
|
if (t.button !== 0) return;
|
|
52
|
-
const
|
|
53
|
-
|
|
77
|
+
const o = y(t);
|
|
78
|
+
o && (t.preventDefault(), t.stopPropagation(), i.onInteractionStart?.(), v.focus({
|
|
54
79
|
preventScroll: !0
|
|
55
|
-
}), t.target.matches(".floe-graph__minimap-viewport") ||
|
|
56
|
-
...
|
|
57
|
-
x:
|
|
58
|
-
y:
|
|
59
|
-
}),
|
|
80
|
+
}), t.target.matches(".floe-graph__minimap-viewport") || i.onViewportChange({
|
|
81
|
+
...i.viewport,
|
|
82
|
+
x: i.size.width / 2 - o.x * i.viewport.scale,
|
|
83
|
+
y: i.size.height / 2 - o.y * i.viewport.scale
|
|
84
|
+
}), s = {
|
|
60
85
|
id: t.pointerId,
|
|
61
|
-
x:
|
|
62
|
-
y:
|
|
86
|
+
x: o.x,
|
|
87
|
+
y: o.y,
|
|
63
88
|
viewport: {
|
|
64
|
-
...
|
|
89
|
+
...i.viewport
|
|
65
90
|
}
|
|
66
|
-
},
|
|
91
|
+
}, v.setPointerCapture(t.pointerId));
|
|
67
92
|
};
|
|
68
|
-
var
|
|
69
|
-
return typeof
|
|
70
|
-
|
|
71
|
-
|
|
93
|
+
var n = v;
|
|
94
|
+
return typeof n == "function" ? S(n, e) : v = e, k(e, _(I, {
|
|
95
|
+
get each() {
|
|
96
|
+
return m().groups;
|
|
97
|
+
},
|
|
98
|
+
children: (t) => (() => {
|
|
99
|
+
var o = V();
|
|
100
|
+
return g((r) => {
|
|
101
|
+
var a = t.path, c = p(t);
|
|
102
|
+
return a !== r.e && h(o, "d", r.e = a), r.t = C(o, c, r.t), r;
|
|
103
|
+
}, {
|
|
104
|
+
e: void 0,
|
|
105
|
+
t: void 0
|
|
106
|
+
}), o;
|
|
107
|
+
})()
|
|
108
|
+
}), l), k(e, _(I, {
|
|
109
|
+
get each() {
|
|
110
|
+
return m().nodes;
|
|
111
|
+
},
|
|
112
|
+
children: (t) => (() => {
|
|
113
|
+
var o = E();
|
|
114
|
+
return g((r) => {
|
|
115
|
+
var a = t.path, c = p(t);
|
|
116
|
+
return a !== r.e && h(o, "d", r.e = a), r.t = C(o, c, r.t), r;
|
|
117
|
+
}, {
|
|
118
|
+
e: void 0,
|
|
119
|
+
t: void 0
|
|
120
|
+
}), o;
|
|
121
|
+
})()
|
|
122
|
+
}), d), g((t) => {
|
|
123
|
+
var o = i.ariaLabel, r = `${u().x} ${u().y} ${u().width} ${u().height}`, a = P(), c = -i.viewport.x / i.viewport.scale, $ = -i.viewport.y / i.viewport.scale, b = i.size.width / i.viewport.scale, M = i.size.height / i.viewport.scale;
|
|
124
|
+
return o !== t.e && h(e, "aria-label", t.e = o), r !== t.t && h(e, "viewBox", t.t = r), a !== t.a && h(l, "d", t.a = a), c !== t.o && h(d, "x", t.o = c), $ !== t.i && h(d, "y", t.i = $), b !== t.n && h(d, "width", t.n = b), M !== t.s && h(d, "height", t.s = M), t;
|
|
72
125
|
}, {
|
|
73
126
|
e: void 0,
|
|
74
127
|
t: void 0,
|
|
@@ -76,13 +129,11 @@ function R(e) {
|
|
|
76
129
|
o: void 0,
|
|
77
130
|
i: void 0,
|
|
78
131
|
n: void 0,
|
|
79
|
-
s: void 0
|
|
80
|
-
|
|
81
|
-
r: void 0
|
|
82
|
-
}), i;
|
|
132
|
+
s: void 0
|
|
133
|
+
}), e;
|
|
83
134
|
})();
|
|
84
135
|
}
|
|
85
|
-
|
|
136
|
+
z(["pointerdown", "pointermove", "pointerup", "keydown"]);
|
|
86
137
|
export {
|
|
87
138
|
R as GraphMinimap
|
|
88
139
|
};
|
package/dist/graph.css
CHANGED
|
@@ -90,13 +90,16 @@
|
|
|
90
90
|
outline-offset: 2px;
|
|
91
91
|
}
|
|
92
92
|
.floe-graph__minimap-nodes {
|
|
93
|
-
fill: var(--muted-foreground);
|
|
94
|
-
|
|
93
|
+
fill: var(--graph-minimap-fill, var(--muted-foreground));
|
|
94
|
+
stroke: var(--graph-minimap-stroke, none);
|
|
95
|
+
stroke-width: 0.7px;
|
|
96
|
+
vector-effect: non-scaling-stroke;
|
|
97
|
+
opacity: var(--graph-minimap-opacity, 0.65);
|
|
95
98
|
pointer-events: none;
|
|
96
99
|
}
|
|
97
100
|
.floe-graph__minimap-groups {
|
|
98
|
-
fill: color-mix(in srgb, var(--primary) 10%, transparent);
|
|
99
|
-
stroke: var(--muted-foreground);
|
|
101
|
+
fill: var(--graph-minimap-fill, color-mix(in srgb, var(--primary) 10%, transparent));
|
|
102
|
+
stroke: var(--graph-minimap-stroke, var(--muted-foreground));
|
|
100
103
|
stroke-width: 0.7px;
|
|
101
104
|
vector-effect: non-scaling-stroke;
|
|
102
105
|
pointer-events: none;
|
|
@@ -147,6 +150,11 @@
|
|
|
147
150
|
}
|
|
148
151
|
.floe-graph__minimap-nodes {
|
|
149
152
|
fill: CanvasText;
|
|
153
|
+
stroke: CanvasText;
|
|
154
|
+
opacity: 1;
|
|
155
|
+
}
|
|
156
|
+
.floe-graph__minimap-groups {
|
|
157
|
+
fill: Canvas;
|
|
150
158
|
}
|
|
151
159
|
.floe-graph__minimap-groups,
|
|
152
160
|
.floe-graph__minimap-edges {
|
package/dist/remote-input.d.ts
CHANGED
|
@@ -23,8 +23,8 @@ export interface RemoteInputOptions<T> {
|
|
|
23
23
|
export interface RemoteInputController<T> {
|
|
24
24
|
readonly element: HTMLTextAreaElement;
|
|
25
25
|
bindTarget(target: T | null): void;
|
|
26
|
-
/** Physical
|
|
27
|
-
setTextInputMode(mode: 'physical' | 'text'): void;
|
|
26
|
+
/** Physical-only bypasses the local editor and input method entirely. */
|
|
27
|
+
setTextInputMode(mode: 'physical' | 'text' | 'physical-only'): void;
|
|
28
28
|
setAnchor(clientX: number, clientY: number): void;
|
|
29
29
|
focus(): void;
|
|
30
30
|
setKeyboardVisible(visible: boolean): void;
|
package/dist/remote-input.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
function
|
|
2
|
-
const { surface:
|
|
3
|
-
if (!
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
let
|
|
7
|
-
const
|
|
1
|
+
function O(a) {
|
|
2
|
+
const { surface: c } = a, k = c.ownerDocument, u = k.defaultView;
|
|
3
|
+
if (!u) throw new Error("Remote input requires an attached document");
|
|
4
|
+
const l = k.createElement("textarea");
|
|
5
|
+
l.className = "floe-remote-input", l.setAttribute("aria-label", a.label), l.setAttribute("autocorrect", "off"), l.autocomplete = "off", l.autocapitalize = "off", l.spellcheck = !1, l.wrap = "off", l.disabled = !0, l.tabIndex = -1, k.body.append(l);
|
|
6
|
+
let i = null, M = 0, d = !1, V = !1, o = null, K = !1, f = null, r = "physical", D = !1;
|
|
7
|
+
const x = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Set(), T = /* @__PURE__ */ new Set(), S = /* @__PURE__ */ new Set();
|
|
8
8
|
let $ = null;
|
|
9
|
-
const
|
|
10
|
-
function s(e, t,
|
|
11
|
-
const
|
|
12
|
-
e.addEventListener(t,
|
|
9
|
+
const I = [];
|
|
10
|
+
function s(e, t, n) {
|
|
11
|
+
const m = n;
|
|
12
|
+
e.addEventListener(t, m), I.push(() => e.removeEventListener(t, m));
|
|
13
13
|
}
|
|
14
|
-
const
|
|
14
|
+
const w = (e) => e.code || e.key, C = (e, t) => ({
|
|
15
15
|
key: e.key,
|
|
16
16
|
code: e.code,
|
|
17
17
|
pressed: t,
|
|
@@ -22,147 +22,165 @@ function j(n) {
|
|
|
22
22
|
altKey: e.altKey,
|
|
23
23
|
metaKey: e.metaKey
|
|
24
24
|
});
|
|
25
|
-
function
|
|
26
|
-
|
|
25
|
+
function L(e) {
|
|
26
|
+
V !== e && (V = e, a.onKeyboardVisibilityChange?.(e));
|
|
27
27
|
}
|
|
28
|
-
function
|
|
29
|
-
const e =
|
|
30
|
-
|
|
31
|
-
const B =
|
|
32
|
-
|
|
28
|
+
function h() {
|
|
29
|
+
const e = c.getBoundingClientRect(), t = u.visualViewport, n = Math.max(e.left, t?.offsetLeft ?? 0), m = Math.max(e.top, t?.offsetTop ?? 0), g = Math.min(e.right, (t?.offsetLeft ?? 0) + (t?.width ?? u.innerWidth)), j = Math.min(e.bottom, (t?.offsetTop ?? 0) + (t?.height ?? u.innerHeight)), q = Math.max(1, Math.min(320, g - n - 8));
|
|
30
|
+
l.style.maxWidth = `${q}px`;
|
|
31
|
+
const B = l.getBoundingClientRect(), G = $?.x ?? n + 12, H = $?.y ?? m + 12;
|
|
32
|
+
l.style.left = `${Math.max(n, Math.min(G, g - B.width - 4))}px`, l.style.top = `${Math.max(m, Math.min(H, j - B.height - 4))}px`;
|
|
33
33
|
}
|
|
34
|
-
function
|
|
35
|
-
|
|
34
|
+
function p() {
|
|
35
|
+
l.value = "", delete l.dataset.composing, f = null;
|
|
36
36
|
}
|
|
37
|
-
function
|
|
38
|
-
const e =
|
|
39
|
-
|
|
37
|
+
function z() {
|
|
38
|
+
const e = i, t = y.size > 0;
|
|
39
|
+
y.clear(), x.clear(), T.clear(), e !== null && t && a.release(e);
|
|
40
40
|
}
|
|
41
|
-
function
|
|
42
|
-
|
|
41
|
+
function b() {
|
|
42
|
+
M++, o && (o.cancelled = !0), K = !0, p(), z(), o && k.activeElement === l && l.blur();
|
|
43
43
|
}
|
|
44
|
-
function
|
|
45
|
-
!e ||
|
|
44
|
+
function A(e) {
|
|
45
|
+
!e || i === null || d || r === "physical-only" || (r === "text" && y.size && (y.clear(), T.clear(), a.release(i)), a.commitText(e, i));
|
|
46
46
|
}
|
|
47
|
-
function
|
|
48
|
-
if (
|
|
47
|
+
function E(e) {
|
|
48
|
+
if (i !== null) {
|
|
49
49
|
if (!/^(Shift|Control|Alt|Meta)(Left|Right)$/.test(e.code))
|
|
50
|
-
for (const [t,
|
|
50
|
+
for (const [t, n] of [
|
|
51
51
|
["Shift", e.shiftKey],
|
|
52
52
|
["Control", e.ctrlKey],
|
|
53
53
|
["Alt", e.altKey],
|
|
54
54
|
["Meta", e.metaKey]
|
|
55
55
|
]) {
|
|
56
|
-
if (!
|
|
57
|
-
const
|
|
58
|
-
|
|
56
|
+
if (!n || [...y].some((g) => g === `${t}Left` || g === `${t}Right`)) continue;
|
|
57
|
+
const m = [...x.values()].find((g) => g.code === `${t}Left` || g.code === `${t}Right`) ?? { ...e, key: t, code: `${t}Left`, pressed: !0, repeat: !1, location: 1 };
|
|
58
|
+
y.add(m.code), x.has(m.code) || T.add(m.code), a.sendKey(m, i);
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
y.add(e.code || e.key), a.sendKey(e, i);
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
function D(e) {
|
|
64
|
-
if (l === null) return;
|
|
65
|
-
const t = { key: e, code: e, pressed: !0, repeat: !1, shiftKey: !1, ctrlKey: !1, altKey: !1, metaKey: !1, location: 0 }, r = l;
|
|
66
|
-
n.sendKey(t, r), l === r && n.sendKey({ ...t, pressed: !1 }, r);
|
|
67
|
-
}
|
|
68
63
|
function F(e) {
|
|
69
|
-
if (
|
|
70
|
-
|
|
64
|
+
if (i === null) return;
|
|
65
|
+
const t = { key: e, code: e, pressed: !0, repeat: !1, shiftKey: !1, ctrlKey: !1, altKey: !1, metaKey: !1, location: 0 }, n = i;
|
|
66
|
+
a.sendKey(t, n), i === n && a.sendKey({ ...t, pressed: !1 }, n);
|
|
67
|
+
}
|
|
68
|
+
function P(e) {
|
|
69
|
+
if (i === null || d || r === "physical-only") {
|
|
70
|
+
p();
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
|
-
if (o?.cancelled || o && o.epoch !==
|
|
74
|
-
|
|
73
|
+
if (o?.cancelled || o && o.epoch !== M) {
|
|
74
|
+
p();
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
77
|
if (e.isComposing) {
|
|
78
|
-
o ??= { epoch:
|
|
78
|
+
o ??= { epoch: M, committed: !1, cancelled: !1 }, l.dataset.composing = "true", h();
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
81
|
if (o) {
|
|
82
|
-
!o.committed &&
|
|
82
|
+
!o.committed && l.value && (o.committed = !0, A(l.value)), p();
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
|
-
if (
|
|
86
|
-
|
|
85
|
+
if (K || e.inputType === "insertFromComposition") {
|
|
86
|
+
K = !1, p();
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
|
-
const t =
|
|
90
|
-
|
|
89
|
+
const t = l.value;
|
|
90
|
+
r === "physical" && f && t === f.key && !f.altKey && t.length === 1 ? E(f) : A(t), p();
|
|
91
91
|
}
|
|
92
|
-
|
|
93
|
-
if (!(
|
|
94
|
-
if (e.stopPropagation(),
|
|
95
|
-
|
|
92
|
+
function N(e) {
|
|
93
|
+
if (!(i === null || d) && e.currentTarget === c == (r === "physical-only")) {
|
|
94
|
+
if (e.stopPropagation(), r === "physical-only") {
|
|
95
|
+
e.preventDefault(), S.delete(w(e)), e.code && !a.clipboard?.(e, i) && E(C(e, !0));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (o?.cancelled && !e.isComposing && e.key !== "Process" && e.keyCode !== 229 && (o = null), e.isComposing || o || e.key === "Process" || e.keyCode === 229) {
|
|
99
|
+
S.add(w(e)), f = null;
|
|
96
100
|
return;
|
|
97
101
|
}
|
|
98
|
-
if (
|
|
99
|
-
|
|
102
|
+
if (S.delete(w(e)), K = !1, a.clipboard?.(e, i)) {
|
|
103
|
+
f = null;
|
|
100
104
|
return;
|
|
101
105
|
}
|
|
102
|
-
if (
|
|
103
|
-
|
|
106
|
+
if (r === "text" && /^(Shift|Control|Alt|Meta)(Left|Right)$/.test(e.code)) {
|
|
107
|
+
x.set(w(e), C(e, !0));
|
|
104
108
|
return;
|
|
105
109
|
}
|
|
106
110
|
if (e.key === "Dead" || e.key === "Unidentified") {
|
|
107
|
-
|
|
111
|
+
f = null;
|
|
108
112
|
return;
|
|
109
113
|
}
|
|
110
114
|
if (Array.from(e.key).length === 1 && !e.metaKey && (!e.ctrlKey || e.getModifierState("AltGraph"))) {
|
|
111
|
-
|
|
115
|
+
f = C(e, !0);
|
|
112
116
|
return;
|
|
113
117
|
}
|
|
114
|
-
e.preventDefault(),
|
|
118
|
+
e.preventDefault(), E(C(e, !0));
|
|
115
119
|
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
}
|
|
121
|
+
function W(e) {
|
|
122
|
+
if (e.currentTarget === c == (r === "physical-only") && (e.stopPropagation(), f = null, x.delete(w(e)), !S.delete(w(e)) && (i !== null && y.delete(w(e)) && a.sendKey(C(e, !1), i), i !== null && ![...y].some((t) => !/^(Shift|Control|Alt|Meta)(Left|Right)$/.test(t))))) {
|
|
123
|
+
for (const t of T)
|
|
124
|
+
y.delete(t), a.sendKey({ ...C(e, !1), code: t, key: t.replace(/Left$/, ""), location: 1 }, i);
|
|
125
|
+
T.clear();
|
|
121
126
|
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
127
|
+
}
|
|
128
|
+
for (const e of [l, c])
|
|
129
|
+
s(e, "keydown", N), s(e, "keyup", W);
|
|
130
|
+
s(l, "beforeinput", (e) => {
|
|
131
|
+
if (i === null || d || r === "physical-only") {
|
|
132
|
+
e.preventDefault(), p();
|
|
125
133
|
return;
|
|
126
134
|
}
|
|
127
135
|
if (e.isComposing || o || e.inputType === "insertCompositionText" || e.inputType === "deleteCompositionText" || e.inputType === "insertFromComposition") return;
|
|
128
|
-
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
}), s(
|
|
132
|
-
|
|
133
|
-
|
|
136
|
+
K = !1;
|
|
137
|
+
const n = { deleteContentBackward: "Backspace", deleteContentForward: "Delete", insertLineBreak: "Enter", insertParagraph: "Enter" }[e.inputType];
|
|
138
|
+
n && (e.preventDefault(), p(), F(n));
|
|
139
|
+
}), s(l, "input", P), s(l, "compositionstart", () => {
|
|
140
|
+
if (r === "physical-only") {
|
|
141
|
+
p();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
o = { epoch: M, committed: !1, cancelled: i === null }, K = !1, f = null, l.dataset.composing = "true", h();
|
|
145
|
+
}), s(l, "compositionend", (e) => {
|
|
134
146
|
const t = o;
|
|
135
|
-
o = null,
|
|
136
|
-
}), s(
|
|
137
|
-
|
|
138
|
-
}), s(c, "blur",
|
|
139
|
-
|
|
147
|
+
o = null, K = !0, p(), t && !t.cancelled && !t.committed && t.epoch === M && A(e.data);
|
|
148
|
+
}), s(l, "blur", () => {
|
|
149
|
+
b(), L(!1);
|
|
150
|
+
}), s(c, "blur", () => {
|
|
151
|
+
r === "physical-only" && b();
|
|
152
|
+
}), s(u, "blur", b), s(u, "pagehide", b), s(u, "resize", h), u.visualViewport && (s(u.visualViewport, "resize", h), s(u.visualViewport, "scroll", h));
|
|
153
|
+
function R() {
|
|
154
|
+
i === null || d || (r === "physical-only" ? (c.hasAttribute("tabindex") || (c.tabIndex = -1, D = !0), c.focus({ preventScroll: !0 })) : (l.focus({ preventScroll: !0 }), h()));
|
|
155
|
+
}
|
|
156
|
+
return h(), {
|
|
157
|
+
element: l,
|
|
140
158
|
bindTarget(e) {
|
|
141
|
-
|
|
159
|
+
d || Object.is(i, e) || (b(), i = e, l.disabled = e === null || r === "physical-only");
|
|
142
160
|
},
|
|
143
161
|
setTextInputMode(e) {
|
|
144
|
-
|
|
162
|
+
if (d || e === r) return;
|
|
163
|
+
const t = k.activeElement === l || k.activeElement === c;
|
|
164
|
+
b(), r = e, l.disabled = i === null || e === "physical-only", e === "physical-only" && L(!1), t && R();
|
|
145
165
|
},
|
|
146
166
|
setAnchor(e, t) {
|
|
147
|
-
!Number.isFinite(e) || !Number.isFinite(t) || ($ = { x: e, y: t },
|
|
148
|
-
},
|
|
149
|
-
focus() {
|
|
150
|
-
l === null || f || (i.focus({ preventScroll: !0 }), p());
|
|
167
|
+
!Number.isFinite(e) || !Number.isFinite(t) || ($ = { x: e, y: t }, h());
|
|
151
168
|
},
|
|
169
|
+
focus: R,
|
|
152
170
|
setKeyboardVisible(e) {
|
|
153
|
-
e &&
|
|
171
|
+
e && i !== null && !d ? (R(), L(r !== "physical-only")) : ((r === "physical-only" ? c : l).blur(), L(!1));
|
|
154
172
|
},
|
|
155
|
-
release:
|
|
156
|
-
reset:
|
|
173
|
+
release: z,
|
|
174
|
+
reset: b,
|
|
157
175
|
dispose() {
|
|
158
|
-
if (!
|
|
159
|
-
|
|
160
|
-
for (const e of
|
|
161
|
-
|
|
176
|
+
if (!d) {
|
|
177
|
+
b(), d = !0, i = null;
|
|
178
|
+
for (const e of I) e();
|
|
179
|
+
D && c.removeAttribute("tabindex"), l.remove(), L(!1);
|
|
162
180
|
}
|
|
163
181
|
}
|
|
164
182
|
};
|
|
165
183
|
}
|
|
166
184
|
export {
|
|
167
|
-
|
|
185
|
+
O as createRemoteInput
|
|
168
186
|
};
|