/** * @oxpulse/chat-widget — Composer (W2.2 slice 2, fix-loop). * * Plain-text message input + send path. * Dispatches `oxpulse-chat:error` on send failure + renders inline error chip. * Uses theme tokens exclusively — no inline hex. */ import type { ProductMeta } from '../types.js'; import { type ReplySnapshot } from '../utils/reply-helpers.js'; import type { EnvelopeAttachment } from '../utils/attachment-envelope.js'; /** Optional args forwarded to the SDK sendText call. */ export interface SendTextArgs { /** W7: thread reply — UUID of the message being replied to. */ threadRootMsgId?: string; productRef?: string; productMeta?: ProductMeta; } /** Minimal SDK client surface required by Composer. */ interface ComposerClient { sendText(roomId: string, text: string, args?: SendTextArgs): Promise<{ msgId: string; }>; sendTextOptimistic?(roomId: string, text: string, args?: SendTextArgs): Promise<{ msgId: string; }>; /** #120: broadcast typing indicator. Fire-and-forget. */ sendTyping?(roomId: string, ttlSecs?: number): Promise; e2ee?: unknown; /** Stage-then-send split (slice 4): upload an attachment and return its id + envelope metadata. */ uploadAttachment?(roomId: string, blob: Blob, args: { mimeType?: string; filename?: string; width?: number; height?: number; signal?: AbortSignal; }): Promise<{ attachmentId: string; attachment: EnvelopeAttachment; }>; /** Stage-then-send split (slice 4): send a message with the given caption + attachment envelope. */ sendAttachmentMessage?(roomId: string, body: string, attachments: readonly EnvelopeAttachment[], args?: SendTextArgs): Promise<{ msgId: string; }>; /** Non-blocking attachment send: enqueues the message to the outbox immediately * and sends it in the background once the attachmentsPromise resolves with * the uploaded attachment metadata. Returns at once with the msgId — the * composer regains control and the user can keep typing/sending. */ sendAttachmentMessageOptimistic?(roomId: string, body: string, attachmentsPromise: Promise, args?: SendTextArgs): { msgId: string; }; } export interface ComposerOptions { client: ComposerClient; roomId: string; container: HTMLElement; signal?: AbortSignal; /** M5: Optional placeholder text. Default: the localized 'composerPlaceholder' key. */ placeholder?: string; /** BCP-47 tag or an already-resolved Locale. Optional — defaults via resolveLocale(). */ lang?: string; /** MAJOR-5: Optional shadow root so the emoji picker mounts outside overflow:hidden * widgetRoot — mirrors MessageList's shadowHost pattern. */ shadowHost?: ShadowRoot; /** Seller product catalog client — when present, shows a product picker * button in the toolbar. onSelect → setProductCard(ref, meta). */ catalogClient?: import('@oxpulse/chat-sdk').SDKCatalogClient; } export declare class Composer { #private; constructor(opts: ComposerOptions); /** * CM1: Pre-fill the textarea with an initial value before mount(). * Must be called before mount(). #updateState() in mount() will reflect this value * so the send button and counter start in the correct state. */ setInitialText(text: string): void; /** * D2: Restore text into the textarea after mount — used by the send-failed * retry flow to put the caption back so the user can re-pick the attachment * and re-send. Triggers #updateState so the send button reflects the new text. */ restoreText(text: string): void; /** * W9: Attach a product card to the next outgoing text message. * The product ref and metadata are forwarded to sendText/sendTextOptimistic * and are cleared once the message is sent. * * E2EE posture: `productMeta` (title/price/imageUrl/productUrl) travels * UNSEALED in the wire payload and is server-visible even in E2EE rooms — * by design, mirroring the sendProductCard contract to enable marketplace * search. Only `productRef` is opaque. Do not put sensitive data in * `productMeta`. * * Routing (#114): the widget sends cards through `sendText()` with * `productRef`/`productMeta` args rather than the SDK's standalone * `sendProductCard()` convenience API — see the doc-comment on * `SDKChatClient.sendProductCard` in packages/chat-sdk/src/client.ts for * the rationale. Both paths produce the same wire payload. */ setProductCard(productRef: string, productMeta: ProductMeta): void; /** Clear a previously set product card without sending. */ clearProductCard(): void; /** * W7: Set the message to reply to. The composer renders a preview bar and * sends the next message with `threadRootMsgId` populated. Pass `null` to clear. */ setReplyTarget(target: ReplySnapshot | null): void; mount(): void; destroy(): void; } export {}; //# sourceMappingURL=composer.d.ts.map