# Tables & Lists

## GridTable

The primary data table with sorting, filtering, selection, and row-level actions.

```tsx
import { GridTable } from '@theorchard/suite-components';
```

### Sub-components

| Sub-component | Usage |
|---|---|
| `GridTable.Column` | Column definition |
| `GridTable.ActionButton` | Row-level action button |

### Key Props

| Prop | Type | Description |
|---|---|---|
| `columns` | `Column[]` | Column definitions (see below) |
| `data` | `object[]` | Row data |
| `onSort` | function | Sort handler `(field, direction) => void` |
| `sortField` | string | Current sort column |
| `sortDirection` | `'asc' \| 'desc'` | Current sort direction |
| `loading` | boolean | Shows loading state |
| `onRowClick` | function | Makes rows clickable |
| `selectedRows` | string[] | Controlled row selection |
| `onRowSelect` | function | Row selection handler |
| `emptyState` | ReactNode | Content when `data` is empty |
| `pagination` | ReactNode | Renders a `Pagination` component below the table |

### Column Definition Shape

```ts
{
  field: string,           // data key
  label: string,           // column header text
  sortable?: boolean,
  width?: string | number,
  render?: (value, row) => ReactNode,  // custom cell renderer
}
```

### Example

```tsx
<GridTable
  columns={[
    { field: 'title', label: 'Title', sortable: true },
    { field: 'artist', label: 'Artist' },
    { field: 'status', label: 'Status', render: (val) => <Status variant={val} text={val} /> },
  ]}
  data={releases}
  onSort={(field, dir) => setSort({ field, dir })}
  sortField={sort.field}
  sortDirection={sort.dir}
  emptyState={<InfoMessage title="No releases found" />}
/>
```

### Key Types

```tsx
import {
  GridTableColumnDefinition,  // column definition shape
  GridTableSortBy,            // sort state: { field: string, direction: 'asc' | 'desc' }
  GridTableCellProps,         // props passed to custom cell renderers
  GridTableProps,             // full component props type
} from '@theorchard/suite-components';
```

`GridTableColumnDefinition` is the typed alternative to the plain object column shape — use it when defining columns outside the JSX:

```tsx
const columns: GridTableColumnDefinition[] = [
  { field: 'title', label: 'Title', sortable: true },
  { field: 'status', label: 'Status', render: (val) => <Status variant={val} text={val} /> },
];
```

### Rules

- Use `GridTable` for all tabular data — never build a custom table with `<table>`.
- Do NOT use the deprecated `Table` component.
- MUST provide an `emptyState` prop — never leave the table blank on empty data.
- Pair `GridTable` with `Pagination` below when the dataset may exceed one page.

---

## ListView

Flexible virtualised list that powers `Select`, `MultiSelect`, `ListBox` and similar components internally. Use directly only when building custom list-based pickers.

```tsx
import { ListView } from '@theorchard/suite-components';
```

---

## ListBox

Inline single-select list — useful when the list of options should be permanently visible rather than behind a dropdown.

```tsx
import { ListBox } from '@theorchard/suite-components';
```

### When to use ListBox vs Select

| ListBox | Select |
|---|---|
| Options always visible inline | Options revealed on click |
| Short list (≤ 10 items) | Any length |
| Filter-style selection | Form field selection |

---

## MarketListBox

Inline multi-country selection list.

```tsx
import { MarketListBox } from '@theorchard/suite-components';
```

Use for inline country selection within a form section where the multi-select should be permanently expanded. For a compact form field use `MarketSelector`.

## Common Mistakes

- Do NOT use the deprecated `Table` component — use `GridTable`.
- Do NOT build a custom `<table>` element — use `GridTable`.
- Do NOT use `ListView` directly unless building a custom picker — use `Select`, `ListBox`, or `MultiSelect` instead.
