Skip to main content

Chat Conversation List Block

The Chat Conversation List Component is a fully customizable and accessible conversation listing interface built with React and TypeScript. It provides a complete conversation overview with search functionality, infinite scrolling, and flexible customization options for chat application interfaces.


πŸš€ Installation​

npm install @nodeblocks/frontend-chat-conversation-list-block

πŸ“– Usage​

import {ChatConversationList} from '@nodeblocks/frontend-chat-conversation-list-block';
Live Editor
function BasicChatConversationList() {
  const [conversations, setConversations] = useState([
    {
      id: 'conv-001',
      title: 'Customer Support',
      content: 'Thank you for contacting us. How can we help you today?',
      dateTime: '2025-02-01T10:00:00Z',
      titleLines: 1,
      unreadCount: 3,
      href: '/chat/conv-001',
      avatar: {
        avatarColor: '1',
        avatarSize: 'medium',
      },
    },
    {
      id: 'conv-002',
      title: 'Project Team Discussion',
      content: 'The new feature implementation is ready for review.',
      dateTime: '2025-02-01T09:30:00Z',
      titleLines: 2,
      unreadCount: 1,
      href: '/chat/conv-002',
      avatar: {
        avatarColor: '2',
        avatarSize: 'medium',
      },
    },
    {
      id: 'conv-003',
      title: 'Marketing Campaign',
      content: 'Let\'s schedule a meeting to discuss the campaign strategy.',
      dateTime: '2025-01-31T16:45:00Z',
      titleLines: 1,
      href: '/chat/conv-003',
      avatar: {
        avatarColor: '3',
        avatarSize: 'medium',
      },
    },
  ]);

  return (
    <ChatConversationList
      conversations={conversations}
      labels={{
        heading: 'Conversations',
        emptyState: 'No conversations yet',
      }}
      placeholders={{
        search: 'Search conversations...',
      }}
      search={{
        defaultValue: '',
        onChange: (value) => {
          console.log('Search changed:', value);
        },
      }}
      onNavigate={(url) => {
        console.log('Navigate to:', url);
      }}
      onScrollBottom={() => {
        console.log('Load more conversations');
      }}
      isLoading={false}>
      <ChatConversationList.Heading />
      <ChatConversationList.SearchBar />
      <ChatConversationList.ScrollPanel />
    </ChatConversationList>
  );
}
Result
Loading...

πŸ”§ Props Reference​

Main Component Props​

The main ChatConversationList component inherits all props from the Spacing component and adds:

PropTypeDefaultDescription
labels{heading?: string; emptyState?: string;}undefinedText labels configuration
placeholders{search?: string;}undefinedPlaceholder text configuration
isLoadingbooleanundefinedShow loading state
onNavigate(url: string) => voidRequiredNavigation callback (required for href)
onScrollBottom() => voidundefinedCallback when the bottom of the list is reached
search{defaultValue?: string; onChange?: (value: string) => void;}undefinedSearch input configuration
conversationsConversation[]RequiredArray of conversation objects to display
classNamestringundefinedAdditional CSS class name for styling
childrenBlocksOverrideundefinedCustom block components to override default rendering

Conversation Object​

PropTypeDefaultDescription
idstringRequiredUnique identifier for the conversation
titlestringRequiredTitle of the conversation
contentstringundefinedConversation body (will be cut off after one line)
dateTimestringundefinedDate time as ISO string (will be formatted by component)
titleLines1 | 2RequiredNumber of lines before the title is cut off
unreadCountnumberundefinedUnread count (>99 will be cut off at 99)
hrefstringundefinedMakes conversation linkable and adds hover state
isSelectedbooleanundefinedWhen true, highlight the conversation
avatarAvatarPropsundefinedAvatar configuration

Sub-Components​

The ChatConversationList component provides several sub-components. All sub-components receive their default values from the main component's context and can override these values through props.

ChatConversationList.Heading​

Renders the conversation list heading.

PropTypeDefaultDescription
labels{heading?: string;}Context valuesLabels configuration (overrides context)
classNamestringundefinedAdditional CSS class name for styling
childrenReactNodeDefault heading contentCustom content to override default heading

Note: This component inherits all HTML div element props.

ChatConversationList.SearchBar​

Renders the search input with debounced search functionality.

PropTypeDefaultDescription
search{defaultValue?: string; onChange?: (value: string) => void;}Context valuesSearch configuration object (overrides context values)
placeholders{search?: string;}Context valuesPlaceholder text configuration (overrides context values)
conversationsConversation[]Context valuesArray of conversations to determine search bar visibility (overrides context)
debounceTimenumber500Delay in milliseconds before triggering search onChange callback
classNamestringundefinedAdditional CSS class name for styling the search container
defaultValuestringundefinedInitial value for the search input field
placeholderstringundefinedPlaceholder text displayed when search input is empty
disabledbooleanundefinedWhether the search input is disabled
idstringundefinedHTML id attribute for the search input
namestringundefinedHTML name attribute for the search input
autoCompletestringundefinedHTML autocomplete attribute for the search input
autoFocusbooleanundefinedWhether to automatically focus the search input on mount

ChatConversationList.ScrollPanel​

Renders the scrollable list of conversations with infinite scroll support.

PropTypeDefaultDescription
conversationsConversation[]Context valuesConversations array (overrides context)
labels{heading?: string; emptyState?: string;}Context valuesLabels configuration (overrides context)
isLoadingbooleanContext valuesLoading state (overrides context)
onScrollBottom() => voidContext valuesScroll callback (overrides context)
classNamestringundefinedAdditional CSS class name for styling
childrenReactNodeDefault conversation itemsCustom content to override default conversation rendering

Note: This component inherits all HTML div element props.


πŸ”§ TypeScript Support​

Full TypeScript support with comprehensive type definitions:

import {ChatConversationList} from '@nodeblocks/frontend-chat-conversation-list-block';
import {AvatarProps} from '@basaldev/blocks-frontend-framework';
import {useState} from 'react';

interface LabelsConfig {
heading?: string;
emptyState?: string;
}

interface SearchConfig {
defaultValue?: string;
onChange?: (value: string) => void;
}

interface PlaceholdersConfig {
search?: string;
}

interface Conversation {
id: string;
title: string;
content?: string;
dateTime?: string;
titleLines: 1 | 2;
unreadCount?: number;
href?: string;
isSelected?: boolean;
avatar?: AvatarProps;
}

// Advanced conversation list with search and infinite scroll
function AdvancedChatConversationList() {
const [conversations, setConversations] = useState<Conversation[]>([
{
id: 'support-001',
title: 'Customer Support Team',
content: 'Your issue has been resolved. Is there anything else we can help you with?',
dateTime: '2025-02-01T14:30:00Z',
titleLines: 1,
unreadCount: 2,
href: '/chat/support-001',
isSelected: false,
avatar: {
avatarColor: '1',
avatarSize: 'medium',
avatarUrl: '/avatars/support-team.jpg',
},
},
{
id: 'team-002',
title: 'Development Team Discussion',
content: 'The code review is complete. Ready to merge the new feature branch.',
dateTime: '2025-02-01T13:15:00Z',
titleLines: 2,
unreadCount: 5,
href: '/chat/team-002',
isSelected: true,
avatar: {
avatarColor: '2',
avatarSize: 'medium',
},
},
{
id: 'client-003',
title: 'Client Project Updates',
content: 'Meeting scheduled for tomorrow at 2 PM to discuss project timeline.',
dateTime: '2025-02-01T11:45:00Z',
titleLines: 1,
href: '/chat/client-003',
avatar: {
avatarColor: '3',
avatarSize: 'medium',
avatarUrl: '/avatars/client.jpg',
},
},
]);

const [isLoading, setIsLoading] = useState(false);
const [searchValue, setSearchValue] = useState('');
const [filteredConversations, setFilteredConversations] = useState(conversations);

const handleSearch = (value: string) => {
setSearchValue(value);

if (!value.trim()) {
setFilteredConversations(conversations);
return;
}

const filtered = conversations.filter(
(conv) =>
conv.title.toLowerCase().includes(value.toLowerCase()) ||
conv.content?.toLowerCase().includes(value.toLowerCase())
);

setFilteredConversations(filtered);
};

const handleScrollBottom = () => {
console.log('Loading more conversations...');
setIsLoading(true);

// Simulate API call
setTimeout(() => {
const newConversations: Conversation[] = [
{
id: `conv-${Date.now()}`,
title: 'New Conversation',
content: 'This is a newly loaded conversation.',
dateTime: new Date().toISOString(),
titleLines: 1,
href: `/chat/conv-${Date.now()}`,
avatar: {
avatarColor: '4',
avatarSize: 'medium',
},
},
];

setConversations(prev => [...prev, ...newConversations]);
if (!searchValue.trim()) {
setFilteredConversations(prev => [...prev, ...newConversations]);
}
setIsLoading(false);
}, 1500);
};

const handleNavigate = (url: string) => {
console.log('Navigating to:', url);
// Update selected conversation
setConversations(prev =>
prev.map(conv => ({
...conv,
isSelected: conv.href === url,
}))
);
};

return (
<ChatConversationList
conversations={filteredConversations}
labels={{
heading: 'Chat Conversations',
emptyState: searchValue ? 'No conversations match your search' : 'No conversations yet',
}}
placeholders={{
search: 'Search by name or message...',
}}
search={{
defaultValue: searchValue,
onChange: handleSearch,
}}
onNavigate={handleNavigate}
onScrollBottom={handleScrollBottom}
isLoading={isLoading}
className="custom-conversation-list"
style={{ maxHeight: '500px', border: '1px solid #e0e0e0' }}>
<ChatConversationList.Heading className="custom-heading" />
<ChatConversationList.SearchBar
className="custom-search-bar"
debounceTime={300}
/>
<ChatConversationList.ScrollPanel className="custom-scroll-panel" />
</ChatConversationList>
);
}

Built with ❀️ using React, TypeScript, and modern web standards.