Renders a collapsible chat history sidebar with a dialog list, infinite scroll pagination, skeleton loading states, and an empty state view for the OpenFrame chat interface. ## Key Components | Export | Type | Description | |---|---|---| | `ChatSidebar` | `forwardRef` component | Main sidebar container managing dialog list, loading, and empty states | | `DialogListItem` | `forwardRef` component | Individual chat entry row with title, timestamp, and unread badge | ### `ChatSidebar` Props | Prop | Type | Description | |---|---|---| | `dialogs` | `Dialog[]` | List of chat sessions to render | | `activeDialogId` | `string` | Highlights the currently selected dialog | | `onNewChat` | `() => void` | Callback for the "Start New Chat" button | | `onDialogSelect` | `(id: string) => void` | Callback when a dialog row is clicked | | `isLoading` | `boolean` | Shows full skeleton when `true` and list is empty | | `isCreatingDialog` | `boolean` | Disables the new chat button during creation | | `hasNextPage` | `boolean` | Enables the `IntersectionObserver`-based infinite scroll trigger | | `isFetchingNextPage` | `boolean` | Shows skeleton rows at the bottom while fetching | | `onLoadMore` | `() => void` | Fired when the sentinel element enters the viewport | | `children` | `ReactNode` | Replaces the default dialog list with custom content | ## Usage Example ```typescript import { ChatSidebar } from "@openframe-oss-lib/components" const dialogs = [ { id: "1", title: "Network Issue", timestamp: new Date(), unreadMessagesCount: 3 }, { id: "2", title: "Printer Setup", timestamp: new Date() }, ] export function AppLayout() { const [activeId, setActiveId] = useState("1") return ( console.log("new chat")} onDialogSelect={(id) => setActiveId(id)} hasNextPage={true} isFetchingNextPage={false} onLoadMore={() => fetchNextPage()} /> ) } ``` > **Infinite scroll:** A sentinel `
` at the bottom of the list is observed via `IntersectionObserver` with a `100px` root margin. `onLoadMore` fires automatically when it enters the scroll container's viewport, provided `hasNextPage` is `true` and a fetch isn't already in progress. **Source:** [`chat-sidebar.tsx`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/chat-sidebar.tsx)