@floegence/floe-webapp-core 0.86.18 → 0.86.19

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.
@@ -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 preserves the host layout; text uses every local confirmed edit. */
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;
@@ -1,17 +1,17 @@
1
- function j(n) {
2
- const { surface: A } = n, x = A.ownerDocument, c = x.defaultView;
3
- if (!c) throw new Error("Remote input requires an attached document");
4
- const i = x.createElement("textarea");
5
- i.className = "floe-remote-input", i.setAttribute("aria-label", n.label), i.setAttribute("autocorrect", "off"), i.autocomplete = "off", i.autocapitalize = "off", i.spellcheck = !1, i.wrap = "off", i.disabled = !0, i.tabIndex = -1, x.body.append(i);
6
- let l = null, K = 0, f = !1, R = !1, o = null, h = !1, a = null, w = "physical";
7
- const k = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Set(), C = /* @__PURE__ */ new Set(), L = /* @__PURE__ */ new Set();
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 V = [];
10
- function s(e, t, r) {
11
- const d = r;
12
- e.addEventListener(t, d), V.push(() => e.removeEventListener(t, d));
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 b = (e) => e.code || e.key, M = (e, t) => ({
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 T(e) {
26
- R !== e && (R = e, n.onKeyboardVisibilityChange?.(e));
25
+ function L(e) {
26
+ V !== e && (V = e, a.onKeyboardVisibilityChange?.(e));
27
27
  }
28
- function p() {
29
- const e = A.getBoundingClientRect(), t = c.visualViewport, r = Math.max(e.left, t?.offsetLeft ?? 0), d = Math.max(e.top, t?.offsetTop ?? 0), y = Math.min(e.right, (t?.offsetLeft ?? 0) + (t?.width ?? c.innerWidth)), I = Math.min(e.bottom, (t?.offsetTop ?? 0) + (t?.height ?? c.innerHeight)), P = Math.max(1, Math.min(320, y - r - 8));
30
- i.style.maxWidth = `${P}px`;
31
- const B = i.getBoundingClientRect(), N = $?.x ?? r + 12, W = $?.y ?? d + 12;
32
- i.style.left = `${Math.max(r, Math.min(N, y - B.width - 4))}px`, i.style.top = `${Math.max(d, Math.min(W, I - B.height - 4))}px`;
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 m() {
35
- i.value = "", delete i.dataset.composing, a = null;
34
+ function p() {
35
+ l.value = "", delete l.dataset.composing, f = null;
36
36
  }
37
- function E() {
38
- const e = l, t = u.size > 0;
39
- u.clear(), k.clear(), C.clear(), e !== null && t && n.release(e);
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 g() {
42
- K++, o && (o.cancelled = !0), h = !0, m(), E(), o && x.activeElement === i && i.blur();
41
+ function b() {
42
+ M++, o && (o.cancelled = !0), K = !0, p(), z(), o && k.activeElement === l && l.blur();
43
43
  }
44
- function S(e) {
45
- !e || l === null || f || (w === "text" && u.size && (u.clear(), C.clear(), n.release(l)), n.commitText(e, l));
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 z(e) {
48
- if (l !== null) {
47
+ function E(e) {
48
+ if (i !== null) {
49
49
  if (!/^(Shift|Control|Alt|Meta)(Left|Right)$/.test(e.code))
50
- for (const [t, r] of [
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 (!r || [...u].some((y) => y === `${t}Left` || y === `${t}Right`)) continue;
57
- const d = [...k.values()].find((y) => y.code === `${t}Left` || y.code === `${t}Right`) ?? { ...e, key: t, code: `${t}Left`, pressed: !0, repeat: !1, location: 1 };
58
- u.add(d.code), k.has(d.code) || C.add(d.code), n.sendKey(d, l);
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
- u.add(e.code || e.key), n.sendKey(e, l);
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 (l === null || f) {
70
- m();
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 !== K) {
74
- m();
73
+ if (o?.cancelled || o && o.epoch !== M) {
74
+ p();
75
75
  return;
76
76
  }
77
77
  if (e.isComposing) {
78
- o ??= { epoch: K, committed: !1, cancelled: !1 }, i.dataset.composing = "true", p();
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 && i.value && (o.committed = !0, S(i.value)), m();
82
+ !o.committed && l.value && (o.committed = !0, A(l.value)), p();
83
83
  return;
84
84
  }
85
- if (h || e.inputType === "insertFromComposition") {
86
- h = !1, m();
85
+ if (K || e.inputType === "insertFromComposition") {
86
+ K = !1, p();
87
87
  return;
88
88
  }
89
- const t = i.value;
90
- w === "physical" && a && t === a.key && !a.altKey && t.length === 1 ? z(a) : S(t), m();
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
- return s(i, "keydown", (e) => {
93
- if (!(l === null || f)) {
94
- if (e.stopPropagation(), o?.cancelled && !e.isComposing && e.key !== "Process" && e.keyCode !== 229 && (o = null), e.isComposing || o || e.key === "Process" || e.keyCode === 229) {
95
- L.add(b(e)), a = null;
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 (L.delete(b(e)), h = !1, n.clipboard?.(e, l)) {
99
- a = null;
102
+ if (S.delete(w(e)), K = !1, a.clipboard?.(e, i)) {
103
+ f = null;
100
104
  return;
101
105
  }
102
- if (w === "text" && /^(Shift|Control|Alt|Meta)(Left|Right)$/.test(e.code)) {
103
- k.set(b(e), M(e, !0));
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
- a = null;
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
- a = M(e, !0);
115
+ f = C(e, !0);
112
116
  return;
113
117
  }
114
- e.preventDefault(), z(M(e, !0));
118
+ e.preventDefault(), E(C(e, !0));
115
119
  }
116
- }), s(i, "keyup", (e) => {
117
- if (e.stopPropagation(), a = null, k.delete(b(e)), !L.delete(b(e)) && (l !== null && u.delete(b(e)) && n.sendKey(M(e, !1), l), l !== null && ![...u].some((t) => !/^(Shift|Control|Alt|Meta)(Left|Right)$/.test(t)))) {
118
- for (const t of C)
119
- u.delete(t), n.sendKey({ ...M(e, !1), code: t, key: t.replace(/Left$/, ""), location: 1 }, l);
120
- C.clear();
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
- }), s(i, "beforeinput", (e) => {
123
- if (l === null || f) {
124
- e.preventDefault();
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
- h = !1;
129
- const r = { deleteContentBackward: "Backspace", deleteContentForward: "Delete", insertLineBreak: "Enter", insertParagraph: "Enter" }[e.inputType];
130
- r && (e.preventDefault(), m(), D(r));
131
- }), s(i, "input", F), s(i, "compositionstart", () => {
132
- o = { epoch: K, committed: !1, cancelled: l === null }, h = !1, a = null, i.dataset.composing = "true", p();
133
- }), s(i, "compositionend", (e) => {
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, h = !0, m(), t && !t.cancelled && !t.committed && t.epoch === K && S(e.data);
136
- }), s(i, "blur", () => {
137
- g(), T(!1);
138
- }), s(c, "blur", g), s(c, "pagehide", g), s(c, "resize", p), c.visualViewport && (s(c.visualViewport, "resize", p), s(c.visualViewport, "scroll", p)), p(), {
139
- element: i,
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
- f || Object.is(l, e) || (g(), l = e, i.disabled = e === null);
159
+ d || Object.is(i, e) || (b(), i = e, l.disabled = e === null || r === "physical-only");
142
160
  },
143
161
  setTextInputMode(e) {
144
- f || e === w || (g(), w = e);
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 }, p());
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 && l !== null && !f ? (i.focus({ preventScroll: !0 }), T(!0), p()) : (i.blur(), T(!1));
171
+ e && i !== null && !d ? (R(), L(r !== "physical-only")) : ((r === "physical-only" ? c : l).blur(), L(!1));
154
172
  },
155
- release: E,
156
- reset: g,
173
+ release: z,
174
+ reset: b,
157
175
  dispose() {
158
- if (!f) {
159
- g(), f = !0, l = null;
160
- for (const e of V) e();
161
- i.remove(), T(!1);
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
- j as createRemoteInput
185
+ O as createRemoteInput
168
186
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floegence/floe-webapp-core",
3
- "version": "0.86.18",
3
+ "version": "0.86.19",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",