A React client component that renders a single ticket row inside a chat/support panel, supporting interactive, loading skeleton, and linked-work states. ## Key Components ### Interfaces - **`ChatTicketItemData`** — Data model for a ticket row, including `id`, `title`, `ticketNumber`, `status`, `statusLabel`, `statusKind`, `statusColor`, `category`, `timeAgo`, and optional `linkedTaskLabel` (renders a wrench-icon chip when present). - **`ChatTicketItemProps`** — Props for the component; extends `HTMLButtonElement` attributes (excluding native `onClick`), accepting `ticket`, a typed `onClick(ticketId: string)` callback, and `isLoading`. ### Component - **`ChatTicketItem`** — A `forwardRef` button component with three render states: - **Loading** (`isLoading=true`): Renders an `aria-hidden` skeleton placeholder sized to match a real row. - **No data** (`ticket` is `undefined`): Returns `null`. - **Populated**: Renders the ticket title, a subtitle line joining `ticketNumber`, `category`, and `timeAgo` with bullet separators, an optional linked-work `Tag` chip (hidden on `sm` and below), a `TicketStatusTag`, and a chevron navigation indicator. ## Usage Example ```typescript import { ChatTicketItem } from './chat-ticket-item' // Loading state // Populated state router.push(`/tickets/${ticketId}`)} /> // With custom HubSpot pipeline stage label console.log('opened', id)} /> ``` ## Notes - Status resolution delegates to `resolveStatusTagProps` and `resolveTicketStatus`, allowing any status string format (`ACTIVE`, `active`, `ACTION_REQUIRED`, etc.). - The linked-work chip (`linkedTaskLabel`) is hidden on small screens via `hidden sm:inline-flex` to prevent row crowding. - Focus styles explicitly suppress the post-click outline ring using `focus:outline-none focus:bg-ods-bg-hover` while preserving keyboard-nav visibility via `focus-visible:ring-2`.