# ConversationListHeader 组件自定义文档

## 概述

ConversationListHeader 是一个会话列表头部组件，提供了灵活的三区域布局结构。组件采用左中右的布局模式，其中 children 作为中心内容区域，left 和 right 分别作为左右两侧的功能区域。适用于各种会话列表场景，支持自定义标题、操作按钮、状态指示器等头部元素，为用户提供清晰的导航和操作入口。

## Props 配置表格

| 字段 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| children | `React.ReactNode` | - | 头部中心区域的主要内容 |
| left | `React.ReactNode` | - | 头部左侧区域的自定义内容 |
| right | `React.ReactNode` | - | 头部右侧区域的自定义内容 |
| className | `string` | - | 自定义样式类名 |
| style | `React.CSSProperties` | - | 自定义样式 |

## Props 详解

### children

type: `React.ReactNode`

children 用于渲染头部中心区域的主要内容，通常是标题或主要信息展示，默认值为 `-`。

### left

type: `React.ReactNode`

left 用于自定义头部左侧区域的内容，通常放置返回按钮、菜单按钮或状态指示器等，默认值为 `-`。

#### Example1: 基础左侧导航

```tsx
import { ConversationListHeader } from 'tuikit-atomicx-react';
import { useState } from 'react';

function ConversationListWithLeftNavigation() {
  const [isMenuOpen, setIsMenuOpen] = useState(false);

  const leftContent = (
    <div className="header-left-content">
      <button 
        className="menu-btn"
        onClick={() => setIsMenuOpen(!isMenuOpen)}
        aria-label="打开菜单"
      >
        <span className="menu-icon">☰</span>
      </button>
      
      {/* 在线状态指示器 */}
      <div className="status-indicator">
        <span className="status-dot online"></span>
        <span className="status-text">在线</span>
      </div>
    </div>
  );

  return (
    <div>
      <ConversationListHeader
        left={leftContent}
      >
        <h1 className="header-title">消息</h1>
      </ConversationListHeader>
      
      {/* 侧边菜单 */}
      {isMenuOpen && (
        <div className="side-menu">
          <div className="menu-item">设置</div>
          <div className="menu-item">帮助</div>
          <div className="menu-item">关于</div>
        </div>
      )}
    </div>
  );
}
```

#### Example2: 用户信息和快捷操作

```tsx
import { ConversationListHeader } from 'tuikit-atomicx-react';
import { useState, useEffect } from 'react';

function ConversationListWithUserInfo() {
  const [userInfo, setUserInfo] = useState(null);
  const [notifications, setNotifications] = useState([]);

  useEffect(() => {
    // 获取用户信息和通知
    Promise.all([
      fetchCurrentUserInfo(),
      fetchNotifications()
    ]).then(([user, notifs]) => {
      setUserInfo(user);
      setNotifications(notifs);
    });
  }, []);

  const leftContent = (
    <div className="header-user-section">
      {/* 用户头像 */}
      <div className="user-avatar-container">
        <img 
          src={userInfo?.avatar || '/default-avatar.png'} 
          alt={userInfo?.nickname || '用户头像'}
          className="user-avatar"
        />
        
        {/* 在线状态 */}
        <div className={`presence-indicator ${userInfo?.presence || 'offline'}`}>
          <div className="presence-dot"></div>
        </div>
      </div>
      
      {/* 快捷操作 */}
      <div className="quick-actions">
        <button 
          className="notification-btn"
          onClick={() => showNotifications()}
          aria-label={`通知 (${notifications.length})`}
        >
          <span className="notification-icon">🔔</span>
          {notifications.length > 0 && (
            <span className="notification-badge">{notifications.length}</span>
          )}
        </button>
        
        <button 
          className="profile-btn"
          onClick={() => openUserProfile()}
          aria-label="用户资料"
        >
          <span className="profile-icon">👤</span>
        </button>
      </div>
    </div>
  );

  return (
    <ConversationListHeader
      left={leftContent}
    >
      <div className="header-title-section">
        <h1>消息</h1>
        <p className="subtitle">
          {userInfo?.nickname || '加载中...'}
        </p>
      </div>
    </ConversationListHeader>
  );
}
```

### right

type: `React.ReactNode`

right 用于自定义头部右侧区域的内容，通常放置操作按钮、搜索入口或功能切换等，默认值为 `-`。

#### Example1: 基础操作按钮

```tsx
import { ConversationListHeader } from 'tuikit-atomicx-react';
import { useState } from 'react';

function ConversationListWithRightActions() {
  const [isSearchMode, setIsSearchMode] = useState(false);
  const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);

  const rightContent = (
    <div className="header-right-actions">
      {/* 搜索按钮 */}
      <button 
        className={`search-btn ${isSearchMode ? 'active' : ''}`}
        onClick={() => setIsSearchMode(!isSearchMode)}
        aria-label="搜索会话"
      >
        <span className="search-icon">🔍</span>
      </button>
      
      {/* 创建会话按钮 */}
      <button 
        className="create-btn"
        onClick={() => setIsCreateModalOpen(true)}
        aria-label="创建新会话"
      >
        <span className="create-icon">➕</span>
      </button>
      
      {/* 更多操作 */}
      <div className="more-actions">
        <button 
          className="more-btn"
          onClick={() => showMoreOptions()}
          aria-label="更多操作"
        >
          <span className="more-icon">⋯</span>
        </button>
      </div>
    </div>
  );

  return (
    <div>
      <ConversationListHeader
        right={rightContent}
      >
        <h1 className="header-title">消息</h1>
      </ConversationListHeader>
      
      {/* 搜索栏 */}
      {isSearchMode && (
        <div className="search-bar">
          <input 
            type="text" 
            placeholder="搜索会话、联系人..."
            className="search-input"
            autoFocus
          />
        </div>
      )}
    </div>
  );
}
```

#### Example2: 智能操作栏

```tsx
import { ConversationListHeader } from 'tuikit-atomicx-react';
import { useState, useEffect } from 'react';

function ConversationListWithSmartActions() {
  const [unreadCount, setUnreadCount] = useState(0);
  const [isOnline, setIsOnline] = useState(navigator.onLine);
  const [lastSyncTime, setLastSyncTime] = useState(null);
  const [currentView, setCurrentView] = useState('all'); // all, unread, groups

  useEffect(() => {
    // 监听网络状态
    const handleOnline = () => setIsOnline(true);
    const handleOffline = () => setIsOnline(false);
    
    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);
    
    // 获取未读消息数量
    fetchUnreadCount().then(setUnreadCount);
    
    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);

  const handleSync = async () => {
    try {
      await syncConversations();
      setLastSyncTime(new Date());
      showSuccessToast('同步成功');
    } catch (error) {
      showErrorToast('同步失败');
    }
  };

  const handleViewFilter = (view: string) => {
    setCurrentView(view);
    // 触发列表过滤
    onViewChange(view);
  };

  const rightContent = (
    <div className="smart-header-actions">
      {/* 网络状态和同步 */}
      <div className="sync-section">
        <div className={`network-status ${isOnline ? 'online' : 'offline'}`}>
          <span className="network-icon">
            {isOnline ? '🌐' : '📡'}
          </span>
        </div>
        
        <button 
          className="sync-btn"
          onClick={handleSync}
          disabled={!isOnline}
          title={lastSyncTime ? `上次同步: ${lastSyncTime.toLocaleTimeString()}` : '点击同步'}
        >
          <span className="sync-icon">🔄</span>
        </button>
      </div>
      
      {/* 视图切换 */}
      <div className="view-filters">
        <button 
          className={`filter-btn ${currentView === 'all' ? 'active' : ''}`}
          onClick={() => handleViewFilter('all')}
        >
          全部
        </button>
        <button 
          className={`filter-btn ${currentView === 'unread' ? 'active' : ''}`}
          onClick={() => handleViewFilter('unread')}
        >
          未读
          {unreadCount > 0 && (
            <span className="unread-badge">{unreadCount}</span>
          )}
        </button>
        <button 
          className={`filter-btn ${currentView === 'groups' ? 'active' : ''}`}
          onClick={() => handleViewFilter('groups')}
        >
          群聊
        </button>
      </div>
      
      {/* 操作按钮组 */}
      <div className="action-buttons">
        <button 
          className="search-btn"
          onClick={() => toggleSearch()}
          aria-label="搜索"
        >
          <span className="icon">🔍</span>
        </button>
        
        <div className="create-dropdown">
          <button 
            className="create-btn"
            onClick={() => toggleCreateDropdown()}
            aria-label="创建"
          >
            <span className="icon">➕</span>
          </button>
          
          <div className="dropdown-menu">
            <button onClick={() => createPrivateChat()}>
              <span className="icon">👤</span>
              <span>私聊</span>
            </button>
            <button onClick={() => createGroupChat()}>
              <span className="icon">👥</span>
              <span>群聊</span>
            </button>
            <button onClick={() => createChannel()}>
              <span className="icon">📢</span>
              <span>频道</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  );

  return (
    <ConversationListHeader
      right={rightContent}
    >
      <div className="header-title-with-status">
        <h1>消息</h1>
        <div className="status-info">
          <span className="total-count">
            {getTotalConversationCount()} 个会话
          </span>
          {!isOnline && (
            <span className="offline-indicator">离线模式</span>
          )}
        </div>
      </div>
    </ConversationListHeader>
  );
}
```

### className

type: `string`

className 用于自定义组件的样式类名，默认值为 `-`。

### style

type: `React.CSSProperties`

style 用于自定义组件的内联样式，默认值为 `-`。 