@bitbaum/chatkit 0.9.0 → 0.11.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 +63 -7
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/react/AnswerActions.d.ts +39 -0
- package/dist/react/AnswerActions.d.ts.map +1 -0
- package/dist/react/AnswerActions.js +50 -0
- package/dist/react/AnswerActions.js.map +1 -0
- package/dist/react/AttachMenu.d.ts +11 -2
- package/dist/react/AttachMenu.d.ts.map +1 -1
- package/dist/react/AttachMenu.js +21 -24
- package/dist/react/AttachMenu.js.map +1 -1
- package/dist/react/Markdown.d.ts +20 -2
- package/dist/react/Markdown.d.ts.map +1 -1
- package/dist/react/Markdown.js +49 -12
- package/dist/react/Markdown.js.map +1 -1
- package/dist/react/RichBlock.d.ts +6 -0
- package/dist/react/RichBlock.d.ts.map +1 -0
- package/dist/react/RichBlock.js +28 -0
- package/dist/react/RichBlock.js.map +1 -0
- package/dist/react/Sheet.d.ts +20 -0
- package/dist/react/Sheet.d.ts.map +1 -0
- package/dist/react/Sheet.js +37 -0
- package/dist/react/Sheet.js.map +1 -0
- package/dist/react/Thread.d.ts +19 -2
- package/dist/react/Thread.d.ts.map +1 -1
- package/dist/react/Thread.js +10 -8
- package/dist/react/Thread.js.map +1 -1
- package/dist/react/icons.d.ts +3 -0
- package/dist/react/icons.d.ts.map +1 -1
- package/dist/react/icons.js +3 -0
- package/dist/react/icons.js.map +1 -1
- package/dist/react/index.d.ts +7 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +5 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/use-speech.d.ts +25 -0
- package/dist/react/use-speech.d.ts.map +1 -0
- package/dist/react/use-speech.js +66 -0
- package/dist/react/use-speech.js.map +1 -0
- package/dist/replies.d.ts +6 -3
- package/dist/replies.d.ts.map +1 -1
- package/dist/replies.js +8 -5
- package/dist/replies.js.map +1 -1
- package/dist/rich.d.ts +43 -0
- package/dist/rich.d.ts.map +1 -0
- package/dist/rich.js +100 -0
- package/dist/rich.js.map +1 -0
- package/dist/speech.d.ts +17 -0
- package/dist/speech.d.ts.map +1 -0
- package/dist/speech.js +82 -0
- package/dist/speech.js.map +1 -0
- package/package.json +1 -1
- package/styles.css +313 -0
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.11.0
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
**Install releases from npm, never a commit or a branch.** A semver range is
|
|
@@ -121,6 +121,31 @@ while a turn runs. Pass `replies` on a message to supply your own instead.
|
|
|
121
121
|
An app with its own thread uses `extractReplies(text)` and `<ChatReplies>`, so
|
|
122
122
|
the buttons look and behave the same everywhere.
|
|
123
123
|
|
|
124
|
+
The model leads. The instruction asks for replies on EVERY answer, the
|
|
125
|
+
recommended next step first, and the first button is drawn as the lead
|
|
126
|
+
(`ck-reply-lead`): on a phone the answer is read and the next move is one
|
|
127
|
+
tap, the way Grok does it. Only an answer that ends the conversation has no
|
|
128
|
+
buttons.
|
|
129
|
+
|
|
130
|
+
### Under every answer — Copy, Listen, Share
|
|
131
|
+
|
|
132
|
+
`AnswerActions` is the row under an answer, the same in every product:
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
<AnswerActions text={answer} onRetry={retry} speaker={studioVoice} share={{ url }}>
|
|
136
|
+
<YourOwnButton />
|
|
137
|
+
</AnswerActions>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Copy copies the markdown. Listen reads the answer aloud as prose (headings,
|
|
141
|
+
emphasis, citations and code fences stripped — `plainTextForSpeech`) with the
|
|
142
|
+
browser's own voice, or with the `speaker` you pass (`{ speak(text), cancel() }`
|
|
143
|
+
— loki hands in its studio voice); while it reads, the row becomes a small
|
|
144
|
+
player: Stop and the time so far. Share opens the system share sheet with the
|
|
145
|
+
answer's prose (or what you pass), only where one exists. A button that does
|
|
146
|
+
nothing is never shown. `ChatThread` renders it under every answer; pass
|
|
147
|
+
`speaker` and `share` through.
|
|
148
|
+
|
|
124
149
|
### The next message while a turn runs
|
|
125
150
|
|
|
126
151
|
`queue` keeps Send live while `sending`, beside Stop, and the placeholder
|
|
@@ -154,7 +179,11 @@ Because Files takes anything, `isTextFile` decides afterwards what can be read
|
|
|
154
179
|
inline; a PDF gets a sentence, not a prompt full of bytes. With a mouse the
|
|
155
180
|
paperclip opens the file dialog directly — on a desktop all three are the
|
|
156
181
|
same dialog. A box that is not chatkit's composer renders `<AttachMenu
|
|
157
|
-
onFiles={…} />` rather than a bare `<input type="file">`.
|
|
182
|
+
onFiles={…} />` rather than a bare `<input type="file">`. An app with more to
|
|
183
|
+
bring into a message than files — one of the person's own things, a note the
|
|
184
|
+
model reads every time — passes `extra={(close) => <YourRows />}`: the rows
|
|
185
|
+
sit under the three sources in the same sheet, and the sheet then opens on a
|
|
186
|
+
mouse too, since a file dialog cannot hold them. Labels:
|
|
158
187
|
`labels={{ attachMenu: { title, close, sources: { camera, photos, files } } }}`.
|
|
159
188
|
|
|
160
189
|
### Picking files anywhere — `@bitbaum/chatkit/attach`
|
|
@@ -213,11 +242,14 @@ three unprompted:
|
|
|
213
242
|
opening with a bold lead — renders as a badge (the number, or the emoji the
|
|
214
243
|
lead opens with: `**🤖 Robot.** …`), the name, and the body under it.
|
|
215
244
|
- **A table is a table**, with the header row kept.
|
|
216
|
-
- **Sources are listed once**,
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
245
|
+
- **Sources are listed once**, under the answer, from the handles the text
|
|
246
|
+
cites and the `citations` map you pass (`{ F1: { label, detail, href? } }`).
|
|
247
|
+
On a mouse they are a row of chips; on a touch screen ONE "Sources · n"
|
|
248
|
+
button opens a sheet with every record — label, detail, link — because a
|
|
249
|
+
row of chips on a phone was a row of cut-off words. `renderCitation`
|
|
250
|
+
replaces the in-text superscript with your own; `renderSources` replaces
|
|
251
|
+
the row with your own; `sources={false}` drops it. `SourcesRow` and `Sheet`
|
|
252
|
+
are exported for an app that lists sources from elsewhere.
|
|
221
253
|
|
|
222
254
|
`demo/screen.html` shows all of it.
|
|
223
255
|
|
|
@@ -280,3 +312,27 @@ pnpm run verify # everything CI runs
|
|
|
280
312
|
```
|
|
281
313
|
|
|
282
314
|
MIT © Cato
|
|
315
|
+
|
|
316
|
+
### Visual answers (0.11)
|
|
317
|
+
|
|
318
|
+
Append `RICH_ANSWERS_INSTRUCTION` from `@bitbaum/chatkit` to a conversational
|
|
319
|
+
system prompt, alongside `REPLIES_INSTRUCTION`. The model can place fenced
|
|
320
|
+
`chat_ui` JSON blocks inline in its answer: galleries with captions and a
|
|
321
|
+
full-size image sheet, dependency diagrams, recommendation callouts, and
|
|
322
|
+
single-choice follow-ups. Markdown tables and step lists remain available.
|
|
323
|
+
`Markdown` renders these automatically; pass `onReply={send}` for choice forms.
|
|
324
|
+
`ChatThread` wires that callback only on the latest answer and disables it
|
|
325
|
+
while another turn is running. Historical forms remain readable.
|
|
326
|
+
|
|
327
|
+
Products keep their own model routing, tools, evidence rules, auth and `--ck-*`
|
|
328
|
+
tokens. For a JSON-output assistant such as Heidi, ask for rich blocks only
|
|
329
|
+
inside its free-text explanation string, never outside the answer envelope.
|
|
330
|
+
Images must come from supplied context or tool results. No HTML or executable
|
|
331
|
+
SVG is accepted. Images suppress referrers and broken thumbnails retain their
|
|
332
|
+
text labels. Blocks are bounded and validated; incomplete/invalid blocks are
|
|
333
|
+
hidden, so always include the takeaway in ordinary prose too. Diagram edges
|
|
334
|
+
retain their direction and labels, including branches and cycles.
|
|
335
|
+
|
|
336
|
+
Release this package before updating consumer lockfiles to `^0.11.0`.
|
|
337
|
+
Run `pnpm run verify`; `demo/index.html` is the visual reference in light/dark
|
|
338
|
+
and at phone width. The diagram and gallery artwork in the demo is a fixture.
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type Speaker } from "../speech.js";
|
|
3
|
+
export type AnswerActionsLabels = {
|
|
4
|
+
copy: string;
|
|
5
|
+
copied: string;
|
|
6
|
+
listen: string;
|
|
7
|
+
stop: string;
|
|
8
|
+
share: string;
|
|
9
|
+
retry: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const DEFAULT_ANSWER_ACTIONS_LABELS: AnswerActionsLabels;
|
|
12
|
+
/**
|
|
13
|
+
* The row under an answer — Copy, Listen, Share, Try again — the same in every
|
|
14
|
+
* product, so an answer is handled the same way wherever it was written.
|
|
15
|
+
*
|
|
16
|
+
* Every button is one that works here: Listen only where something can
|
|
17
|
+
* speak, Share only where the system share sheet exists (phones), Try again
|
|
18
|
+
* only when the caller can re-ask. A button that does nothing is worse than
|
|
19
|
+
* a missing one. While an answer is being read, a small player takes the
|
|
20
|
+
* row's place: a stop and the time read so far.
|
|
21
|
+
*
|
|
22
|
+
* `children` are the app's own buttons after these (loki's thumbs-down).
|
|
23
|
+
*/
|
|
24
|
+
export declare function AnswerActions({ text, onRetry, speaker, share, labels: overrides, children, }: {
|
|
25
|
+
/** The answer's markdown. Copied as written; read as prose. */
|
|
26
|
+
text: string;
|
|
27
|
+
onRetry?: () => void;
|
|
28
|
+
/** The app's voice. Without it, the browser's; without either, no Listen. */
|
|
29
|
+
speaker?: Speaker | null;
|
|
30
|
+
/** What the share sheet gets. Defaults to the answer's prose. `false` hides Share. */
|
|
31
|
+
share?: {
|
|
32
|
+
title?: string;
|
|
33
|
+
text?: string;
|
|
34
|
+
url?: string;
|
|
35
|
+
} | false;
|
|
36
|
+
labels?: Partial<AnswerActionsLabels>;
|
|
37
|
+
children?: ReactNode;
|
|
38
|
+
}): import("react").JSX.Element;
|
|
39
|
+
//# sourceMappingURL=AnswerActions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnswerActions.d.ts","sourceRoot":"","sources":["../../src/react/AnswerActions.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAsB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAOhE,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,mBAO3C,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,OAAO,EACP,OAAO,EACP,KAAK,EACL,MAAM,EAAE,SAAS,EACjB,QAAQ,GACT,EAAE;IACD,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,sFAAsF;IACtF,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;IAChE,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,+BAoFA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { richAnswerText } from "../rich.js";
|
|
4
|
+
import { useSyncExternalStore } from "react";
|
|
5
|
+
import { formatElapsed } from "../composer.js";
|
|
6
|
+
import { plainTextForSpeech } from "../speech.js";
|
|
7
|
+
import { useClipboard } from "./hooks.js";
|
|
8
|
+
import { useSpeech } from "./use-speech.js";
|
|
9
|
+
import { IconCheck, IconCopy, IconRetry, IconShare, IconSpeaker, IconStop } from "./icons.js";
|
|
10
|
+
const noSubscribe = () => () => { };
|
|
11
|
+
export const DEFAULT_ANSWER_ACTIONS_LABELS = {
|
|
12
|
+
copy: "Copy",
|
|
13
|
+
copied: "Copied",
|
|
14
|
+
listen: "Listen",
|
|
15
|
+
stop: "Stop",
|
|
16
|
+
share: "Share",
|
|
17
|
+
retry: "Try again",
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The row under an answer — Copy, Listen, Share, Try again — the same in every
|
|
21
|
+
* product, so an answer is handled the same way wherever it was written.
|
|
22
|
+
*
|
|
23
|
+
* Every button is one that works here: Listen only where something can
|
|
24
|
+
* speak, Share only where the system share sheet exists (phones), Try again
|
|
25
|
+
* only when the caller can re-ask. A button that does nothing is worse than
|
|
26
|
+
* a missing one. While an answer is being read, a small player takes the
|
|
27
|
+
* row's place: a stop and the time read so far.
|
|
28
|
+
*
|
|
29
|
+
* `children` are the app's own buttons after these (loki's thumbs-down).
|
|
30
|
+
*/
|
|
31
|
+
export function AnswerActions({ text, onRetry, speaker, share, labels: overrides, children, }) {
|
|
32
|
+
const labels = { ...DEFAULT_ANSWER_ACTIONS_LABELS, ...overrides };
|
|
33
|
+
const { copied, copy } = useClipboard();
|
|
34
|
+
const speech = useSpeech(speaker);
|
|
35
|
+
const canShare = useSyncExternalStore(noSubscribe, () => typeof navigator !== "undefined" && typeof navigator.share === "function", () => false);
|
|
36
|
+
if (speech.speaking) {
|
|
37
|
+
return (_jsxs("div", { className: "ck-turn-actions ck-player", role: "status", "aria-live": "polite", children: [_jsxs("button", { type: "button", className: "ck-action ck-action-stop", onClick: speech.stop, "aria-label": labels.stop, children: [_jsx(IconStop, {}), _jsx("span", { children: labels.stop })] }), _jsx("span", { className: "ck-player-wave", "aria-hidden": true, children: Array.from({ length: 7 }).map((_, i) => (_jsx("span", {}, i))) }), _jsx("span", { className: "ck-player-time", children: formatElapsed(speech.elapsed) })] }));
|
|
38
|
+
}
|
|
39
|
+
return (_jsxs("div", { className: "ck-turn-actions", children: [_jsxs("button", { type: "button", className: "ck-action", onClick: () => copy(richAnswerText(text)), "aria-label": copied ? labels.copied : labels.copy, children: [copied ? _jsx(IconCheck, {}) : _jsx(IconCopy, {}), _jsx("span", { children: copied ? labels.copied : labels.copy })] }), speech.supported && (_jsxs("button", { type: "button", className: "ck-action", onClick: () => speech.speak(text), "aria-label": labels.listen, children: [_jsx(IconSpeaker, {}), _jsx("span", { children: labels.listen })] })), canShare && share !== false && (_jsxs("button", { type: "button", className: "ck-action",
|
|
40
|
+
// A dismissed share sheet rejects; that is the person changing their
|
|
41
|
+
// mind, not an error to report.
|
|
42
|
+
onClick: () => void navigator
|
|
43
|
+
.share({
|
|
44
|
+
title: share?.title,
|
|
45
|
+
text: share?.text ?? plainTextForSpeech(text),
|
|
46
|
+
url: share?.url,
|
|
47
|
+
})
|
|
48
|
+
.catch(() => { }), "aria-label": labels.share, children: [_jsx(IconShare, {}), _jsx("span", { children: labels.share })] })), onRetry && (_jsxs("button", { type: "button", className: "ck-action", onClick: onRetry, children: [_jsx(IconRetry, {}), _jsx("span", { children: labels.retry })] })), children] }));
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=AnswerActions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnswerActions.js","sourceRoot":"","sources":["../../src/react/AnswerActions.tsx"],"names":[],"mappings":"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"}
|
|
@@ -21,9 +21,13 @@ export declare const DEFAULT_ATTACH_MENU_LABELS: AttachMenuLabels;
|
|
|
21
21
|
* browser supplies Escape, the focus trap and focus restore.
|
|
22
22
|
*
|
|
23
23
|
* Every app that attaches anything gets this from the composer. An app with a
|
|
24
|
-
* custom box renders `<AttachMenu>` itself rather than a bare file input
|
|
24
|
+
* custom box renders `<AttachMenu>` itself rather than a bare file input, and
|
|
25
|
+
* an app with more to bring into a message than files — one of the person's
|
|
26
|
+
* own things, a note the model reads every time — puts those rows in `extra`:
|
|
27
|
+
* they sit under Camera · Photos · Files in the same sheet, on every pointer,
|
|
28
|
+
* since a mouse cannot reach them through a file dialog.
|
|
25
29
|
*/
|
|
26
|
-
export declare function AttachMenu({ onFiles, disabled, labels, sources, trigger, }: {
|
|
30
|
+
export declare function AttachMenu({ onFiles, disabled, labels, sources, trigger, extra, onOpenChange, }: {
|
|
27
31
|
onFiles: (files: FileList | null) => void;
|
|
28
32
|
disabled?: boolean;
|
|
29
33
|
labels?: AttachMenuLabels;
|
|
@@ -33,5 +37,10 @@ export declare function AttachMenu({ onFiles, disabled, labels, sources, trigger
|
|
|
33
37
|
/** The button's content. Defaults to a paperclip icon; an uploader passes
|
|
34
38
|
* its own ("Add photo"). The button keeps chatkit's 44px target. */
|
|
35
39
|
trigger?: ReactNode;
|
|
40
|
+
/** The app's own rows under the three sources (see above). With it the
|
|
41
|
+
* sheet opens on every pointer. A row that should close the sheet calls
|
|
42
|
+
* the `close` it is given. */
|
|
43
|
+
extra?: (close: () => void) => ReactNode;
|
|
44
|
+
onOpenChange?: (open: boolean) => void;
|
|
36
45
|
}): import("react").JSX.Element;
|
|
37
46
|
//# sourceMappingURL=AttachMenu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttachMenu.d.ts","sourceRoot":"","sources":["../../src/react/AttachMenu.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"AttachMenu.d.ts","sourceRoot":"","sources":["../../src/react/AttachMenu.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAI3E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,gBAKxC,CAAC;AASF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,QAAgB,EAChB,MAAmC,EACnC,OAAiB,EACjB,OAAO,EACP,KAAK,EACL,YAAY,GACb,EAAE;IACD,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B;8EAC0E;IAC1E,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAClC;yEACqE;IACrE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;mCAE+B;IAC/B,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,SAAS,CAAC;IACzC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC,+BAuEA"}
|
package/dist/react/AttachMenu.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { useRef } from "react";
|
|
3
|
+
import { useRef, useState } from "react";
|
|
4
4
|
import { ATTACH_SOURCE_INPUT } from "../attachments.js";
|
|
5
|
-
import { IconCamera, IconFileUp, IconImage, IconPaperclip
|
|
5
|
+
import { IconCamera, IconFileUp, IconImage, IconPaperclip } from "./icons.js";
|
|
6
|
+
import { Sheet, prefersSheet } from "./Sheet.js";
|
|
6
7
|
export const DEFAULT_ATTACH_MENU_LABELS = {
|
|
7
8
|
attach: "Attach a screenshot or file",
|
|
8
9
|
title: "Add to message",
|
|
@@ -15,11 +16,6 @@ const ICONS = {
|
|
|
15
16
|
photos: IconImage,
|
|
16
17
|
files: IconFileUp,
|
|
17
18
|
};
|
|
18
|
-
/** A touch screen gets the sheet; a mouse gets the file dialog in one click,
|
|
19
|
-
* because on a desktop Camera / Photos / Files are all the same dialog. */
|
|
20
|
-
function prefersSheet() {
|
|
21
|
-
return typeof window !== "undefined" && window.matchMedia?.("(pointer: coarse)").matches;
|
|
22
|
-
}
|
|
23
19
|
/**
|
|
24
20
|
* The paperclip, and what it opens on a phone: a sheet with Camera, Photos and
|
|
25
21
|
* Files — one input each. See `ATTACH_SOURCE_INPUT` for why three inputs and
|
|
@@ -32,20 +28,27 @@ function prefersSheet() {
|
|
|
32
28
|
* browser supplies Escape, the focus trap and focus restore.
|
|
33
29
|
*
|
|
34
30
|
* Every app that attaches anything gets this from the composer. An app with a
|
|
35
|
-
* custom box renders `<AttachMenu>` itself rather than a bare file input
|
|
31
|
+
* custom box renders `<AttachMenu>` itself rather than a bare file input, and
|
|
32
|
+
* an app with more to bring into a message than files — one of the person's
|
|
33
|
+
* own things, a note the model reads every time — puts those rows in `extra`:
|
|
34
|
+
* they sit under Camera · Photos · Files in the same sheet, on every pointer,
|
|
35
|
+
* since a mouse cannot reach them through a file dialog.
|
|
36
36
|
*/
|
|
37
|
-
export function AttachMenu({ onFiles, disabled = false, labels = DEFAULT_ATTACH_MENU_LABELS, sources = SOURCES, trigger, }) {
|
|
37
|
+
export function AttachMenu({ onFiles, disabled = false, labels = DEFAULT_ATTACH_MENU_LABELS, sources = SOURCES, trigger, extra, onOpenChange, }) {
|
|
38
38
|
const inputs = useRef({});
|
|
39
|
-
const
|
|
40
|
-
const
|
|
39
|
+
const [sheetOpen, setSheetOpen] = useState(false);
|
|
40
|
+
const setOpen = (next) => {
|
|
41
|
+
setSheetOpen(next);
|
|
42
|
+
onOpenChange?.(next);
|
|
43
|
+
};
|
|
44
|
+
const close = () => setOpen(false);
|
|
41
45
|
const pick = (source) => {
|
|
42
46
|
close();
|
|
43
47
|
inputs.current[source]?.click();
|
|
44
48
|
};
|
|
45
49
|
const open = () => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
d.showModal();
|
|
50
|
+
if (extra || (sources.length > 1 && prefersSheet()))
|
|
51
|
+
setOpen(true);
|
|
49
52
|
// A mouse gets the broadest picker offered: Files when it is one of the
|
|
50
53
|
// sources, else the last one (Photos, for an image uploader).
|
|
51
54
|
else
|
|
@@ -56,15 +59,9 @@ export function AttachMenu({ onFiles, disabled = false, labels = DEFAULT_ATTACH_
|
|
|
56
59
|
}, type: "file", hidden: true, multiple: source !== "camera", "data-ck-source": source, ...ATTACH_SOURCE_INPUT[source], onChange: (e) => {
|
|
57
60
|
onFiles(e.target.files);
|
|
58
61
|
e.target.value = "";
|
|
59
|
-
} }, source))), _jsx("button", { type: "button", className: trigger ? "ck-attach-trigger" : "ck-icon-btn", onClick: open, disabled: disabled, "aria-label": labels.attach, "aria-haspopup": "dialog", title: labels.attach, children: trigger ?? _jsx(IconPaperclip, {}) }),
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (e.target === e.currentTarget)
|
|
64
|
-
close();
|
|
65
|
-
}, children: _jsxs("div", { className: "ck-sheet-panel", children: [_jsxs("div", { className: "ck-sheet-head", children: [_jsx("span", { className: "ck-sheet-title", children: labels.title }), _jsx("button", { type: "button", className: "ck-icon-btn ck-sheet-close", onClick: close, "aria-label": labels.close, title: labels.close, children: _jsx(IconX, {}) })] }), _jsx("div", { className: "ck-attach-sources", children: sources.map((source) => {
|
|
66
|
-
const Icon = ICONS[source];
|
|
67
|
-
return (_jsxs("button", { type: "button", className: "ck-attach-source", "data-ck-source": source, onClick: () => pick(source), children: [_jsx(Icon, {}), _jsx("span", { children: labels.sources[source] })] }, source));
|
|
68
|
-
}) })] }) })] }));
|
|
62
|
+
} }, source))), _jsx("button", { type: "button", className: trigger ? "ck-attach-trigger" : "ck-icon-btn", onClick: open, disabled: disabled, "aria-label": labels.attach, "aria-haspopup": "dialog", title: labels.attach, children: trigger ?? _jsx(IconPaperclip, {}) }), _jsxs(Sheet, { open: sheetOpen, onClose: close, title: labels.title, closeLabel: labels.close, children: [_jsx("div", { className: "ck-attach-sources", children: sources.map((source) => {
|
|
63
|
+
const Icon = ICONS[source];
|
|
64
|
+
return (_jsxs("button", { type: "button", className: "ck-attach-source", "data-ck-source": source, onClick: () => pick(source), children: [_jsx(Icon, {}), _jsx("span", { children: labels.sources[source] })] }, source));
|
|
65
|
+
}) }), extra && _jsx("div", { className: "ck-sheet-extra", children: extra(close) })] })] }));
|
|
69
66
|
}
|
|
70
67
|
//# sourceMappingURL=AttachMenu.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttachMenu.js","sourceRoot":"","sources":["../../src/react/AttachMenu.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,MAAM,EAAkB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AttachMenu.js","sourceRoot":"","sources":["../../src/react/AttachMenu.tsx"],"names":[],"mappings":"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"}
|
package/dist/react/Markdown.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
2
|
/** What a grounded answer's `[F8]` / `[D1]` handle refers to. Unknown handles
|
|
3
3
|
* are dropped rather than shown bare: a dangling `[F8]` implies a source the
|
|
4
4
|
* reader cannot reach. */
|
|
@@ -34,6 +34,22 @@ export type RenderSources = (sources: {
|
|
|
34
34
|
}) => ReactNode;
|
|
35
35
|
/** A plain anchor: same-site paths in place, everything else in a new tab. */
|
|
36
36
|
export declare const defaultRenderLink: RenderLink;
|
|
37
|
+
/**
|
|
38
|
+
* The sources an answer cites, listed once under it. On a mouse, a row of
|
|
39
|
+
* chips. On a touch screen, ONE "Sources" button that opens a sheet with every
|
|
40
|
+
* record — its label, what it is, and a link — the way the ChatGPT app lists
|
|
41
|
+
* them: a row of chips on a phone was a row of cut-off words.
|
|
42
|
+
*/
|
|
43
|
+
export declare function SourcesRow({ records, label, renderLink, }: {
|
|
44
|
+
records: {
|
|
45
|
+
id: string;
|
|
46
|
+
label: string;
|
|
47
|
+
detail: string;
|
|
48
|
+
href?: string;
|
|
49
|
+
}[];
|
|
50
|
+
label: string;
|
|
51
|
+
renderLink?: RenderLink;
|
|
52
|
+
}): import("react").JSX.Element | null;
|
|
37
53
|
export declare const defaultRenderCitation: RenderCitation;
|
|
38
54
|
/**
|
|
39
55
|
* Model output as readable text: paragraphs, lists, headings, tables, bold,
|
|
@@ -45,8 +61,10 @@ export declare const defaultRenderCitation: RenderCitation;
|
|
|
45
61
|
* instead of breaking the page; the sources an answer cites are listed once
|
|
46
62
|
* under it as chips.
|
|
47
63
|
*/
|
|
48
|
-
export declare function Markdown({ text, citations, renderLink, renderCitation, renderSources, sources, sourcesLabel, className, }: {
|
|
64
|
+
export declare function Markdown({ text, citations, renderLink, renderCitation, renderSources, sources, sourcesLabel, className, onReply, }: {
|
|
49
65
|
text: string;
|
|
66
|
+
/** A visual choice sends a normal conversation message. Omit while streaming. */
|
|
67
|
+
onReply?: (text: string) => void;
|
|
50
68
|
citations?: CitationMap;
|
|
51
69
|
renderLink?: RenderLink;
|
|
52
70
|
renderCitation?: RenderCitation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/react/Markdown.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/react/Markdown.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAgBjD;;2BAE2B;AAC3B,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE3F,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;CACrB,KAAK,SAAS,CAAC;AAEhB;;yBAEyB;AACzB,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE;IAClC,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,SAAS,EAAE,WAAW,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB,KAAK,SAAS,CAAC;AAEhB;uEACuE;AACvE,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE;IACpC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACxE,KAAK,EAAE,MAAM,CAAC;CACf,KAAK,SAAS,CAAC;AAEhB,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,EAAE,UAS7B,CAAC;AAEJ;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EACL,UAA8B,GAC/B,EAAE;IACD,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,sCA+EA;AAED,eAAO,MAAM,qBAAqB,EAAE,cASnC,CAAC;AAwEF;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,SAAS,EACT,UAA8B,EAC9B,cAAsC,EACtC,aAAa,EACb,OAAc,EACd,YAAwB,EACxB,SAAS,EACT,OAAO,GACR,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,gFAAgF;IAChF,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BA2IA"}
|
package/dist/react/Markdown.js
CHANGED
|
@@ -1,7 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { parseRichBlock } from "../rich.js";
|
|
5
|
+
import { RichAnswerBlock } from "./RichBlock.js";
|
|
6
|
+
import { IconBook } from "./icons.js";
|
|
7
|
+
import { Sheet, prefersSheet } from "./Sheet.js";
|
|
2
8
|
import { citedIds, isCardList, isInternalHref, listLead, parseBlocks, parseInline, } from "../markdown.js";
|
|
3
9
|
/** A plain anchor: same-site paths in place, everything else in a new tab. */
|
|
4
10
|
export const defaultRenderLink = ({ href, internal, className, children }) => internal ? (_jsx("a", { href: href, className: className, children: children })) : (_jsx("a", { href: href, className: className, target: "_blank", rel: "noopener noreferrer", children: children }));
|
|
11
|
+
/**
|
|
12
|
+
* The sources an answer cites, listed once under it. On a mouse, a row of
|
|
13
|
+
* chips. On a touch screen, ONE "Sources" button that opens a sheet with every
|
|
14
|
+
* record — its label, what it is, and a link — the way the ChatGPT app lists
|
|
15
|
+
* them: a row of chips on a phone was a row of cut-off words.
|
|
16
|
+
*/
|
|
17
|
+
export function SourcesRow({ records, label, renderLink = defaultRenderLink, }) {
|
|
18
|
+
const [open, setOpen] = useState(false);
|
|
19
|
+
const sheet = prefersSheet();
|
|
20
|
+
if (records.length === 0)
|
|
21
|
+
return null;
|
|
22
|
+
if (!sheet) {
|
|
23
|
+
return (_jsxs("div", { className: "ck-sources", role: "list", "aria-label": label, children: [_jsx("span", { className: "ck-sources-label", children: label }), records.map((c) => {
|
|
24
|
+
const chip = (_jsxs(_Fragment, { children: [_jsx("span", { className: "ck-source-id", children: c.id }), _jsx("span", { className: "ck-source-label", children: c.label })] }));
|
|
25
|
+
return c.href ? (_jsx("span", { role: "listitem", children: renderLink({
|
|
26
|
+
href: c.href,
|
|
27
|
+
internal: isInternalHref(c.href),
|
|
28
|
+
className: "ck-source",
|
|
29
|
+
children: chip,
|
|
30
|
+
}) }, c.id)) : (_jsx("span", { role: "listitem", className: "ck-source", title: c.detail, children: chip }, c.id));
|
|
31
|
+
})] }));
|
|
32
|
+
}
|
|
33
|
+
return (_jsxs("div", { className: "ck-sources", children: [_jsxs("button", { type: "button", className: "ck-source ck-sources-open", onClick: () => setOpen(true), "aria-haspopup": "dialog", children: [_jsx(IconBook, {}), _jsxs("span", { className: "ck-source-label", children: [label, " \u00B7 ", records.length] })] }), _jsx(Sheet, { open: open, onClose: () => setOpen(false), title: label, children: _jsx("ol", { className: "ck-source-list", children: records.map((c) => {
|
|
34
|
+
const body = (_jsxs(_Fragment, { children: [_jsx("span", { className: "ck-source-id", children: c.id }), _jsxs("span", { className: "ck-source-body", children: [_jsx("span", { className: "ck-source-title", children: c.label }), c.detail && c.detail !== c.label && (_jsx("span", { className: "ck-source-detail", children: c.detail }))] })] }));
|
|
35
|
+
return (_jsx("li", { children: c.href ? (renderLink({
|
|
36
|
+
href: c.href,
|
|
37
|
+
internal: isInternalHref(c.href),
|
|
38
|
+
className: "ck-source-row",
|
|
39
|
+
children: body,
|
|
40
|
+
})) : (_jsx("span", { className: "ck-source-row", children: body })) }, c.id));
|
|
41
|
+
}) }) })] }));
|
|
42
|
+
}
|
|
5
43
|
export const defaultRenderCitation = ({ ids, citations, className }) => (_jsx("sup", { className: className, title: ids
|
|
6
44
|
.map((id) => `${id} — ${citations[id].label}\n${citations[id].detail}`)
|
|
7
45
|
.join("\n\n"), children: ids.join(" ") }));
|
|
@@ -48,7 +86,7 @@ function Inline({ spans, citations, renderLink, renderCitation, }) {
|
|
|
48
86
|
* instead of breaking the page; the sources an answer cites are listed once
|
|
49
87
|
* under it as chips.
|
|
50
88
|
*/
|
|
51
|
-
export function Markdown({ text, citations, renderLink = defaultRenderLink, renderCitation = defaultRenderCitation, renderSources, sources = true, sourcesLabel = "Sources", className, }) {
|
|
89
|
+
export function Markdown({ text, citations, renderLink = defaultRenderLink, renderCitation = defaultRenderCitation, renderSources, sources = true, sourcesLabel = "Sources", className, onReply, }) {
|
|
52
90
|
const inline = (t) => (_jsx(Inline, { spans: parseInline(t), citations: citations, renderLink: renderLink, renderCitation: renderCitation }));
|
|
53
91
|
const items = (list, ordered, start = 1) => {
|
|
54
92
|
const List = ordered ? "ol" : "ul";
|
|
@@ -61,8 +99,16 @@ export function Markdown({ text, citations, renderLink = defaultRenderLink, rend
|
|
|
61
99
|
const cited = citations ? citedIds(text).filter((id) => citations[id]) : [];
|
|
62
100
|
return (_jsxs("div", { className: className ? `ck-md ${className}` : "ck-md", children: [parseBlocks(text).map((b, i) => {
|
|
63
101
|
switch (b.kind) {
|
|
64
|
-
case "code":
|
|
102
|
+
case "code": {
|
|
103
|
+
if (b.lang === "chat_ui") {
|
|
104
|
+
const block = parseRichBlock(b.code);
|
|
105
|
+
if (block)
|
|
106
|
+
return _jsx(RichAnswerBlock, { block: block, onReply: onReply }, i);
|
|
107
|
+
// A partial JSON block must not flash in the conversation.
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
65
110
|
return (_jsx("pre", { className: "ck-pre", "data-lang": b.lang || undefined, children: _jsx("code", { children: b.code }) }, i));
|
|
111
|
+
}
|
|
66
112
|
case "ul":
|
|
67
113
|
return (_jsx("div", { children: isCardList(b.items) ? cards(b.items, false) : items(b.items, false) }, i));
|
|
68
114
|
case "ol":
|
|
@@ -85,15 +131,6 @@ export function Markdown({ text, citations, renderLink = defaultRenderLink, rend
|
|
|
85
131
|
}), sources && cited.length > 0 && citations && renderSources ? (renderSources({
|
|
86
132
|
records: cited.map((id) => ({ id, ...citations[id] })),
|
|
87
133
|
label: sourcesLabel,
|
|
88
|
-
})) : sources && cited.length > 0 && citations ? (
|
|
89
|
-
const c = citations[id];
|
|
90
|
-
const chip = (_jsxs(_Fragment, { children: [_jsx("span", { className: "ck-source-id", children: id }), _jsx("span", { className: "ck-source-label", children: c.label })] }));
|
|
91
|
-
return c.href ? (_jsx("span", { role: "listitem", children: renderLink({
|
|
92
|
-
href: c.href,
|
|
93
|
-
internal: isInternalHref(c.href),
|
|
94
|
-
className: "ck-source",
|
|
95
|
-
children: chip,
|
|
96
|
-
}) }, id)) : (_jsx("span", { role: "listitem", className: "ck-source", title: c.detail, children: chip }, id));
|
|
97
|
-
})] })) : null] }));
|
|
134
|
+
})) : sources && cited.length > 0 && citations ? (_jsx(SourcesRow, { records: cited.map((id) => ({ id, ...citations[id] })), label: sourcesLabel, renderLink: renderLink })) : null] }));
|
|
98
135
|
}
|
|
99
136
|
//# sourceMappingURL=Markdown.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.js","sourceRoot":"","sources":["../../src/react/Markdown.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"Markdown.js","sourceRoot":"","sources":["../../src/react/Markdown.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RichBlock.d.ts","sourceRoot":"","sources":["../../src/react/RichBlock.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC,+BA2HA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId, useState } from "react";
|
|
4
|
+
import { Sheet } from "./Sheet.js";
|
|
5
|
+
export function RichAnswerBlock({ block, onReply, }) {
|
|
6
|
+
const id = useId();
|
|
7
|
+
const [selected, setSelected] = useState(null);
|
|
8
|
+
const [sent, setSent] = useState(false);
|
|
9
|
+
const [photo, setPhoto] = useState(null);
|
|
10
|
+
if (block.type === "gallery") {
|
|
11
|
+
const active = photo === null ? null : block.images[photo];
|
|
12
|
+
return (_jsxs("figure", { className: "ck-rich ck-gallery", children: [_jsx("figcaption", { className: "ck-rich-title", children: block.title }), _jsx("div", { className: "ck-gallery-grid", children: block.images.map((item, i) => (_jsxs("figure", { children: [_jsxs("button", { type: "button", className: "ck-photo", onClick: () => setPhoto(i), "aria-label": item.alt, "aria-haspopup": "dialog", children: [_jsx("img", { src: item.src, alt: item.alt, loading: "lazy", referrerPolicy: "no-referrer", onError: (e) => {
|
|
13
|
+
e.currentTarget.hidden = true;
|
|
14
|
+
} }), _jsx("span", { className: "ck-photo-label", children: item.alt })] }), item.caption && _jsx("figcaption", { children: item.caption })] }, i))) }), _jsxs(Sheet, { open: !!active, onClose: () => setPhoto(null), title: active?.alt ?? block.title, children: [active && (_jsx("img", { className: "ck-photo-full", src: active.src, alt: active.alt, referrerPolicy: "no-referrer" })), active?.caption && _jsx("p", { children: active.caption })] })] }));
|
|
15
|
+
}
|
|
16
|
+
if (block.type === "diagram")
|
|
17
|
+
return (_jsxs("figure", { className: "ck-rich ck-diagram", children: [_jsx("figcaption", { className: "ck-rich-title", children: block.title }), _jsx("ol", { className: "ck-diagram-nodes", children: block.nodes.map((n, i) => (_jsxs("li", { children: [_jsx("span", { className: "ck-diagram-number", "aria-hidden": true, children: i + 1 }), _jsxs("div", { children: [_jsx("strong", { children: n.label }), n.detail && _jsx("p", { children: n.detail })] })] }, n.id))) }), block.edges.length > 0 && (_jsx("ul", { className: "ck-diagram-edges", children: block.edges.map((e, i) => (_jsxs("li", { children: [_jsx("span", { children: block.nodes.find((n) => n.id === e.from).label }), _jsx("span", { className: "ck-diagram-arrow", "aria-hidden": true, children: "\u2192" }), _jsx("span", { children: block.nodes.find((n) => n.id === e.to).label }), e.label && _jsx("small", { children: e.label })] }, i))) }))] }));
|
|
18
|
+
if (block.type === "callout")
|
|
19
|
+
return (_jsxs("aside", { className: "ck-rich ck-callout", children: [_jsx("strong", { className: "ck-rich-title", children: block.title }), _jsx("p", { children: block.body })] }));
|
|
20
|
+
return (_jsx("form", { className: "ck-rich ck-choice", onSubmit: (e) => {
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
if (selected !== null && onReply && !sent) {
|
|
23
|
+
setSent(true);
|
|
24
|
+
onReply(block.options[selected].reply);
|
|
25
|
+
}
|
|
26
|
+
}, children: _jsxs("fieldset", { disabled: !onReply || sent, children: [_jsx("legend", { className: "ck-rich-title", children: block.title }), block.options.map((option, i) => (_jsxs("label", { className: "ck-choice-option", children: [_jsx("input", { type: "radio", name: id, value: i, checked: selected === i, onChange: () => setSelected(i) }), _jsx("span", { children: option.label })] }, i))), onReply && (_jsxs("button", { type: "submit", className: "ck-choice-submit", disabled: selected === null || sent, children: [block.submit, _jsx("span", { "aria-hidden": true, children: "\u2192" })] }))] }) }));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=RichBlock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RichBlock.js","sourceRoot":"","sources":["../../src/react/RichBlock.tsx"],"names":[],"mappings":"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"}
|