Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
106 lines
2.9 KiB
TypeScript
106 lines
2.9 KiB
TypeScript
import { useId, type ReactNode } from "react";
|
|
import { ChevronDown } from "lucide-react";
|
|
import { cn } from "../../app/renderer/lib/utils";
|
|
import styles from "./AgentGUIChrome.styles";
|
|
|
|
/**
|
|
* Product-neutral composer accessory that expands upward from its persistent
|
|
* banner. The disclosure trigger and trailing actions are siblings so actions
|
|
* never become nested interactive controls.
|
|
*/
|
|
export function AgentComposerDisclosureCard({
|
|
actions,
|
|
bannerClassName,
|
|
children,
|
|
expanded,
|
|
icon,
|
|
labels,
|
|
onExpandedChange,
|
|
panelClassName,
|
|
summary,
|
|
testId,
|
|
title
|
|
}: {
|
|
actions?: ReactNode;
|
|
/** Extra class applied to the persistent banner card only. */
|
|
bannerClassName?: string;
|
|
children: ReactNode;
|
|
expanded: boolean;
|
|
icon: ReactNode;
|
|
labels: {
|
|
collapse: string;
|
|
expand: string;
|
|
};
|
|
onExpandedChange(expanded: boolean): void;
|
|
/** Extra class applied to the expanded panel surface only. */
|
|
panelClassName?: string;
|
|
summary: string;
|
|
testId: string;
|
|
title: string;
|
|
}): React.JSX.Element {
|
|
const panelId = useId();
|
|
const disclosureLabel = expanded ? labels.collapse : labels.expand;
|
|
|
|
return (
|
|
<div className={styles.sessionChrome}>
|
|
<section
|
|
className={styles.composerDisclosure}
|
|
data-expanded={expanded ? "true" : "false"}
|
|
data-testid={testId}
|
|
>
|
|
{expanded ? (
|
|
<div
|
|
id={panelId}
|
|
className={cn(styles.composerDisclosurePanel, panelClassName)}
|
|
data-testid={`${testId}-panel`}
|
|
>
|
|
{children}
|
|
</div>
|
|
) : null}
|
|
<div
|
|
className={cn(
|
|
styles.chromeCard,
|
|
styles.chromeCardMuted,
|
|
styles.composerDisclosureBanner,
|
|
bannerClassName
|
|
)}
|
|
>
|
|
<button
|
|
type="button"
|
|
className={styles.composerDisclosureTrigger}
|
|
aria-controls={panelId}
|
|
aria-expanded={expanded}
|
|
aria-label={disclosureLabel}
|
|
title={disclosureLabel}
|
|
onClick={() => onExpandedChange(!expanded)}
|
|
>
|
|
<span className={styles.chromeIcon}>{icon}</span>
|
|
<span
|
|
className={cn(styles.chromeMessage, styles.chromeNoticeMessage)}
|
|
title={`${title} · ${summary}`}
|
|
>
|
|
<span className={styles.chromeNoticeTitle}>{title}</span>
|
|
<span
|
|
className={styles.chromeNoticeDescription}
|
|
aria-live="polite"
|
|
>
|
|
{summary}
|
|
</span>
|
|
</span>
|
|
<ChevronDown
|
|
aria-hidden
|
|
className={cn(
|
|
styles.composerDisclosureChevron,
|
|
expanded && styles.composerDisclosureChevronExpanded
|
|
)}
|
|
/>
|
|
</button>
|
|
{actions ? (
|
|
<div className={styles.chromeGoalActions}>{actions}</div>
|
|
) : null}
|
|
</div>
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|