# ConciseListTable 简洁数据表格组件

一个高性能、轻量级的数据表格组件，具有自动滚动功能、自定义格式化和响应式设计。非常适合仪表板、数据展示和实时监控界面。

## 功能特性

- **高性能**：通过最少的 DOM 操作实现高效渲染
- **自动滚动**：用于连续数据显示的无缝无限滚动
- **灵活列配置**：可配置宽度、对齐方式和自定义格式化
- **响应式设计**：使用 ResizeObserver 自动调整宽度
- **无障碍访问**：ARIA 属性和键盘导航支持
- **自定义样式**：全面的主题和样式选项
- **事件处理**：行点击事件和焦点管理
- **类型安全**：完整的 TypeScript 支持和详细接口

## 基本用法

```svelte
<script>
import ConciseListTable, { type Column, type TableOptions } from '@ticatec/uniface-element/ConciseListTable';

const columns: Column[] = [
  { title: '姓名', field: 'name', width: 150, align: 'left' },
  { title: '年龄', field: 'age', width: 80, align: 'center' },
  { title: '邮箱', field: 'email', width: 200, weight: 1 }
];

const data = [
  { name: '张三', age: 30, email: 'zhang@example.com' },
  { name: '李四', age: 25, email: 'li@example.com' },
  { name: '王五', age: 35, email: 'wang@example.com' }
];

const options: TableOptions = {
  headerHeight: 40,
  rowHeight: 35,
  backgroundColor: '#ffffff',
  headerBackgroundColor: '#f5f5f5'
};

const handleRowClick = (row) => {
  console.log('点击行:', row);
};
</script>

<ConciseListTable 
  list={data}
  {columns}
  {options}
  rowClickHandler={handleRowClick}
/>
```

## 属性

| 属性 | 类型 | 默认值 | 描述 |
|------|------|---------|-------------|
| `list` | `Array<any>` | - | 要显示的数据对象数组 |
| `columns` | `Array<Column>` | - | 列定义配置 |
| `options` | `TableOptions` | - | 表格样式和行为选项 |
| `autoScroll` | `boolean` | `false` | 启用自动滚动 |
| `scrollInterval` | `number` | `2000` | 滚动步骤间隔毫秒数 |
| `rowClickHandler` | `RowClickHandler \| null` | `null` | 行点击事件处理器 |
| `style` | `string` | `''` | 容器的自定义 CSS 样式 |
| `className` | `string` | `''` | 附加的 CSS 类名 |
| `onfocus` | `((event: FocusEvent) => void) \| null` | `null` | 焦点事件处理器 |
| `onblur` | `((event: FocusEvent) => void) \| null` | `null` | 失焦事件处理器 |

## 方法

| 方法 | 描述 |
|--------|-------------|
| `setFocus()` | 编程方式聚焦到第一个表格行 |

## Column 接口

```typescript
interface Column {
  title: string;                    // 列标题显示文本
  field: string;                    // 数据对象中的字段名
  width: number;                    // 宽度（像素）
  align?: "left" | "center" | "right"; // 文本对齐方式
  weight?: number;                  // 弹性权重（0 = 固定，>0 = 比例）
  formatter?: (value: any) => string; // 自定义格式化函数
  escapeHTML?: boolean;             // 允许单元格中的 HTML 内容
}
```

## TableOptions 接口

```typescript
interface TableOptions {
  backgroundColor?: string;           // 表格背景色
  color?: string;                    // 表格文字颜色
  headerHeight?: number;             // 标题行高度（像素）
  headerBackgroundColor?: string;    // 标题背景色
  headerColor?: string;              // 标题文字颜色
  alternativeBackgroundColor?: string; // 交替行背景色
  alternativeColor?: string;         // 交替行文字颜色
  rowHeight?: number;                // 数据行高度（像素）
}
```

## 基础示例

### 简单数据表格

```svelte
<script>
import ConciseListTable from '@ticatec/uniface-element/ConciseListTable';

const employees = [
  { id: 1, name: '张小明', department: '工程部', salary: 75000 },
  { id: 2, name: '李小红', department: '市场部', salary: 65000 },
  { id: 3, name: '王小强', department: '销售部', salary: 70000 }
];

const columns = [
  { title: 'ID', field: 'id', width: 60, align: 'center' },
  { title: '姓名', field: 'name', width: 150, align: 'left' },
  { title: '部门', field: 'department', width: 120, align: 'center' },
  { title: '薪资', field: 'salary', width: 100, align: 'right', 
    formatter: (value) => `¥${value.toLocaleString()}` }
];

const options = {
  headerHeight: 40,
  rowHeight: 35,
  headerBackgroundColor: '#f8f9fa',
  alternativeBackgroundColor: '#f8f9fa'
};
</script>

<ConciseListTable 
  list={employees}
  {columns}
  {options}
/>
```

### 自动滚动表格

```svelte
<script>
import ConciseListTable from '@ticatec/uniface-element/ConciseListTable';

const stockPrices = [
  { symbol: 'AAPL', price: 150.25, change: '+2.15', volume: '45.2M' },
  { symbol: 'GOOGL', price: 2800.50, change: '-12.30', volume: '1.8M' },
  { symbol: 'MSFT', price: 305.75, change: '+1.45', volume: '28.5M' },
  { symbol: 'TSLA', price: 850.20, change: '+15.60', volume: '35.1M' },
  // ... 更多数据
];

const columns = [
  { title: '股票代码', field: 'symbol', width: 80, align: 'center' },
  { title: '价格', field: 'price', width: 100, align: 'right',
    formatter: (value) => `$${value.toFixed(2)}` },
  { title: '涨跌', field: 'change', width: 80, align: 'right' },
  { title: '成交量', field: 'volume', width: 100, align: 'right' }
];

const options = {
  rowHeight: 30,
  headerHeight: 35,
  backgroundColor: '#000',
  color: '#00ff00',
  headerBackgroundColor: '#333',
  headerColor: '#fff'
};
</script>

<div style="height: 300px;">
  <ConciseListTable 
    list={stockPrices}
    {columns}
    {options}
    autoScroll={true}
    scrollInterval={3000}
  />
</div>
```

### 自定义格式化表格

```svelte
<script>
import ConciseListTable from '@ticatec/uniface-element/ConciseListTable';

const orders = [
  { id: 'ORD-001', customer: '张三', date: '2024-01-15', 
    amount: 299.99, status: 'shipped' },
  { id: 'ORD-002', customer: '李四', date: '2024-01-16', 
    amount: 149.50, status: 'pending' },
  { id: 'ORD-003', customer: '王五', date: '2024-01-17', 
    amount: 599.99, status: 'delivered' }
];

const formatDate = (dateStr) => {
  return new Date(dateStr).toLocaleDateString('zh-CN', {
    year: 'numeric', month: '2-digit', day: '2-digit'
  });
};

const formatStatus = (status) => {
  const statusMap = {
    shipped: { text: '已发货', color: '#ffc107' },
    pending: { text: '待处理', color: '#6c757d' },
    delivered: { text: '已送达', color: '#28a745' }
  };
  const { text, color } = statusMap[status];
  return `<span style="color: ${color}; font-weight: bold;">${text}</span>`;
};

const columns = [
  { title: '订单号', field: 'id', width: 100, align: 'left' },
  { title: '客户', field: 'customer', width: 150, weight: 1 },
  { title: '日期', field: 'date', width: 120, align: 'center', 
    formatter: formatDate },
  { title: '金额', field: 'amount', width: 100, align: 'right',
    formatter: (value) => `¥${value.toFixed(2)}` },
  { title: '状态', field: 'status', width: 100, align: 'center',
    formatter: formatStatus, escapeHTML: true }
];

const options = {
  headerHeight: 45,
  rowHeight: 40,
  headerBackgroundColor: '#007bff',
  headerColor: '#ffffff',
  alternativeBackgroundColor: '#f8f9fa'
};
</script>

<ConciseListTable 
  list={orders}
  {columns}
  {options}
/>
```

### 响应式弹性列表格

```svelte
<script>
import ConciseListTable from '@ticatec/uniface-element/ConciseListTable';

const products = [
  { id: 1, name: '无线耳机高级版', 
    category: '电子产品', price: 199.99, stock: 15 },
  { id: 2, name: '人体工学办公椅带腰部支撑', 
    category: '家具', price: 299.99, stock: 8 },
  { id: 3, name: '智能家居安防摄像头系统', 
    category: '电子产品', price: 149.99, stock: 23 }
];

const columns = [
  { title: 'ID', field: 'id', width: 50, align: 'center' },
  { title: '产品名称', field: 'name', width: 200, weight: 2 }, // 弹性
  { title: '分类', field: 'category', width: 120, weight: 1 }, // 弹性
  { title: '价格', field: 'price', width: 100, align: 'right',
    formatter: (value) => `¥${value.toFixed(2)}` },
  { title: '库存', field: 'stock', width: 80, align: 'center' }
];

const options = {
  headerHeight: 40,
  rowHeight: 45,
  backgroundColor: '#ffffff',
  headerBackgroundColor: '#e9ecef',
  alternativeBackgroundColor: '#f8f9fa'
};
</script>

<div style="width: 100%; min-width: 600px;">
  <ConciseListTable 
    list={products}
    {columns}
    {options}
  />
</div>
```

## 事件处理

```svelte
<script>
import ConciseListTable from '@ticatec/uniface-element/ConciseListTable';

let selectedRow = null;
let focusCount = 0;
let tableRef;

const data = [
  { id: 1, name: '项目 1', value: 100 },
  { id: 2, name: '项目 2', value: 200 },
  { id: 3, name: '项目 3', value: 300 }
];

const columns = [
  { title: 'ID', field: 'id', width: 60, align: 'center' },
  { title: '名称', field: 'name', width: 150 },
  { title: '数值', field: 'value', width: 100, align: 'right' }
];

const options = {
  headerHeight: 35,
  rowHeight: 30
};

const handleRowClick = (row) => {
  selectedRow = row;
  console.log('选中行:', row);
};

const handleFocus = (event) => {
  focusCount++;
  console.log('表格获得焦点', focusCount);
};

const handleBlur = (event) => {
  console.log('表格失去焦点');
};

const focusTable = () => {
  tableRef?.setFocus();
};
</script>

<div>
  <button on:click={focusTable}>聚焦表格</button>
  
  <ConciseListTable 
    bind:this={tableRef}
    list={data}
    {columns}
    {options}
    rowClickHandler={handleRowClick}
    onfocus={handleFocus}
    onblur={handleBlur}
  />
  
  {#if selectedRow}
    <div class="selected-info">
      已选中: {selectedRow.name} (ID: {selectedRow.id})
    </div>
  {/if}
  
  <div class="focus-info">
    焦点次数: {focusCount}
  </div>
</div>

<style>
  .selected-info, .focus-info {
    margin-top: 10px;
    padding: 8px;
    background: #e7f3ff;
    border: 1px solid #b3d9ff;
    border-radius: 4px;
  }
</style>
```

## 高级示例

### 实时数据仪表板

```svelte
<script>
import ConciseListTable from '@ticatec/uniface-element/ConciseListTable';
import { onMount, onDestroy } from 'svelte';

let realtimeData = [];
let updateInterval;

// 模拟实时数据更新
const generateRandomData = () => {
  return Array.from({ length: 20 }, (_, i) => ({
    id: `SRV-${String(i + 1).padStart(3, '0')}`,
    name: `服务器 ${i + 1}`,
    cpu: (Math.random() * 100).toFixed(1),
    memory: (Math.random() * 100).toFixed(1),
    disk: (Math.random() * 100).toFixed(1),
    status: Math.random() > 0.8 ? 'warning' : 'healthy',
    uptime: Math.floor(Math.random() * 365) + 1
  }));
};

const columns = [
  { title: '服务器ID', field: 'id', width: 100, align: 'center' },
  { title: '名称', field: 'name', width: 120, weight: 1 },
  { title: 'CPU %', field: 'cpu', width: 80, align: 'right',
    formatter: (value) => `${value}%` },
  { title: '内存 %', field: 'memory', width: 80, align: 'right',
    formatter: (value) => `${value}%` },
  { title: '磁盘 %', field: 'disk', width: 80, align: 'right',
    formatter: (value) => `${value}%` },
  { title: '状态', field: 'status', width: 100, align: 'center',
    formatter: (status) => {
      const statusMap = {
        healthy: { text: '正常', color: '#28a745' },
        warning: { text: '警告', color: '#ffc107' }
      };
      const { text, color } = statusMap[status];
      return `<span style="color: ${color}; font-weight: bold;">${text}</span>`;
    },
    escapeHTML: true
  },
  { title: '运行天数', field: 'uptime', width: 100, align: 'right' }
];

const options = {
  headerHeight: 40,
  rowHeight: 35,
  backgroundColor: '#1a1a1a',
  color: '#ffffff',
  headerBackgroundColor: '#333333',
  headerColor: '#ffffff',
  alternativeBackgroundColor: '#2a2a2a'
};

onMount(() => {
  realtimeData = generateRandomData();
  
  // 每5秒更新数据
  updateInterval = setInterval(() => {
    realtimeData = generateRandomData();
  }, 5000);
});

onDestroy(() => {
  if (updateInterval) {
    clearInterval(updateInterval);
  }
});
</script>

<div class="dashboard">
  <h3>服务器监控仪表板</h3>
  <div style="height: 400px; border: 1px solid #333;">
    <ConciseListTable 
      list={realtimeData}
      {columns}
      {options}
      autoScroll={true}
      scrollInterval={4000}
    />
  </div>
</div>

<style>
  .dashboard {
    background: #1a1a1a;
    color: #ffffff;
    padding: 20px;
    border-radius: 8px;
  }
  
  .dashboard h3 {
    margin: 0 0 16px 0;
    color: #ffffff;
  }
</style>
```

### 金融交易表格

```svelte
<script>
import ConciseListTable from '@ticatec/uniface-element/ConciseListTable';

const tradingData = [
  { symbol: 'AAPL', price: 150.25, change: 2.15, changePercent: 1.45, volume: 45200000 },
  { symbol: 'GOOGL', price: 2800.50, change: -12.30, changePercent: -0.44, volume: 1800000 },
  { symbol: 'MSFT', price: 305.75, change: 1.45, changePercent: 0.48, volume: 28500000 },
  { symbol: 'TSLA', price: 850.20, change: 15.60, changePercent: 1.87, volume: 35100000 }
];

const formatPrice = (value) => `$${value.toFixed(2)}`;

const formatChange = (value) => {
  const color = value >= 0 ? '#28a745' : '#dc3545';
  const sign = value >= 0 ? '+' : '';
  return `<span style="color: ${color}; font-weight: bold;">${sign}${value.toFixed(2)}</span>`;
};

const formatPercent = (value) => {
  const color = value >= 0 ? '#28a745' : '#dc3545';
  const sign = value >= 0 ? '+' : '';
  return `<span style="color: ${color};">${sign}${value.toFixed(2)}%</span>`;
};

const formatVolume = (value) => {
  if (value >= 1000000) {
    return `${(value / 1000000).toFixed(1)}M`;
  } else if (value >= 1000) {
    return `${(value / 1000).toFixed(1)}K`;
  }
  return value.toString();
};

const columns = [
  { title: '股票代码', field: 'symbol', width: 80, align: 'center' },
  { title: '价格', field: 'price', width: 100, align: 'right', 
    formatter: formatPrice },
  { title: '涨跌', field: 'change', width: 80, align: 'right',
    formatter: formatChange, escapeHTML: true },
  { title: '涨跌幅 %', field: 'changePercent', width: 80, align: 'right',
    formatter: formatPercent, escapeHTML: true },
  { title: '成交量', field: 'volume', width: 80, align: 'right',
    formatter: formatVolume }
];

const options = {
  headerHeight: 35,
  rowHeight: 30,
  backgroundColor: '#000000',
  color: '#ffffff',
  headerBackgroundColor: '#1a1a1a',
  headerColor: '#ffffff'
};

const handleStockClick = (stock) => {
  console.log('选中股票:', stock.symbol);
  // 可以打开详细视图、下单等
};
</script>

<div class="trading-table">
  <h4>实时股价</h4>
  <ConciseListTable 
    list={tradingData}
    {columns}
    {options}
    rowClickHandler={handleStockClick}
  />
</div>

<style>
  .trading-table {
    background: #000;
    color: #fff;
    padding: 16px;
    border-radius: 4px;
    font-family: 'Courier New', monospace;
  }
  
  .trading-table h4 {
    margin: 0 0 12px 0;
    color: #00ff00;
  }
</style>
```

## 无障碍访问

ConciseListTable 组件包含全面的无障碍功能：

- **ARIA 角色**：正确的 `table`、`row`、`cell` 和 `columnheader` 角色
- **键盘导航**：Tab 导航和 Enter/Space 激活
- **屏幕阅读器支持**：适当的标签和行索引
- **焦点管理**：编程焦点控制
- **语义结构**：正确的表格标记和关系

### 最佳实践

```svelte
<!-- 好的：描述性表格标签 -->
<ConciseListTable 
  list={data}
  columns={columns}
  options={options}
  aria-label="员工信息表格"
/>

<!-- 好的：一致的列对齐 -->
const columns = [
  { title: 'ID', field: 'id', width: 60, align: 'center' },
  { title: '姓名', field: 'name', width: 150, align: 'left' },
  { title: '薪资', field: 'salary', width: 100, align: 'right' }
];

<!-- 好的：有意义的格式化器 -->
{ title: '状态', field: 'status', formatter: (value) => 
  value ? '激活' : '未激活' }
```

## 性能优化

- **高效渲染**：通过响应式变化实现最小 DOM 更新
- **自动滚动性能**：优化的基于 transform 的动画
- **ResizeObserver**：高效的视口大小监控
- **内存管理**：定时器和观察器的正确清理
- **类型安全**：完整的 TypeScript 支持减少运行时错误

## 浏览器支持

支持所有现代浏览器：
- ES6+ JavaScript
- ResizeObserver API
- CSS transforms 和 transitions
- 现代 DOM API

## 迁移说明

从旧版本升级时：
- `onChange` 事件现在是 `onchange`（小写）
- `onClick` 事件现在是 `onclick`（小写）
- 新的无障碍功能无需代码更改
- 增强的 TypeScript 支持提供更好的开发体验