メインコンテンツまでスキップ

チャット会話リストブロック

ChatConversationList は、MUI TypographyAvatar 要素に基づく、レスポンシブで高度にカスタマイズ可能な受信トレイ一覧ビューです。組み込みの検索バー、サブコンポーネント単位のデバウンス制御、未読バッジカウンター、遅延読み込み/最下部スクロール時コールバックフック、レスポンシブな2カラムの分割ペインレイアウトをサポートします。

インストール

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

必要なもの

項目理由
conversations受信トレイの会話エントリ配列(idtitlecontentdateTimeunreadCount など)
onNavigate会話項目をクリックしたときに呼び出されるコールバック
labels (optional)一覧の見出しや空状態のテキストマッピング
search (optional)onChange などのコールバックとデフォルト値を含む状態を持つ検索設定
renderDesktopPane (optional)md 以上のビューポートに右側の詳細ペイン(ChatConversation など)を差し込むレンダープロップ
制御コンポーネント

ChatConversationList は制御された表示専用コンポーネントであり、アクティブなスレッド状態、検索フィルタリング、ページネーション一覧を内部では管理しません。アクティブな conversations 配列と選択中のスレッド index/ID は親コンポーネントの state に保持し、search.onChange に応じて項目をフィルタし、isLoading プロパティでローディング表示を管理してください。

コード例

ライブエディター
function Example() {
  const conversations = [
    {
      id: '1',
      title: 'Customer Support',
      content: 'Thank you for contacting us. How can we help you?',
      dateTime: new Date(Date.now() - 3 * 60 * 1000).toISOString(),
      titleLines: 1,
      unreadCount: 3,
      href: '#support',
      avatar: {children: 'CS', sx: {bgcolor: 'primary.main'}},
    },
    {
      id: '2',
      title: 'Project Discussion Group',
      content: 'The review slides are ready for feedback.',
      dateTime: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(),
      titleLines: 2,
      unreadCount: 0,
      href: '#team',
      avatar: {children: 'PD', sx: {bgcolor: 'secondary.main'}},
    },
  ];
  const [searchValue, setSearchValue] = React.useState('');
  const [lastEvent, setLastEvent] = React.useState('Ready');
  const visibleConversations = conversations.filter((conversation) => {
    const haystack = `${conversation.title} ${conversation.content ?? ''}`.toLowerCase();
    return !searchValue || haystack.includes(searchValue.toLowerCase());
  });

  return (
    <div style={{height: 400, border: '1px solid #e0e0e0', borderRadius: 8, overflow: 'hidden'}}>
      <ChatConversationList
        conversations={visibleConversations}
        labels={{
          heading: 'Conversations',
          emptyState: 'No chats found',
        }}
        placeholders={{
          search: 'Search conversations...',
        }}
        search={{
          defaultValue: '',
          onChange: val => {
            setSearchValue(val);
            setLastEvent(`Search key: ${val}`);
          },
        }}
        onNavigate={url => setLastEvent(`Routing to: ${url}`)}
      />
      <div style={{marginTop: 8, fontSize: 12, color: '#666'}}>{lastEvent}</div>
    </div>
  );
}
結果
Loading...

重要なプロパティ

コアプロパティ

プロパティ必須デフォルト説明
conversationsArray<{ id: string; title: string; titleLines: 1 | 2; content?: string; dateTime?: string; href?: string; isSelected?: boolean; unreadCount?: number; avatar?: Partial<AvatarProps> & { isLoading?: boolean } }>はい-一覧内に表示される受信トレイ会話スレッドの配列
onNavigate(url: string) => voidはい-href を持つ会話をクリックしたときに呼び出されるナビゲーションコールバック
isLoadingbooleanいいえfalsetrue のときにスクロールパネル内へローディングスピナーを表示します
onScrollBottom() => voidいいえundefined一覧の最下部までスクロールしたときに呼び出されるコールバック(遅延読み込みによる追加に使用)

会話オブジェクト

conversations 配列内の各会話オブジェクトにプロパティを設定します:

プロパティ必須デフォルト説明
idstringはい-会話スレッドの一意な識別子
titlestringはい-会話スレッドの見出しラベル
titleLines1 | 2はい-切り詰めと省略表示の前に表示するタイトル行数
contentstringいいえundefinedメインメッセージのプレビュー本文(1行後に切り詰め)
dateTimestringいいえundefinedformatRelativeDateText で整形される ISO 日時文字列
hrefstringいいえundefined行クリック時に onNavigate コールバックへ渡されるルーティング用アンカーリンク
isSelectedbooleanいいえfalsetrue のときにアクティブな選択をハイライト
unreadCountnumberいいえundefined未読件数バッジを表示(99を超えると 99... と表示)
avatarPartial<AvatarProps> & { isLoading?: boolean }いいえundefinedMUI Avatar の標準 props + ローディング状態のプレースホルダー。リンク付きアバターは component="a" で設定できます

コンテンツプロパティ

プロパティ必須デフォルト説明
labels{ heading?: string; emptyState?: string }いいえundefined受信トレイ見出しのカスタムテキストと空の受信トレイ表示テキスト
placeholders{ search?: string }いいえundefined検索テキスト入力のプレースホルダー
search{ defaultValue?: string; onChange?: (value: string) => void }いいえundefined初期値と変更コールバックを含む状態を持つ検索制御
renderDesktopPane() => ReactNodeいいえundefinedmd 以上のビューポートで右側に分割ペインレイアウトを読み込むレンダープロップ
formatRelativeDateText(dateTime: string) => stringいいえ(dateTime) => DateTime.fromISO(dateTime).toRelative() ?? ''各行の ISO dateTime プレビュー用のカスタム整形関数

レイアウトと構成のプロパティ

プロパティ必須デフォルト説明
childrenBlocksOverride | ReactNodeいいえundefinedコンパウンド子要素またはオーバーライド関数の子
classNamestringいいえundefined外側コンテナに適用されるスタイルクラス
sxSxPropsいいえundefined外側の Stack に渡される MUI SX スタイル上書き

ChatConversationListStackPropschildren を除く)をすべて継承します。defaultBlockOrder['heading', 'searchBar', 'header', 'scrollPanel', 'item'] で、デフォルトのルート描画では単独の headingsearchBaritem を除外し、その後に headerscrollPanel を描画します。

デフォルト UI ブロック

ブロック基盤備考
ChatConversationList (root)Stackデフォルトのヘッダーとスクロールパネルを縦に積み重ねます
ChatConversationList.HeaderStackHeading と SearchBar の子セクションをまとめるラッパー
ChatConversationList.HeadingTypography一覧のメインヘッダーを表示します
ChatConversationList.SearchBarTextFielddebounceTime が 500 ms の検索入力とアイコン装飾付き
ChatConversationList.ScrollPanelStack一覧項目、ローディングスピナー、空状態をマッピングするスクロール可能な表示領域
ChatConversationList.ConversationItemLink + Avatarタイトル、本文プレビュー、未読バッジ、日付を表示します

TypeScript

import {ChatConversationList} from '@nodeblocks/frontend-chat-conversation-list-block';
import type {AvatarProps} from '@mui/material';

type Conversation = {
id: string;
title: string;
titleLines: 1 | 2;
content?: string;
dateTime?: string;
href?: string;
isSelected?: boolean;
unreadCount?: number;
avatar?: Partial<AvatarProps> & {
isLoading?: boolean;
};
};

const conversations: Conversation[] = [
{
id: 'thread-1',
title: 'Customer support',
content: 'Ticket resolved successfully.',
dateTime: '2026-05-27T02:00:00Z',
titleLines: 1,
unreadCount: 1,
avatar: {children: 'CS', sx: {bgcolor: 'primary.main'}},
},
];

<ChatConversationList
conversations={conversations}
labels={{
heading: 'Inbox',
emptyState: 'No threads active',
}}
placeholders={{
search: 'Filter threads...',
}}
search={{
onChange: val => void val,
}}
onNavigate={url => void url}
/>;