# Table

Displays data in a structured table format with customizable content and appearance.

### **Import**
```tsx
import { Table } from '@app-studio/web';
```

### **Default**
```tsx
import React from 'react';
import {
  TableContainer,
  TableCaption,
  TableHead,
  TableRow,
  TableHeadCell,
  TableBody,
  TableCell,
} from '../Table/Table.view';

export const DefaultDemo = () => {
  interface DataRow {
    invoice: string;
    paymentStatus: string;
    totalAmount: string;
    paymentMethod: string;
  }

  const columns = [
    { title: 'Invoice', field: 'invoice' },
    { title: 'Payment Status', field: 'paymentStatus' },
    { title: 'Total Amount', field: 'totalAmount' },
    { title: 'Payment Method', field: 'paymentMethod' },
  ];
  const data: DataRow[] = [
    {
      invoice: 'INV001',
      paymentStatus: 'Paid',
      totalAmount: '$250.00',
      paymentMethod: 'Credit Card',
    },
    {
      invoice: 'INV002',
      paymentStatus: 'Pending',
      totalAmount: '$150.00',
      paymentMethod: 'PayPal',
    },
    {
      invoice: 'INV003',
      paymentStatus: 'Unpaid',
      totalAmount: '$350.00',
      paymentMethod: 'Bank Transfer',
    },
    {
      invoice: 'INV004',
      paymentStatus: 'Paid',
      totalAmount: '$450.00',
      paymentMethod: 'Credit Card',
    },
    {
      invoice: 'INV005',
      paymentStatus: 'Paid',
      totalAmount: '$550.00',
      paymentMethod: 'PayPal',
    },
    {
      invoice: 'INV006',
      paymentStatus: 'Pending',
      totalAmount: '$200.00',
      paymentMethod: 'Bank Transfer',
    },
    {
      invoice: 'INV007',
      paymentStatus: 'Unpaid',
      totalAmount: '$300.00',
      paymentMethod: 'Credit Card',
    },
  ];
  return (
    <TableContainer>
      <TableCaption>A list of your recent invoices.</TableCaption>
      <TableHead>
        <TableRow>
          {columns.map((column) => (
            <TableHeadCell key={column.field}>{column.title}</TableHeadCell>
          ))}
        </TableRow>
      </TableHead>
      <TableBody>
        {data.map((row, index) => (
          <TableRow key={index}>
            {columns.map((column, columnIndex) => (
              <TableCell key={column.field} isFirstColumn={columnIndex === 0}>
                {row[column.field as keyof DataRow]}
              </TableCell>
            ))}
          </TableRow>
        ))}
      </TableBody>
    </TableContainer>
  );
};
```

### **data**
An array of data objects to be displayed in the table rows.

- **Type:** `any[]`
- **Default:** `None`
- **Possible Values:** `Array of any type`

```tsx
import React from 'react';
import { Table } from '../Table';

export const DataDemo = () => {
  const cols = [
    { title: 'Invoice', field: 'invoice' },
    { title: 'Payment Status', field: 'paymentStatus' },
    { title: 'Total Amount', field: 'totalAmount' },
    { title: 'Payment Method', field: 'paymentMethod' },
  ];
  const invoices = [
    {
      invoice: 'INV001',
      paymentStatus: 'Paid',
      totalAmount: '$250.00',
      paymentMethod: 'Credit Card',
    },
    {
      invoice: 'INV002',
      paymentStatus: 'Pending',
      totalAmount: '$150.00',
      paymentMethod: 'PayPal',
    },
    {
      invoice: 'INV003',
      paymentStatus: 'Unpaid',
      totalAmount: '$350.00',
      paymentMethod: 'Bank Transfer',
    },
    {
      invoice: 'INV004',
      paymentStatus: 'Paid',
      totalAmount: '$450.00',
      paymentMethod: 'Credit Card',
    },
    {
      invoice: 'INV005',
      paymentStatus: 'Paid',
      totalAmount: '$550.00',
      paymentMethod: 'PayPal',
    },
    {
      invoice: 'INV006',
      paymentStatus: 'Pending',
      totalAmount: '$200.00',
      paymentMethod: 'Bank Transfer',
    },
    {
      invoice: 'INV007',
      paymentStatus: 'Unpaid',
      totalAmount: '$300.00',
      paymentMethod: 'Credit Card',
    },
  ];
  return <Table.Template columns={cols} data={invoices} />;
};
```

### **footer**
An optional array of footer cell definitions to display at the bottom of the table.

- **Type:** `FooterCell[]`
- **Default:** `None`
- **Possible Values:** `{ value: string; props?: ViewProps; }[]`

```tsx
import React from 'react';
import { Table } from '../Table';

export const FooterDemo = () => {
  const cols = [
    { title: 'Invoice', field: 'invoice' },
    { title: 'Payment Status', field: 'paymentStatus' },
    { title: 'Total Amount', field: 'totalAmount' },
    { title: 'Payment Method', field: 'paymentMethod' },
  ];
  const invoices = [
    {
      invoice: 'INV001',
      paymentStatus: 'Paid',
      totalAmount: '$250.00',
      paymentMethod: 'Credit Card',
    },
    {
      invoice: 'INV002',
      paymentStatus: 'Pending',
      totalAmount: '$150.00',
      paymentMethod: 'PayPal',
    },
    {
      invoice: 'INV003',
      paymentStatus: 'Unpaid',
      totalAmount: '$350.00',
      paymentMethod: 'Bank Transfer',
    },
    {
      invoice: 'INV004',
      paymentStatus: 'Paid',
      totalAmount: '$450.00',
      paymentMethod: 'Credit Card',
    },
    {
      invoice: 'INV005',
      paymentStatus: 'Paid',
      totalAmount: '$550.00',
      paymentMethod: 'PayPal',
    },
    {
      invoice: 'INV006',
      paymentStatus: 'Pending',
      totalAmount: '$200.00',
      paymentMethod: 'Bank Transfer',
    },
    {
      invoice: 'INV007',
      paymentStatus: 'Unpaid',
      totalAmount: '$300.00',
      paymentMethod: 'Credit Card',
    },
  ];
  return (
    <Table
      views={{
        tfoot: {
          borderTop: '1px solid gray',
          borderBottom: '1px solid gray',
        },
      }}
    >
      <Table.Template
        columns={cols}
        data={invoices}
        footer={[
          {
            value: 'Total Amount',
            props: { colSpan: 3, style: { fontWeight: 'bold' } },
          },
          { value: '$2,500.00' },
        ]}
      />
    </Table>
  );
};
```

### **caption**
An optional React node to be displayed as the table caption.

- **Type:** `React.ReactNode`
- **Default:** `None`
- **Possible Values:** `Any valid React node (string, number, element, fragment, portal, boolean, null, undefined)`

```tsx
import React from 'react';
import { Table } from '../Table';

export const CaptionDemo = () => {
  const cols = [
    { title: 'Invoice', field: 'invoice' },
    { title: 'Payment Status', field: 'paymentStatus' },
    { title: 'Total Amount', field: 'totalAmount' },
    { title: 'Payment Method', field: 'paymentMethod' },
  ];
  const invoices = [
    {
      invoice: 'INV001',
      paymentStatus: 'Paid',
      totalAmount: '$250.00',
      paymentMethod: 'Credit Card',
    },
    {
      invoice: 'INV002',
      paymentStatus: 'Pending',
      totalAmount: '$150.00',
      paymentMethod: 'PayPal',
    },
    {
      invoice: 'INV003',
      paymentStatus: 'Unpaid',
      totalAmount: '$350.00',
      paymentMethod: 'Bank Transfer',
    },
    {
      invoice: 'INV004',
      paymentStatus: 'Paid',
      totalAmount: '$450.00',
      paymentMethod: 'Credit Card',
    },
    {
      invoice: 'INV005',
      paymentStatus: 'Paid',
      totalAmount: '$550.00',
      paymentMethod: 'PayPal',
    },
    {
      invoice: 'INV006',
      paymentStatus: 'Pending',
      totalAmount: '$200.00',
      paymentMethod: 'Bank Transfer',
    },
    {
      invoice: 'INV007',
      paymentStatus: 'Unpaid',
      totalAmount: '$300.00',
      paymentMethod: 'Credit Card',
    },
  ];
  return (
    <Table.Template
      caption="A list of your recent invoices."
      columns={cols}
      data={invoices}
    />
  );
};
```

### **DesignSystem**

```tsx
/**
 * Table Examples - Design System
 *
 * Showcases the Table component following the design guidelines:
 * - Typography: Inter/Geist font, specific sizes/weights
 * - Spacing: 4px grid system
 * - Colors: Neutral palette with semantic colors
 * - Rounded corners: Consistent border radius
 * - Transitions: Subtle animations
 */

import React from 'react';
import { Table } from '../Table';
import { Vertical } from 'app-studio';
import { Horizontal } from 'app-studio';
import { Text } from 'app-studio';
import { View } from 'app-studio';
import { Button } from '../../Button/Button';
import { Badge } from '../../Badge/Badge';

export const DesignSystemTable = () => {
  // Sample data for all examples
  const users = [
    {
      id: 1,
      name: 'John Doe',
      email: 'john@example.com',
      status: 'Active',
      role: 'Admin',
    },
    {
      id: 2,
      name: 'Jane Smith',
      email: 'jane@example.com',
      status: 'Inactive',
      role: 'User',
    },
    {
      id: 3,
      name: 'Bob Johnson',
      email: 'bob@example.com',
      status: 'Active',
      role: 'User',
    },
    {
      id: 4,
      name: 'Alice Brown',
      email: 'alice@example.com',
      status: 'Active',
      role: 'Manager',
    },
  ];

  // Columns for basic table
  const basicColumns = [
    { title: 'ID', field: 'id' },
    { title: 'Name', field: 'name' },
    { title: 'Email', field: 'email' },
    { title: 'Role', field: 'role' },
  ];

  // Status badge renderer
  const renderStatus = (status: string) => {
    const color = status === 'Active' ? 'green' : 'red';
    return (
      <Badge
        variant="outline"
        backgroundColor={color}
        borderRadius="4px"
        paddingLeft="8px"
        paddingTop="2px"
        fontWeight="500"
        content={status}
      >
        {status}
      </Badge>
    );
  };

  // Columns with custom rendering
  const customColumns = [
    {
      title: 'Name',
      field: 'name',
      render: (name: string, row: any) => (
        <View>
          <Text fontWeight="600">{name}</Text>
          <Text color="color-gray-500">{row.email}</Text>
        </View>
      ),
    },
    {
      title: 'Status',
      field: 'status',
      render: renderStatus,
    },
    {
      title: 'Role',
      field: 'role',
    },
    {
      title: 'Actions',
      field: 'actions',
      render: () => (
        <Horizontal gap={8}>
          <Button size="xs">Edit</Button>
          <Button size="xs" variant="outline" backgroundColor="red">
            Delete
          </Button>
        </Horizontal>
      ),
    },
  ];

  // Data for custom rendering
  const customData = users.map((user) => ({
    ...user,
    actions: null, // Placeholder for the actions column
  }));

  return (
    <Vertical gap={32}>
      {/* Basic Table */}
      <View>
        <Text marginBottom={8} fontWeight="600">
          Basic Table
        </Text>
        <Table
          views={{
            table: {
              width: '100%',
              fontFamily:
                'Inter, -apple-system, BlinkMacSystemFont, sans-serif',
              borderRadius: '8px', // 2 × 4px grid
              overflow: 'hidden',
              boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',
              border: '1px solid',
              borderColor: 'color-gray-200',
            },
            thead: {
              backgroundColor: 'color-gray-50',
              borderBottom: '1px solid',
              borderBottomColor: 'color-gray-200',
            },
            th: {
              padding: '12px 16px', // 3 × 4px and 4 × 4px grid
              fontWeight: '600',
              fontSize: '14px',
              color: 'color-gray-700',
              textTransform: 'uppercase',
              letterSpacing: '0.05em',
            },
            td: {
              padding: '12px 16px', // 3 × 4px and 4 × 4px grid
              fontSize: '14px',
              borderBottom: '1px solid',
              borderBottomColor: 'color-gray-100',
            },
            tr: {
              transition: 'background-color 0.2s ease',
              _hover: {
                backgroundColor: 'color-gray-50',
              },
            },
          }}
        >
          <Table.Template
            columns={basicColumns}
            data={users}
            caption="User Information"
          />
        </Table>
      </View>

      {/* Striped Table */}
      <View>
        <Text marginBottom={8} fontWeight="600">
          Striped Table
        </Text>
        <Table
          views={{
            table: {
              width: '100%',
              fontFamily:
                'Inter, -apple-system, BlinkMacSystemFont, sans-serif',
              borderRadius: '8px', // 2 × 4px grid
              overflow: 'hidden',
              boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',
            },
            thead: {
              backgroundColor: 'color-blue-600',
              color: 'color-white',
            },
            th: {
              padding: '12px 16px', // 3 × 4px and 4 × 4px grid
              fontWeight: '600',
              fontSize: '14px',
              color: 'color-white',
            },
            td: {
              padding: '12px 16px', // 3 × 4px and 4 × 4px grid
              fontSize: '14px',
              borderBottom: '1px solid',
              borderBottomColor: 'color-gray-100',
            },
            tr: {
              _even: {
                backgroundColor: 'color-gray-50',
              },
              transition: 'background-color 0.2s ease',
              _hover: {
                backgroundColor: 'color-blue-50',
              },
            },
          }}
        >
          <Table.Template columns={basicColumns} data={users} />
        </Table>
      </View>

      {/* Custom Rendering Table */}
      <View>
        <Text marginBottom={8} fontWeight="600">
          Custom Rendering
        </Text>
        <Table
          views={{
            table: {
              width: '100%',
              fontFamily:
                'Inter, -apple-system, BlinkMacSystemFont, sans-serif',
              borderRadius: '8px', // 2 × 4px grid
              overflow: 'hidden',
              boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
              border: '1px solid',
              borderColor: 'color-gray-200',
            },
            thead: {
              backgroundColor: 'color-white',
              borderBottom: '2px solid',
              borderBottomColor: 'color-gray-200',
            },
            th: {
              padding: '16px', // 4 × 4px grid
              fontWeight: '600',
              fontSize: '14px',
              color: 'color-gray-700',
            },
            td: {
              padding: '16px', // 4 × 4px grid
              fontSize: '14px',
              borderBottom: '1px solid',
              borderBottomColor: 'color-gray-100',
            },
            tr: {
              transition: 'background-color 0.2s ease',
              _hover: {
                backgroundColor: 'color-gray-50',
              },
            },
          }}
        >
          <Table.Container>
            <Table.Head>
              <Table.Row>
                {customColumns.map((column) => (
                  <Table.HeadCell key={column.field}>
                    {column.title}
                  </Table.HeadCell>
                ))}
              </Table.Row>
            </Table.Head>
            <Table.Body>
              {customData.map((row: any, rowIndex) => (
                <Table.Row key={rowIndex}>
                  {customColumns.map((column: any, colIndex) => (
                    <Table.Cell
                      key={`${rowIndex}-${colIndex}`}
                      isFirstColumn={colIndex === 0}
                    >
                      {column.render
                        ? column.render(row[column.field], row)
                        : row[column.field]}
                    </Table.Cell>
                  ))}
                </Table.Row>
              ))}
            </Table.Body>
          </Table.Container>
        </Table>
      </View>

      {/* Compact Table */}
      <View>
        <Text marginBottom={8} fontWeight="600">
          Compact Table
        </Text>
        <Table
          views={{
            table: {
              width: '100%',
              fontFamily:
                'Inter, -apple-system, BlinkMacSystemFont, sans-serif',
              borderRadius: '8px', // 2 × 4px grid
              overflow: 'hidden',
              boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',
              border: '1px solid',
              borderColor: 'color-gray-200',
            },
            thead: {
              backgroundColor: 'color-gray-50',
              borderBottom: '1px solid',
              borderBottomColor: 'color-gray-200',
            },
            th: {
              padding: '8px 12px', // 2 × 4px and 3 × 4px grid
              fontWeight: '600',
              fontSize: '12px',
              color: 'color-gray-700',
            },
            td: {
              padding: '8px 12px', // 2 × 4px and 3 × 4px grid
              fontSize: '12px',
              borderBottom: '1px solid',
              borderBottomColor: 'color-gray-100',
            },
            tr: {
              transition: 'background-color 0.2s ease',
              _hover: {
                backgroundColor: 'color-gray-50',
              },
            },
          }}
        >
          <Table.Template columns={basicColumns} data={users} />
        </Table>
      </View>

      {/* Table with Footer */}
      <View>
        <Text marginBottom={8} fontWeight="600">
          Table with Footer
        </Text>
        <Table
          views={{
            table: {
              width: '100%',
              fontFamily:
                'Inter, -apple-system, BlinkMacSystemFont, sans-serif',
              borderRadius: '8px', // 2 × 4px grid
              overflow: 'hidden',
              boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)',
              border: '1px solid',
              borderColor: 'color-gray-200',
            },
            thead: {
              backgroundColor: 'color-gray-50',
              borderBottom: '1px solid',
              borderBottomColor: 'color-gray-200',
            },
            th: {
              padding: '12px 16px', // 3 × 4px and 4 × 4px grid
              fontWeight: '600',
              fontSize: '14px',
              color: 'color-gray-700',
            },
            td: {
              padding: '12px 16px', // 3 × 4px and 4 × 4px grid
              fontSize: '14px',
              borderBottom: '1px solid',
              borderBottomColor: 'color-gray-100',
            },
            tfoot: {
              backgroundColor: 'color-gray-50',
              fontWeight: '600',
              borderTop: '2px solid',
              borderTopColor: 'color-gray-200',
            },
            tr: {
              transition: 'background-color 0.2s ease',
              _hover: {
                backgroundColor: 'color-gray-50',
              },
            },
          }}
        >
          <Table.Template
            columns={[
              { title: 'Name', field: 'name' },
              { title: 'Role', field: 'role' },
              { title: 'Status', field: 'status' },
            ]}
            data={users}
            footer={[
              {
                value: 'Total Users',
                props: { colSpan: 2, style: { textAlign: 'right' } },
              },
              { value: `${users.length}` },
            ]}
          />
        </Table>
      </View>
    </Vertical>
  );
};
```

### **Index**

```tsx
export * from './caption';
export * from './default';
export * from './designSystem';
export * from './footer';
export * from './styles';
export * from './data';
```

### **Styles**

```tsx
import React from 'react';
import { Table } from '../Table';

export const StylesDemo = () => {
  const cols = [
    { title: 'Invoice', field: 'invoice' },
    { title: 'Payment Status', field: 'paymentStatus' },
    { title: 'Total Amount', field: 'totalAmount' },
    { title: 'Payment Method', field: 'paymentMethod' },
  ];
  const invoices = [
    {
      invoice: 'INV001',
      paymentStatus: 'Paid',
      totalAmount: '$250.00',
      paymentMethod: 'Credit Card',
    },
    {
      invoice: 'INV002',
      paymentStatus: 'Pending',
      totalAmount: '$150.00',
      paymentMethod: 'PayPal',
    },
    {
      invoice: 'INV003',
      paymentStatus: 'Unpaid',
      totalAmount: '$350.00',
      paymentMethod: 'Bank Transfer',
    },
    {
      invoice: 'INV004',
      paymentStatus: 'Paid',
      totalAmount: '$450.00',
      paymentMethod: 'Credit Card',
    },
    {
      invoice: 'INV005',
      paymentStatus: 'Paid',
      totalAmount: '$550.00',
      paymentMethod: 'PayPal',
    },
    {
      invoice: 'INV006',
      paymentStatus: 'Pending',
      totalAmount: '$200.00',
      paymentMethod: 'Bank Transfer',
    },
    {
      invoice: 'INV007',
      paymentStatus: 'Unpaid',
      totalAmount: '$300.00',
      paymentMethod: 'Credit Card',
    },
  ];
  return (
    <Table
      views={{
        table: {
          boxShadow:
            ' 0 4px 6px rgba(0, 0, 0, 0.1), 0 5px 15px rgba(0, 0, 0, 0.1)',

          borderRadius: '1em',
        },
      }}
    >
      <Table.Template columns={cols} data={invoices} />
    </Table>
  );
};
```

