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}