Reply composer component for open support tickets, combining a `ChatInput` with file attachment support and a close-ticket confirmation dialog. ## Key Components ### `TicketReplyComposer` The main exported component. Renders a unified composer layout with: - **`ChatAttachmentChipStrip`** — staged file chips displayed above the input - **`ChatInput`** — primary text input with send button; disabled during in-flight uploads or when the support system is down - **`ChatAttachmentAddButton`** — attachment trigger in the bottom toolbar (hidden when `supportSystemDown`) - **`Close ticket` button** — opens an `AlertDialog` to confirm closure with an optional resolution note ### `TicketReplyComposerProps` | Prop | Type | Description | |---|---|---| | `ticket` | `AnyTicket` | The ticket being replied to | | `busy` | `boolean` | Disables input while a send is in progress | | `supportSystemDown` | `boolean` | Signals connection loss; swaps in a placeholder and hides attachments | | `onSendMessage` | `TicketDetailDrawerProps['onSendMessage']` | Async send handler; returns `boolean` indicating success | | `onClose` | `TicketDetailDrawerProps['onClose']` | Async close handler; receives an optional resolution string | ## Usage Example ```typescript { const ok = await sendReply(ref.id, text, attachments) return ok }} onClose={async (ref, resolution) => { await closeTicket(ref.id, resolution) }} /> ``` ## Behavior Notes - Draft text and staged files **survive a failed send** — `ChatInput` retains text; attachments are only cleared on success - Close confirmation uses a **non-destructive accent button** (closing is reversible via Reopen) - `autoFocus` uses `{ preventScroll: true }` internally, so the drawer's scroll-to-top animation is not interrupted - The drawer is **not collapsed** after closing a ticket (no `onActionCollapsed`) to preserve the in-place status badge update ## Source [`ticket-reply-composer.tsx`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/ticket-reply-composer.tsx)