Table

Example

1import {
2  createColumnHelper,
3  flexRender,
4  getCoreRowModel,
5  useReactTable,
6  RowData,
7} from '@tanstack/react-table'
8
9declare module '@tanstack/react-table' {
10  interface ColumnMeta<TData extends RowData, TValue> {
11    className?: string
12  }
13}
14
15const data: Ranking[] = [
16  { rank: '1', user: 'powz', score: 5054.25054 },
17  { rank: '2', user: 'Bijak', score: 3605.23605 },
18  { rank: '3', user: 'ShockOLatte', score: 2518.72518 },
19  { rank: '4', user: 'Ludie', score: 2517.32517 },
20  { rank: '5', user: 'Chamsae', score: 2434.42434 },
21  { rank: '6', user: 'Salome', score: 2107.12107 },
22  { rank: '7', user: 'mmmm', score: 2060.1206 },
23  { rank: '8', user: 'Yaku', score: 1667.21667 },
24  { rank: '9', user: 'Socks', score: 1635.81635 },
25  { rank: '10', user: 'clair', score: 1592.91592 },
26]
27
28interface Ranking {
29  rank: string
30  user: string
31  score: number
32}
33
34const columnHelper = createColumnHelper<Ranking>()
35
36const columns = [
37  columnHelper.accessor('rank', {
38    header: () => 'Rank',
39    size: 5,
40    meta: {
41      className: 'justify-center',
42    },
43  }),
44  columnHelper.accessor('user', {
45    header: () => 'User',
46  }),
47  columnHelper.accessor('score', {
48    header: () => 'Score',
49    size: 20,
50    cell: info => Math.round(info.getValue()),
51    meta: {
52      className: 'justify-end text-right',
53    },
54  }),
55]
56
57function ExampleTable() {
58  const table = useReactTable({
59    defaultColumn: {
60      minSize: 0,
61      size: 0,
62    },
63    data,
64    columns,
65    getCoreRowModel: getCoreRowModel(),
66  })
67
68  return (
69    <table className="w-full border-collapse">
70      <thead>
71        {table.getHeaderGroups().map(headerGroup => (
72          <tr key={headerGroup.id}>
73            {headerGroup.headers.map(header => (
74              <th
75                key={header.id}
76                style={{
77                  width: header.getSize() !== 0 ? header.getSize() : undefined,
78                }}
79                className={`subtitle px-4 h-14 inline-flex items-center text-left ${
80                  header.column.columnDef.meta?.className
81                }`}
82              >
83                {header.isPlaceholder
84                  ? null
85                  : flexRender(
86                      header.column.columnDef.header,
87                      header.getContext(),
88                    )}
89              </th>
90            ))}
91          </tr>
92        ))}
93      </thead>
94      <tbody>
95        {table.getRowModel().rows.map(row => (
96          <tr
97            key={row.id}
98            className="font-bold text-xl hover:bg-primary hover:text-white h-14"
99          >
100            {row.getVisibleCells().map(cell => (
101              <td key={cell.id} className="border-0 p-0">
102                <a
103                  href={`#${row.renderValue('rank')}`}
104                  className={`reset h-14 px-4 flex items-center ${
105                    cell.column.columnDef.meta?.className
106                  }`}
107                >
108                  {flexRender(cell.column.columnDef.cell, cell.getContext())}
109                </a>
110              </td>
111            ))}
112          </tr>
113        ))}
114      </tbody>
115    </table>
116  )
117}

Clickable Rows with ActionMenu

1import { ActionMenu } from 'ui'
2import {
3  createColumnHelper,
4  flexRender,
5  getCoreRowModel,
6  useReactTable,
7  RowData,
8} from '@tanstack/react-table'
9import { EllipsisVerticalIcon } from '@heroicons/react/20/solid'
10
11const data: Ranking[] = [
12  { rank: '1', user: 'powz', score: 5054.25054 },
13  { rank: '2', user: 'Bijak', score: 3605.23605 },
14  { rank: '3', user: 'ShockOLatte', score: 2518.72518 },
15  { rank: '4', user: 'Ludie', score: 2517.32517 },
16  { rank: '5', user: 'Chamsae', score: 2434.42434 },
17]
18
19interface Ranking {
20  rank: string
21  user: string
22  score: number
23}
24
25const columnHelper = createColumnHelper<Ranking>()
26
27const columns = [
28  columnHelper.accessor('rank', {
29    header: () => 'Rank',
30    size: 5,
31    meta: {
32      className: 'justify-center',
33    },
34  }),
35  columnHelper.accessor('user', {
36    header: () => 'User',
37  }),
38  columnHelper.accessor('score', {
39    header: () => 'Score',
40    size: 20,
41    cell: info => Math.round(info.getValue()),
42    meta: {
43      className: 'justify-end text-right',
44    },
45  }),
46  columnHelper.display({
47    id: 'actions',
48    header: () => 'Actions',
49    size: 10,
50    cell: () => (
51      <ActionMenu
52        orientation="right"
53        links={[
54          { label: 'Edit', href: '#edit', type: 'normal' },
55          { label: 'Delete', href: '#delete', type: 'danger' },
56        ]}
57      >
58        <EllipsisVerticalIcon className="w-4 h-5" />
59      </ActionMenu>
60    ),
61  }),
62]
63
64function TableWithActionMenu() {
65  const table = useReactTable({
66    defaultColumn: {
67      minSize: 0,
68      size: 0,
69    },
70    data,
71    columns,
72    getCoreRowModel: getCoreRowModel(),
73  })
74
75  return (
76    <table className="default w-full border-collapse">
77      <thead>
78        {table.getHeaderGroups().map(headerGroup => (
79          <tr key={headerGroup.id}>
80            {headerGroup.headers.map(header => (
81              <th
82                key={header.id}
83                style={{
84                  width: header.getSize() !== 0 ? header.getSize() : undefined,
85                }}
86                className={`default ${header.column.columnDef.meta?.className}`}
87              >
88                {header.isPlaceholder
89                  ? null
90                  : flexRender(
91                      header.column.columnDef.header,
92                      header.getContext(),
93                    )}
94              </th>
95            ))}
96          </tr>
97        ))}
98      </thead>
99      <tbody>
100        {table.getRowModel().rows.map(row => (
101          <tr key={row.id} className="link">
102            {row.getVisibleCells().map(cell => {
103              const isActionColumn = cell.column.id === 'actions'
104              return (
105                <td key={cell.id} className="font-bold link">
106                  {isActionColumn ? (
107                    <div className="h-14 px-4 flex items-center justify-end">
108                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
109                    </div>
110                  ) : (
111                    <a
112                      href={`#${row.renderValue('rank')}`}
113                      className={`reset ${
114                        cell.column.columnDef.meta?.className
115                      }`}
116                    >
117                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
118                    </a>
119                  )}
120                </td>
121              )
122            })}
123          </tr>
124        ))}
125      </tbody>
126    </table>
127  )
128}