npm package: @sproutsocial/seeds-react-table-v2
Description: Seeds React TableV2
Author: Sprout Social, Inc.
Latest version: 1.0.1

# TableV2

A simple, accessible table component for displaying basic tabular data. Designed for straightforward use cases with string and ReactNode arrays.

## Installation

```bash
yarn add @sproutsocial/seeds-react-table-v2
```

## Features

- **Simple API**: Easy to use with string and ReactNode arrays
- **Accessible**: Built-in ARIA attributes and semantic HTML
- **Flexible Content**: Support for strings and React elements in cells
- **Composable**: Compound component pattern for advanced use cases
- **Scrollable**: Automatic horizontal scroll for wide tables
- **Styled**: Pre-styled with Seeds design tokens

## When to Use TableV2

### Use TableV2 when:
- You have simple arrays of strings or React elements
- You don't need sorting functionality
- Dataset is small to medium (< 100 rows)
- You want maximum simplicity
- You're rendering pre-formatted content

### Use DataTable instead when:
- You need sorting functionality
- You have typed object data
- You want automatic camelCase column mapping
- You need custom cell rendering based on data
- You need API-driven component rendering

## Basic Usage

### Simple String Table

The most basic usage with string arrays:

```tsx
import { TableV2 } from '@sproutsocial/seeds-react-table-v2';

<TableV2
  caption="User Information"
  columns={['Name', 'Email', 'Role']}
  data={[
    ['John Doe', 'john@example.com', 'Engineer'],
    ['Jane Smith', 'jane@example.com', 'Designer'],
    ['Bob Johnson', 'bob@example.com', 'Manager'],
  ]}
/>
```

### With React Elements

Cells can contain any React elements:

```tsx
import { TableV2 } from '@sproutsocial/seeds-react-table-v2';
import { Badge } from '@sproutsocial/seeds-react-badge';
import { Avatar } from '@sproutsocial/seeds-react-avatar';

<TableV2
  caption="Team Members"
  columns={['User', 'Status', 'Actions']}
  data={[
    [
      <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
        <Avatar name="John Doe" size="small" />
        <span>John Doe</span>
      </div>,
      <Badge badgeColor="green">Active</Badge>,
      <button>Edit</button>,
    ],
    [
      <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
        <Avatar name="Jane Smith" size="small" />
        <span>Jane Smith</span>
      </div>,
      <Badge badgeColor="red">Inactive</Badge>,
      <button>Edit</button>,
    ],
  ]}
/>
```

### Hidden Caption

Keep the caption for accessibility but hide it visually:

```tsx
<TableV2
  caption="User Data"
  displayCaption={false}
  columns={['Name', 'Email']}
  data={[
    ['John Doe', 'john@example.com'],
    ['Jane Smith', 'jane@example.com'],
  ]}
/>
```

## Advanced Usage: Compound Components

For more control, use the compound component pattern:

```tsx
import { TableV2 } from '@sproutsocial/seeds-react-table-v2';

<TableV2.Container>
  <TableV2.Table>
    <TableV2.Caption isVisible={true}>
      Custom Table
    </TableV2.Caption>

    <TableV2.TableHead>
      <TableV2.TableRow>
        <TableV2.TableHeaderCell id="name">
          Name
        </TableV2.TableHeaderCell>
        <TableV2.TableHeaderCell id="email">
          Email
        </TableV2.TableHeaderCell>
        <TableV2.TableHeaderCell id="role">
          Role
        </TableV2.TableHeaderCell>
      </TableV2.TableRow>
    </TableV2.TableHead>

    <TableV2.TableBody>
      <TableV2.TableRow>
        <TableV2.TableCell id="name-1">John Doe</TableV2.TableCell>
        <TableV2.TableCell id="email-1">john@example.com</TableV2.TableCell>
        <TableV2.TableCell id="role-1">Engineer</TableV2.TableCell>
      </TableV2.TableRow>
      <TableV2.TableRow>
        <TableV2.TableCell id="name-2">Jane Smith</TableV2.TableCell>
        <TableV2.TableCell id="email-2">jane@example.com</TableV2.TableCell>
        <TableV2.TableCell id="role-2">Designer</TableV2.TableCell>
      </TableV2.TableRow>
    </TableV2.TableBody>
  </TableV2.Table>
</TableV2.Container>
```

### Custom Row Rendering

Use compound components for custom row logic:

```tsx
<TableV2.Container>
  <TableV2.Table>
    <TableV2.Caption isVisible={true}>Users</TableV2.Caption>

    <TableV2.TableHead>
      <TableV2.TableRow>
        <TableV2.TableHeaderCell id="name">Name</TableV2.TableHeaderCell>
        <TableV2.TableHeaderCell id="status">Status</TableV2.TableHeaderCell>
      </TableV2.TableRow>
    </TableV2.TableHead>

    <TableV2.TableBody>
      {users.map((user) => (
        <TableV2.TableRow
          key={user.id}
          onClick={() => handleRowClick(user)}
          style={{ cursor: 'pointer' }}
        >
          <TableV2.TableCell id={`name-${user.id}`}>
            {user.name}
          </TableV2.TableCell>
          <TableV2.TableCell id={`status-${user.id}`}>
            <Badge badgeColor={user.active ? 'green' : 'red'}>
              {user.active ? 'Active' : 'Inactive'}
            </Badge>
          </TableV2.TableCell>
        </TableV2.TableRow>
      ))}
    </TableV2.TableBody>
  </TableV2.Table>
</TableV2.Container>
```

### With Custom Styling

Apply custom styles to individual components:

```tsx
<TableV2.Container style={{ maxWidth: '800px' }}>
  <TableV2.Table>
    <TableV2.Caption isVisible={true}>Styled Table</TableV2.Caption>

    <TableV2.TableHead>
      <TableV2.TableRow style={{ backgroundColor: '#f0f0f0' }}>
        <TableV2.TableHeaderCell
          id="name"
          style={{ fontWeight: 'bold', color: '#333' }}
        >
          Name
        </TableV2.TableHeaderCell>
      </TableV2.TableRow>
    </TableV2.TableHead>

    <TableV2.TableBody>
      <TableV2.TableRow style={{ '&:hover': { backgroundColor: '#f9f9f9' } }}>
        <TableV2.TableCell id="name-1">John Doe</TableV2.TableCell>
      </TableV2.TableRow>
    </TableV2.TableBody>
  </TableV2.Table>
</TableV2.Container>
```

## Component API

### TableV2 (Main Component)

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `caption` | `string` | Yes | - | Table caption for accessibility |
| `displayCaption` | `boolean` | No | `true` | Whether to visually display the caption |
| `columns` | `ColumnHeader[]` | Yes | - | Array of column headers (strings or React elements) |
| `data` | `RowData[]` | Yes | - | 2D array of cell data (strings or React elements) |

**Types:**
```tsx
type ColumnHeader = string | React.ReactNode;
type RowData = Array<string | React.ReactNode>;
```

### Compound Components

#### TableV2.Container
The outer scrollable container for the table.

```tsx
<TableV2.Container>
  {/* Table content */}
</TableV2.Container>
```

**Props:** Standard HTML div props

#### TableV2.Table
The main table element.

```tsx
<TableV2.Table>
  {/* Caption, TableHead, TableBody */}
</TableV2.Table>
```

**Props:** Standard HTML table props

#### TableV2.Caption
The table caption for accessibility.

```tsx
<TableV2.Caption isVisible={true}>
  Table Title
</TableV2.Caption>
```

**Props:**
- `isVisible`: `boolean` - Whether to display the caption visually
- `children`: `React.ReactNode` - Caption content

#### TableV2.TableHead
The table header section.

```tsx
<TableV2.TableHead>
  <TableV2.TableRow>
    {/* Header cells */}
  </TableV2.TableRow>
</TableV2.TableHead>
```

**Props:** Standard HTML thead props

#### TableV2.TableBody
The table body section.

```tsx
<TableV2.TableBody>
  {/* Rows */}
</TableV2.TableBody>
```

**Props:** Standard HTML tbody props

#### TableV2.TableRow
A table row.

```tsx
<TableV2.TableRow>
  {/* Cells */}
</TableV2.TableRow>
```

**Props:** Standard HTML tr props

#### TableV2.TableHeaderCell
A header cell.

```tsx
<TableV2.TableHeaderCell id="column-name" scope="col">
  Column Name
</TableV2.TableHeaderCell>
```

**Props:**
- `id`: `string` - Required ID for accessibility
- `scope`: `"col" | "row"` - Scope attribute for accessibility
- Standard HTML th props

#### TableV2.TableCell
A data cell.

```tsx
<TableV2.TableCell id="cell-id">
  Cell Content
</TableV2.TableCell>
```

**Props:**
- `id`: `string` - Required ID for accessibility
- Standard HTML td props

## Examples

### Product List

```tsx
<TableV2
  caption="Product Inventory"
  columns={['Product', 'Price', 'Stock']}
  data={[
    ['Laptop Pro', '$1,299', 'In Stock'],
    ['Wireless Mouse', '$29', 'Low Stock'],
    ['Keyboard', '$149', 'Out of Stock'],
  ]}
/>
```

### With Icons and Badges

```tsx
import { Icon } from '@sproutsocial/seeds-react-icon';
import { Badge } from '@sproutsocial/seeds-react-badge';

<TableV2
  caption="Task Status"
  columns={['Task', 'Priority', 'Status']}
  data={[
    [
      'Complete project documentation',
      <Badge badgeColor="red">High</Badge>,
      <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
        <Icon name="circle-check-solid" size="mini" />
        <span>Complete</span>
      </div>,
    ],
    [
      'Review pull requests',
      <Badge badgeColor="yellow">Medium</Badge>,
      <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
        <Icon name="clock-outline" size="mini" />
        <span>In Progress</span>
      </div>,
    ],
  ]}
/>
```

### Interactive Table with Buttons

```tsx
<TableV2
  caption="User Management"
  columns={['Name', 'Role', 'Actions']}
  data={users.map(user => [
    user.name,
    user.role,
    <div style={{ display: 'flex', gap: '8px' }}>
      <button onClick={() => handleEdit(user.id)}>Edit</button>
      <button onClick={() => handleDelete(user.id)}>Delete</button>
    </div>,
  ])}
/>
```

### Empty State

```tsx
<TableV2
  caption="Search Results"
  columns={['Name', 'Email', 'Role']}
  data={results.length > 0 ? results : [
    [
      <div style={{ textAlign: 'center', padding: '20px', gridColumn: '1 / -1' }}>
        No results found. Try adjusting your search.
      </div>,
      '', // Empty cells for proper column count
      '',
    ],
  ]}
/>
```

## Accessibility

TableV2 is built with accessibility in mind:

- **Required Caption**: All tables must have a caption for screen readers
- **Semantic HTML**: Uses proper table elements (`<table>`, `<thead>`, `<tbody>`, etc.)
- **ARIA Attributes**: Container has `role="region"` and `aria-labelledby`
- **Keyboard Navigation**: Scrollable container is keyboard accessible with `tabIndex={0}`
- **Screen Reader Support**: Proper heading structure and scope attributes

## Scrolling

Tables automatically become horizontally scrollable when content exceeds the container width. The scroll container is keyboard accessible.

## Styling

TableV2 uses Seeds design tokens for consistent styling:
- Border colors from Seeds color palette
- Spacing using Seeds spacing scale
- Typography from Seeds text styles
- Focus states following Seeds patterns

Custom styling can be applied via the `style` prop on any compound component.

## Migration from Table

If you're migrating from an older Table component:

1. **Import Path**: Update to `@sproutsocial/seeds-react-table-v2`
2. **Props**: Rename any old props to match TableV2Props
3. **Data Format**: Ensure data is a 2D array of strings/ReactNodes
4. **Caption**: Caption is now required (was optional)

## Related Components

- **DataTable**: For typed object data with sorting, custom cell rendering, and API-driven component rendering

## Examples in Storybook

Check out the Storybook examples for more patterns:
- Default table with strings
- Hidden caption
- Tables with React elements
- Interactive tables
- Custom styled tables