# List 组件使用指南

## 1. 快速开始

### 1.1 基本导入

```typescript
import { List } from '@pisell/private-materials';
// 或者导入类型
import { ListProps, BaseListItem } from '@pisell/private-materials';
```

### 1.2 最简单的使用

```tsx
import React from 'react';
import { List } from '@pisell/private-materials';

const BasicExample = () => {
  const data = [
    { id: 1, title: '项目 1', category: 'A' },
    { id: 2, title: '项目 2', category: 'B' },
    { id: 3, title: '项目 3', category: 'A' },
  ];

  return (
    <List
      data={data}
      renderItem={(item) => (
        <div>{item.title}</div>
      )}
    />
  );
};
```

## 2. 配置选项详解

### 2.1 基础配置

#### 2.1.1 尺寸和样式

```tsx
<List
  className="my-list"           // 自定义类名
  style={{ border: '1px solid #ccc' }}  // 自定义样式
  width={800}                   // 宽度：数字(px) | 字符串('100%', '800px')
  height={600}                  // 高度：数字(px) | 字符串('auto', '600px')
  zoom={1.2}                    // 缩放比例
/>
```

#### 2.1.2 数据配置

```tsx
interface MyItem extends BaseListItem {
  id: string | number;
  title: string;
  category: string;
  status: 'active' | 'inactive';
}

const data: MyItem[] = [
  { id: 1, title: '项目 1', category: 'frontend', status: 'active' },
  { id: 2, title: '项目 2', category: 'backend', status: 'inactive' },
];

<List<MyItem>
  data={data}
  renderItem={(item: MyItem, index: number) => (
    <div className="item">
      <h3>{item.title}</h3>
      <span>状态: {item.status}</span>
    </div>
  )}
/>
```

### 2.2 布局配置

#### 2.2.1 网格布局

```tsx
// 垂直网格布局（默认）
<List
  displayStyle="grid"
  layoutDirection="vertical"
  columns={3}                   // 3列显示
  columnGap={16}               // 列间距16px
  rowGap={12}                  // 行间距12px
  data={data}
  renderItem={renderItem}
/>

// 水平网格布局
<List
  displayStyle="grid"
  layoutDirection="horizontal"
  rows={2}                     // 2行显示
  columnGap={16}
  rowGap={12}
  data={data}
  renderItem={renderItem}
/>
```

#### 2.2.2 瀑布流布局

```tsx
// 垂直瀑布流
<List
  displayStyle="waterfall"
  layoutDirection="vertical"
  columns={4}                  // 4列瀑布流
  columnGap={12}
  rowGap={12}
  data={dataWithHeights}       // 数据最好包含预设高度
  renderItem={renderItem}
/>

// 水平瀑布流
<List
  displayStyle="waterfall"
  layoutDirection="horizontal"
  rows={3}                     // 3行瀑布流
  columnGap={12}
  rowGap={12}
  data={dataWithWidths}        // 数据最好包含预设宽度
  renderItem={renderItem}
/>
```

### 2.3 标签页配置

#### 2.3.1 切换模式标签页

```tsx
const tabData = [
  { key: 'all', label: '全部' },
  { key: 'frontend', label: '前端', group: 'frontend' },
  { key: 'backend', label: '后端', group: 'backend' },
  { key: 'design', label: '设计', group: 'design' },
];

<List
  tabStyle="switch"            // 切换模式
  tabData={tabData}
  tabGroup="category"          // 根据category字段分组
  data={data}
  renderItem={renderItem}
  onLoadData={(params) => {
    console.log('Tab changed:', params.activeTab);
    // 根据activeTab加载对应数据
  }}
/>
```

#### 2.3.2 锚点模式标签页

```tsx
<List
  tabStyle="anchor"            // 锚点模式
  tabData={tabData}
  tabGroup="category"
  stickyTop={true}            // 滚动时标签页固定在顶部
  data={data}
  renderItem={renderItem}
/>
```

#### 2.3.3 无标签页

```tsx
<List
  tabStyle="none"             // 隐藏标签页
  data={data}
  renderItem={renderItem}
/>
```

### 2.4 分页配置

#### 2.4.1 全部显示模式

```tsx
<List
  paginationType="all"        // 显示所有数据，无分页
  data={data}
  renderItem={renderItem}
/>
```

#### 2.4.2 滚动加载模式

```tsx
<List
  paginationType="scroll"
  defaultPageSize={10}        // 每页10条
  height={400}               // 固定高度启用滚动
  data={data}
  renderItem={renderItem}
  pagination={{
    current: currentPage,
    total: totalPages,
    totalCount: totalCount
  }}
  onLoadData={(params) => {
    if (params.trigger === 'scroll') {
      console.log('滚动加载更多数据，页码:', params.currentPage);
      // 加载下一页数据
      loadMoreData(params.currentPage);
    }
  }}
  loading={loading}
/>
```

#### 2.4.3 分页器模式

```tsx
<List
  paginationType="pager"
  defaultPageSize={12}
  data={data}
  renderItem={renderItem}
  pagination={{
    current: currentPage,
    total: totalPages,
    totalCount: totalCount
  }}
  onLoadData={(params) => {
    if (params.trigger === 'pagination') {
      console.log('分页变化:', params.currentPage);
      loadPageData(params.currentPage, params.pageSize);
    }
  }}
/>
```

#### 2.4.4 查看更多模式

```tsx
<List
  paginationType="more"
  defaultPageSize={6}
  data={data}
  renderItem={renderItem}
  pagination={{
    current: currentPage,
    total: totalPages
  }}
  onLoadData={(params) => {
    if (params.trigger === 'loadMore') {
      console.log('加载更多数据');
      loadMoreData();
    }
  }}
  loading={loading}
/>
```

### 2.5 空状态配置

```tsx
<List
  data={[]}
  emptyConfig={{
    show: true,
    text: '暂无数据',
    description: '请稍后再试',
    icon: <CustomEmptyIcon />
  }}
  renderItem={renderItem}
/>
```

## 3. 响应式使用

### 3.1 响应式列表

```tsx
import { ResponsiveList, createResponsiveConfig } from '@pisell/private-materials';

const responsiveConfig = createResponsiveConfig({
  // 默认配置（移动端）
  default: {
    displayStyle: 'grid',
    layoutDirection: 'vertical',
    columns: 1,
    columnGap: 8,
    rowGap: 8,
    defaultPageSize: 5
  },
  // 平板配置
  pad: {
    columns: 2,
    columnGap: 12,
    rowGap: 12,
    defaultPageSize: 8
  },
  // PC配置
  pc: {
    columns: 3,
    columnGap: 16,
    rowGap: 16,
    defaultPageSize: 12
  }
});

<ResponsiveList
  responsive={responsiveConfig}
  data={data}
  renderItem={renderItem}
/>
```

### 3.2 设备检测Hook

```tsx
import { useDevice } from '@pisell/private-materials';

const MyComponent = () => {
  const device = useDevice();
  
  console.log('设备信息:', device);
  // {
  //   type: 'pc' | 'pad' | 'mobile',
  //   isMobile: boolean,
  //   isPad: boolean,
  //   isPc: boolean,
  //   width: number,
  //   height: number
  // }

  return (
    <List
      columns={device.isMobile ? 1 : device.isPad ? 2 : 3}
      data={data}
      renderItem={renderItem}
    />
  );
};
```

## 4. 高级用法

### 4.1 使用子组件模式

```tsx
// 定义子组件
const ListItemComponent = ({ item, index }) => (
  <div className="custom-item">
    <h3>{item.title}</h3>
    <p>{item.description}</p>
    <span>索引: {index}</span>
  </div>
);

// 使用子组件
<List data={data}>
  <ListItemComponent />
</List>
```

### 4.2 复杂数据加载

```tsx
const ComplexList = () => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);
  const [pagination, setPagination] = useState({
    current: 1,
    total: 0,
    totalCount: 0
  });

  const handleLoadData = async (params: LoadDataParams) => {
    setLoading(true);
    
    try {
      const result = await fetchData({
        page: params.currentPage,
        pageSize: params.pageSize,
        category: params.activeTab !== 'all' ? params.activeTab : undefined,
        trigger: params.trigger
      });
      
      if (params.trigger === 'scroll' || params.trigger === 'loadMore') {
        // 滚动加载：追加数据
        setData(prevData => [...prevData, ...result.items]);
      } else {
        // 其他情况：替换数据
        setData(result.items);
      }
      
      setPagination({
        current: result.currentPage,
        total: result.totalPages,
        totalCount: result.totalCount
      });
    } catch (error) {
      console.error('加载数据失败:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <List
      paginationType="scroll"
      tabStyle="switch"
      tabData={tabData}
      data={data}
      pagination={pagination}
      loading={loading}
      onLoadData={handleLoadData}
      renderItem={renderItem}
    />
  );
};
```

### 4.3 自定义样式主题

```less
// 自定义主题样式
.my-custom-list {
  // 重写CSS变量
  --list-primary-color: #722ed1;
  --list-border-color: #b37feb;
  --list-border-radius: 8px;
  
  // 自定义列表项样式
  .list-item {
    border: 1px solid var(--list-border-color);
    border-radius: var(--list-border-radius);
    padding: 16px;
    transition: all 0.3s ease;
    
    &:hover {
      box-shadow: 0 4px 8px rgba(114, 46, 209, 0.2);
      transform: translateY(-2px);
    }
  }
  
  // 自定义标签页样式
  .pisell-list-tabs {
    background: linear-gradient(90deg, #722ed1 0%, #b37feb 100%);
    border-radius: 8px;
    padding: 4px;
    
    .pisell-tab-item {
      color: white;
      border-radius: 4px;
      
      &.pisell-tab-item-active {
        background: rgba(255, 255, 255, 0.2);
      }
    }
  }
}
```

## 5. 最佳实践

### 5.1 性能优化

#### 5.1.1 数据优化

```tsx
// ✅ 好的做法：为列表项提供稳定的key
const data = items.map(item => ({
  ...item,
  id: item.id || `item-${index}` // 确保每项都有唯一ID
}));

// ✅ 好的做法：使用React.memo优化子组件
const ListItem = React.memo(({ item, index }) => (
  <div className="item">
    <h3>{item.title}</h3>
    <p>{item.description}</p>
  </div>
));

// ✅ 好的做法：缓存渲染函数
const renderItem = useCallback((item, index) => (
  <ListItem key={item.id} item={item} index={index} />
), []);
```

#### 5.1.2 滚动优化

```tsx
// ✅ 好的做法：合理设置页面大小
<List
  paginationType="scroll"
  defaultPageSize={20}        // 不要设置过大，避免初始渲染过多
  height={400}               // 给定固定高度启用滚动
/>

// ✅ 好的做法：防抖处理数据加载
const debouncedLoadData = useMemo(
  () => debounce(handleLoadData, 300),
  [handleLoadData]
);
```

### 5.2 用户体验优化

#### 5.2.1 加载状态

```tsx
<List
  data={data}
  loading={loading}           // 显示加载状态
  emptyConfig={{
    show: true,
    text: loading ? '加载中...' : '暂无数据',
    icon: loading ? <LoadingIcon /> : <EmptyIcon />
  }}
  renderItem={renderItem}
/>
```

#### 5.2.2 错误处理

```tsx
const [error, setError] = useState(null);

const handleLoadData = async (params) => {
  try {
    setError(null);
    setLoading(true);
    const result = await fetchData(params);
    setData(result.items);
  } catch (err) {
    setError(err.message);
    console.error('数据加载失败:', err);
  } finally {
    setLoading(false);
  }
};

return (
  <List
    data={error ? [] : data}
    loading={loading}
    emptyConfig={{
      show: true,
      text: error ? '加载失败，请重试' : '暂无数据',
      icon: error ? <ErrorIcon /> : <EmptyIcon />
    }}
    onLoadData={handleLoadData}
    renderItem={renderItem}
  />
);
```

### 5.3 可访问性优化

```tsx
// ✅ 好的做法：提供语义化的结构
const renderItem = (item, index) => (
  <article 
    role="listitem"
    aria-label={`列表项 ${index + 1}: ${item.title}`}
    tabIndex={0}
  >
    <h3>{item.title}</h3>
    <p>{item.description}</p>
  </article>
);

<List
  role="list"
  aria-label="项目列表"
  data={data}
  renderItem={renderItem}
/>
```

### 5.4 国际化支持

```tsx
import { getText } from '@pisell/materials/lib/locales';

<List
  data={data}
  emptyConfig={{
    show: true,
    text: getText('custom-empty-message') || '暂无数据'
  }}
  renderItem={renderItem}
/>
```

## 6. 常见问题

### 6.1 为什么滚动加载不起作用？

**原因**：容器高度为auto，无法触发滚动事件。

**解决方案**：为List组件设置固定高度。

```tsx
// ❌ 错误做法
<List paginationType="scroll" height="auto" />

// ✅ 正确做法
<List paginationType="scroll" height={400} />
```

### 6.2 为什么标签页分组不起作用？

**原因**：数据项中缺少对应的分组字段，或tabGroup配置错误。

**解决方案**：确保数据结构和配置匹配。

```tsx
// ❌ 错误：数据结构和配置不匹配
const data = [{ id: 1, type: 'A' }];
<List tabGroup="category" tabData={[{ key: 'A', label: 'A类' }]} />

// ✅ 正确：确保字段匹配
const data = [{ id: 1, category: 'A' }];
<List tabGroup="category" tabData={[{ key: 'A', label: 'A类' }]} />
```

### 6.3 为什么瀑布流布局不平衡？

**原因**：缺少预设高度信息，无法提前计算布局。

**解决方案**：为数据项提供预设高度。

```tsx
// ✅ 提供预设高度
const data = [
  { id: 1, title: '项目1', height: 200 },
  { id: 2, title: '项目2', height: 150 },
];

<List displayStyle="waterfall" data={data} />
```

### 6.4 如何自定义分页器样式？

**方案1**：使用CSS覆盖默认样式

```less
.my-list .list-footer .pisell-pagination {
  .pisell-pagination-item {
    border-color: #722ed1;
    
    &.pisell-pagination-item-active {
      background: #722ed1;
    }
  }
}
```

**方案2**：使用CSS变量

```less
.my-list {
  --pagination-primary-color: #722ed1;
  --pagination-border-color: #d9d9d9;
}
```

## 7. API 参考

详细的API参考请查看类型定义文件 `types.ts`，其中包含了所有配置选项的完整定义和说明。

### 7.1 主要接口

- `ListProps<T>`：主组件属性接口
- `BaseListItem`：列表项基础接口
- `TabItem`：标签页配置接口
- `LoadDataParams`：数据加载参数接口
- `ResponsiveProps`：响应式配置接口

### 7.2 主要Hooks

- `useDevice()`：设备检测Hook
- `useListState()`：列表状态管理Hook（内部使用）
- `useWaterfall()`：瀑布流布局Hook（内部使用）
