mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-18 19:03:48 +00:00
Share chat UI components in @sandbox-agent/react (#228)
* Extract shared chat UI components * chore(release): update version to 0.3.1 * Use shared chat UI in Foundry
This commit is contained in:
parent
6d7e67fe72
commit
0471214d65
19 changed files with 1679 additions and 727 deletions
85
sdks/react/src/AgentConversation.tsx
Normal file
85
sdks/react/src/AgentConversation.tsx
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
"use client";
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
import { AgentTranscript, type AgentTranscriptClassNames, type AgentTranscriptProps, type TranscriptEntry } from "./AgentTranscript.tsx";
|
||||
import { ChatComposer, type ChatComposerClassNames, type ChatComposerProps } from "./ChatComposer.tsx";
|
||||
|
||||
export interface AgentConversationClassNames {
|
||||
root: string;
|
||||
transcript: string;
|
||||
emptyState: string;
|
||||
composer: string;
|
||||
}
|
||||
|
||||
export interface AgentConversationProps {
|
||||
entries: TranscriptEntry[];
|
||||
className?: string;
|
||||
classNames?: Partial<AgentConversationClassNames>;
|
||||
emptyState?: ReactNode;
|
||||
transcriptClassName?: string;
|
||||
transcriptClassNames?: Partial<AgentTranscriptClassNames>;
|
||||
composerClassName?: string;
|
||||
composerClassNames?: Partial<ChatComposerClassNames>;
|
||||
transcriptProps?: Omit<AgentTranscriptProps, "entries" | "className" | "classNames">;
|
||||
composerProps?: Omit<ChatComposerProps, "className" | "classNames">;
|
||||
}
|
||||
|
||||
const DEFAULT_CLASS_NAMES: AgentConversationClassNames = {
|
||||
root: "sa-agent-conversation",
|
||||
transcript: "sa-agent-conversation-transcript",
|
||||
emptyState: "sa-agent-conversation-empty-state",
|
||||
composer: "sa-agent-conversation-composer",
|
||||
};
|
||||
|
||||
const cx = (...values: Array<string | false | null | undefined>) => values.filter(Boolean).join(" ");
|
||||
|
||||
const mergeClassNames = (
|
||||
defaults: AgentConversationClassNames,
|
||||
overrides?: Partial<AgentConversationClassNames>,
|
||||
): AgentConversationClassNames => ({
|
||||
root: cx(defaults.root, overrides?.root),
|
||||
transcript: cx(defaults.transcript, overrides?.transcript),
|
||||
emptyState: cx(defaults.emptyState, overrides?.emptyState),
|
||||
composer: cx(defaults.composer, overrides?.composer),
|
||||
});
|
||||
|
||||
export const AgentConversation = ({
|
||||
entries,
|
||||
className,
|
||||
classNames: classNameOverrides,
|
||||
emptyState,
|
||||
transcriptClassName,
|
||||
transcriptClassNames,
|
||||
composerClassName,
|
||||
composerClassNames,
|
||||
transcriptProps,
|
||||
composerProps,
|
||||
}: AgentConversationProps) => {
|
||||
const resolvedClassNames = mergeClassNames(DEFAULT_CLASS_NAMES, classNameOverrides);
|
||||
const hasTranscriptContent =
|
||||
entries.length > 0 || Boolean(transcriptProps?.sessionError) || Boolean(transcriptProps?.eventError);
|
||||
|
||||
return (
|
||||
<div className={cx(resolvedClassNames.root, className)} data-slot="root">
|
||||
{hasTranscriptContent ? (
|
||||
<AgentTranscript
|
||||
entries={entries}
|
||||
className={cx(resolvedClassNames.transcript, transcriptClassName)}
|
||||
classNames={transcriptClassNames}
|
||||
{...transcriptProps}
|
||||
/>
|
||||
) : emptyState ? (
|
||||
<div className={resolvedClassNames.emptyState} data-slot="empty-state">
|
||||
{emptyState}
|
||||
</div>
|
||||
) : null}
|
||||
{composerProps ? (
|
||||
<ChatComposer
|
||||
className={cx(resolvedClassNames.composer, composerClassName)}
|
||||
classNames={composerClassNames}
|
||||
{...composerProps}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue