inline-chat-kit 0.49.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/CHANGELOG.md +2111 -0
- package/LICENSE +21 -0
- package/README.md +1430 -0
- package/dist/AnswerActions/AnswerActions.d.ts +35 -0
- package/dist/Approval/Approval.d.ts +42 -0
- package/dist/Artifact/ArtifactCard.d.ts +45 -0
- package/dist/Artifact/ArtifactPane.d.ts +50 -0
- package/dist/Artifact/ChatLayout.d.ts +35 -0
- package/dist/Artifact/useArtifacts.d.ts +21 -0
- package/dist/Attachments/Attachments.d.ts +50 -0
- package/dist/Branch/Branch.d.ts +28 -0
- package/dist/Button/Button.d.ts +23 -0
- package/dist/ChainOfThought/ChainOfThought.d.ts +49 -0
- package/dist/ChatHeader/ChatHeader.d.ts +89 -0
- package/dist/ChatInput/AddCardsOverlay.d.ts +11 -0
- package/dist/ChatInput/ChatInput.d.ts +118 -0
- package/dist/ChatInput/HoverActionsRow.d.ts +13 -0
- package/dist/ChatInput/MorphGlyph.d.ts +15 -0
- package/dist/ChatTurnRow/ChatTurnRow.d.ts +115 -0
- package/dist/Chip/Chip.d.ts +7 -0
- package/dist/CodeBlock/CodeBlock.d.ts +24 -0
- package/dist/CodeBlock/grammars.d.ts +16 -0
- package/dist/CodeBlock/highlight.d.ts +38 -0
- package/dist/Context/Context.d.ts +36 -0
- package/dist/Conversation/Conversation.d.ts +64 -0
- package/dist/CustomCursor/CustomCursor.d.ts +1 -0
- package/dist/EmptyState/EmptyState.d.ts +24 -0
- package/dist/GlassButton/GlassButton.d.ts +19 -0
- package/dist/InlineCitation/InlineCitation.d.ts +30 -0
- package/dist/Loader/Loader.d.ts +23 -0
- package/dist/QuestionCard/QuestionCard.d.ts +32 -0
- package/dist/QuestionCard/parts.d.ts +84 -0
- package/dist/QuestionCard/types.d.ts +54 -0
- package/dist/QuestionGroup/QuestionGroup.d.ts +87 -0
- package/dist/Reasoning/Reasoning.d.ts +37 -0
- package/dist/ReplyThreadPopup/ReplyThreadPopup.d.ts +18 -0
- package/dist/Sources/Sources.d.ts +46 -0
- package/dist/SystemMessage/SystemMessage.d.ts +39 -0
- package/dist/TaskList/TaskList.d.ts +42 -0
- package/dist/TextHighlighter/TextHighlighter.d.ts +17 -0
- package/dist/Tool/Tool.d.ts +41 -0
- package/dist/announce/announce.d.ts +27 -0
- package/dist/disclosure/DisclosureBody.d.ts +22 -0
- package/dist/disclosure/DisclosureHeader.d.ts +42 -0
- package/dist/disclosure/useDisclosure.d.ts +30 -0
- package/dist/duration/formatDuration.d.ts +9 -0
- package/dist/grammars-B19jp7qm.js +3181 -0
- package/dist/grammars-B19jp7qm.js.map +1 -0
- package/dist/index.d.ts +80 -0
- package/dist/inline-chat-kit.css +2 -0
- package/dist/inline-chat-kit.js +5314 -0
- package/dist/inline-chat-kit.js.map +1 -0
- package/dist/markdown/parse.d.ts +105 -0
- package/dist/markdown/parseMarkdown.d.ts +47 -0
- package/dist/radiusCorrection/useCorrectedRadius.d.ts +24 -0
- package/dist/reducedMotion/reducedMotion.d.ts +3 -0
- package/dist/stateGlyph/StateGlyph.d.ts +23 -0
- package/dist/turnParts/turnParts.d.ts +156 -0
- package/dist/useChatTurns/useChatTurns.d.ts +127 -0
- package/dist/voice/useVoiceInput.d.ts +79 -0
- package/package.json +95 -0
- package/theming.md +234 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { Answer, Question } from '../QuestionCard/types';
|
|
3
|
+
/** Below this, folding saves less room than the summary row costs. */
|
|
4
|
+
export declare const FOLDABLE_FROM = 3;
|
|
5
|
+
/**
|
|
6
|
+
* What the fold is made of, in numbers.
|
|
7
|
+
*
|
|
8
|
+
* Springs for anything that moves, tweens for opacity alone.
|
|
9
|
+
*
|
|
10
|
+
* That split is not a preference. A spring is a description of *travel* —
|
|
11
|
+
* where a thing is going and how it arrives — and opacity has nowhere to
|
|
12
|
+
* travel: it is bounded at 0 and 1, so a spring with any bounce in it
|
|
13
|
+
* overshoots into a clamp and spends the overshoot sitting still. Position and
|
|
14
|
+
* size have no such ceiling, which is exactly why they are worth springing.
|
|
15
|
+
*
|
|
16
|
+
* `visualDuration` rather than stiffness and damping, for the same reason
|
|
17
|
+
* throughout: the two of them describe one spring between them without either
|
|
18
|
+
* answering "how long is this", which is the only question anybody tuning it
|
|
19
|
+
* is asking. Motion solves the spring for the duration you name.
|
|
20
|
+
*/
|
|
21
|
+
export interface FoldMotion {
|
|
22
|
+
/** How long the ground looks like it takes to resize, in seconds. */
|
|
23
|
+
visualDuration: number;
|
|
24
|
+
/** The ground's overshoot, 0–1. */
|
|
25
|
+
bounce: number;
|
|
26
|
+
/** How long a row takes to arrive, in seconds. */
|
|
27
|
+
rowDuration: number;
|
|
28
|
+
/** A row's overshoot, 0–1. Enough to read as arriving, not as bouncing. */
|
|
29
|
+
rowBounce: number;
|
|
30
|
+
/** How far above its place a row starts, in pixels. */
|
|
31
|
+
rowOffset: number;
|
|
32
|
+
/** Between one row and the next, in seconds. */
|
|
33
|
+
stagger: number;
|
|
34
|
+
/** A row's fade, in seconds. Tween: see the note above. */
|
|
35
|
+
fadeIn: number;
|
|
36
|
+
/** And the fade of one leaving. */
|
|
37
|
+
fadeOut: number;
|
|
38
|
+
/**
|
|
39
|
+
* How long the arriving body waits, in seconds.
|
|
40
|
+
*
|
|
41
|
+
* Not a stylistic pause — it is what stops the two bodies from being in the
|
|
42
|
+
* same pixels at once. They are anchored to the same top edge, so the folded
|
|
43
|
+
* row and the first card always want that same band; crossfading them put
|
|
44
|
+
* two different sentences on top of each other at half opacity, which is
|
|
45
|
+
* mush rather than motion. At `fadeOut` the one is gone before the other
|
|
46
|
+
* starts, and the box growing underneath is what carries the eye across.
|
|
47
|
+
*/
|
|
48
|
+
fadeInDelay: number;
|
|
49
|
+
}
|
|
50
|
+
export declare const defaultFoldMotion: FoldMotion;
|
|
51
|
+
export interface QuestionGroupProps {
|
|
52
|
+
/** Distinguishes one group's layout animations from another's. */
|
|
53
|
+
id: string;
|
|
54
|
+
/**
|
|
55
|
+
* What this step is about, at the top of the group.
|
|
56
|
+
*
|
|
57
|
+
* Also the fold control when there is one — which is the point of putting it
|
|
58
|
+
* there. A control at the top does not move when the thing under it opens,
|
|
59
|
+
* so folding stops being two shapes swapping places and becomes a body
|
|
60
|
+
* changing under a header that stays put.
|
|
61
|
+
*
|
|
62
|
+
* Left out on a foldable group, the count stands in, so the control still
|
|
63
|
+
* has a name.
|
|
64
|
+
*/
|
|
65
|
+
title?: ReactNode;
|
|
66
|
+
questions: Question[];
|
|
67
|
+
answers: Record<string, Answer | undefined>;
|
|
68
|
+
/** Index of the question being answered, or `null` when none is. */
|
|
69
|
+
activeIndex?: number | null;
|
|
70
|
+
/** Offer to fold the whole group into one row. */
|
|
71
|
+
collapsible?: boolean;
|
|
72
|
+
onCommit?: (questionId: string, answer: Answer) => void;
|
|
73
|
+
onEdit?: (index: number) => void;
|
|
74
|
+
readOnly?: boolean;
|
|
75
|
+
labels?: Partial<Record<"answers", string>>;
|
|
76
|
+
/** Overrides for the fold's timing. See `defaultFoldMotion`. */
|
|
77
|
+
foldMotion?: Partial<FoldMotion>;
|
|
78
|
+
className?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* One step of a questionnaire: the surface holding its questions.
|
|
82
|
+
*
|
|
83
|
+
* Once the conversation has moved past it, it folds down to a single row.
|
|
84
|
+
* Not a peek at the list — a peek costs more height than the answers it shows,
|
|
85
|
+
* and a conversation with four half-open steps above it is unreadable.
|
|
86
|
+
*/
|
|
87
|
+
export declare function QuestionGroup({ id, title, questions, answers, activeIndex, collapsible, onCommit, onEdit, readOnly, labels, foldMotion, className, }: QuestionGroupProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
/** Still working it out, or finished. */
|
|
3
|
+
export type ReasoningState = "thinking" | "done";
|
|
4
|
+
type Labels = Record<"thinking" | "thought" | "thoughtFor", string>;
|
|
5
|
+
export interface ReasoningProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
|
|
6
|
+
/** The thinking itself. Prose, not structure — see `Tool` for that. */
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
state?: ReasoningState;
|
|
9
|
+
/**
|
|
10
|
+
* How long it took, in ms.
|
|
11
|
+
*
|
|
12
|
+
* Left out, the block times itself: it starts a clock when it begins
|
|
13
|
+
* thinking and reads it when it stops. Pass one when you already know —
|
|
14
|
+
* replaying a transcript, where the thinking did not happen just now.
|
|
15
|
+
*/
|
|
16
|
+
duration?: number;
|
|
17
|
+
/** Controlled. Leave it out and the block looks after itself. */
|
|
18
|
+
open?: boolean;
|
|
19
|
+
/** Where it starts, overruling the block's own preference. */
|
|
20
|
+
defaultOpen?: boolean;
|
|
21
|
+
onOpenChange?: (open: boolean) => void;
|
|
22
|
+
labels?: Partial<Labels>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* What the model worked through before it answered.
|
|
26
|
+
*
|
|
27
|
+
* **Open while it thinks, folded away once the answer starts.** That is the
|
|
28
|
+
* one detail every kit that ships this has converged on, and it is right:
|
|
29
|
+
* thinking is worth watching while it is happening and worth almost nothing
|
|
30
|
+
* afterwards — but it has to stay reachable, because the times it matters are
|
|
31
|
+
* exactly the times the answer looks wrong.
|
|
32
|
+
*
|
|
33
|
+
* Folding is the block's *preference*, not something done to the reader. Open
|
|
34
|
+
* it and it stays open, however many times the state changes underneath.
|
|
35
|
+
*/
|
|
36
|
+
export declare function Reasoning({ children, state, duration, open, defaultOpen, onOpenChange, labels, className, ...rest }: ReasoningProps): import("react").JSX.Element;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ChatTurn, SendContext } from '../useChatTurns/useChatTurns';
|
|
2
|
+
/** @deprecated Use `ChatTurn`. Kept so existing imports keep resolving. */
|
|
3
|
+
export type Turn = ChatTurn;
|
|
4
|
+
export interface ReplyThreadPopupProps {
|
|
5
|
+
activeReply: {
|
|
6
|
+
text: string;
|
|
7
|
+
rect: DOMRect;
|
|
8
|
+
};
|
|
9
|
+
onClose: () => void;
|
|
10
|
+
onSave?: () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Produce the reply to a message sent inside the thread. Receives the
|
|
13
|
+
* message and the passage the thread hangs off. Required — the popup has no
|
|
14
|
+
* answers of its own to fall back on.
|
|
15
|
+
*/
|
|
16
|
+
onSendMessage: (message: string, quotedText: string, context: SendContext) => AsyncIterable<string> | Promise<string> | string;
|
|
17
|
+
}
|
|
18
|
+
export declare function ReplyThreadPopup({ activeReply, onClose, onSave, onSendMessage }: ReplyThreadPopupProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
/** Where a claim came from. */
|
|
3
|
+
export interface Source {
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
/** Opened when the entry is a link. Without one it is a row, not a link. */
|
|
7
|
+
url?: string;
|
|
8
|
+
/** A domain, a filename, a page — whatever names where this is. */
|
|
9
|
+
origin?: string;
|
|
10
|
+
/** The passage in the source that carries the claim. */
|
|
11
|
+
quote?: string;
|
|
12
|
+
}
|
|
13
|
+
type Labels = {
|
|
14
|
+
title: string;
|
|
15
|
+
one: string;
|
|
16
|
+
many: string;
|
|
17
|
+
};
|
|
18
|
+
export interface SourcesProps extends Omit<HTMLAttributes<HTMLElement>, "title" | "onSelect"> {
|
|
19
|
+
sources: Source[];
|
|
20
|
+
/** Heads the list. Defaults to `labels.title`. */
|
|
21
|
+
title?: ReactNode;
|
|
22
|
+
/** Offer to fold the list to its own row. */
|
|
23
|
+
collapsible?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The one just arrived at, from a citation in the text.
|
|
26
|
+
*
|
|
27
|
+
* Marked rather than scrolled to: the list is directly under the answer, and
|
|
28
|
+
* moving the page under somebody who clicked a marker in a sentence they
|
|
29
|
+
* were reading loses them the sentence.
|
|
30
|
+
*/
|
|
31
|
+
activeId?: string | null;
|
|
32
|
+
onSelect?: (source: Source, index: number) => void;
|
|
33
|
+
open?: boolean;
|
|
34
|
+
defaultOpen?: boolean;
|
|
35
|
+
onOpenChange?: (open: boolean) => void;
|
|
36
|
+
labels?: Partial<Labels>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* What the answer was drawn from, numbered to match the markers in it.
|
|
40
|
+
*
|
|
41
|
+
* Open by default. Sources are the difference between an answer somebody can
|
|
42
|
+
* check and one they have to trust, and folding that away by default says the
|
|
43
|
+
* opposite of what a citation is for.
|
|
44
|
+
*/
|
|
45
|
+
export declare function Sources({ sources, title, collapsible, activeId, onSelect, open, defaultOpen, onOpenChange, labels, className, ...rest }: SourcesProps): import("react").JSX.Element;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Two, not three.
|
|
4
|
+
*
|
|
5
|
+
* `Context` settled this already: an amber in the middle makes somebody learn
|
|
6
|
+
* a scale to read a state they can already read in words. Something either
|
|
7
|
+
* went wrong or it did not.
|
|
8
|
+
*/
|
|
9
|
+
export type SystemTone = "notice" | "danger";
|
|
10
|
+
export interface SystemMessageProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
tone?: SystemTone;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The conversation itself saying something — not the reader, not the agent.
|
|
16
|
+
*
|
|
17
|
+
* "The oldest messages are dropping out of the window." "The model changed
|
|
18
|
+
* partway through this answer." "You went offline." Things that happened *to*
|
|
19
|
+
* the conversation, which until now had nowhere to be said: `Context` warns
|
|
20
|
+
* that the window is nearly full and then nothing speaks when it fills.
|
|
21
|
+
*
|
|
22
|
+
* **No glyph**, deliberately, and for the reason the approval's shield came
|
|
23
|
+
* off an hour before this was written. Every picture in this kit carries a
|
|
24
|
+
* state the words beside it also carry — queued, running, failed, allowed — so
|
|
25
|
+
* that a reader the picture does not reach loses nothing. An icon here would
|
|
26
|
+
* carry "something is being announced", next to a sentence announcing it. The
|
|
27
|
+
* tint says which of the two tones it is and the sentence says the rest, which
|
|
28
|
+
* is the only part anybody can act on.
|
|
29
|
+
*
|
|
30
|
+
* **No dismiss, and no action.** It is a line of the transcript rather than a
|
|
31
|
+
* toast: dismissing one would be editing what happened. A host that needs a
|
|
32
|
+
* button under it composes one, which costs them a line and costs this
|
|
33
|
+
* component a whole API.
|
|
34
|
+
*
|
|
35
|
+
* **No live region either.** The kit has one, shared and written to on a later
|
|
36
|
+
* tick — see `announce`. A second one says everything twice, which is the
|
|
37
|
+
* fault that region exists to have fixed.
|
|
38
|
+
*/
|
|
39
|
+
export declare function SystemMessage({ children, tone, className, ...rest }: SystemMessageProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { WorkState } from '../stateGlyph/StateGlyph';
|
|
3
|
+
/** The same four as a tool call. See `StateGlyph`. */
|
|
4
|
+
export type TaskState = WorkState;
|
|
5
|
+
export interface Task {
|
|
6
|
+
id: string;
|
|
7
|
+
label: ReactNode;
|
|
8
|
+
state?: TaskState;
|
|
9
|
+
/** A line under the label — what it found, or why it failed. */
|
|
10
|
+
detail?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
type Labels = Record<TaskState, string> & {
|
|
13
|
+
/** `{done}` and `{total}` are filled in. */
|
|
14
|
+
progress: string;
|
|
15
|
+
};
|
|
16
|
+
export interface TaskListProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
|
|
17
|
+
tasks: Task[];
|
|
18
|
+
/** Names the list, and gives it a row to fold into. */
|
|
19
|
+
title?: ReactNode;
|
|
20
|
+
/**
|
|
21
|
+
* Let the whole list fold away.
|
|
22
|
+
*
|
|
23
|
+
* It folds itself once every task is done — a plan is worth watching while
|
|
24
|
+
* it runs and worth little afterwards — and anybody reading it can overrule
|
|
25
|
+
* that, in either direction, for good.
|
|
26
|
+
*/
|
|
27
|
+
collapsible?: boolean;
|
|
28
|
+
open?: boolean;
|
|
29
|
+
defaultOpen?: boolean;
|
|
30
|
+
onOpenChange?: (open: boolean) => void;
|
|
31
|
+
labels?: Partial<Labels>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* What the agent means to do, what it is doing, and what it has finished.
|
|
35
|
+
*
|
|
36
|
+
* The order never changes. A list that sorted itself as work progressed would
|
|
37
|
+
* move the line somebody is reading out from under them, and the sequence is
|
|
38
|
+
* half of what the list is saying — these steps, in this order. Only the
|
|
39
|
+
* glyphs change.
|
|
40
|
+
*/
|
|
41
|
+
export declare function TaskList({ tasks, title, collapsible, open, defaultOpen, onOpenChange, labels, className, ...rest }: TaskListProps): import("react").JSX.Element;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { Source } from '../Sources/Sources';
|
|
3
|
+
export interface TextHighlighterProps {
|
|
4
|
+
text: string;
|
|
5
|
+
selectionMode?: "marker" | "precise";
|
|
6
|
+
onHighlightComplete?: (highlightedText: string) => void;
|
|
7
|
+
onReplyInThread?: (text: string, rect: DOMRect) => void;
|
|
8
|
+
/**
|
|
9
|
+
* What `[^1]` in the text points at, in the order the answer cites them.
|
|
10
|
+
*
|
|
11
|
+
* Leave it out and a marker still draws — as a number with nothing behind
|
|
12
|
+
* it, which is what it is until the list arrives.
|
|
13
|
+
*/
|
|
14
|
+
sources?: Source[];
|
|
15
|
+
onSelectSource?: (index: number, source?: Source) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare function TextHighlighter({ text, selectionMode, onHighlightComplete, onReplyInThread, sources, onSelectSource, }: TextHighlighterProps): React.JSX.Element;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { WorkState } from '../stateGlyph/StateGlyph';
|
|
3
|
+
/** Queued, working, finished, or failed — the kit's four, shared with `TaskList`. */
|
|
4
|
+
export type ToolState = WorkState;
|
|
5
|
+
type Labels = Record<"input" | "output" | "error" | ToolState, string>;
|
|
6
|
+
export interface ToolProps extends Omit<HTMLAttributes<HTMLDivElement>, "title" | "onToggle"> {
|
|
7
|
+
/** What was called. Set in mono: it is an identifier, not prose. */
|
|
8
|
+
name: string;
|
|
9
|
+
state?: ToolState;
|
|
10
|
+
/** A sentence for what it did — "Searched the web", "Read 3 files". */
|
|
11
|
+
summary?: ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* What it was called with.
|
|
14
|
+
*
|
|
15
|
+
* A string is shown as text and an object as JSON. Anything you want drawn
|
|
16
|
+
* some other way, pass as an element and it is rendered untouched.
|
|
17
|
+
*/
|
|
18
|
+
input?: unknown;
|
|
19
|
+
/** What came back. Read the same way as `input`. */
|
|
20
|
+
output?: unknown;
|
|
21
|
+
/** What went wrong. Drawn instead of the output, and opens the row. */
|
|
22
|
+
error?: ReactNode;
|
|
23
|
+
/** How long it took, in ms. Shown once it has finished. */
|
|
24
|
+
duration?: number;
|
|
25
|
+
/** Open, controlled. Leave out and the row keeps its own. */
|
|
26
|
+
open?: boolean;
|
|
27
|
+
/** Where it starts. Defaults to open only if it failed. */
|
|
28
|
+
defaultOpen?: boolean;
|
|
29
|
+
onOpenChange?: (open: boolean) => void;
|
|
30
|
+
labels?: Partial<Labels>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* One tool call: what was run, what with, what came back.
|
|
34
|
+
*
|
|
35
|
+
* Collapsed, because most of the time nobody cares — and open when it failed,
|
|
36
|
+
* because an error nobody can see has not been reported. The glyph says which
|
|
37
|
+
* state it is in and the row says so in words too; a status carried only by
|
|
38
|
+
* colour is a status half the people reading it do not have.
|
|
39
|
+
*/
|
|
40
|
+
export declare function Tool({ name, state, summary, input, output, error, duration, open, defaultOpen, onOpenChange, labels, className, ...rest }: ToolProps): import("react").JSX.Element;
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A shared live region, for telling a screen reader what just happened.
|
|
3
|
+
*
|
|
4
|
+
* Three things about live regions decide the shape of this file:
|
|
5
|
+
*
|
|
6
|
+
* 1. The region has to be in the document *before* the text goes into it.
|
|
7
|
+
* Adding a region and its content in the same commit is, to most screen
|
|
8
|
+
* readers, an ordinary DOM insertion — nothing is spoken. So the node is
|
|
9
|
+
* created first and written to on a later tick.
|
|
10
|
+
* 2. Writing the same string twice is not a change, and is not announced.
|
|
11
|
+
* Clearing first makes a repeated answer speak again.
|
|
12
|
+
* 3. One region per politeness, shared by every component on the page. Several
|
|
13
|
+
* regions competing is how announcements get dropped or interleaved.
|
|
14
|
+
*
|
|
15
|
+
* This is deliberately not a React component: it must not be something a
|
|
16
|
+
* consumer can forget to render.
|
|
17
|
+
*/
|
|
18
|
+
export type Politeness = "polite" | "assertive";
|
|
19
|
+
/**
|
|
20
|
+
* Speak a message. Empty strings are ignored — clearing is not an announcement.
|
|
21
|
+
*/
|
|
22
|
+
export declare function announce(message: string, politeness?: Politeness): void;
|
|
23
|
+
/**
|
|
24
|
+
* Drop the regions and anything queued. For tests, so one case cannot hear
|
|
25
|
+
* what a previous one said.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resetAnnouncer(): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface DisclosureBodyProps {
|
|
3
|
+
/** What the header's `aria-controls` points at. */
|
|
4
|
+
id: string;
|
|
5
|
+
open: boolean;
|
|
6
|
+
/** On the animated box, so a caller can pad or lay out what is revealed. */
|
|
7
|
+
className?: string;
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* What a `DisclosureHeader` opens, and how it opens.
|
|
12
|
+
*
|
|
13
|
+
* The outer box is **always rendered**, empty and flat when shut, so the
|
|
14
|
+
* header's `aria-controls` always points at something — a control that names
|
|
15
|
+
* an id nothing has is a control that says nothing.
|
|
16
|
+
*
|
|
17
|
+
* The reveal was ten lines of identical `motion` props in five components. The
|
|
18
|
+
* height animation is what makes growing read as a reveal rather than as
|
|
19
|
+
* content arriving before its container has caught up, and `overflow: hidden`
|
|
20
|
+
* on the moving box is what keeps it from spilling on the way.
|
|
21
|
+
*/
|
|
22
|
+
export declare function DisclosureBody({ id, open, className, children }: DisclosureBodyProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface DisclosureHeaderProps {
|
|
3
|
+
/**
|
|
4
|
+
* `band` is a full-width row — it has a right edge, so the meta and the
|
|
5
|
+
* chevron are pushed to it. `inline` is a label that hugs its own words,
|
|
6
|
+
* for a header that sits in the flow of an answer as an aside.
|
|
7
|
+
*
|
|
8
|
+
* The two are not a style choice. An inline header's chevron pushed to a
|
|
9
|
+
* right edge 500px away floats alone in white space with nothing beside it.
|
|
10
|
+
*/
|
|
11
|
+
fit?: "band" | "inline";
|
|
12
|
+
open: boolean;
|
|
13
|
+
/** Leave it out and this is a heading rather than a control — no chevron,
|
|
14
|
+
no `aria-expanded`, nothing to press. */
|
|
15
|
+
onToggle?: () => void;
|
|
16
|
+
/** The id of the box it opens. Always present, so this always points at
|
|
17
|
+
something even while the box is empty. */
|
|
18
|
+
controls: string;
|
|
19
|
+
/** A control with nothing to open yet. Still a row worth reading. */
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
glyph?: ReactNode;
|
|
22
|
+
/** The control's name. */
|
|
23
|
+
label: ReactNode;
|
|
24
|
+
/** Shimmers the label: the kit's way of saying "still happening". */
|
|
25
|
+
pending?: boolean;
|
|
26
|
+
/** A duration, a count — pushed to the right end of a band. */
|
|
27
|
+
meta?: ReactNode;
|
|
28
|
+
/** Anything between the label and the meta. */
|
|
29
|
+
children?: ReactNode;
|
|
30
|
+
className?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The row you click to open something.
|
|
34
|
+
*
|
|
35
|
+
* Five components had one of these and the markup was written out five times,
|
|
36
|
+
* with two pairs byte-for-byte identical and the others differing in ways
|
|
37
|
+
* nobody had decided on. The shimmer under the label was in two of them, with
|
|
38
|
+
* the same twenty lines of gradient in each.
|
|
39
|
+
*
|
|
40
|
+
* What it does not do is force one shape on all five — see `fit`.
|
|
41
|
+
*/
|
|
42
|
+
export declare function DisclosureHeader({ fit, open, onToggle, controls, disabled, glyph, label, pending, meta, children, className, }: DisclosureHeaderProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface DisclosureOptions {
|
|
2
|
+
/** Controlled. Leave it out and the row keeps its own. */
|
|
3
|
+
open?: boolean;
|
|
4
|
+
/** Where it starts, when the row's own preference is not what you want. */
|
|
5
|
+
defaultOpen?: boolean;
|
|
6
|
+
onOpenChange?: (open: boolean) => void;
|
|
7
|
+
/**
|
|
8
|
+
* What the row would do if nobody had an opinion.
|
|
9
|
+
*
|
|
10
|
+
* Read every render, so it follows the state: a tool call that fails later
|
|
11
|
+
* opens itself, a reasoning block folds away when the answer starts.
|
|
12
|
+
*/
|
|
13
|
+
preferOpen: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Open or shut, decided by three sources in order of who gets the last word:
|
|
17
|
+
* the host if it is controlling the row, then whoever clicked it, then the
|
|
18
|
+
* row's own preference.
|
|
19
|
+
*
|
|
20
|
+
* That order is the whole point, and it is why this is not an effect. An
|
|
21
|
+
* effect forcing the row open on a state change would also reopen one that
|
|
22
|
+
* somebody had deliberately shut — showing a reader again what they have
|
|
23
|
+
* already dismissed is not help. Derived, a reader's decision simply outlives
|
|
24
|
+
* every state change after it, and a row nobody has touched still follows
|
|
25
|
+
* along.
|
|
26
|
+
*/
|
|
27
|
+
export declare function useDisclosure({ open, defaultOpen, onOpenChange, preferOpen }: DisclosureOptions): {
|
|
28
|
+
isOpen: boolean;
|
|
29
|
+
toggle: () => void;
|
|
30
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How long something took, in words somebody reads rather than in the number
|
|
3
|
+
* the clock handed over.
|
|
4
|
+
*
|
|
5
|
+
* `840ms` under a second, `1.2s` over it, whole seconds past ten. Nobody reads
|
|
6
|
+
* `1173ms`, and the tenth stops mattering once there are two digits in front
|
|
7
|
+
* of it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function formatDuration(ms: number): string;
|