inline-chat-kit 0.54.1 → 0.54.3
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/CHANGELOG.md +75 -0
- package/dist/inline-chat-kit.js +21 -12
- package/dist/inline-chat-kit.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,81 @@ The versions before 1.0 follow the pre-release convention: **a breaking change
|
|
|
8
8
|
or new public API bumps the minor**, and the patch is for fixes. Anything that would break an
|
|
9
9
|
existing install is called out under **Breaking**, with what to do about it.
|
|
10
10
|
|
|
11
|
+
## 0.54.3 — 2026-09-13
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **The sent message flickered a pixel up and down for the whole length of
|
|
16
|
+
every answer after the first.** Measured while a second answer was written:
|
|
17
|
+
the message sat at y=100 and flipped to 101 and back thirty-one times, with
|
|
18
|
+
the room under the conversation going 418, 379, 374, 372, 362, 360, 351
|
|
19
|
+
underneath it — a new value on every frame.
|
|
20
|
+
|
|
21
|
+
It was a feedback loop. That room is part of `scrollHeight`, the scroll
|
|
22
|
+
target is clamped to `scrollHeight`, and the room was recomputed from
|
|
23
|
+
measurements on every frame: the room moved the view, the view moved the
|
|
24
|
+
measurements, and the measurements moved the room. Sized to be *exactly*
|
|
25
|
+
enough for the anchored turn to reach the anchor, the clamp sat on a knife
|
|
26
|
+
edge and a fraction of a pixel chose the side.
|
|
27
|
+
|
|
28
|
+
A floor does not drop while the thing standing on it is still standing. So
|
|
29
|
+
while a turn is anchored the room only grows, and it is recomputed the
|
|
30
|
+
moment the anchor is let go — a long answer carries some spare room until it
|
|
31
|
+
settles, and nothing carries it afterwards. Growing stays allowed, which is
|
|
32
|
+
what keeps it self-correcting: a first measurement taken before layout is
|
|
33
|
+
final is raised by the next one rather than standing for the whole answer.
|
|
34
|
+
|
|
35
|
+
After: the message decelerates into the anchor and then holds one position
|
|
36
|
+
for the rest of the answer — 473 frames at a 680px viewport, 466 at 1400px,
|
|
37
|
+
not one of them a pixel off.
|
|
38
|
+
|
|
39
|
+
### Internal
|
|
40
|
+
|
|
41
|
+
- **`follow-check` has a guard for it**, and it had none before: every check
|
|
42
|
+
in there measured a *transition* — where a message lands, where the view
|
|
43
|
+
comes to rest, whether it travelled — and this fault lived in the quiet
|
|
44
|
+
stretch between them, which is why it was reported three times and "fixed"
|
|
45
|
+
twice on measurements that were each true.
|
|
46
|
+
|
|
47
|
+
The window comes from `aria-busy`, which the turn already carries for
|
|
48
|
+
screen readers while its answer arrives, so it is the window the assertion
|
|
49
|
+
names rather than one inferred from the turn's height — that one ran past
|
|
50
|
+
the end of the answer and counted the settle. The fault inside it is a
|
|
51
|
+
**reversal**, because jitter is not motion, it is motion that changes its
|
|
52
|
+
mind; the arrival is required to move and is asserted elsewhere. A creep
|
|
53
|
+
never reverses, so the back half of the window has to be a single number as
|
|
54
|
+
well, and that number the anchor.
|
|
55
|
+
|
|
56
|
+
Watched failing on the fault before it was trusted: 4 reversals at both
|
|
57
|
+
heights with the room recomputing per frame, none with the floor.
|
|
58
|
+
|
|
59
|
+
## 0.54.2 — 2026-09-12
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
|
|
63
|
+
- **The sent message leapt off the top of the view when an answer settled.**
|
|
64
|
+
Measured on the demo at 1100×700, at the frame the turn count went from one
|
|
65
|
+
to two: `scrollTop` 0 → 175, in a single frame, and the message that had
|
|
66
|
+
just been sent went from 100px down the view to −75.
|
|
67
|
+
|
|
68
|
+
It was not the scroll logic. `Conversation` made **exactly one** correction
|
|
69
|
+
in the whole session — a smooth one, arriving after the jump had already
|
|
70
|
+
happened. The jump was `focus()`: when an answer settles the next turn is
|
|
71
|
+
appended, its composer mounts at the bottom of the conversation and focuses
|
|
72
|
+
itself, and focusing an element brings it into view. Instantly, and without
|
|
73
|
+
asking anyone.
|
|
74
|
+
|
|
75
|
+
`preventScroll` now. Where the view goes belongs to `Conversation`, which
|
|
76
|
+
knows about anchors, tails, and whether the reader has scrolled away; focus
|
|
77
|
+
is about the keyboard. The same moment is now eight frames with a largest
|
|
78
|
+
step of 48px.
|
|
79
|
+
|
|
80
|
+
Three traces to find, because every instrument pointed at the scroll logic
|
|
81
|
+
and the scroll logic was innocent. The first two also measured the wrong
|
|
82
|
+
element — during an answer the last editable belongs to the turn being
|
|
83
|
+
written, and afterwards to a different turn entirely, so the trace read a
|
|
84
|
+
change of subject as a movement.
|
|
85
|
+
|
|
11
86
|
## 0.54.1 — 2026-09-12
|
|
12
87
|
|
|
13
88
|
### Fixed
|
package/dist/inline-chat-kit.js
CHANGED
|
@@ -853,7 +853,7 @@ var Ue = {
|
|
|
853
853
|
Le,
|
|
854
854
|
et
|
|
855
855
|
]), o(() => {
|
|
856
|
-
(e === "idle" || e === "typing") && F.current?.focus();
|
|
856
|
+
(e === "idle" || e === "typing") && F.current?.focus({ preventScroll: !0 });
|
|
857
857
|
}, [e]), o(() => {
|
|
858
858
|
let e = F.current;
|
|
859
859
|
e && (ve.current = e.scrollHeight || 17);
|
|
@@ -4950,17 +4950,18 @@ var Xr = {
|
|
|
4950
4950
|
let n = t.lastElementChild, a = n ? ei(n, e) + n.offsetHeight : ei(t, e) + t.offsetHeight - D.current;
|
|
4951
4951
|
return Math.max(0, a + r - e.clientHeight);
|
|
4952
4952
|
}, [r, i]), j = a(() => {
|
|
4953
|
-
let e = S.current,
|
|
4954
|
-
if (!e || !
|
|
4955
|
-
if (i !== "auto") return ni(
|
|
4956
|
-
let
|
|
4957
|
-
if (k.current = !!
|
|
4958
|
-
let
|
|
4959
|
-
ni(
|
|
4953
|
+
let e = S.current, a = C.current;
|
|
4954
|
+
if (!e || !a) return;
|
|
4955
|
+
if (i !== "auto") return ni(a, D, Math.max(0, i));
|
|
4956
|
+
let o = parseFloat(getComputedStyle(e).paddingBottom) || 0, s = Math.max(0, r - o), c = a.lastElementChild, l = ti(e, O.current);
|
|
4957
|
+
if (k.current = !!c && !!l, !k.current || !c || !l) return ni(a, D, s);
|
|
4958
|
+
let u = ei(c, e) + c.offsetHeight - ei(l, e), d = Math.max(s, e.clientHeight - n - u - o);
|
|
4959
|
+
ni(a, D, t ? Math.max(d, D.current) : d);
|
|
4960
4960
|
}, [
|
|
4961
4961
|
i,
|
|
4962
4962
|
n,
|
|
4963
|
-
r
|
|
4963
|
+
r,
|
|
4964
|
+
t
|
|
4964
4965
|
]), M = a(() => {
|
|
4965
4966
|
let e = S.current;
|
|
4966
4967
|
if (!e) return 0;
|
|
@@ -4996,12 +4997,20 @@ var Xr = {
|
|
|
4996
4997
|
let e = S.current, n = C.current;
|
|
4997
4998
|
if (!e || !n || typeof ResizeObserver > "u") return;
|
|
4998
4999
|
let r = () => {
|
|
4999
|
-
let
|
|
5000
|
+
let n = M();
|
|
5000
5001
|
if (N.current) {
|
|
5001
|
-
if (performance.now() < N.current && Math.abs(e.scrollTop -
|
|
5002
|
+
if (performance.now() < N.current && Math.abs(e.scrollTop - n) > 1) return;
|
|
5002
5003
|
N.current = 0;
|
|
5003
5004
|
}
|
|
5004
|
-
e.scrollTop
|
|
5005
|
+
let r = n - e.scrollTop;
|
|
5006
|
+
if (O.current && !t && Math.abs(r) > s && !K()) {
|
|
5007
|
+
N.current = performance.now() + Qr, e.scrollTo({
|
|
5008
|
+
top: n,
|
|
5009
|
+
behavior: "smooth"
|
|
5010
|
+
});
|
|
5011
|
+
return;
|
|
5012
|
+
}
|
|
5013
|
+
e.scrollTop = n;
|
|
5005
5014
|
}, i = t != null && t !== P.current;
|
|
5006
5015
|
t && (P.current = t), i && !K() && Math.abs(e.scrollTop - M()) > s ? (N.current = performance.now() + Qr, e.scrollTo({
|
|
5007
5016
|
top: M(),
|