/**
* Synthetic waveform when real audio is unavailable: `ambient` is calm,
* `speaking` is active, and `thinking` is a travelling pulse.
*/
export type WaveformPreset = "ambient" | "speaking" | "thinking";
/**
* Drives waveform bar heights. Prefer `stream`; use `analyser` for an existing
* audio graph, `amplitude` for a caller-computed `0..1` level, or `preset` when
* real audio is unavailable. The component never requests microphone access.
*/
export type WaveformSource = {
type: "amplitude";
value: number;
} | {
type: "analyser";
node: AnalyserNode;
} | {
type: "stream";
stream: MediaStream;
} | {
type: "preset";
name: WaveformPreset;
};
/** Attachment rendered as a thumbnail in the PromptBar. */
export type PromptAttachment = {
/** Stable identity, used for removal and React keys. */
id: string;
/**
* Used for thumbnail alt text, the remove label, and fallback content.
*/
name: string;
/** Preview image; the tile shows `name` when omitted. */
thumbnailUrl?: string;
};
/** Live transcription feed. Mode is derived from `active`. */
export type PromptBarTranscription = {
/** Replaces the editor with transcription UI while `true`. */
active: boolean;
/**
* Waveform input while active. Defaults to the `ambient` preset.
* See {@link WaveformSource}.
*/
source?: WaveformSource | undefined;
/**
* Replaces the active waveform with a critical error message. The primary
* action becomes Dismiss and exits via cancel, not confirm.
*/
error?: string | undefined;
};
/**
* Prop-derived layout: empty `idle`, content-bearing `draft`, or
* `transcribing`, which replaces the editor with transcription controls.
*/
export type PromptBarMode = "idle" | "draft" | "transcribing";
/** Primary action currently shown by the bar. */
export type PrimaryActionKind = "send" | "confirm" | "stop";
/** Disclaimer shown below the bar. */
export type PromptBarDisclaimer = {
/**
* Full sentence. Wrap linked text in `…`. Defaults to the
* standard Atlas notice.
*
* This is parsed as ICU: escape apostrophes as `''` and quote literal braces.
*
* @example "AI responses may be inaccurate. Learn more"
*/
message?: string;
/**
* Destination for ``. Without it, linked text renders as plain text.
*/
linkHref?: string;
};
/**
* Controlled chat composer for text, attachments, and transcription. Its
* primary action switches among Send, Stop, and transcription confirmation.
*/
export type PromptBarProps = {
/** Editor contents; empty text and no attachments select the idle layout. */
value: string;
/** Receives editor contents after each text edit. */
onChange: (value: string) => void;
/** Thumbnails shown above the editor; hidden while transcribing. */
attachments?: PromptAttachment[];
/** Add control remains visible but inert when omitted. */
onAddAttachment?: () => void;
/** Remove controls remain visible but inert when omitted. */
onRemoveAttachment?: (id: string) => void;
/** Invoked by the enabled primary action or unmodified Enter. */
onSend?: () => void;
/**
* Overrides whether sending is allowed. Defaults to any non-empty draft or
* attachment.
*/
canSend?: boolean;
/**
* Withholds sending while a response is in flight. When `onStop` is set, the
* primary action becomes Stop.
*/
isSending?: boolean;
/** Enables Stop while `isSending`. */
onStop?: () => void;
/** Microphone control remains visible but inert when omitted. */
onStartTranscription?: () => void;
/** Replaces the editor with waveform or error UI while active. */
transcription?: PromptBarTranscription | undefined;
/** Cancel control remains visible but inert when omitted. */
onCancelTranscription?: () => void;
/** Done control remains visible but inert when omitted. */
onConfirmTranscription?: () => void;
/**
* Composer hint shown only while the editor is empty. Defaults to the
* localized prompt.
*/
placeholder?: string;
/** Makes composer controls inert without hiding their content. */
disabled?: boolean;
/**
* Omit for the default notice, customize with an object, or pass `null` to
* hide it.
*/
disclaimer?: PromptBarDisclaimer | null;
className?: string;
};