@bitbaum/chatkit 0.7.0 → 0.8.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/README.md +34 -1
- package/dist/react/Screen.d.ts +37 -0
- package/dist/react/Screen.d.ts.map +1 -0
- package/dist/react/Screen.js +56 -0
- package/dist/react/Screen.js.map +1 -0
- package/dist/react/hooks.d.ts +1 -1
- package/dist/react/hooks.d.ts.map +1 -1
- package/dist/react/hooks.js +29 -2
- package/dist/react/hooks.js.map +1 -1
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -0
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
- package/styles.css +160 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ interface that calls them.)
|
|
|
15
15
|
## Install
|
|
16
16
|
|
|
17
17
|
```sh
|
|
18
|
-
pnpm add @bitbaum/chatkit@^0.
|
|
18
|
+
pnpm add @bitbaum/chatkit@^0.8.0
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
**Install releases from npm, never a commit or a branch.** A semver range is
|
|
@@ -51,6 +51,37 @@ import "@bitbaum/chatkit/styles.css";
|
|
|
51
51
|
/>
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
+
### The whole screen — `ChatScreen`
|
|
55
|
+
|
|
56
|
+
A chat page is the conversation, edge to edge and top to bottom, as in the
|
|
57
|
+
ChatGPT and Claude apps. The header and the composer float OVER it instead of
|
|
58
|
+
each taking a strip of the screen: words scroll under both and fade as they
|
|
59
|
+
pass, the header's buttons are frosted pills (`ck-glass`), and the composer is
|
|
60
|
+
a see-through pill. The last line of an answer always rests above the
|
|
61
|
+
composer — the scroller is padded by the measured height of each.
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
<ChatScreen
|
|
65
|
+
fill="viewport" // or "parent": fill the box you give it
|
|
66
|
+
header={<>
|
|
67
|
+
<button className="ck-glass" aria-label="Chats"><IconMenu /></button>
|
|
68
|
+
<span style={{ flex: 1 }} />
|
|
69
|
+
<button className="ck-glass" aria-label="New chat"><IconPen /></button>
|
|
70
|
+
</>}
|
|
71
|
+
composer={<Composer … />} // plus an error or a queue, if you have one
|
|
72
|
+
footnote="Answers can be wrong."
|
|
73
|
+
>
|
|
74
|
+
<ChatThread … />
|
|
75
|
+
</ChatScreen>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`fill="viewport"` follows the VISUAL viewport, so the composer rides above the
|
|
79
|
+
phone keyboard. An app with its own thread pads its scroller with the two
|
|
80
|
+
measured heights: `padding-block: var(--ck-top-inset) var(--ck-bottom-inset)`.
|
|
81
|
+
The reading column is `--ck-measure` (48rem) wide with `--ck-gutter` (1rem)
|
|
82
|
+
to the edge; the page behind it is `--ck-page`. `demo/screen.html` is the
|
|
83
|
+
reference: look at it at 390px before changing any of this.
|
|
84
|
+
|
|
54
85
|
### The microphone
|
|
55
86
|
|
|
56
87
|
`voice` is on by default. Give it a server leg so it works everywhere:
|
|
@@ -199,6 +230,8 @@ on `Composer`, `labels` on `ChatThread`.
|
|
|
199
230
|
8. Starters in the empty state; suggested replies under the latest answer;
|
|
200
231
|
the speaker's name on every answer once more than one agent speaks.
|
|
201
232
|
9. Nothing overflows at 320–390px.
|
|
233
|
+
10. In `ChatScreen`, the conversation fills the display and opens at the
|
|
234
|
+
latest message, with its end above the composer, not behind it.
|
|
202
235
|
|
|
203
236
|
`pnpm run verify` proves all of it: unit and render tests, then
|
|
204
237
|
`test/browser.mjs` drives Chromium through the demo at desktop and 390px, light
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* The chat as the whole screen, the way the ChatGPT and Claude apps lay it
|
|
4
|
+
* out: the conversation runs edge to edge and top to bottom, and the controls
|
|
5
|
+
* FLOAT over it — a see-through header at the top, the composer at the bottom
|
|
6
|
+
* — instead of each taking a strip of the screen away from the reading.
|
|
7
|
+
*
|
|
8
|
+
* Words scroll under both. They fade out as they pass beneath the header and
|
|
9
|
+
* the composer, so the controls stay legible without an opaque bar behind
|
|
10
|
+
* them; the last line of an answer always rests above the composer, never
|
|
11
|
+
* behind it (the scroller is padded by the measured height of each).
|
|
12
|
+
*
|
|
13
|
+
* The heights are published as `--ck-top-inset` and `--ck-bottom-inset` on
|
|
14
|
+
* the screen, so an app whose thread is its own scroller pads it with them:
|
|
15
|
+
*
|
|
16
|
+
* .my-thread { padding-block: var(--ck-top-inset) var(--ck-bottom-inset); }
|
|
17
|
+
*
|
|
18
|
+
* chatkit's own `ChatThread` does that already.
|
|
19
|
+
*/
|
|
20
|
+
export declare function ChatScreen({ header, composer, footnote, children, fill, className, }: {
|
|
21
|
+
/** Floats over the top of the conversation. Give its buttons `ck-glass`. */
|
|
22
|
+
header?: ReactNode;
|
|
23
|
+
/** The composer (and anything that belongs with it: an error, a queue). */
|
|
24
|
+
composer: ReactNode;
|
|
25
|
+
/** One quiet line under the composer ("Answers can be wrong"). */
|
|
26
|
+
footnote?: ReactNode;
|
|
27
|
+
/** The conversation: a `ChatThread`, or an app's own scroller. */
|
|
28
|
+
children: ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* "parent" fills the box the app gives it. "viewport" takes the visual
|
|
31
|
+
* viewport — the height that shrinks when the phone keyboard opens, so the
|
|
32
|
+
* composer rides on top of the keyboard instead of behind it.
|
|
33
|
+
*/
|
|
34
|
+
fill?: "parent" | "viewport";
|
|
35
|
+
className?: string;
|
|
36
|
+
}): import("react").JSX.Element;
|
|
37
|
+
//# sourceMappingURL=Screen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Screen.d.ts","sourceRoot":"","sources":["../../src/react/Screen.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGhE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,IAAe,EACf,SAAS,GACV,EAAE;IACD,4EAA4E;IAC5E,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,2EAA2E;IAC3E,QAAQ,EAAE,SAAS,CAAC;IACpB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,kEAAkE;IAClE,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BA2CA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useLayoutEffect, useRef } from "react";
|
|
4
|
+
import { useViewportHeight } from "./hooks.js";
|
|
5
|
+
/**
|
|
6
|
+
* The chat as the whole screen, the way the ChatGPT and Claude apps lay it
|
|
7
|
+
* out: the conversation runs edge to edge and top to bottom, and the controls
|
|
8
|
+
* FLOAT over it — a see-through header at the top, the composer at the bottom
|
|
9
|
+
* — instead of each taking a strip of the screen away from the reading.
|
|
10
|
+
*
|
|
11
|
+
* Words scroll under both. They fade out as they pass beneath the header and
|
|
12
|
+
* the composer, so the controls stay legible without an opaque bar behind
|
|
13
|
+
* them; the last line of an answer always rests above the composer, never
|
|
14
|
+
* behind it (the scroller is padded by the measured height of each).
|
|
15
|
+
*
|
|
16
|
+
* The heights are published as `--ck-top-inset` and `--ck-bottom-inset` on
|
|
17
|
+
* the screen, so an app whose thread is its own scroller pads it with them:
|
|
18
|
+
*
|
|
19
|
+
* .my-thread { padding-block: var(--ck-top-inset) var(--ck-bottom-inset); }
|
|
20
|
+
*
|
|
21
|
+
* chatkit's own `ChatThread` does that already.
|
|
22
|
+
*/
|
|
23
|
+
export function ChatScreen({ header, composer, footnote, children, fill = "parent", className, }) {
|
|
24
|
+
const rootRef = useRef(null);
|
|
25
|
+
const headerRef = useRef(null);
|
|
26
|
+
const dockRef = useRef(null);
|
|
27
|
+
useViewportHeight(rootRef, fill === "viewport");
|
|
28
|
+
const hasHeader = header != null && header !== false;
|
|
29
|
+
// Measured, not guessed: the composer grows with a long draft, a staged
|
|
30
|
+
// screenshot or a dictation problem, and the reading has to move with it.
|
|
31
|
+
useLayoutEffect(() => {
|
|
32
|
+
const root = rootRef.current;
|
|
33
|
+
if (!root)
|
|
34
|
+
return;
|
|
35
|
+
const sync = () => {
|
|
36
|
+
root.style.setProperty("--ck-top-inset", `${headerRef.current?.offsetHeight ?? 0}px`);
|
|
37
|
+
root.style.setProperty("--ck-bottom-inset", `${dockRef.current?.offsetHeight ?? 0}px`);
|
|
38
|
+
};
|
|
39
|
+
sync();
|
|
40
|
+
if (typeof ResizeObserver === "undefined")
|
|
41
|
+
return;
|
|
42
|
+
const observer = new ResizeObserver(sync);
|
|
43
|
+
if (headerRef.current)
|
|
44
|
+
observer.observe(headerRef.current);
|
|
45
|
+
if (dockRef.current)
|
|
46
|
+
observer.observe(dockRef.current);
|
|
47
|
+
return () => observer.disconnect();
|
|
48
|
+
}, [hasHeader]);
|
|
49
|
+
const cls = ["ck-screen"];
|
|
50
|
+
if (fill === "viewport")
|
|
51
|
+
cls.push("ck-screen-viewport");
|
|
52
|
+
if (className)
|
|
53
|
+
cls.push(className);
|
|
54
|
+
return (_jsxs("div", { ref: rootRef, className: cls.join(" "), children: [_jsx("div", { className: "ck-screen-body", children: children }), hasHeader && (_jsx("div", { ref: headerRef, className: "ck-screen-header", children: _jsx("div", { className: "ck-screen-header-row", children: header }) })), _jsx("div", { ref: dockRef, className: "ck-screen-dock", children: _jsxs("div", { className: "ck-screen-column", children: [composer, footnote != null && _jsx("p", { className: "ck-screen-footnote", children: footnote })] }) })] }));
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=Screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Screen.js","sourceRoot":"","sources":["../../src/react/Screen.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,eAAe,EAAE,MAAM,EAAkB,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,IAAI,GAAG,QAAQ,EACf,SAAS,GAiBV;IACC,MAAM,OAAO,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACpD,iBAAiB,CAAC,OAAO,EAAE,IAAI,KAAK,UAAU,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,MAAM,IAAI,IAAI,IAAI,MAAM,KAAK,KAAK,CAAC;IAErD,wEAAwE;IACxE,0EAA0E;IAC1E,eAAe,CAAC,GAAG,EAAE;QACnB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,gBAAgB,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,YAAY,IAAI,CAAC,IAAI,CAAC,CAAC;YACtF,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,mBAAmB,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,YAAY,IAAI,CAAC,IAAI,CAAC,CAAC;QACzF,CAAC,CAAC;QACF,IAAI,EAAE,CAAC;QACP,IAAI,OAAO,cAAc,KAAK,WAAW;YAAE,OAAO;QAClD,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,SAAS,CAAC,OAAO;YAAE,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC3D,IAAI,OAAO,CAAC,OAAO;YAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvD,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;IACrC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC;IAC1B,IAAI,IAAI,KAAK,UAAU;QAAE,GAAG,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACxD,IAAI,SAAS;QAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnC,OAAO,CACL,eAAK,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,aACzC,cAAK,SAAS,EAAC,gBAAgB,YAAE,QAAQ,GAAO,EAC/C,SAAS,IAAI,CACZ,cAAK,GAAG,EAAE,SAAS,EAAE,SAAS,EAAC,kBAAkB,YAC/C,cAAK,SAAS,EAAC,sBAAsB,YAAE,MAAM,GAAO,GAChD,CACP,EACD,cAAK,GAAG,EAAE,OAAO,EAAE,SAAS,EAAC,gBAAgB,YAC3C,eAAK,SAAS,EAAC,kBAAkB,aAC9B,QAAQ,EACR,QAAQ,IAAI,IAAI,IAAI,YAAG,SAAS,EAAC,oBAAoB,YAAE,QAAQ,GAAK,IACjE,GACF,IACF,CACP,CAAC;AACJ,CAAC"}
|
package/dist/react/hooks.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export declare function useStickToBottom(changes: DependencyList, grew: number):
|
|
|
33
33
|
* keyboard (orangecat `ViewportHeightSync`, #1094). Rounded down: sub-pixel
|
|
34
34
|
* heights leave a 1px seam under the composer on some devices.
|
|
35
35
|
*/
|
|
36
|
-
export declare function useViewportHeight(target?: RefObject<HTMLElement | null
|
|
36
|
+
export declare function useViewportHeight(target?: RefObject<HTMLElement | null>, enabled?: boolean): void;
|
|
37
37
|
/** Grow a textarea to its content up to `max` px, keyed on the VALUE so a
|
|
38
38
|
* prefill, a dictated transcript or the clear after send resize it too.
|
|
39
39
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,SAAO;;iBAUhC,MAAM;EAYhB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM;;;;;;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,SAAO;;iBAUhC,MAAM;EAYhB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM;;;;;;EAgDrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,OAAO,UAAO,QAqBvF;AAED;;;;;;;;gFAQgF;AAChF,wBAAgB,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAM,QAqB/F"}
|
package/dist/react/hooks.js
CHANGED
|
@@ -51,6 +51,31 @@ export function useStickToBottom(changes, grew) {
|
|
|
51
51
|
if (following)
|
|
52
52
|
endRef.current?.scrollIntoView({ block: "end" });
|
|
53
53
|
}, [following, ...changes]);
|
|
54
|
+
// Pinned through SIZE changes too, not only new tokens: a composer that
|
|
55
|
+
// grows (a long draft, a staged screenshot), ChatScreen measuring its insets
|
|
56
|
+
// after the first paint, a rotated phone — each moves the bottom away, and
|
|
57
|
+
// a reader who was at the bottom must still be there afterwards.
|
|
58
|
+
const followingRef = useRef(following);
|
|
59
|
+
followingRef.current = following;
|
|
60
|
+
const observed = useRef(null);
|
|
61
|
+
const observer = useRef(null);
|
|
62
|
+
useLayoutEffect(() => {
|
|
63
|
+
const el = scrollRef.current;
|
|
64
|
+
if (el === observed.current || typeof ResizeObserver === "undefined")
|
|
65
|
+
return;
|
|
66
|
+
observer.current?.disconnect();
|
|
67
|
+
observed.current = el;
|
|
68
|
+
if (!el)
|
|
69
|
+
return;
|
|
70
|
+
observer.current = new ResizeObserver(() => {
|
|
71
|
+
if (followingRef.current)
|
|
72
|
+
el.scrollTop = el.scrollHeight;
|
|
73
|
+
});
|
|
74
|
+
observer.current.observe(el);
|
|
75
|
+
if (el.firstElementChild)
|
|
76
|
+
observer.current.observe(el.firstElementChild);
|
|
77
|
+
});
|
|
78
|
+
useEffect(() => () => observer.current?.disconnect(), []);
|
|
54
79
|
const previous = useRef(grew);
|
|
55
80
|
useEffect(() => {
|
|
56
81
|
if (grew > previous.current)
|
|
@@ -68,8 +93,10 @@ export function useStickToBottom(changes, grew) {
|
|
|
68
93
|
* keyboard (orangecat `ViewportHeightSync`, #1094). Rounded down: sub-pixel
|
|
69
94
|
* heights leave a 1px seam under the composer on some devices.
|
|
70
95
|
*/
|
|
71
|
-
export function useViewportHeight(target) {
|
|
96
|
+
export function useViewportHeight(target, enabled = true) {
|
|
72
97
|
useEffect(() => {
|
|
98
|
+
if (!enabled)
|
|
99
|
+
return;
|
|
73
100
|
const vv = window.visualViewport;
|
|
74
101
|
const el = target?.current ?? document.documentElement;
|
|
75
102
|
const sync = () => el.style.setProperty("--ck-viewport-height", `${Math.floor(vv?.height ?? window.innerHeight)}px`);
|
|
@@ -83,7 +110,7 @@ export function useViewportHeight(target) {
|
|
|
83
110
|
window.removeEventListener("orientationchange", sync);
|
|
84
111
|
el.style.removeProperty("--ck-viewport-height");
|
|
85
112
|
};
|
|
86
|
-
}, [target]);
|
|
113
|
+
}, [target, enabled]);
|
|
87
114
|
}
|
|
88
115
|
/** Grow a textarea to its content up to `max` px, keyed on the VALUE so a
|
|
89
116
|
* prefill, a dictated transcript or the clear after send resize it too.
|
package/dist/react/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { Composer, DEFAULT_COMPOSER_LABELS } from "./Composer.js";
|
|
|
11
11
|
export type { ComposerProps, ComposerLabels, ComposerLabelOverrides, ComposerVoice, } from "./Composer.js";
|
|
12
12
|
export { ChatThread, ChatMessage, ChatReplies, ChatStarters, DEFAULT_THREAD_LABELS, } from "./Thread.js";
|
|
13
13
|
export type { ChatMessageData, ChatSpeaker, LiveTurn, Starter, ThreadLabels } from "./Thread.js";
|
|
14
|
+
export { ChatScreen } from "./Screen.js";
|
|
14
15
|
export { Markdown, defaultRenderLink } from "./Markdown.js";
|
|
15
16
|
export type { CitationMap, RenderLink } from "./Markdown.js";
|
|
16
17
|
export { useDictation } from "./use-dictation.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EACV,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,UAAU,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACjG,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC5D,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACpG,OAAO,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AACzE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EACV,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,UAAU,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC5D,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACpG,OAAO,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AACzE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/react/index.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export { Composer, DEFAULT_COMPOSER_LABELS } from "./Composer.js";
|
|
11
11
|
export { ChatThread, ChatMessage, ChatReplies, ChatStarters, DEFAULT_THREAD_LABELS, } from "./Thread.js";
|
|
12
|
+
export { ChatScreen } from "./Screen.js";
|
|
12
13
|
export { Markdown, defaultRenderLink } from "./Markdown.js";
|
|
13
14
|
export { useDictation } from "./use-dictation.js";
|
|
14
15
|
export { AttachMenu, DEFAULT_ATTACH_MENU_LABELS } from "./AttachMenu.js";
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAOlE,OAAO,EACL,UAAU,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAOlE,OAAO,EACL,UAAU,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitbaum/chatkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "One chat for every product: a composer with a microphone that always works, a thread that does not fight the reader, messages with copy and retry, and LLM markdown \u2014 the fleet's chat standard as a package.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Cato",
|
package/styles.css
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
/* Defaults at ZERO specificity on the root: an app's own :root (or any
|
|
21
21
|
container) rule setting a --ck-* variable always wins. Declaring these on
|
|
22
22
|
the chat's elements instead would silently override the app. */
|
|
23
|
+
--ck-page: hsl(var(--surface-page, 0 0% 99%));
|
|
23
24
|
--ck-bg: hsl(var(--surface-base, 0 0% 100%));
|
|
24
25
|
--ck-raised: hsl(var(--surface-raised, 0 0% 96%));
|
|
25
26
|
--ck-overlay: hsl(var(--surface-overlay, 0 0% 98%));
|
|
@@ -43,8 +44,15 @@
|
|
|
43
44
|
--ck-text: 1rem;
|
|
44
45
|
--ck-leading: 1.6;
|
|
45
46
|
--ck-target: 2.75rem;
|
|
47
|
+
/* ChatScreen: the reading column, and the margin it keeps from the edge. */
|
|
48
|
+
--ck-measure: 48rem;
|
|
49
|
+
--ck-gutter: 1rem;
|
|
50
|
+
/* The person's own words. Neutral, not the accent: the accent is for the
|
|
51
|
+
one thing to press, and a column of tinted pills spent it on every turn. */
|
|
52
|
+
--ck-bubble: var(--ck-raised);
|
|
46
53
|
}
|
|
47
54
|
|
|
55
|
+
.ck-screen,
|
|
48
56
|
.ck-composer-wrap,
|
|
49
57
|
.ck-thread-wrap,
|
|
50
58
|
.ck-starters,
|
|
@@ -53,6 +61,7 @@
|
|
|
53
61
|
color: var(--ck-fg);
|
|
54
62
|
}
|
|
55
63
|
|
|
64
|
+
.ck-screen *,
|
|
56
65
|
.ck-composer-wrap *,
|
|
57
66
|
.ck-thread-wrap *,
|
|
58
67
|
.ck-starters *,
|
|
@@ -468,7 +477,7 @@
|
|
|
468
477
|
max-width: min(85%, 42rem);
|
|
469
478
|
padding: 0.625rem 1rem;
|
|
470
479
|
border-radius: calc(var(--ck-radius) * 1.25);
|
|
471
|
-
background: var(--ck-
|
|
480
|
+
background: var(--ck-bubble);
|
|
472
481
|
color: var(--ck-fg);
|
|
473
482
|
font-size: var(--ck-text);
|
|
474
483
|
line-height: var(--ck-leading);
|
|
@@ -590,6 +599,156 @@
|
|
|
590
599
|
box-shadow: 0 6px 20px -8px rgb(0 0 0 / 0.35);
|
|
591
600
|
}
|
|
592
601
|
|
|
602
|
+
/* ── screen ─────────────────────────────────────────────────────────────
|
|
603
|
+
The whole display is the conversation; header and composer float over it.
|
|
604
|
+
--ck-top-inset / --ck-bottom-inset are measured by ChatScreen. */
|
|
605
|
+
.ck-screen {
|
|
606
|
+
position: relative;
|
|
607
|
+
display: flex;
|
|
608
|
+
flex-direction: column;
|
|
609
|
+
height: 100%;
|
|
610
|
+
min-height: 0;
|
|
611
|
+
min-width: 0;
|
|
612
|
+
overflow: hidden;
|
|
613
|
+
background: var(--ck-page);
|
|
614
|
+
}
|
|
615
|
+
.ck-screen-viewport {
|
|
616
|
+
height: var(--ck-viewport-height, 100dvh);
|
|
617
|
+
}
|
|
618
|
+
.ck-screen-body {
|
|
619
|
+
position: relative;
|
|
620
|
+
display: flex;
|
|
621
|
+
flex: 1;
|
|
622
|
+
flex-direction: column;
|
|
623
|
+
min-height: 0;
|
|
624
|
+
min-width: 0;
|
|
625
|
+
}
|
|
626
|
+
/* Words pass under the header and fade as they do: the page colour at the
|
|
627
|
+
very top, nothing by the bottom of the row. No bar, no border. */
|
|
628
|
+
.ck-screen-header {
|
|
629
|
+
position: absolute;
|
|
630
|
+
inset: 0 0 auto;
|
|
631
|
+
z-index: 3;
|
|
632
|
+
padding: env(safe-area-inset-top, 0px) var(--ck-gutter) 0;
|
|
633
|
+
background: linear-gradient(
|
|
634
|
+
to bottom,
|
|
635
|
+
var(--ck-page) 0%,
|
|
636
|
+
color-mix(in srgb, var(--ck-page) 75%, transparent) 55%,
|
|
637
|
+
transparent 100%
|
|
638
|
+
);
|
|
639
|
+
pointer-events: none;
|
|
640
|
+
}
|
|
641
|
+
.ck-screen-header-row {
|
|
642
|
+
display: flex;
|
|
643
|
+
align-items: center;
|
|
644
|
+
gap: 0.5rem;
|
|
645
|
+
min-width: 0;
|
|
646
|
+
min-height: 3.5rem;
|
|
647
|
+
padding-block: 0.375rem;
|
|
648
|
+
}
|
|
649
|
+
.ck-screen-header-row > * {
|
|
650
|
+
pointer-events: auto;
|
|
651
|
+
}
|
|
652
|
+
.ck-screen-dock {
|
|
653
|
+
position: absolute;
|
|
654
|
+
inset: auto 0 0;
|
|
655
|
+
z-index: 3;
|
|
656
|
+
padding: 1.5rem var(--ck-gutter) calc(0.5rem + env(safe-area-inset-bottom, 0px));
|
|
657
|
+
background: linear-gradient(to top, var(--ck-page) 0%, var(--ck-page) 40%, transparent 100%);
|
|
658
|
+
pointer-events: none;
|
|
659
|
+
}
|
|
660
|
+
.ck-screen-column {
|
|
661
|
+
display: flex;
|
|
662
|
+
flex-direction: column;
|
|
663
|
+
gap: 0.5rem;
|
|
664
|
+
width: 100%;
|
|
665
|
+
max-width: var(--ck-measure);
|
|
666
|
+
margin-inline: auto;
|
|
667
|
+
pointer-events: auto;
|
|
668
|
+
}
|
|
669
|
+
.ck-screen-footnote {
|
|
670
|
+
margin: 0;
|
|
671
|
+
color: var(--ck-muted);
|
|
672
|
+
font-size: 0.75rem;
|
|
673
|
+
line-height: 1.4;
|
|
674
|
+
text-align: center;
|
|
675
|
+
}
|
|
676
|
+
/* The composer as a floating pill: see-through enough to show the words
|
|
677
|
+
passing under it, solid enough to type on. */
|
|
678
|
+
.ck-screen-dock .ck-composer {
|
|
679
|
+
border-color: color-mix(in srgb, var(--ck-line-2) 70%, transparent);
|
|
680
|
+
border-radius: 1.75rem;
|
|
681
|
+
background: color-mix(in srgb, var(--ck-bg) 86%, transparent);
|
|
682
|
+
-webkit-backdrop-filter: blur(20px) saturate(1.4);
|
|
683
|
+
backdrop-filter: blur(20px) saturate(1.4);
|
|
684
|
+
box-shadow: 0 6px 28px -12px rgb(0 0 0 / 0.28);
|
|
685
|
+
}
|
|
686
|
+
.ck-screen-dock .ck-voice-bar {
|
|
687
|
+
border-radius: 1.75rem;
|
|
688
|
+
}
|
|
689
|
+
/* The thread scrolls the full width (the scrollbar sits at the screen's
|
|
690
|
+
edge, and a swipe anywhere moves it); its column keeps a reading measure. */
|
|
691
|
+
.ck-screen .ck-thread {
|
|
692
|
+
padding: var(--ck-top-inset, 0px) var(--ck-gutter) calc(var(--ck-bottom-inset, 0px) + 0.75rem);
|
|
693
|
+
scroll-padding-top: var(--ck-top-inset, 0px);
|
|
694
|
+
scroll-padding-bottom: var(--ck-bottom-inset, 0px);
|
|
695
|
+
}
|
|
696
|
+
.ck-screen .ck-thread-inner {
|
|
697
|
+
width: 100%;
|
|
698
|
+
max-width: var(--ck-measure);
|
|
699
|
+
margin-inline: auto;
|
|
700
|
+
}
|
|
701
|
+
.ck-screen .ck-jump {
|
|
702
|
+
bottom: calc(var(--ck-bottom-inset, 0px) + 0.5rem);
|
|
703
|
+
z-index: 4;
|
|
704
|
+
}
|
|
705
|
+
.ck-screen-body > .ck-starters,
|
|
706
|
+
.ck-screen-body > .ck-thread-loading {
|
|
707
|
+
flex: 1;
|
|
708
|
+
justify-content: center;
|
|
709
|
+
width: 100%;
|
|
710
|
+
max-width: calc(var(--ck-measure) + 2 * var(--ck-gutter));
|
|
711
|
+
margin-inline: auto;
|
|
712
|
+
padding: var(--ck-top-inset, 0px) var(--ck-gutter) var(--ck-bottom-inset, 0px);
|
|
713
|
+
overflow-y: auto;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/* A control floating over the conversation: a frosted pill, the way the
|
|
717
|
+
header buttons sit over the words in the ChatGPT app. For an app's own
|
|
718
|
+
header buttons inside ChatScreen. */
|
|
719
|
+
.ck-glass {
|
|
720
|
+
display: inline-flex;
|
|
721
|
+
align-items: center;
|
|
722
|
+
justify-content: center;
|
|
723
|
+
gap: 0.375rem;
|
|
724
|
+
min-width: var(--ck-target);
|
|
725
|
+
min-height: var(--ck-target);
|
|
726
|
+
padding: 0 0.75rem;
|
|
727
|
+
border: 1px solid color-mix(in srgb, var(--ck-line-2) 60%, transparent);
|
|
728
|
+
border-radius: 999px;
|
|
729
|
+
background: color-mix(in srgb, var(--ck-bg) 70%, transparent);
|
|
730
|
+
-webkit-backdrop-filter: blur(16px) saturate(1.4);
|
|
731
|
+
backdrop-filter: blur(16px) saturate(1.4);
|
|
732
|
+
box-shadow: 0 2px 10px -4px rgb(0 0 0 / 0.18);
|
|
733
|
+
color: var(--ck-fg);
|
|
734
|
+
font: inherit;
|
|
735
|
+
font-size: 0.9375rem;
|
|
736
|
+
cursor: pointer;
|
|
737
|
+
}
|
|
738
|
+
.ck-glass:hover {
|
|
739
|
+
background: color-mix(in srgb, var(--ck-bg) 88%, transparent);
|
|
740
|
+
}
|
|
741
|
+
.ck-glass:focus-visible {
|
|
742
|
+
outline: 2px solid var(--ck-accent);
|
|
743
|
+
outline-offset: 2px;
|
|
744
|
+
}
|
|
745
|
+
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
|
|
746
|
+
.ck-glass,
|
|
747
|
+
.ck-screen-dock .ck-composer {
|
|
748
|
+
background: var(--ck-bg);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
593
752
|
/* markdown: 16px, readable measure, no leaked ** or > */
|
|
594
753
|
.ck-md {
|
|
595
754
|
min-width: 0;
|