Chat Conversations
A two-pane inbox layout. The left pane is a searchable, sortable list of conversations; the right pane renders whatever you put inside (typically a ChatWindow). Pin, archive, badge, count unread, group, sort — all driven by your own data shape.
Live Demo
Multi-Conversation Inbox
A working inbox with multiple conversations. Click any thread on the left to switch — the right pane updates instantly. Each conversation gets its own theme to make context-switching obvious.
<ChatConversations
conversations={conversations}
activeId={activeId}
onSelect={setActiveId}
title="Inbox"
>
<ChatWindow messages={messagesFor(activeId)} onSendMessage={handleSend} />
</ChatConversations>Import
import { ChatConversations, ChatWindow } from 'fluxo-ui';
import type { ChatConversationItem, ChatConversationsProps } from 'fluxo-ui';ChatConversations Props
conversationsreqChatConversationItem[]List of conversations to render in the sidebar.
conversationsreqChatConversationItem[]List of conversations to render in the sidebar.
activeIdstringID of the currently active conversation; highlighted in the list.
activeIdstringID of the currently active conversation; highlighted in the list.
onSelect(id: string) => voidFires when a conversation row is clicked.
onSelect(id: string) => voidFires when a conversation row is clicked.
onSearch(query: string) => voidFires when the search input changes. Internal filtering still runs in addition to this.
onSearch(query: string) => voidFires when the search input changes. Internal filtering still runs in addition to this.
onPin(id: string, pinned: boolean) => voidFires when an item is pinned/unpinned (consumer-triggered actions).
onPin(id: string, pinned: boolean) => voidFires when an item is pinned/unpinned (consumer-triggered actions).
onArchive(id: string, archived: boolean) => voidFires when an item is archived/unarchived.
onArchive(id: string, archived: boolean) => voidFires when an item is archived/unarchived.
onDelete(id: string) => voidFires when an item is deleted.
onDelete(id: string) => voidFires when an item is deleted.
searchableboolean"true"Show the built-in search input above the list.
searchableboolean"true"Show the built-in search input above the list.
sidebarWidthnumber | string"'280px'"Initial width of the sidebar panel.
sidebarWidthnumber | string"'280px'"Initial width of the sidebar panel.
minSidebarWidthnumber"200"Minimum sidebar panel width.
minSidebarWidthnumber"200"Minimum sidebar panel width.
maxSidebarWidthnumber"480"Maximum sidebar panel width.
maxSidebarWidthnumber"480"Maximum sidebar panel width.
hideArchivedbooleanFilter archived conversations out of the visible list.
hideArchivedbooleanFilter archived conversations out of the visible list.
emptyStateReactNodeContent rendered when no conversations match.
emptyStateReactNodeContent rendered when no conversations match.
renderItem(item: ChatConversationItem, ctx) => ReactNodeCustom row renderer.
renderItem(item: ChatConversationItem, ctx) => ReactNodeCustom row renderer.
childrenReactNodeRight-side content. Typically a <ChatWindow /> for the active conversation.
childrenReactNodeRight-side content. Typically a <ChatWindow /> for the active conversation.
classNamestringExtra class on the root container.
classNamestringExtra class on the root container.
styleCSSPropertiesExtra inline styles on the root container.
styleCSSPropertiesExtra inline styles on the root container.
placeholderstring"'Search conversations…'"Search input placeholder.
placeholderstring"'Search conversations…'"Search input placeholder.
titleReactNodeOptional title shown above the search input.
titleReactNodeOptional title shown above the search input.