# Table

## Description

A comprehensive data table component that provides structure for presenting tabular data in an organized, accessible format. The Table component serves as the root container for table content and offers features like sticky headers for enhanced usability in data-heavy interfaces.

## Aliases

- Table
- DataTable
- Grid
- TableContainer
- DataGrid

## Props Breakdown

**Extends:** `TableHTMLAttributes<HTMLTableElement>`

| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `stickyHeader` | `boolean` | `false` | No | Whether the table header should stick to the top when scrolling |
| `children` | `ReactNode` | - | Yes | Table content including TableHeader, TableBody, and TableRow components |

Plus all standard HTML table attributes (id, className, style, role, etc.).

## Examples

### Basic Data Table
```tsx
import { Table, TableHeader, TableBody, TableRow, TableHeaderCell, TableCell, Text } from '@delightui/components';

function BasicTableExample() {
  const users = [
    { id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin' },
    { id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User' },
    { id: 3, name: 'Bob Johnson', email: 'bob@example.com', role: 'Editor' }
  ];

  return (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHeaderCell>Name</TableHeaderCell>
          <TableHeaderCell>Email</TableHeaderCell>
          <TableHeaderCell>Role</TableHeaderCell>
        </TableRow>
      </TableHeader>
      <TableBody>
        <List
          data={users}
          component={({ name, email, role }) => (
            <TableRow>
              <TableCell>{name}</TableCell>
              <TableCell>{email}</TableCell>
              <TableCell>{role}</TableCell>
            </TableRow>
          )}
          keyExtractor={(user) => user.id}
        />
      </TableBody>
    </Table>
  );
}
```

### Sticky Header Table
```tsx
function StickyHeaderExample() {
  const products = Array.from({ length: 50 }, (_, i) => ({
    id: i + 1,
    name: `Product ${i + 1}`,
    category: ['Electronics', 'Clothing', 'Books', 'Home'][i % 4],
    price: (Math.random() * 1000).toFixed(2),
    stock: Math.floor(Math.random() * 100)
  }));

  return (
    <div className="table-container" style={{ height: '400px', overflow: 'auto' }}>
      <Table stickyHeader>
        <TableHeader>
          <TableRow>
            <TableHeaderCell>ID</TableHeaderCell>
            <TableHeaderCell>Product Name</TableHeaderCell>
            <TableHeaderCell>Category</TableHeaderCell>
            <TableHeaderCell>Price</TableHeaderCell>
            <TableHeaderCell>Stock</TableHeaderCell>
          </TableRow>
        </TableHeader>
        <TableBody>
          <List
            data={products}
            component={({ id, name, category, price, stock }) => (
              <TableRow>
                <TableCell>{id}</TableCell>
                <TableCell>{name}</TableCell>
                <TableCell>{category}</TableCell>
                <TableCell>${price}</TableCell>
                <TableCell>{stock}</TableCell>
              </TableRow>
            )}
            keyExtractor={(product) => product.id}
          />
        </TableBody>
      </Table>
    </div>
  );
}
```

### Sortable Table with Actions
```tsx
import { Table, TableHeader, TableBody, TableRow, TableHeaderCell, TableCell, Button, Icon } from '@delightui/components';

function SortableTableExample() {
  const [sortField, setSortField] = useState('name');
  const [sortDirection, setSortDirection] = useState('asc');
  
  const data = [
    { id: 1, name: 'Alice Johnson', department: 'Engineering', salary: 95000, startDate: '2021-03-15' },
    { id: 2, name: 'Bob Smith', department: 'Marketing', salary: 75000, startDate: '2020-11-20' },
    { id: 3, name: 'Carol Williams', department: 'Design', salary: 85000, startDate: '2022-01-10' }
  ];

  const handleSort = (field) => {
    if (sortField === field) {
      setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc');
    } else {
      setSortField(field);
      setSortDirection('asc');
    }
  };

  const sortedData = [...data].sort((a, b) => {
    const aVal = a[sortField];
    const bVal = b[sortField];
    const modifier = sortDirection === 'asc' ? 1 : -1;
    return aVal < bVal ? -1 * modifier : aVal > bVal ? 1 * modifier : 0;
  });

  return (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHeaderCell 
            onClick={() => handleSort('name')}
            className="sortable-header"
          >
            Name
            <Icon 
              icon={sortField === 'name' && sortDirection === 'desc' ? 'ArrowUp' : 'ArrowDown'} 
              size="Small" 
            />
          </TableHeaderCell>
          <TableHeaderCell 
            onClick={() => handleSort('department')}
            className="sortable-header"
          >
            Department
            <Icon 
              icon={sortField === 'department' && sortDirection === 'desc' ? 'ArrowUp' : 'ArrowDown'} 
              size="Small" 
            />
          </TableHeaderCell>
          <TableHeaderCell 
            onClick={() => handleSort('salary')}
            className="sortable-header"
          >
            Salary
            <Icon 
              icon={sortField === 'salary' && sortDirection === 'desc' ? 'ArrowUp' : 'ArrowDown'} 
              size="Small" 
            />
          </TableHeaderCell>
          <TableHeaderCell>Actions</TableHeaderCell>
        </TableRow>
      </TableHeader>
      <TableBody>
        {sortedData.map(employee => (
          <TableRow key={employee.id}>
            <TableCell>{employee.name}</TableCell>
            <TableCell>{employee.department}</TableCell>
            <TableCell>${employee.salary.toLocaleString()}</TableCell>
            <TableCell>
              <div className="action-buttons">
                <Button size="Small" type="Ghost">Edit</Button>
                <Button size="Small" type="Ghost">Delete</Button>
              </div>
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  );
}
```

### Table with Row Selection
```tsx
function SelectableTableExample() {
  const [selectedRows, setSelectedRows] = useState(new Set());
  
  const tasks = [
    { id: 1, title: 'Update documentation', status: 'In Progress', assignee: 'John', priority: 'High' },
    { id: 2, title: 'Fix login bug', status: 'Todo', assignee: 'Jane', priority: 'Critical' },
    { id: 3, title: 'Design new feature', status: 'Done', assignee: 'Bob', priority: 'Medium' }
  ];

  const handleSelectAll = (checked) => {
    if (checked) {
      setSelectedRows(new Set(tasks.map(task => task.id)));
    } else {
      setSelectedRows(new Set());
    }
  };

  const handleSelectRow = (id, checked) => {
    const newSelected = new Set(selectedRows);
    if (checked) {
      newSelected.add(id);
    } else {
      newSelected.delete(id);
    }
    setSelectedRows(newSelected);
  };

  return (
    <div>
      <div className="table-actions">
        <Text>Selected: {selectedRows.size} items</Text>
        {selectedRows.size > 0 && (
          <Button size="Small" type="Outlined">
            Delete Selected
          </Button>
        )}
      </div>
      
      <Table>
        <TableHeader>
          <TableRow>
            <TableHeaderCell>
              <Checkbox 
                checked={selectedRows.size === tasks.length}
                indeterminate={selectedRows.size > 0 && selectedRows.size < tasks.length}
                onChange={(e) => handleSelectAll(e.target.checked)}
              />
            </TableHeaderCell>
            <TableHeaderCell>Task</TableHeaderCell>
            <TableHeaderCell>Status</TableHeaderCell>
            <TableHeaderCell>Assignee</TableHeaderCell>
            <TableHeaderCell>Priority</TableHeaderCell>
          </TableRow>
        </TableHeader>
        <TableBody>
          {tasks.map(task => (
            <TableRow key={task.id} className={selectedRows.has(task.id) ? 'selected-row' : ''}>
              <TableCell>
                <Checkbox 
                  checked={selectedRows.has(task.id)}
                  onChange={(e) => handleSelectRow(task.id, e.target.checked)}
                />
              </TableCell>
              <TableCell>{task.title}</TableCell>
              <TableCell>
                <Chip 
                  style={task.status === 'Done' ? 'Success' : task.status === 'In Progress' ? 'Warning' : 'Default'}
                >
                  {task.status}
                </Chip>
              </TableCell>
              <TableCell>{task.assignee}</TableCell>
              <TableCell>
                <Chip 
                  style={task.priority === 'Critical' ? 'Error' : task.priority === 'High' ? 'Warning' : 'Default'}
                >
                  {task.priority}
                </Chip>
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </div>
  );
}
```

### Expandable Rows Table
```tsx
function ExpandableTableExample() {
  const [expandedRows, setExpandedRows] = useState(new Set());
  
  const orders = [
    { 
      id: '001', 
      customer: 'John Doe', 
      total: 299.99, 
      date: '2023-10-15',
      items: [
        { name: 'Laptop', quantity: 1, price: 199.99 },
        { name: 'Mouse', quantity: 2, price: 50.00 }
      ]
    },
    { 
      id: '002', 
      customer: 'Jane Smith', 
      total: 159.97, 
      date: '2023-10-14',
      items: [
        { name: 'Keyboard', quantity: 1, price: 79.99 },
        { name: 'Monitor Stand', quantity: 1, price: 79.98 }
      ]
    }
  ];

  const toggleRow = (id) => {
    const newExpanded = new Set(expandedRows);
    if (newExpanded.has(id)) {
      newExpanded.delete(id);
    } else {
      newExpanded.add(id);
    }
    setExpandedRows(newExpanded);
  };

  return (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHeaderCell></TableHeaderCell>
          <TableHeaderCell>Order ID</TableHeaderCell>
          <TableHeaderCell>Customer</TableHeaderCell>
          <TableHeaderCell>Date</TableHeaderCell>
          <TableHeaderCell>Total</TableHeaderCell>
        </TableRow>
      </TableHeader>
      <TableBody>
        {orders.map(order => (
          <React.Fragment key={order.id}>
            <TableRow>
              <TableCell>
                <Button 
                  size="Small" 
                  type="Ghost"
                  onClick={() => toggleRow(order.id)}
                >
                  <Icon 
                    icon={expandedRows.has(order.id) ? 'ExpandLess' : 'ExpandMore'} 
                    size="Small" 
                  />
                </Button>
              </TableCell>
              <TableCell>{order.id}</TableCell>
              <TableCell>{order.customer}</TableCell>
              <TableCell>{order.date}</TableCell>
              <TableCell>${order.total}</TableCell>
            </TableRow>
            {expandedRows.has(order.id) && (
              <TableRow className="expanded-row">
                <TableCell colSpan={5}>
                  <div className="order-details">
                    <Text type="Heading6">Order Items:</Text>
                    <Table>
                      <TableHeader>
                        <TableRow>
                          <TableHeaderCell>Item</TableHeaderCell>
                          <TableHeaderCell>Quantity</TableHeaderCell>
                          <TableHeaderCell>Price</TableHeaderCell>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {order.items.map((item, index) => (
                          <TableRow key={index}>
                            <TableCell>{item.name}</TableCell>
                            <TableCell>{item.quantity}</TableCell>
                            <TableCell>${item.price}</TableCell>
                          </TableRow>
                        ))}
                      </TableBody>
                    </Table>
                  </div>
                </TableCell>
              </TableRow>
            )}
          </React.Fragment>
        ))}
      </TableBody>
    </Table>
  );
}
```

### Responsive Table
```tsx
function ResponsiveTableExample() {
  const transactions = [
    { id: 'TX001', type: 'Purchase', amount: -99.99, merchant: 'Amazon', date: '2023-10-15', category: 'Shopping' },
    { id: 'TX002', type: 'Deposit', amount: 2500.00, merchant: 'Direct Deposit', date: '2023-10-14', category: 'Income' },
    { id: 'TX003', type: 'Purchase', amount: -45.67, merchant: 'Gas Station', date: '2023-10-13', category: 'Transport' }
  ];

  return (
    <div className="responsive-table-wrapper">
      <Table className="responsive-table">
        <TableHeader>
          <TableRow>
            <TableHeaderCell>Transaction</TableHeaderCell>
            <TableHeaderCell className="hide-mobile">Type</TableHeaderCell>
            <TableHeaderCell>Amount</TableHeaderCell>
            <TableHeaderCell className="hide-mobile">Merchant</TableHeaderCell>
            <TableHeaderCell className="hide-tablet">Date</TableHeaderCell>
            <TableHeaderCell className="hide-mobile">Category</TableHeaderCell>
          </TableRow>
        </TableHeader>
        <TableBody>
          {transactions.map(transaction => (
            <TableRow key={transaction.id}>
              <TableCell>
                <div className="transaction-info">
                  <Text type="BodyMedium">{transaction.id}</Text>
                  <Text type="BodySmall" className="show-mobile">
                    {transaction.type} • {transaction.merchant}
                  </Text>
                </div>
              </TableCell>
              <TableCell className="hide-mobile">{transaction.type}</TableCell>
              <TableCell>
                <Text 
                  type="BodyMedium" 
                  className={transaction.amount > 0 ? 'positive-amount' : 'negative-amount'}
                >
                  ${Math.abs(transaction.amount).toFixed(2)}
                </Text>
              </TableCell>
              <TableCell className="hide-mobile">{transaction.merchant}</TableCell>
              <TableCell className="hide-tablet">{transaction.date}</TableCell>
              <TableCell className="hide-mobile">
                <Chip size="Small">{transaction.category}</Chip>
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </div>
  );
}
```

### Table with Pagination
```tsx
function PaginatedTableExample() {
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize] = useState(5);
  
  const allData = Array.from({ length: 50 }, (_, i) => ({
    id: i + 1,
    name: `User ${i + 1}`,
    email: `user${i + 1}@example.com`,
    status: ['Active', 'Inactive', 'Pending'][i % 3],
    lastLogin: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000).toLocaleDateString()
  }));

  const totalPages = Math.ceil(allData.length / pageSize);
  const startIndex = (currentPage - 1) * pageSize;
  const currentData = allData.slice(startIndex, startIndex + pageSize);

  return (
    <div>
      <Table>
        <TableHeader>
          <TableRow>
            <TableHeaderCell>ID</TableHeaderCell>
            <TableHeaderCell>Name</TableHeaderCell>
            <TableHeaderCell>Email</TableHeaderCell>
            <TableHeaderCell>Status</TableHeaderCell>
            <TableHeaderCell>Last Login</TableHeaderCell>
          </TableRow>
        </TableHeader>
        <TableBody>
          {currentData.map(user => (
            <TableRow key={user.id}>
              <TableCell>{user.id}</TableCell>
              <TableCell>{user.name}</TableCell>
              <TableCell>{user.email}</TableCell>
              <TableCell>
                <Chip 
                  style={user.status === 'Active' ? 'Success' : user.status === 'Inactive' ? 'Error' : 'Warning'}
                >
                  {user.status}
                </Chip>
              </TableCell>
              <TableCell>{user.lastLogin}</TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
      
      <div className="table-pagination">
        <Pagination
          currentPage={currentPage}
          totalPages={totalPages}
          onPageChange={setCurrentPage}
        />
        <Text type="BodySmall">
          Showing {startIndex + 1}-{Math.min(startIndex + pageSize, allData.length)} of {allData.length} results
        </Text>
      </div>
    </div>
  );
}
```

### Loading State Table
```tsx
function LoadingTableExample() {
  const [isLoading, setIsLoading] = useState(true);
  const [data, setData] = useState([]);

  useEffect(() => {
    // Simulate API call
    setTimeout(() => {
      setData([
        { id: 1, name: 'John Doe', role: 'Admin', lastActive: '2 hours ago' },
        { id: 2, name: 'Jane Smith', role: 'User', lastActive: '1 day ago' },
        { id: 3, name: 'Bob Johnson', role: 'Editor', lastActive: '3 days ago' }
      ]);
      setIsLoading(false);
    }, 2000);
  }, []);

  return (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHeaderCell>Name</TableHeaderCell>
          <TableHeaderCell>Role</TableHeaderCell>
          <TableHeaderCell>Last Active</TableHeaderCell>
          <TableHeaderCell>Actions</TableHeaderCell>
        </TableRow>
      </TableHeader>
      <TableBody>
        {isLoading ? (
          Array.from({ length: 3 }).map((_, index) => (
            <TableRow key={index}>
              <TableCell>
                <div className="skeleton-loader skeleton-text"></div>
              </TableCell>
              <TableCell>
                <div className="skeleton-loader skeleton-text-small"></div>
              </TableCell>
              <TableCell>
                <div className="skeleton-loader skeleton-text-small"></div>
              </TableCell>
              <TableCell>
                <div className="skeleton-loader skeleton-button"></div>
              </TableCell>
            </TableRow>
          ))
        ) : (
          data.map(user => (
            <TableRow key={user.id}>
              <TableCell>{user.name}</TableCell>
              <TableCell>{user.role}</TableCell>
              <TableCell>{user.lastActive}</TableCell>
              <TableCell>
                <Button size="Small" type="Ghost">View</Button>
              </TableCell>
            </TableRow>
          ))
        )}
      </TableBody>
    </Table>
  );
}
```

### Empty State Table
```tsx
function EmptyStateTableExample() {
  const [hasData] = useState(false);

  return (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHeaderCell>Product Name</TableHeaderCell>
          <TableHeaderCell>Category</TableHeaderCell>
          <TableHeaderCell>Price</TableHeaderCell>
          <TableHeaderCell>Stock</TableHeaderCell>
          <TableHeaderCell>Actions</TableHeaderCell>
        </TableRow>
      </TableHeader>
      <TableBody>
        {!hasData ? (
          <TableRow>
            <TableCell colSpan={5} className="empty-state-cell">
              <div className="empty-state">
                <Icon icon="Inventory" size="Large" className="empty-state-icon" />
                <Text type="Heading5">No products found</Text>
                <Text type="BodySmall">
                  Start by adding your first product to the inventory.
                </Text>
                <Button>Add Product</Button>
              </div>
            </TableCell>
          </TableRow>
        ) : null}
      </TableBody>
    </Table>
  );
}
```