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

Chat Conversation Listブロック

Chat Conversation Listコンポーネントは、ReactとTypeScriptで構築された完全にカスタマイズ可能でアクセシブルな会話リストインターフェースです。検索機能、無限スクロール、チャットアプリケーションインターフェースのための柔軟なカスタマイズオプションを備えた完全な会話概要を提供します。


🚀 インストール

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

📖 使用法

import {ChatConversationList} from '@nodeblocks/frontend-chat-conversation-list-block';
ライブエディター
function BasicChatConversationList() {
  const [conversations, setConversations] = useState([
    {
      id: 'conv-001',
      title: 'カスタマーサポート',
      content: 'お問い合わせありがとうございます。今日はどのようなお手伝いができますか?',
      dateTime: '2025-02-01T10:00:00Z',
      titleLines: 1,
      unreadCount: 3,
      href: '/chat/conv-001',
      avatar: {
        avatarColor: '1',
        avatarSize: 'medium',
      },
    },
    {
      id: 'conv-002',
      title: 'プロジェクトチーム討議',
      content: '新機能の実装準備ができました。レビューをお願いします。',
      dateTime: '2025-02-01T09:30:00Z',
      titleLines: 2,
      unreadCount: 1,
      href: '/chat/conv-002',
      avatar: {
        avatarColor: '2',
        avatarSize: 'medium',
      },
    },
    {
      id: 'conv-003',
      title: 'マーケティングキャンペーン',
      content: 'キャンペーン戦略について話し合うミーティングをスケジュールしましょう。',
      dateTime: '2025-01-31T16:45:00Z',
      titleLines: 1,
      href: '/chat/conv-003',
      avatar: {
        avatarColor: '3',
        avatarSize: 'medium',
      },
    },
  ]);

  return (
    <ChatConversationList
      conversations={conversations}
      labels={{
        heading: '会話',
        emptyState: 'まだ会話がありません',
      }}
      placeholders={{
        search: '会話を検索...',
      }}
      search={{
        defaultValue: '',
        onChange: (value) => {
          console.log('検索が変更されました:', value);
        },
      }}
      onNavigate={(url) => {
        console.log('ナビゲート:', url);
      }}
      onScrollBottom={() => {
        console.log('さらに会話を読み込み');
      }}
      isLoading={false}>
      <ChatConversationList.Heading />
      <ChatConversationList.SearchBar />
      <ChatConversationList.ScrollPanel />
    </ChatConversationList>
  );
}
結果
Loading...

🔧 プロパティリファレンス

メインコンポーネントプロパティ

メインのChatConversationListコンポーネントはSpacingコンポーネントのすべてのプロパティを継承し、以下を追加します:

プロパティデフォルト説明
labels{heading?: string; emptyState?: string;}undefinedテキストラベルの設定
placeholders{search?: string;}undefinedプレースホルダーテキストの設定
isLoadingbooleanundefinedローディング状態を表示
onNavigate(url: string) => void必須ナビゲーションコールバック(hrefに必要)
onScrollBottom() => voidundefinedリストの下部に到達したときのコールバック
search{defaultValue?: string; onChange?: (value: string) => void;}undefined検索入力の設定
conversationsConversation[]必須表示する会話オブジェクトの配列
classNamestringundefinedスタイリング用の追加CSSクラス名
childrenBlocksOverrideundefinedデフォルトレンダリングをオーバーライドするカスタムブロックコンポーネント

会話オブジェクト

プロパティデフォルト説明
idstring必須会話の一意識別子
titlestring必須会話のタイトル
contentstringundefined会話本文(一行後に切り取られます)
dateTimestringundefinedISO文字列としての日時(コンポーネントによってフォーマットされます)
titleLines1 | 2必須タイトルが切り取られる前の行数
unreadCountnumberundefined未読数(99を超えると99で切り取られます)
hrefstringundefined会話をリンク可能にし、ホバー状態を追加
isSelectedbooleanundefinedtrueの場合、会話をハイライト
avatarAvatarPropsundefinedアバターの設定

サブコンポーネント

ChatConversationListコンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントは、メインコンポーネントのコンテキストからデフォルト値を受け取り、プロパティを通じてこれらの値をオーバーライドできます。

ChatConversationList.Heading

会話リストのヘッダーをレンダリングします。

プロパティデフォルト説明
labels{heading?: string;}コンテキスト値ラベル設定(コンテキストをオーバーライド)
classNamestringundefinedスタイリング用の追加CSSクラス名
childrenReactNodeデフォルトヘッダーコンテンツデフォルトヘッダーをオーバーライドするカスタムコンテンツ

注意: このコンポーネントはすべてのHTML div要素プロパティを継承します。

ChatConversationList.SearchBar

デバウンス検索機能付きの検索入力をレンダリングします。

プロパティデフォルト説明
search{defaultValue?: string; onChange?: (value: string) => void;}コンテキスト値検索設定オブジェクト(コンテキスト値をオーバーライド)
placeholders{search?: string;}コンテキスト値プレースホルダーテキスト設定(コンテキスト値をオーバーライド)
conversationsConversation[]コンテキスト値検索バーの表示を決定する会話配列(コンテキストをオーバーライド)
debounceTimenumber500検索onChangeコールバックをトリガーする前の遅延(ミリ秒)
classNamestringundefined検索コンテナのスタイリング用の追加CSSクラス名
defaultValuestringundefined検索入力フィールドの初期値
placeholderstringundefined検索入力が空のときに表示されるプレースホルダーテキスト
disabledbooleanundefined検索入力が無効かどうか
idstringundefined検索入力のHTML id属性
namestringundefined検索入力のHTML name属性
autoCompletestringundefined検索入力のHTML autocomplete属性
autoFocusbooleanundefinedマウント時に検索入力を自動的にフォーカスするかどうか

ChatConversationList.ScrollPanel

無限スクロールサポート付きのスクロール可能な会話リストをレンダリングします。

プロパティデフォルト説明
conversationsConversation[]コンテキスト値会話配列(コンテキストをオーバーライド)
labels{heading?: string; emptyState?: string;}コンテキスト値ラベル設定(コンテキストをオーバーライド)
isLoadingbooleanコンテキスト値ローディング状態(コンテキストをオーバーライド)
onScrollBottom() => voidコンテキスト値スクロールコールバック(コンテキストをオーバーライド)
classNamestringundefinedスタイリング用の追加CSSクラス名
childrenReactNodeデフォルト会話アイテムデフォルト会話レンダリングをオーバーライドするカスタムコンテンツ

注意: このコンポーネントはすべてのHTML div要素プロパティを継承します。


🔧 TypeScriptサポート

包括的な型定義による完全なTypeScriptサポート:

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;
}

// 検索と無限スクロール付きの高度な会話リスト
function AdvancedChatConversationList() {
const [conversations, setConversations] = useState<Conversation[]>([
{
id: 'support-001',
title: 'カスタマーサポートチーム',
content: 'あなたの問題は解決されました。他にお手伝いできることはありますか?',
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: '開発チーム討議',
content: 'コードレビューが完了しました。新機能ブランチをマージする準備ができています。',
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: 'クライアントプロジェクト更新',
content: 'プロジェクトのタイムラインについて話し合うため、明日午後2時にミーティングを予定しています。',
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('さらに会話を読み込み中...');
setIsLoading(true);

// API呼び出しをシミュレート
setTimeout(() => {
const newConversations: Conversation[] = [
{
id: `conv-${Date.now()}`,
title: '新しい会話',
content: 'これは新しく読み込まれた会話です。',
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('ナビゲート:', url);
// 選択された会話を更新
setConversations(prev =>
prev.map(conv => ({
...conv,
isSelected: conv.href === url,
}))
);
};

return (
<ChatConversationList
conversations={filteredConversations}
labels={{
heading: 'チャット会話',
emptyState: searchValue ? '検索に一致する会話がありません' : 'まだ会話がありません',
}}
placeholders={{
search: '名前またはメッセージで検索...',
}}
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>
);
}

React、TypeScript、モダンWebスタンダードを使用して❤️で構築されました。