inline-chat-kit 0.54.0 → 0.54.1

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 CHANGED
@@ -1,11 +1,70 @@
1
1
  # Changelog
2
2
 
3
- Dates are the day the work landed on `main`.
3
+ Dates are the day the work landed on `main`, which is not always the day it
4
+ reached npm: `0.52.1` and `0.53.0` were written up here and never published,
5
+ and their changes shipped in `0.54.0`. Each is marked.
4
6
 
5
7
  The versions before 1.0 follow the pre-release convention: **a breaking change
6
8
  or new public API bumps the minor**, and the patch is for fixes. Anything that would break an
7
9
  existing install is called out under **Breaking**, with what to do about it.
8
10
 
11
+ ## 0.54.1 — 2026-09-12
12
+
13
+ ### Fixed
14
+
15
+ - **Scrolling up was fought for the first 64 pixels, then let go all at
16
+ once.** Since 0.54.0 measured the room under the last turn, the view comes
17
+ to rest exactly at the end of the scroll — so every upward scroll now starts
18
+ inside the band that counts as "back at the end", and the scroll event
19
+ re-acquired a reader who was still on their way out. Measured at rest, with
20
+ a real wheel:
21
+
22
+ | wheeled up | wanted | ended at |
23
+ | --- | --- | --- |
24
+ | 20px | 134 | **154** |
25
+ | 40px | 114 | **154** |
26
+ | 63px | 91 | **154** |
27
+ | 80px | 74 | 74 |
28
+
29
+ Arriving and leaving are different questions and no longer share a number.
30
+ `threshold` stays what it was — how far you must go before the view accepts
31
+ you have left, generous so a nudge does not abandon the answer you are
32
+ reading. Coming back now means coming back: four pixels, a rounding
33
+ allowance rather than an opinion.
34
+
35
+ A test asserted the old behaviour in so many words — "inside the 64px
36
+ threshold" — which is the fault written down as a rule. It says the opposite
37
+ now, beside one that pins the fault.
38
+
39
+ ### Added
40
+
41
+ - **[Getting started](./getting-started.md)** — one file, ten minutes, a chat
42
+ that runs with no backend, then one paragraph to point it at a model. The
43
+ README's first example was a single `<ChatInput>`, which is a text box: to
44
+ get the experience the page describes you also needed `useChatTurns`,
45
+ `Conversation` and the anchoring, and those were three sections apart with no
46
+ runnable file between them.
47
+
48
+ The example is `src/examples/minimal.tsx`, so `tsc -b` compiles it on every
49
+ build; a test asserts the page quotes it character for character; and a
50
+ Storybook story renders it, so the claim that it works is checked three ways
51
+ and none of them is a screenshot somebody took once. Nothing imports it, so
52
+ the library build never reaches it — verified at zero occurrences in the
53
+ bundle.
54
+
55
+ ### Fixed
56
+
57
+ - **The default placeholder was `"Placeholder text..."`** — a stand-in nobody
58
+ replaced. A default is what every consumer who has not thought about it yet
59
+ ships in production, which is most of them on their first afternoon. It is
60
+ `"Ask anything…"` now. Found by writing the getting-started page and looking
61
+ at what it drew, which is the argument for having one.
62
+
63
+ - **The changelog promised two versions that were never published.** The
64
+ registry goes `0.52.0` → `0.54.0`; this file described `0.52.1` and `0.53.0`
65
+ with dates, so anyone reaching for `npm i inline-chat-kit@0.53.0` got
66
+ nothing. Both are marked, and their changes shipped in `0.54.0`.
67
+
9
68
  ## 0.54.0 — 2026-09-12
10
69
 
11
70
  Everything here came out of using the kit on a phone. It is better there than
@@ -202,6 +261,10 @@ see *Where it is meant to run*.
202
261
 
203
262
  ## 0.53.0 — 2026-09-03
204
263
 
264
+ > **Never published.** This version exists in this file and not on npm —
265
+ > the registry goes `0.52.0` → `0.54.0`. Everything below shipped in 0.54.0,
266
+ > which is the version to install if you came here looking for it.
267
+
205
268
  ### Changed
206
269
 
207
270
  - **The artifact card moves instead of changing colour.** Pointing at it lifted
@@ -272,6 +335,10 @@ see *Where it is meant to run*.
272
335
 
273
336
  ## 0.52.1 — 2026-09-03
274
337
 
338
+ > **Never published.** This version exists in this file and not on npm —
339
+ > the registry goes `0.52.0` → `0.54.0`. Everything below shipped in 0.54.0,
340
+ > which is the version to install if you came here looking for it.
341
+
275
342
  ### Fixed
276
343
 
277
344
  - **The composer's editor was 16px wider than the box that clips it.**
package/README.md CHANGED
@@ -10,6 +10,10 @@ answers you can draw on with a marker,
10
10
  syntax-highlighted code blocks, a scroll container that keeps up with an
11
11
  answer, and reply-in-thread popups.
12
12
 
13
+ **New here?** [**Getting started**](./getting-started.md) is one file, ten
14
+ minutes, and a chat that runs with no backend. The rest of this page is the
15
+ reference.
16
+
13
17
  ## Where it is meant to run
14
18
 
15
19
  **Desktop and tablet.** That is what this is designed for, tuned for, and what
@@ -0,0 +1 @@
1
+ export declare function MinimalChat(): import("react").JSX.Element;
@@ -747,7 +747,7 @@ var Ue = {
747
747
  n.deleteContents();
748
748
  let r = document.createTextNode(e);
749
749
  return n.insertNode(r), n.setStartAfter(r), n.collapse(!0), t.removeAllRanges(), t.addRange(n), !1;
750
- }, Ke = n(function({ state: e, value: t, onChange: n, onSubmit: r, onStop: i, onAdd: l, attachments: u, onAttach: p, onRemoveAttachment: C, accept: w = "image/*", multiple: T = !1, onTranscribe: E, onCopy: D, onEdit: O, onCancelEdit: k, isEditing: A = !1, placeholder: j = "Placeholder text...", animationConfig: M, style: N }, P) {
750
+ }, Ke = n(function({ state: e, value: t, onChange: n, onSubmit: r, onStop: i, onAdd: l, attachments: u, onAttach: p, onRemoveAttachment: C, accept: w = "image/*", multiple: T = !1, onTranscribe: E, onCopy: D, onEdit: O, onCancelEdit: k, isEditing: A = !1, placeholder: j = "Ask anything…", animationConfig: M, style: N }, P) {
751
751
  let ee = s(), F = d(null), I = d(null), te = d(null), ne = d(0), re = d(!1), ie = d(null), [ae, oe] = f(!1), [se, ce] = f(!1), [le, ue] = f(!1), [fe, pe] = f(!0), [me, he] = f(!1), [L, ge] = f(!1), [_e, z] = f(!1), ve = d(0), B = d(!1), H = d(0), ye = d(!1), U = d(null);
752
752
  o(() => () => {
753
753
  U.current && clearTimeout(U.current);
@@ -4938,25 +4938,25 @@ var Xr = {
4938
4938
  viewport: "ick-viewport-C3hz",
4939
4939
  content: "ick-content-33lN",
4940
4940
  jump: "ick-jump-nd6O"
4941
- }, Zr = 64, Qr = 500, $r = (e, t) => e.offsetTop - t.offsetTop, ei = (e, t) => t ? e.querySelector(`[id="${CSS.escape(t)}"]`) : null, ti = (e, t, n) => {
4941
+ }, Zr = 64, Qr = 500, $r = 4, ei = (e, t) => e.offsetTop - t.offsetTop, ti = (e, t) => t ? e.querySelector(`[id="${CSS.escape(t)}"]`) : null, ni = (e, t, n) => {
4942
4942
  n !== t.current && (t.current = n, e.style.setProperty("--ick-conversation-tail", `${Math.round(n)}px`));
4943
- }, ni = n(function({ children: e, anchorId: t, anchorOffset: n = 0, endOffset: r = 0, tail: i = "auto", threshold: s = Zr, scrollButton: u = !0, scrollButtonLabel: p = "Jump to the latest", follow: m = !0, className: _, viewportClassName: v, onScroll: y, ...b }, x) {
4943
+ }, ri = n(function({ children: e, anchorId: t, anchorOffset: n = 0, endOffset: r = 0, tail: i = "auto", threshold: s = Zr, scrollButton: u = !0, scrollButtonLabel: p = "Jump to the latest", follow: m = !0, className: _, viewportClassName: v, onScroll: y, ...b }, x) {
4944
4944
  let S = d(null);
4945
4945
  c(x, () => S.current, []);
4946
4946
  let C = d(null), [w, E] = f(!0), D = d(-1), O = d(null), k = d(!1), A = a(() => {
4947
4947
  let e = S.current, t = C.current;
4948
4948
  if (!e || !t) return 0;
4949
4949
  if (i === "auto" && k.current) return Math.max(0, e.scrollHeight - e.clientHeight);
4950
- let n = t.lastElementChild, a = n ? $r(n, e) + n.offsetHeight : $r(t, e) + t.offsetHeight - D.current;
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
4953
  let e = S.current, t = C.current;
4954
4954
  if (!e || !t) return;
4955
- if (i !== "auto") return ti(t, D, Math.max(0, i));
4956
- let a = parseFloat(getComputedStyle(e).paddingBottom) || 0, o = Math.max(0, r - a), s = t.lastElementChild, c = ei(e, O.current);
4957
- if (k.current = !!s && !!c, !k.current || !s || !c) return ti(t, D, o);
4958
- let l = $r(s, e) + s.offsetHeight - $r(c, e);
4959
- ti(t, D, Math.max(o, e.clientHeight - n - l - a));
4955
+ if (i !== "auto") return ni(t, D, Math.max(0, i));
4956
+ let a = parseFloat(getComputedStyle(e).paddingBottom) || 0, o = Math.max(0, r - a), s = t.lastElementChild, c = ti(e, O.current);
4957
+ if (k.current = !!s && !!c, !k.current || !s || !c) return ni(t, D, o);
4958
+ let l = ei(s, e) + s.offsetHeight - ei(c, e);
4959
+ ni(t, D, Math.max(o, e.clientHeight - n - l - a));
4960
4960
  }, [
4961
4961
  i,
4962
4962
  n,
@@ -4967,7 +4967,7 @@ var Xr = {
4967
4967
  if (t) {
4968
4968
  let r = e.querySelector(`[id="${CSS.escape(t)}"]`);
4969
4969
  if (r) {
4970
- let t = Math.max(0, e.scrollHeight - e.clientHeight), i = $r(r, e), a = i - n, o = i + r.offsetHeight - e.clientHeight;
4970
+ let t = Math.max(0, e.scrollHeight - e.clientHeight), i = ei(r, e), a = i - n, o = i + r.offsetHeight - e.clientHeight;
4971
4971
  return Math.max(0, Math.min(Math.max(a, o), t));
4972
4972
  }
4973
4973
  }
@@ -5052,11 +5052,10 @@ var Xr = {
5052
5052
  let F = a((e) => {
5053
5053
  if (y?.(e), !m) return;
5054
5054
  let t = S.current;
5055
- t && Math.abs(t.scrollTop - M()) <= s && (N.current = 0, E(!0));
5055
+ t && Math.abs(t.scrollTop - M()) <= $r && (N.current = 0, E(!0));
5056
5056
  }, [
5057
5057
  m,
5058
5058
  y,
5059
- s,
5060
5059
  M
5061
5060
  ]), I = m && !w;
5062
5061
  return /* @__PURE__ */ g("div", {
@@ -5085,14 +5084,14 @@ var Xr = {
5085
5084
  })
5086
5085
  })]
5087
5086
  });
5088
- }), ri = 24, ii = 480, ai = 80, oi = 260;
5089
- function si(e, t, n = Infinity) {
5090
- let r = Math.max(t - 48, 0), i = Math.min(Math.max(e.width + ai, ii), r), a = e.left + e.width / 2 - i / 2, o = Math.min(Math.max(a, ri), t - ri - i), s = Math.max(ri, n - ri - oi), c = Math.min(Math.max(e.top - ri, Math.min(ri, n)), Number.isFinite(s) ? s : Infinity);
5087
+ }), ii = 24, ai = 480, oi = 80, si = 260;
5088
+ function ci(e, t, n = Infinity) {
5089
+ let r = Math.max(t - 48, 0), i = Math.min(Math.max(e.width + oi, ai), r), a = e.left + e.width / 2 - i / 2, o = Math.min(Math.max(a, ii), t - ii - i), s = Math.max(ii, n - ii - si), c = Math.min(Math.max(e.top - ii, Math.min(ii, n)), Number.isFinite(s) ? s : Infinity);
5091
5090
  return {
5092
5091
  x: o,
5093
5092
  y: c,
5094
5093
  width: i,
5095
- maxHeight: Number.isFinite(n) ? Math.max(oi, n - c - ri) : Infinity
5094
+ maxHeight: Number.isFinite(n) ? Math.max(si, n - c - ii) : Infinity
5096
5095
  };
5097
5096
  }
5098
5097
  var $ = {
@@ -5116,7 +5115,7 @@ var $ = {
5116
5115
  turn: "ick-turn-ogjU",
5117
5116
  turnRow: "ick-turnRow-0OuP",
5118
5117
  srOnly: "ick-srOnly-LwE1"
5119
- }, ci = 760, li = {
5118
+ }, li = 760, ui = {
5120
5119
  closed: {
5121
5120
  y: "100%",
5122
5121
  opacity: 1,
@@ -5135,11 +5134,11 @@ var $ = {
5135
5134
  bounce: .18
5136
5135
  }
5137
5136
  }
5138
- }, ui = "a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [contenteditable]:not([contenteditable=\"false\"]), [tabindex]:not([tabindex=\"-1\"])";
5139
- function di({ activeReply: e, onClose: t, onSave: n, onSendMessage: r }) {
5140
- let [i, a] = f("none"), c = d(null), l = d(null), u = d(null), [p] = f(() => typeof document > "u" ? null : document.activeElement), m = s(), _ = s(), v = Ue, [b, S] = f(() => typeof window > "u" ? !1 : window.matchMedia?.(`(max-width: ${ci}px)`)?.matches ?? !1);
5137
+ }, di = "a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [contenteditable]:not([contenteditable=\"false\"]), [tabindex]:not([tabindex=\"-1\"])";
5138
+ function fi({ activeReply: e, onClose: t, onSave: n, onSendMessage: r }) {
5139
+ let [i, a] = f("none"), c = d(null), l = d(null), u = d(null), [p] = f(() => typeof document > "u" ? null : document.activeElement), m = s(), _ = s(), v = Ue, [b, S] = f(() => typeof window > "u" ? !1 : window.matchMedia?.(`(max-width: ${li}px)`)?.matches ?? !1);
5141
5140
  o(() => {
5142
- let e = window.matchMedia?.(`(max-width: ${ci}px)`);
5141
+ let e = window.matchMedia?.(`(max-width: ${li}px)`);
5143
5142
  if (!e?.addEventListener) return;
5144
5143
  let t = () => S(e.matches);
5145
5144
  return t(), e.addEventListener("change", t), () => e.removeEventListener("change", t);
@@ -5155,7 +5154,7 @@ function di({ activeReply: e, onClose: t, onSave: n, onSendMessage: r }) {
5155
5154
  return;
5156
5155
  }
5157
5156
  if (e.key !== "Tab") return;
5158
- let n = [...u.current?.querySelectorAll(ui) ?? []];
5157
+ let n = [...u.current?.querySelectorAll(di) ?? []];
5159
5158
  if (n.length === 0) return;
5160
5159
  let r = n[0], i = n[n.length - 1], a = document.activeElement;
5161
5160
  e.shiftKey && a === r ? (e.preventDefault(), i.focus()) : !e.shiftKey && a === i && (e.preventDefault(), r.focus());
@@ -5192,7 +5191,7 @@ function di({ activeReply: e, onClose: t, onSave: n, onSendMessage: r }) {
5192
5191
  y: 0,
5193
5192
  width: 480,
5194
5193
  maxHeight: Infinity
5195
- } : si(e.rect, window.innerWidth, window.innerHeight);
5194
+ } : ci(e.rect, window.innerWidth, window.innerHeight);
5196
5195
  return /* @__PURE__ */ h(y, {
5197
5196
  reducedMotion: "user",
5198
5197
  children: /* @__PURE__ */ h("div", {
@@ -5226,7 +5225,7 @@ function di({ activeReply: e, onClose: t, onSave: n, onSendMessage: r }) {
5226
5225
  scale: .95,
5227
5226
  filter: "blur(4px)"
5228
5227
  },
5229
- variants: b ? li : void 0,
5228
+ variants: b ? ui : void 0,
5230
5229
  transition: b ? void 0 : {
5231
5230
  type: "spring",
5232
5231
  bounce: 0,
@@ -5370,7 +5369,7 @@ function di({ activeReply: e, onClose: t, onSave: n, onSendMessage: r }) {
5370
5369
  }
5371
5370
  //#endregion
5372
5371
  //#region src/CustomCursor/CustomCursor.tsx
5373
- function fi() {
5372
+ function pi() {
5374
5373
  let e = C(-100), t = C(-100), [n, r] = f("default"), [i, a] = f(!1), [s, c] = f(!1);
5375
5374
  return o(() => {
5376
5375
  let n = (n) => {
@@ -5528,20 +5527,20 @@ function fi() {
5528
5527
  }
5529
5528
  //#endregion
5530
5529
  //#region src/GlassButton/GlassButton.tsx
5531
- var pi = {
5530
+ var mi = {
5532
5531
  s: "m",
5533
5532
  m: "l",
5534
5533
  l: "xl"
5535
- }, mi = n(function({ size: e = "m", iconLeft: t, ...n }, r) {
5534
+ }, hi = n(function({ size: e = "m", iconLeft: t, ...n }, r) {
5536
5535
  return /* @__PURE__ */ h(V, {
5537
5536
  ref: r,
5538
5537
  variant: "glass",
5539
- size: pi[e],
5538
+ size: mi[e],
5540
5539
  icon: t,
5541
5540
  ...n
5542
5541
  });
5543
5542
  });
5544
5543
  //#endregion
5545
- export { Oe as AddCardsOverlay, ht as AnswerActions, tn as Approval, Rn as ArtifactCard, Ir as ArtifactPane, Ce as Attachments, vt as Branch, V as Button, cn as ChainOfThought, lt as ChatHeader, Ke as ChatInput, Kr as ChatLayout, Or as ChatTurnRow, pn as Chip, Wt as CodeBlock, Pr as Context, ni as Conversation, fi as CustomCursor, Yr as EmptyState, kn as FOLDABLE_FROM, mi as GlassButton, Ee as HoverActionsRow, hr as InlineCitation, bt as Loader, Te as MorphGlyph, mn as QuestionBadge, Dn as QuestionCard, gn as QuestionFieldRow, Mn as QuestionGroup, hn as QuestionOptionRow, _n as QuestionOtherRow, vn as QuestionShell, At as Reasoning, di as ReplyThreadPopup, dn as Sources, Pn as SystemMessage, an as TaskList, Tr as TextHighlighter, Zt as Tool, G as announce, Tn as answerChips, It as canHighlight, An as defaultFoldMotion, Ue as defaultInlineAnimConfig, U as formatSize, rt as headerIconSize, Vt as loadHighlighter, qe as mergeParts, qr as useArtifacts, tt as useChatTurns, ze as useVoiceInput };
5544
+ export { Oe as AddCardsOverlay, ht as AnswerActions, tn as Approval, Rn as ArtifactCard, Ir as ArtifactPane, Ce as Attachments, vt as Branch, V as Button, cn as ChainOfThought, lt as ChatHeader, Ke as ChatInput, Kr as ChatLayout, Or as ChatTurnRow, pn as Chip, Wt as CodeBlock, Pr as Context, ri as Conversation, pi as CustomCursor, Yr as EmptyState, kn as FOLDABLE_FROM, hi as GlassButton, Ee as HoverActionsRow, hr as InlineCitation, bt as Loader, Te as MorphGlyph, mn as QuestionBadge, Dn as QuestionCard, gn as QuestionFieldRow, Mn as QuestionGroup, hn as QuestionOptionRow, _n as QuestionOtherRow, vn as QuestionShell, At as Reasoning, fi as ReplyThreadPopup, dn as Sources, Pn as SystemMessage, an as TaskList, Tr as TextHighlighter, Zt as Tool, G as announce, Tn as answerChips, It as canHighlight, An as defaultFoldMotion, Ue as defaultInlineAnimConfig, U as formatSize, rt as headerIconSize, Vt as loadHighlighter, qe as mergeParts, qr as useArtifacts, tt as useChatTurns, ze as useVoiceInput };
5546
5545
 
5547
5546
  //# sourceMappingURL=inline-chat-kit.js.map