@truefoundry/agent-ui-sdk 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +192 -80
- package/dist/index.d.ts +229 -281
- package/dist/index.js +1824 -1791
- package/dist/index.js.map +1 -1
- package/dist/styles.css +2 -0
- package/package.json +36 -19
- package/src/atoms/AskUserPrompt.tsx +0 -102
- package/src/atoms/AttachmentCard.tsx +0 -92
- package/src/atoms/AttachmentPickerButton.tsx +0 -19
- package/src/atoms/AttachmentPreviewDialog.tsx +0 -34
- package/src/atoms/BranchIndicator.tsx +0 -41
- package/src/atoms/CodeBlockHeader.tsx +0 -44
- package/src/atoms/ComposerShell.tsx +0 -112
- package/src/atoms/Markdown.test.tsx +0 -28
- package/src/atoms/Markdown.tsx +0 -288
- package/src/atoms/McpAuthPrompt.tsx +0 -60
- package/src/atoms/MessageActionBar.tsx +0 -60
- package/src/atoms/MessageBubble.tsx +0 -80
- package/src/atoms/MessageErrorBanner.tsx +0 -26
- package/src/atoms/MessageIndicator.tsx +0 -23
- package/src/atoms/OpenUIBlock.test.tsx +0 -37
- package/src/atoms/OpenUIBlock.tsx +0 -50
- package/src/atoms/ReasoningCard.tsx +0 -52
- package/src/atoms/SandboxArtifactList.tsx +0 -63
- package/src/atoms/ScrollToBottomButton.tsx +0 -34
- package/src/atoms/Skeletons.tsx +0 -32
- package/src/atoms/ThreadListMisc.tsx +0 -76
- package/src/atoms/ThreadListRow.tsx +0 -81
- package/src/atoms/ThreadShell.tsx +0 -93
- package/src/atoms/Toast.tsx +0 -60
- package/src/atoms/ToolApprovalBar.tsx +0 -92
- package/src/atoms/ToolCallCard.tsx +0 -186
- package/src/atoms/ToolGroupCard.tsx +0 -52
- package/src/atoms/UserMessageActionBar.tsx +0 -62
- package/src/atoms/WelcomeScreen.tsx +0 -22
- package/src/atoms/lib/cn.ts +0 -6
- package/src/atoms/primitives/Avatar.tsx +0 -57
- package/src/atoms/primitives/Button.tsx +0 -73
- package/src/atoms/primitives/Collapsible.tsx +0 -32
- package/src/atoms/primitives/Dialog.tsx +0 -152
- package/src/atoms/primitives/IconButton.tsx +0 -43
- package/src/atoms/primitives/Skeleton.tsx +0 -17
- package/src/atoms/primitives/Tooltip.tsx +0 -58
- package/src/containers/AskUserContainer.tsx +0 -49
- package/src/containers/AssistantMessageContainer.test.tsx +0 -56
- package/src/containers/AssistantMessageContainer.tsx +0 -128
- package/src/containers/AssistantTextContainer.test.tsx +0 -111
- package/src/containers/AssistantTextContainer.tsx +0 -54
- package/src/containers/AttachmentsContainer.tsx +0 -83
- package/src/containers/ComposerContainer.tsx +0 -66
- package/src/containers/ErrorToasterContainer.tsx +0 -76
- package/src/containers/McpAuthContainer.test.tsx +0 -100
- package/src/containers/McpAuthContainer.tsx +0 -22
- package/src/containers/MessageImageContainer.tsx +0 -37
- package/src/containers/ReasoningContainer.tsx +0 -32
- package/src/containers/RuntimeHarness.tsx +0 -39
- package/src/containers/Thread.tsx +0 -9
- package/src/containers/ThreadContainer.test.tsx +0 -52
- package/src/containers/ThreadContainer.tsx +0 -87
- package/src/containers/ThreadListContainer.tsx +0 -63
- package/src/containers/ToolCallContainer.test.tsx +0 -135
- package/src/containers/ToolCallContainer.tsx +0 -167
- package/src/containers/ToolGroupContainer.test.tsx +0 -56
- package/src/containers/ToolGroupContainer.tsx +0 -24
- package/src/containers/UserEditComposerContainer.test.tsx +0 -52
- package/src/containers/UserEditComposerContainer.tsx +0 -86
- package/src/containers/UserMessageContainer.test.tsx +0 -99
- package/src/containers/UserMessageContainer.tsx +0 -26
- package/src/containers/nestedApprovalBridge.ts +0 -20
- package/src/containers/useAttachmentPreviewSrc.ts +0 -42
- package/src/hooks/useComposerBusyState.test.ts +0 -78
- package/src/hooks/useComposerBusyState.ts +0 -69
- package/src/index.ts +0 -193
- package/src/testSetup.ts +0 -42
- package/src/theme/SlotsProvider.test.tsx +0 -64
- package/src/theme/SlotsProvider.tsx +0 -41
- package/src/theme/defaultSlots.ts +0 -131
- package/src/theme/tokens.ts +0 -98
- package/src/theme/useClassDarkMode.ts +0 -24
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useThreadIsRunning } from "@assistant-ui/core/react";
|
|
4
|
-
import { createContext, createElement, useCallback, useContext, useEffect, useState, type ReactNode } from "react";
|
|
5
|
-
|
|
6
|
-
export type ComposerBusyState = {
|
|
7
|
-
/** True while submitting or while the turn stream is active. */
|
|
8
|
-
isBusy: boolean;
|
|
9
|
-
isRunning: boolean;
|
|
10
|
-
isSubmitting: boolean;
|
|
11
|
-
send: (sendFn: () => void | Promise<void>) => void;
|
|
12
|
-
resetBusy: () => void;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const ComposerBusyContext = createContext<ComposerBusyState | null>(null);
|
|
16
|
-
|
|
17
|
-
function useComposerBusyStateValue(): ComposerBusyState {
|
|
18
|
-
const isRunning = useThreadIsRunning();
|
|
19
|
-
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
20
|
-
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
if (!isRunning) {
|
|
23
|
-
setIsSubmitting(false);
|
|
24
|
-
}
|
|
25
|
-
}, [isRunning]);
|
|
26
|
-
|
|
27
|
-
const isBusy = isRunning || isSubmitting;
|
|
28
|
-
|
|
29
|
-
const resetBusy = useCallback(() => {
|
|
30
|
-
setIsSubmitting(false);
|
|
31
|
-
}, []);
|
|
32
|
-
|
|
33
|
-
const send = useCallback((sendFn: () => void | Promise<void>) => {
|
|
34
|
-
setIsSubmitting(true);
|
|
35
|
-
try {
|
|
36
|
-
const result = sendFn();
|
|
37
|
-
if (result != null && typeof result.then === "function") {
|
|
38
|
-
void result.catch(() => {
|
|
39
|
-
setIsSubmitting(false);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
} catch {
|
|
43
|
-
setIsSubmitting(false);
|
|
44
|
-
}
|
|
45
|
-
}, []);
|
|
46
|
-
|
|
47
|
-
return { isBusy, isRunning, isSubmitting, send, resetBusy };
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function ComposerBusyProvider({ children }: { children: ReactNode }) {
|
|
51
|
-
const value = useComposerBusyStateValue();
|
|
52
|
-
return createElement(ComposerBusyContext.Provider, { value }, children);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Optimistic composer busy state shared across the thread. `useThreadIsRunning()`
|
|
57
|
-
* only becomes true once the turn stream starts; this hook flips to busy
|
|
58
|
-
* immediately on submit so the send button shows loading before session setup /
|
|
59
|
-
* turn API work finishes.
|
|
60
|
-
*
|
|
61
|
-
* Must be used within `<ComposerBusyProvider>` (wired by default in `<Thread />`).
|
|
62
|
-
*/
|
|
63
|
-
export function useComposerBusyState(): ComposerBusyState {
|
|
64
|
-
const value = useContext(ComposerBusyContext);
|
|
65
|
-
if (value == null) {
|
|
66
|
-
throw new Error("useComposerBusyState must be used within ComposerBusyProvider");
|
|
67
|
-
}
|
|
68
|
-
return value;
|
|
69
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
export { SlotsProvider, useSlot } from "./theme/SlotsProvider.js";
|
|
4
|
-
export type { AtomSlots, SlotOverrides } from "./theme/SlotsProvider.js";
|
|
5
|
-
export { defaultSlots } from "./theme/defaultSlots.js";
|
|
6
|
-
export { TokensProvider, useTokens, defaultTokens } from "./theme/tokens.js";
|
|
7
|
-
export type {
|
|
8
|
-
ColorToken,
|
|
9
|
-
RadiusToken,
|
|
10
|
-
SpacingToken,
|
|
11
|
-
TypeRoleToken,
|
|
12
|
-
TypeRoleValue,
|
|
13
|
-
DesignTokens,
|
|
14
|
-
} from "./theme/tokens.js";
|
|
15
|
-
|
|
16
|
-
export { Button, buttonVariants } from "./atoms/primitives/Button.js";
|
|
17
|
-
export type { ButtonProps } from "./atoms/primitives/Button.js";
|
|
18
|
-
export { IconButton } from "./atoms/primitives/IconButton.js";
|
|
19
|
-
export type { IconButtonProps } from "./atoms/primitives/IconButton.js";
|
|
20
|
-
export { Avatar, AvatarImage, AvatarFallback } from "./atoms/primitives/Avatar.js";
|
|
21
|
-
export type {
|
|
22
|
-
AvatarProps,
|
|
23
|
-
AvatarImageProps,
|
|
24
|
-
AvatarFallbackProps,
|
|
25
|
-
} from "./atoms/primitives/Avatar.js";
|
|
26
|
-
export {
|
|
27
|
-
Tooltip,
|
|
28
|
-
TooltipProvider,
|
|
29
|
-
TooltipTrigger,
|
|
30
|
-
TooltipContent,
|
|
31
|
-
} from "./atoms/primitives/Tooltip.js";
|
|
32
|
-
export type {
|
|
33
|
-
TooltipProps,
|
|
34
|
-
TooltipProviderProps,
|
|
35
|
-
TooltipTriggerProps,
|
|
36
|
-
TooltipContentProps,
|
|
37
|
-
} from "./atoms/primitives/Tooltip.js";
|
|
38
|
-
export {
|
|
39
|
-
Dialog,
|
|
40
|
-
DialogTrigger,
|
|
41
|
-
DialogPortal,
|
|
42
|
-
DialogClose,
|
|
43
|
-
DialogOverlay,
|
|
44
|
-
DialogContent,
|
|
45
|
-
DialogHeader,
|
|
46
|
-
DialogFooter,
|
|
47
|
-
DialogTitle,
|
|
48
|
-
DialogDescription,
|
|
49
|
-
} from "./atoms/primitives/Dialog.js";
|
|
50
|
-
export type {
|
|
51
|
-
DialogProps,
|
|
52
|
-
DialogTriggerProps,
|
|
53
|
-
DialogPortalProps,
|
|
54
|
-
DialogCloseProps,
|
|
55
|
-
DialogOverlayProps,
|
|
56
|
-
DialogContentProps,
|
|
57
|
-
DialogHeaderProps,
|
|
58
|
-
DialogFooterProps,
|
|
59
|
-
DialogTitleProps,
|
|
60
|
-
DialogDescriptionProps,
|
|
61
|
-
} from "./atoms/primitives/Dialog.js";
|
|
62
|
-
export {
|
|
63
|
-
Collapsible,
|
|
64
|
-
CollapsibleTrigger,
|
|
65
|
-
CollapsibleContent,
|
|
66
|
-
} from "./atoms/primitives/Collapsible.js";
|
|
67
|
-
export type {
|
|
68
|
-
CollapsibleProps,
|
|
69
|
-
CollapsibleTriggerProps,
|
|
70
|
-
CollapsibleContentProps,
|
|
71
|
-
} from "./atoms/primitives/Collapsible.js";
|
|
72
|
-
export { Skeleton } from "./atoms/primitives/Skeleton.js";
|
|
73
|
-
export type { SkeletonProps } from "./atoms/primitives/Skeleton.js";
|
|
74
|
-
|
|
75
|
-
export { Markdown } from "./atoms/Markdown.js";
|
|
76
|
-
export type { MarkdownProps } from "./atoms/Markdown.js";
|
|
77
|
-
export { OpenUIBlock } from "./atoms/OpenUIBlock.js";
|
|
78
|
-
export type { OpenUIBlockProps } from "./atoms/OpenUIBlock.js";
|
|
79
|
-
export { SandboxArtifactList } from "./atoms/SandboxArtifactList.js";
|
|
80
|
-
export type { SandboxArtifactListProps, SandboxArtifactLink } from "./atoms/SandboxArtifactList.js";
|
|
81
|
-
export { CodeBlockHeader } from "./atoms/CodeBlockHeader.js";
|
|
82
|
-
export type { CodeBlockHeaderProps } from "./atoms/CodeBlockHeader.js";
|
|
83
|
-
export { MessageBubble } from "./atoms/MessageBubble.js";
|
|
84
|
-
export type {
|
|
85
|
-
MessageBubbleProps,
|
|
86
|
-
AssistantMessageBubbleProps,
|
|
87
|
-
UserMessageBubbleProps,
|
|
88
|
-
} from "./atoms/MessageBubble.js";
|
|
89
|
-
export { MessageErrorBanner } from "./atoms/MessageErrorBanner.js";
|
|
90
|
-
export type { MessageErrorBannerProps } from "./atoms/MessageErrorBanner.js";
|
|
91
|
-
export { MessageActionBar } from "./atoms/MessageActionBar.js";
|
|
92
|
-
export type { MessageActionBarProps } from "./atoms/MessageActionBar.js";
|
|
93
|
-
export { UserMessageActionBar } from "./atoms/UserMessageActionBar.js";
|
|
94
|
-
export type { UserMessageActionBarProps } from "./atoms/UserMessageActionBar.js";
|
|
95
|
-
export { BranchIndicator } from "./atoms/BranchIndicator.js";
|
|
96
|
-
export type { BranchIndicatorProps } from "./atoms/BranchIndicator.js";
|
|
97
|
-
export { MessageIndicator } from "./atoms/MessageIndicator.js";
|
|
98
|
-
export type { MessageIndicatorProps } from "./atoms/MessageIndicator.js";
|
|
99
|
-
export { WelcomeScreen } from "./atoms/WelcomeScreen.js";
|
|
100
|
-
export type { WelcomeScreenProps } from "./atoms/WelcomeScreen.js";
|
|
101
|
-
export { MessageListSkeleton } from "./atoms/Skeletons.js";
|
|
102
|
-
export type { MessageListSkeletonProps } from "./atoms/Skeletons.js";
|
|
103
|
-
export { ScrollToBottomButton } from "./atoms/ScrollToBottomButton.js";
|
|
104
|
-
export type { ScrollToBottomButtonProps } from "./atoms/ScrollToBottomButton.js";
|
|
105
|
-
export {
|
|
106
|
-
ThreadRootShell,
|
|
107
|
-
ThreadViewportShell,
|
|
108
|
-
ThreadComposerAreaShell,
|
|
109
|
-
MessageGroup,
|
|
110
|
-
} from "./atoms/ThreadShell.js";
|
|
111
|
-
export type {
|
|
112
|
-
ThreadRootShellProps,
|
|
113
|
-
ThreadViewportShellProps,
|
|
114
|
-
ThreadComposerAreaShellProps,
|
|
115
|
-
MessageGroupProps,
|
|
116
|
-
} from "./atoms/ThreadShell.js";
|
|
117
|
-
|
|
118
|
-
export { ToolCallCard } from "./atoms/ToolCallCard.js";
|
|
119
|
-
export type {
|
|
120
|
-
ToolCallStatus,
|
|
121
|
-
ToolCallCardProps,
|
|
122
|
-
ToolCallCardToolProps,
|
|
123
|
-
ToolCallCardSubAgentProps,
|
|
124
|
-
ToolCallCardMcpProps,
|
|
125
|
-
} from "./atoms/ToolCallCard.js";
|
|
126
|
-
export { ToolApprovalBar } from "./atoms/ToolApprovalBar.js";
|
|
127
|
-
export type { ToolApprovalOption, ToolApprovalBarProps } from "./atoms/ToolApprovalBar.js";
|
|
128
|
-
export { ToolGroupCard } from "./atoms/ToolGroupCard.js";
|
|
129
|
-
export type { ToolGroupCardProps } from "./atoms/ToolGroupCard.js";
|
|
130
|
-
export { ReasoningCard } from "./atoms/ReasoningCard.js";
|
|
131
|
-
export type { ReasoningCardProps } from "./atoms/ReasoningCard.js";
|
|
132
|
-
export { ComposerShell } from "./atoms/ComposerShell.js";
|
|
133
|
-
export type { ComposerShellProps } from "./atoms/ComposerShell.js";
|
|
134
|
-
export { AskUserPrompt } from "./atoms/AskUserPrompt.js";
|
|
135
|
-
export type { AskUserOption, AskUserPromptProps } from "./atoms/AskUserPrompt.js";
|
|
136
|
-
export { McpAuthPrompt } from "./atoms/McpAuthPrompt.js";
|
|
137
|
-
export type { McpAuthServer, McpAuthPromptProps } from "./atoms/McpAuthPrompt.js";
|
|
138
|
-
export {
|
|
139
|
-
AttachmentCard,
|
|
140
|
-
USER_MESSAGE_ATTACHMENT_PREVIEW_REM,
|
|
141
|
-
} from "./atoms/AttachmentCard.js";
|
|
142
|
-
export type { AttachmentCardProps, AttachmentCardSize } from "./atoms/AttachmentCard.js";
|
|
143
|
-
export { AttachmentPreviewDialog } from "./atoms/AttachmentPreviewDialog.js";
|
|
144
|
-
export type { AttachmentPreviewDialogProps } from "./atoms/AttachmentPreviewDialog.js";
|
|
145
|
-
export { AttachmentPickerButton } from "./atoms/AttachmentPickerButton.js";
|
|
146
|
-
export type { AttachmentPickerButtonProps } from "./atoms/AttachmentPickerButton.js";
|
|
147
|
-
export { ThreadListRow } from "./atoms/ThreadListRow.js";
|
|
148
|
-
export type { ThreadListRowProps } from "./atoms/ThreadListRow.js";
|
|
149
|
-
export {
|
|
150
|
-
ThreadListNewButton,
|
|
151
|
-
ThreadListRowSkeleton,
|
|
152
|
-
ThreadListEmptyState,
|
|
153
|
-
ThreadListShell,
|
|
154
|
-
} from "./atoms/ThreadListMisc.js";
|
|
155
|
-
export type {
|
|
156
|
-
ThreadListNewButtonProps,
|
|
157
|
-
ThreadListRowSkeletonProps,
|
|
158
|
-
ThreadListEmptyStateProps,
|
|
159
|
-
ThreadListShellProps,
|
|
160
|
-
} from "./atoms/ThreadListMisc.js";
|
|
161
|
-
export { Toast, ToastStack } from "./atoms/Toast.js";
|
|
162
|
-
export type { ToastProps, ToastStackProps } from "./atoms/Toast.js";
|
|
163
|
-
|
|
164
|
-
export { ThreadContainer } from "./containers/ThreadContainer.js";
|
|
165
|
-
export type { ThreadContainerProps } from "./containers/ThreadContainer.js";
|
|
166
|
-
export { AssistantMessageContainer } from "./containers/AssistantMessageContainer.js";
|
|
167
|
-
export { UserMessageContainer } from "./containers/UserMessageContainer.js";
|
|
168
|
-
export { UserEditComposerContainer } from "./containers/UserEditComposerContainer.js";
|
|
169
|
-
export { AssistantTextContainer } from "./containers/AssistantTextContainer.js";
|
|
170
|
-
export { ToolCallContainer } from "./containers/ToolCallContainer.js";
|
|
171
|
-
export { ToolGroupContainer } from "./containers/ToolGroupContainer.js";
|
|
172
|
-
export type { ThreadGroupPart } from "./containers/ToolGroupContainer.js";
|
|
173
|
-
export { ReasoningContainer } from "./containers/ReasoningContainer.js";
|
|
174
|
-
export { ComposerContainer } from "./containers/ComposerContainer.js";
|
|
175
|
-
export {
|
|
176
|
-
ComposerBusyProvider,
|
|
177
|
-
useComposerBusyState,
|
|
178
|
-
} from "./hooks/useComposerBusyState.js";
|
|
179
|
-
export type { ComposerBusyState } from "./hooks/useComposerBusyState.js";
|
|
180
|
-
export { AskUserContainer } from "./containers/AskUserContainer.js";
|
|
181
|
-
export { McpAuthContainer } from "./containers/McpAuthContainer.js";
|
|
182
|
-
export {
|
|
183
|
-
ComposerAttachmentsContainer,
|
|
184
|
-
ComposerAttachmentPickerContainer,
|
|
185
|
-
MessageAttachmentsContainer,
|
|
186
|
-
} from "./containers/AttachmentsContainer.js";
|
|
187
|
-
export { ThreadListContainer } from "./containers/ThreadListContainer.js";
|
|
188
|
-
export {
|
|
189
|
-
ErrorToasterProvider,
|
|
190
|
-
useErrorToaster,
|
|
191
|
-
useErrorToasterOptional,
|
|
192
|
-
} from "./containers/ErrorToasterContainer.js";
|
|
193
|
-
export { Thread } from "./containers/Thread.js";
|
package/src/testSetup.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import "@testing-library/jest-dom/vitest";
|
|
2
|
-
import { createElement, type ReactNode } from "react";
|
|
3
|
-
import { vi } from "vitest";
|
|
4
|
-
|
|
5
|
-
vi.mock("@openuidev/react-lang", () => ({
|
|
6
|
-
Renderer: ({
|
|
7
|
-
response,
|
|
8
|
-
isStreaming,
|
|
9
|
-
}: {
|
|
10
|
-
response: string;
|
|
11
|
-
isStreaming?: boolean;
|
|
12
|
-
}) =>
|
|
13
|
-
createElement(
|
|
14
|
-
"div",
|
|
15
|
-
{
|
|
16
|
-
"data-testid": "openui-renderer",
|
|
17
|
-
"data-streaming": String(!!isStreaming),
|
|
18
|
-
},
|
|
19
|
-
response,
|
|
20
|
-
),
|
|
21
|
-
}));
|
|
22
|
-
|
|
23
|
-
vi.mock("@openuidev/react-ui", () => ({
|
|
24
|
-
ThemeProvider: ({ children, mode }: { children?: ReactNode; mode?: string }) =>
|
|
25
|
-
createElement("div", { "data-testid": "openui-theme-provider", "data-mode": mode }, children),
|
|
26
|
-
}));
|
|
27
|
-
|
|
28
|
-
vi.mock("@openuidev/react-ui/genui-lib", () => ({
|
|
29
|
-
openuiLibrary: {},
|
|
30
|
-
}));
|
|
31
|
-
|
|
32
|
-
// jsdom does not implement ResizeObserver; assistant-ui's viewport/scroll
|
|
33
|
-
// tracking primitives use it, so tests need a no-op stand-in.
|
|
34
|
-
class ResizeObserverStub {
|
|
35
|
-
observe() {}
|
|
36
|
-
unobserve() {}
|
|
37
|
-
disconnect() {}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (typeof globalThis.ResizeObserver === "undefined") {
|
|
41
|
-
globalThis.ResizeObserver = ResizeObserverStub as unknown as typeof ResizeObserver;
|
|
42
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
import { render, screen } from "@testing-library/react";
|
|
3
|
-
import { describe, expect, it } from "vitest";
|
|
4
|
-
|
|
5
|
-
import { Button } from "../atoms/primitives/Button.js";
|
|
6
|
-
import { useSlot, SlotsProvider } from "./SlotsProvider.js";
|
|
7
|
-
|
|
8
|
-
function ButtonConsumer() {
|
|
9
|
-
const SlotButton = useSlot("Button");
|
|
10
|
-
return <SlotButton>hello</SlotButton>;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function CustomButton() {
|
|
14
|
-
return <button data-testid="custom-button">custom</button>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
describe("SlotsProvider", () => {
|
|
18
|
-
it("resolves the default atom when no override is provided", () => {
|
|
19
|
-
render(<ButtonConsumer />);
|
|
20
|
-
const button = screen.getByRole("button", { name: "hello" });
|
|
21
|
-
expect(button).toHaveAttribute("data-slot", "button");
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it("resolves the default atom even without a wrapping SlotsProvider", () => {
|
|
25
|
-
render(<ButtonConsumer />);
|
|
26
|
-
expect(screen.getByRole("button", { name: "hello" })).toBeInTheDocument();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it("resolves an overridden atom when wrapped in SlotsProvider", () => {
|
|
30
|
-
render(
|
|
31
|
-
<SlotsProvider overrides={{ Button }}>
|
|
32
|
-
<ButtonConsumer />
|
|
33
|
-
</SlotsProvider>,
|
|
34
|
-
);
|
|
35
|
-
expect(screen.getByRole("button", { name: "hello" })).toHaveAttribute("data-slot", "button");
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("replaces the resolved atom entirely with the override, not merging it", () => {
|
|
39
|
-
render(
|
|
40
|
-
<SlotsProvider overrides={{ Button: CustomButton as unknown as typeof Button }}>
|
|
41
|
-
<ButtonConsumer />
|
|
42
|
-
</SlotsProvider>,
|
|
43
|
-
);
|
|
44
|
-
expect(screen.getByTestId("custom-button")).toBeInTheDocument();
|
|
45
|
-
expect(screen.queryByRole("button", { name: "hello" })).not.toBeInTheDocument();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("nested SlotsProviders only override the slots they specify, inheriting the rest", () => {
|
|
49
|
-
function IconButtonConsumer() {
|
|
50
|
-
const SlotIconButton = useSlot("IconButton");
|
|
51
|
-
return <SlotIconButton tooltip="tip">icon</SlotIconButton>;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
render(
|
|
55
|
-
<SlotsProvider overrides={{ Button: CustomButton as unknown as typeof Button }}>
|
|
56
|
-
<IconButtonConsumer />
|
|
57
|
-
</SlotsProvider>,
|
|
58
|
-
);
|
|
59
|
-
// IconButton isn't overridden, so it falls through to the default IconButton atom,
|
|
60
|
-
// which internally imports the default Button directly (not via useSlot) -- so it
|
|
61
|
-
// renders its own button, unaffected by the Button override above it.
|
|
62
|
-
expect(screen.getByText("icon")).toBeInTheDocument();
|
|
63
|
-
});
|
|
64
|
-
});
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext, useMemo, type ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
import { defaultSlots } from "./defaultSlots.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Registry of atom-name -> atom-implementation. Empty by default; each atom module
|
|
7
|
-
* augments this interface via `declare module "../theme/SlotsProvider"` when it is
|
|
8
|
-
* introduced, so adding an atom never requires editing this file or any container.
|
|
9
|
-
*/
|
|
10
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
11
|
-
export interface AtomSlots {}
|
|
12
|
-
|
|
13
|
-
export type SlotOverrides = Partial<AtomSlots>;
|
|
14
|
-
|
|
15
|
-
const SlotsContext = createContext<AtomSlots>(defaultSlots);
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Wrap a subtree to override one or more atoms with a different design system.
|
|
19
|
-
* Containers never reference concrete atoms directly -- they resolve everything
|
|
20
|
-
* through `useSlot`, so this is the only thing a design-system swap has to touch.
|
|
21
|
-
*/
|
|
22
|
-
export function SlotsProvider({
|
|
23
|
-
overrides,
|
|
24
|
-
children,
|
|
25
|
-
}: {
|
|
26
|
-
overrides?: SlotOverrides;
|
|
27
|
-
children: ReactNode;
|
|
28
|
-
}) {
|
|
29
|
-
const parentSlots = useContext(SlotsContext);
|
|
30
|
-
const resolved = useMemo(
|
|
31
|
-
() => ({ ...parentSlots, ...overrides }),
|
|
32
|
-
[parentSlots, overrides],
|
|
33
|
-
);
|
|
34
|
-
return <SlotsContext.Provider value={resolved}>{children}</SlotsContext.Provider>;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** Resolves the atom implementation registered for `name` -- default unless overridden. */
|
|
38
|
-
export function useSlot<K extends keyof AtomSlots>(name: K): AtomSlots[K] {
|
|
39
|
-
const slots = useContext(SlotsContext);
|
|
40
|
-
return slots[name];
|
|
41
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { Avatar, AvatarFallback, AvatarImage } from "../atoms/primitives/Avatar.js";
|
|
2
|
-
import { Button } from "../atoms/primitives/Button.js";
|
|
3
|
-
import {
|
|
4
|
-
Collapsible,
|
|
5
|
-
CollapsibleContent,
|
|
6
|
-
CollapsibleTrigger,
|
|
7
|
-
} from "../atoms/primitives/Collapsible.js";
|
|
8
|
-
import {
|
|
9
|
-
Dialog,
|
|
10
|
-
DialogClose,
|
|
11
|
-
DialogContent,
|
|
12
|
-
DialogDescription,
|
|
13
|
-
DialogFooter,
|
|
14
|
-
DialogHeader,
|
|
15
|
-
DialogOverlay,
|
|
16
|
-
DialogPortal,
|
|
17
|
-
DialogTitle,
|
|
18
|
-
DialogTrigger,
|
|
19
|
-
} from "../atoms/primitives/Dialog.js";
|
|
20
|
-
import { IconButton } from "../atoms/primitives/IconButton.js";
|
|
21
|
-
import { Skeleton } from "../atoms/primitives/Skeleton.js";
|
|
22
|
-
import {
|
|
23
|
-
Tooltip,
|
|
24
|
-
TooltipContent,
|
|
25
|
-
TooltipProvider,
|
|
26
|
-
TooltipTrigger,
|
|
27
|
-
} from "../atoms/primitives/Tooltip.js";
|
|
28
|
-
import { BranchIndicator } from "../atoms/BranchIndicator.js";
|
|
29
|
-
import { CodeBlockHeader } from "../atoms/CodeBlockHeader.js";
|
|
30
|
-
import { Markdown } from "../atoms/Markdown.js";
|
|
31
|
-
import { OpenUIBlock } from "../atoms/OpenUIBlock.js";
|
|
32
|
-
import { SandboxArtifactList } from "../atoms/SandboxArtifactList.js";
|
|
33
|
-
import { MessageActionBar } from "../atoms/MessageActionBar.js";
|
|
34
|
-
import { UserMessageActionBar } from "../atoms/UserMessageActionBar.js";
|
|
35
|
-
import { MessageBubble } from "../atoms/MessageBubble.js";
|
|
36
|
-
import { MessageErrorBanner } from "../atoms/MessageErrorBanner.js";
|
|
37
|
-
import { MessageIndicator } from "../atoms/MessageIndicator.js";
|
|
38
|
-
import { ScrollToBottomButton } from "../atoms/ScrollToBottomButton.js";
|
|
39
|
-
import { MessageListSkeleton } from "../atoms/Skeletons.js";
|
|
40
|
-
import {
|
|
41
|
-
MessageGroup,
|
|
42
|
-
ThreadComposerAreaShell,
|
|
43
|
-
ThreadRootShell,
|
|
44
|
-
ThreadViewportShell,
|
|
45
|
-
} from "../atoms/ThreadShell.js";
|
|
46
|
-
import { AskUserPrompt } from "../atoms/AskUserPrompt.js";
|
|
47
|
-
import { AttachmentCard } from "../atoms/AttachmentCard.js";
|
|
48
|
-
import { AttachmentPickerButton } from "../atoms/AttachmentPickerButton.js";
|
|
49
|
-
import { AttachmentPreviewDialog } from "../atoms/AttachmentPreviewDialog.js";
|
|
50
|
-
import { ComposerShell } from "../atoms/ComposerShell.js";
|
|
51
|
-
import { McpAuthPrompt } from "../atoms/McpAuthPrompt.js";
|
|
52
|
-
import { ReasoningCard } from "../atoms/ReasoningCard.js";
|
|
53
|
-
import { ToolApprovalBar } from "../atoms/ToolApprovalBar.js";
|
|
54
|
-
import { ThreadListRow } from "../atoms/ThreadListRow.js";
|
|
55
|
-
import {
|
|
56
|
-
ThreadListEmptyState,
|
|
57
|
-
ThreadListNewButton,
|
|
58
|
-
ThreadListRowSkeleton,
|
|
59
|
-
ThreadListShell,
|
|
60
|
-
} from "../atoms/ThreadListMisc.js";
|
|
61
|
-
import { Toast, ToastStack } from "../atoms/Toast.js";
|
|
62
|
-
import { ToolCallCard } from "../atoms/ToolCallCard.js";
|
|
63
|
-
import { ToolGroupCard } from "../atoms/ToolGroupCard.js";
|
|
64
|
-
import { WelcomeScreen } from "../atoms/WelcomeScreen.js";
|
|
65
|
-
import type { AtomSlots } from "./SlotsProvider.js";
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* This SDK's default atom implementations, keyed by slot name. Populated
|
|
69
|
-
* incrementally as atoms are added under `src/atoms/**`; each atom module
|
|
70
|
-
* augments `AtomSlots` and this object gains the matching entry in the same
|
|
71
|
-
* milestone.
|
|
72
|
-
*/
|
|
73
|
-
export const defaultSlots: AtomSlots = {
|
|
74
|
-
Button,
|
|
75
|
-
IconButton,
|
|
76
|
-
Avatar,
|
|
77
|
-
AvatarImage,
|
|
78
|
-
AvatarFallback,
|
|
79
|
-
Tooltip,
|
|
80
|
-
TooltipProvider,
|
|
81
|
-
TooltipTrigger,
|
|
82
|
-
TooltipContent,
|
|
83
|
-
Dialog,
|
|
84
|
-
DialogTrigger,
|
|
85
|
-
DialogPortal,
|
|
86
|
-
DialogClose,
|
|
87
|
-
DialogOverlay,
|
|
88
|
-
DialogContent,
|
|
89
|
-
DialogHeader,
|
|
90
|
-
DialogFooter,
|
|
91
|
-
DialogTitle,
|
|
92
|
-
DialogDescription,
|
|
93
|
-
Collapsible,
|
|
94
|
-
CollapsibleTrigger,
|
|
95
|
-
CollapsibleContent,
|
|
96
|
-
Skeleton,
|
|
97
|
-
Markdown,
|
|
98
|
-
OpenUIBlock,
|
|
99
|
-
SandboxArtifactList,
|
|
100
|
-
CodeBlockHeader,
|
|
101
|
-
MessageBubble,
|
|
102
|
-
MessageErrorBanner,
|
|
103
|
-
MessageActionBar,
|
|
104
|
-
UserMessageActionBar,
|
|
105
|
-
BranchIndicator,
|
|
106
|
-
MessageIndicator,
|
|
107
|
-
WelcomeScreen,
|
|
108
|
-
MessageListSkeleton,
|
|
109
|
-
ScrollToBottomButton,
|
|
110
|
-
ThreadRootShell,
|
|
111
|
-
ThreadViewportShell,
|
|
112
|
-
ThreadComposerAreaShell,
|
|
113
|
-
MessageGroup,
|
|
114
|
-
ToolCallCard,
|
|
115
|
-
ToolApprovalBar,
|
|
116
|
-
ToolGroupCard,
|
|
117
|
-
ReasoningCard,
|
|
118
|
-
ComposerShell,
|
|
119
|
-
AskUserPrompt,
|
|
120
|
-
McpAuthPrompt,
|
|
121
|
-
AttachmentCard,
|
|
122
|
-
AttachmentPreviewDialog,
|
|
123
|
-
AttachmentPickerButton,
|
|
124
|
-
ThreadListRow,
|
|
125
|
-
ThreadListNewButton,
|
|
126
|
-
ThreadListRowSkeleton,
|
|
127
|
-
ThreadListEmptyState,
|
|
128
|
-
ThreadListShell,
|
|
129
|
-
Toast,
|
|
130
|
-
ToastStack,
|
|
131
|
-
};
|
package/src/theme/tokens.ts
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { createContext, createElement, useContext, type ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Semantic color roles. Atoms reference these instead of raw hex/HSL values so a
|
|
5
|
-
* future design-system swap only has to repoint the token values, not the atoms.
|
|
6
|
-
*/
|
|
7
|
-
export type ColorToken =
|
|
8
|
-
| "background"
|
|
9
|
-
| "foreground"
|
|
10
|
-
| "muted"
|
|
11
|
-
| "mutedForeground"
|
|
12
|
-
| "border"
|
|
13
|
-
| "primary"
|
|
14
|
-
| "primaryForeground"
|
|
15
|
-
| "destructive"
|
|
16
|
-
| "destructiveForeground"
|
|
17
|
-
| "accent"
|
|
18
|
-
| "accentForeground";
|
|
19
|
-
|
|
20
|
-
export type RadiusToken = "none" | "sm" | "md" | "lg" | "full";
|
|
21
|
-
|
|
22
|
-
export type SpacingToken = "none" | "xs" | "sm" | "md" | "lg" | "xl";
|
|
23
|
-
|
|
24
|
-
export type TypeRoleToken = "body" | "bodySmall" | "label" | "heading" | "code" | "caption";
|
|
25
|
-
|
|
26
|
-
export interface TypeRoleValue {
|
|
27
|
-
fontSize: string;
|
|
28
|
-
lineHeight: string;
|
|
29
|
-
fontWeight: string | number;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface DesignTokens {
|
|
33
|
-
colors: Record<ColorToken, string>;
|
|
34
|
-
radii: Record<RadiusToken, string>;
|
|
35
|
-
spacing: Record<SpacingToken, string>;
|
|
36
|
-
typography: Record<TypeRoleToken, TypeRoleValue>;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Values reference the CSS custom properties already emitted by the shadcn/Tailwind
|
|
41
|
-
* theme in the ported reference app, so default atoms render identically to today
|
|
42
|
-
* without requiring every atom to be rewritten to consume tokens in this pass.
|
|
43
|
-
*/
|
|
44
|
-
export const defaultTokens: DesignTokens = {
|
|
45
|
-
colors: {
|
|
46
|
-
background: "var(--background)",
|
|
47
|
-
foreground: "var(--foreground)",
|
|
48
|
-
muted: "var(--muted)",
|
|
49
|
-
mutedForeground: "var(--muted-foreground)",
|
|
50
|
-
border: "var(--border)",
|
|
51
|
-
primary: "var(--primary)",
|
|
52
|
-
primaryForeground: "var(--primary-foreground)",
|
|
53
|
-
destructive: "var(--destructive)",
|
|
54
|
-
destructiveForeground: "var(--destructive-foreground)",
|
|
55
|
-
accent: "var(--accent)",
|
|
56
|
-
accentForeground: "var(--accent-foreground)",
|
|
57
|
-
},
|
|
58
|
-
radii: {
|
|
59
|
-
none: "0px",
|
|
60
|
-
sm: "calc(var(--radius) - 4px)",
|
|
61
|
-
md: "calc(var(--radius) - 2px)",
|
|
62
|
-
lg: "var(--radius)",
|
|
63
|
-
full: "9999px",
|
|
64
|
-
},
|
|
65
|
-
spacing: {
|
|
66
|
-
none: "0px",
|
|
67
|
-
xs: "0.25rem",
|
|
68
|
-
sm: "0.5rem",
|
|
69
|
-
md: "0.75rem",
|
|
70
|
-
lg: "1rem",
|
|
71
|
-
xl: "1.5rem",
|
|
72
|
-
},
|
|
73
|
-
typography: {
|
|
74
|
-
body: { fontSize: "0.875rem", lineHeight: "1.5rem", fontWeight: 400 },
|
|
75
|
-
bodySmall: { fontSize: "0.75rem", lineHeight: "1.25rem", fontWeight: 400 },
|
|
76
|
-
label: { fontSize: "0.75rem", lineHeight: "1rem", fontWeight: 500 },
|
|
77
|
-
heading: { fontSize: "1.25rem", lineHeight: "1.75rem", fontWeight: 600 },
|
|
78
|
-
code: { fontSize: "0.8125rem", lineHeight: "1.25rem", fontWeight: 400 },
|
|
79
|
-
caption: { fontSize: "0.6875rem", lineHeight: "1rem", fontWeight: 400 },
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const TokensContext = createContext<DesignTokens>(defaultTokens);
|
|
84
|
-
|
|
85
|
-
export function TokensProvider({
|
|
86
|
-
tokens,
|
|
87
|
-
children,
|
|
88
|
-
}: {
|
|
89
|
-
tokens: DesignTokens;
|
|
90
|
-
children: ReactNode;
|
|
91
|
-
}) {
|
|
92
|
-
return createElement(TokensContext.Provider, { value: tokens }, children);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/** Atoms may call this for theme-driven values; it is not an assistant-ui/runtime hook. */
|
|
96
|
-
export function useTokens(): DesignTokens {
|
|
97
|
-
return useContext(TokensContext);
|
|
98
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { useSyncExternalStore } from "react";
|
|
2
|
-
|
|
3
|
-
export type ThemeMode = "light" | "dark";
|
|
4
|
-
|
|
5
|
-
function getThemeMode(): ThemeMode {
|
|
6
|
-
if (typeof document === "undefined") {
|
|
7
|
-
return "light";
|
|
8
|
-
}
|
|
9
|
-
return document.documentElement.classList.contains("dark") ? "dark" : "light";
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function subscribe(onStoreChange: () => void) {
|
|
13
|
-
const observer = new MutationObserver(onStoreChange);
|
|
14
|
-
observer.observe(document.documentElement, {
|
|
15
|
-
attributes: true,
|
|
16
|
-
attributeFilter: ["class"],
|
|
17
|
-
});
|
|
18
|
-
return () => observer.disconnect();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/** Syncs OpenUI theme mode with a `.dark` class on `<html>`. */
|
|
22
|
-
export function useClassDarkMode(): ThemeMode {
|
|
23
|
-
return useSyncExternalStore(subscribe, getThemeMode, () => "light");
|
|
24
|
-
}
|