import { Canvas, Meta, Subtitle, Title } from '@storybook/addon-docs/blocks'
import * as TableStories from './Table.stories'
import { LifecycleTag, SourceLinks } from '../../docs/components'

<Meta of={TableStories} />

<Title>Table</Title>
<Subtitle>
  A table component for displaying structured data in rows and columns. Built on
  semantic HTML table elements with accessible styling.
</Subtitle>
<SourceLinks
  links={[
    {
      label: 'shadcn/ui',
      href: 'https://ui.shadcn.com/docs/components/table',
    },
  ]}
/>
<LifecycleTag variant="Stable" />

<Canvas of={TableStories.Default} sourceState="shown" />

## Components

The table component family consists of the following sub-components:

- `TableRoot`: The root container that wraps the table and provides overflow handling.
- `TableHeader`: The header section of the table, typically containing column headers.
- `TableBody`: The body section of the table, containing the data rows.
- `TableRow`: A single row within the table.
- `TableHead`: A header cell, typically used within `TableHeader` to define column headers.
- `TableCell`: A data cell, used within `TableBody` to display table data.

## Import

```tsx
import {
  TableRoot,
  TableHeader,
  TableBody,
  TableHead,
  TableRow,
  TableCell,
} from '@chainlink/blocks'
```

## Usage

The Table component uses semantic HTML table elements (`<table>`, `<thead>`, `<tbody>`, `<tr>`, `<th>`, `<td>`) to ensure proper accessibility and structure. Compose the table by nesting the sub-components:

```tsx
import {
  TableRoot,
  TableHeader,
  TableBody,
  TableHead,
  TableRow,
  TableCell,
  Typography,
} from '@chainlink/blocks'

export function MyTable() {
  return (
    <TableRoot>
      <TableHeader>
        <TableRow>
          <TableHead>Name</TableHead>
          <TableHead>Email</TableHead>
          <TableHead>Role</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        <TableRow>
          <TableCell>
            <Typography variant="body-s">John Doe</Typography>
          </TableCell>
          <TableCell>
            <Typography variant="body-s">john.doe@example.com</Typography>
          </TableCell>
          <TableCell>
            <Typography variant="body-s">Admin</Typography>
          </TableCell>
        </TableRow>
      </TableBody>
    </TableRoot>
  )
}
```

### Using TablePagination

To add pagination to your table, you can use the `TablePagination` component alongside the Table primitives. This requires setting up a TanStack Table instance:

```tsx
import {
  TableRoot,
  TableHeader,
  TableBody,
  TableHead,
  TableRow,
  TableCell,
  TablePagination,
  Typography,
} from '@chainlink/blocks'
import {
  type ColumnDef,
  flexRender,
  getCoreRowModel,
  useReactTable,
  getPaginationRowModel,
} from '@tanstack/react-table'

type DataType = {
  name: string
  email: string
}

const columns: ColumnDef<DataType>[] = [
  {
    accessorKey: 'name',
    header: 'Name',
    cell: ({ getValue }) => (
      <Typography variant="body-s">{getValue() as string}</Typography>
    ),
  },
  {
    accessorKey: 'email',
    header: 'Email',
    cell: ({ getValue }) => (
      <Typography variant="body-s">{getValue() as string}</Typography>
    ),
  },
]

export function PaginatedTable({ data }: { data: DataType[] }) {
  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    initialState: {
      pagination: {
        pageSize: 10,
      },
    },
  })

  return (
    <>
      <TableRoot>
        <TableHeader>
          {table.getHeaderGroups().map((headerGroup) => (
            <TableRow key={headerGroup.id}>
              {headerGroup.headers.map((header) => (
                <TableHead key={header.id}>
                  {header.isPlaceholder
                    ? null
                    : flexRender(
                        header.column.columnDef.header,
                        header.getContext(),
                      )}
                </TableHead>
              ))}
            </TableRow>
          ))}
        </TableHeader>
        <TableBody>
          {table.getRowModel().rows.map((row) => (
            <TableRow key={row.id}>
              {row.getVisibleCells().map((cell) => (
                <TableCell key={cell.id}>
                  {flexRender(cell.column.columnDef.cell, cell.getContext())}
                </TableCell>
              ))}
            </TableRow>
          ))}
        </TableBody>
      </TableRoot>
      <TablePagination table={table} />
    </>
  )
}
```

To use a static `Page N` control instead of the page select dropdown, use the same setup as the display pagination story:

```tsx
const PaginatedTableDisplayExample = () => {
  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    initialState: {
      pagination: {
        pageSize: 10,
      },
    },
  })

  return (
    <>
      <TableRoot>{/* ...table header/body rendering... */}</TableRoot>
      <TablePagination table={table} pageControlMode="display" />
    </>
  )
}
```

<Canvas of={TableStories.WithDisplayPagination} sourceState="shown" />

## Rendered Element

The `TableRoot` component renders a `<div>` wrapper containing a `<table>` element. The sub-components render their corresponding semantic HTML elements:

- `TableHeader` renders a `<thead>` element
- `TableBody` renders a `<tbody>` element
- `TableRow` renders a `<tr>` element
- `TableHead` renders a `<th>` element
- `TableCell` renders a `<td>` element

This semantic structure ensures proper accessibility and allows screen readers to understand the table structure.

## Examples

### With Actions

Tables can include action buttons in cells for row-level operations.

<Canvas of={TableStories.WithActions} sourceState="shown" />

### Invoice Table

A practical example showing invoice data with status indicators using Tags.

<Canvas of={TableStories.InvoiceTable} sourceState="shown" />

### Product Table

An example displaying product information with conditional styling based on stock levels.

<Canvas of={TableStories.ProductTable} sourceState="shown" />

### Empty Table

Display a message when no data is available using `colSpan` to span all columns.

<Canvas of={TableStories.EmptyTable} sourceState="shown" />

### Single Column

A simple single-column table for displaying lists or tasks.

<Canvas of={TableStories.SingleColumn} sourceState="shown" />

### Expandable Rows

Tables can include expandable rows to show additional details. This pattern is useful for displaying error messages, detailed information, or nested content. Use `colSpan` to span the expanded content across all columns, and manage the expanded state with React's `useState` hook.

<Canvas of={TableStories.ExpandableRows} sourceState="shown" />

### With Pagination

The Table primitives can be combined with `TablePagination` to add pagination controls. This requires setting up a TanStack Table instance with pagination enabled. The `TablePagination` component displays whatever pagination information is available, from a static `Page N` control up to range text and a page select when the total is known.

<Canvas of={TableStories.WithPagination} sourceState="shown" />

### With Display Pagination

Use `pageControlMode="display"` to show a static `Page N` control between the previous/next buttons.

<Canvas of={TableStories.WithDisplayPagination} sourceState="shown" />
