@tanstack/react-table 0.0.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/react-table.development.js +3406 -0
  2. package/dist/react-table.development.js.map +1 -0
  3. package/dist/react-table.production.min.js +2 -0
  4. package/dist/react-table.production.min.js.map +1 -0
  5. package/lib/index.js +65 -0
  6. package/package.json +122 -0
  7. package/src/.DS_Store +0 -0
  8. package/src/aggregationTypes.ts +115 -0
  9. package/src/core.tsx +1194 -0
  10. package/src/createTable.tsx +181 -0
  11. package/src/features/Expanding.ts +388 -0
  12. package/src/features/Filters.ts +707 -0
  13. package/src/features/Grouping.ts +451 -0
  14. package/src/features/Headers.ts +907 -0
  15. package/src/features/Ordering.ts +134 -0
  16. package/src/features/Pinning.ts +213 -0
  17. package/src/features/Sorting.ts +487 -0
  18. package/src/features/Visibility.ts +281 -0
  19. package/src/features/notest/useAbsoluteLayout.test.js +152 -0
  20. package/src/features/notest/useBlockLayout.test.js +158 -0
  21. package/src/features/notest/useColumnOrder.test.js +186 -0
  22. package/src/features/notest/useExpanded.test.js +125 -0
  23. package/src/features/notest/useFilters.test.js +393 -0
  24. package/src/features/notest/useFiltersAndRowSelect.test.js +256 -0
  25. package/src/features/notest/useFlexLayout.test.js +152 -0
  26. package/src/features/notest/useGroupBy.test.js +259 -0
  27. package/src/features/notest/usePagination.test.js +231 -0
  28. package/src/features/notest/useResizeColumns.test.js +229 -0
  29. package/src/features/notest/useRowSelect.test.js +250 -0
  30. package/src/features/notest/useRowState.test.js +178 -0
  31. package/src/features/tests/Visibility.test.tsx +225 -0
  32. package/src/features/tests/__snapshots__/Visibility.test.tsx.snap +390 -0
  33. package/src/features/tests/withSorting.notest.tsx +341 -0
  34. package/src/features/withColumnResizing.ts +281 -0
  35. package/src/features/withPagination.ts +208 -0
  36. package/src/features/withRowSelection.ts +467 -0
  37. package/src/filterTypes.ts +251 -0
  38. package/src/index.tsx +7 -0
  39. package/src/sortTypes.ts +159 -0
  40. package/src/test-utils/makeTestData.ts +41 -0
  41. package/src/tests/__snapshots__/core.test.tsx.snap +148 -0
  42. package/src/tests/core.test.tsx +241 -0
  43. package/src/types.ts +285 -0
  44. package/src/utils/columnFilterRowsFn.ts +162 -0
  45. package/src/utils/expandRowsFn.ts +53 -0
  46. package/src/utils/globalFilterRowsFn.ts +129 -0
  47. package/src/utils/groupRowsFn.ts +196 -0
  48. package/src/utils/sortRowsFn.ts +115 -0
  49. package/src/utils.tsx +243 -0
@@ -0,0 +1,178 @@
1
+ import React from 'react'
2
+ import { render, fireEvent } from '../../../test-utils/react-testing'
3
+ import { useTable } from '../../hooks/useTable'
4
+ import { useRowState } from '../useRowState'
5
+
6
+ const data = [
7
+ {
8
+ firstName: 'tanner',
9
+ lastName: 'linsley',
10
+ age: 29,
11
+ visits: 100,
12
+ status: 'In Relationship',
13
+ progress: 50,
14
+ },
15
+ {
16
+ firstName: 'derek',
17
+ lastName: 'perkins',
18
+ age: 40,
19
+ visits: 40,
20
+ status: 'Single',
21
+ progress: 80,
22
+ },
23
+ {
24
+ firstName: 'joe',
25
+ lastName: 'bergevin',
26
+ age: 45,
27
+ visits: 20,
28
+ status: 'Complicated',
29
+ progress: 10,
30
+ },
31
+ {
32
+ firstName: 'jaylen',
33
+ lastName: 'linsley',
34
+ age: 26,
35
+ visits: 99,
36
+ status: 'In Relationship',
37
+ progress: 70,
38
+ },
39
+ ]
40
+
41
+ const defaultColumn = {
42
+ Cell: ({ column, cell, row }) => (
43
+ <div>
44
+ Row {row.id} Cell {column.id} Count {cell.state.count}{' '}
45
+ <button
46
+ onClick={() => cell.setState(old => ({ ...old, count: old.count + 1 }))}
47
+ >
48
+ Row {row.id} Cell {column.id} Toggle
49
+ </button>
50
+ </div>
51
+ ),
52
+ }
53
+
54
+ function Table({ columns, data }) {
55
+ const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
56
+ useTable(
57
+ {
58
+ columns,
59
+ data,
60
+ defaultColumn,
61
+ initialRowStateAccessor: () => ({ count: 0 }),
62
+ initialCellStateAccessor: () => ({ count: 0 }),
63
+ },
64
+ useRowState
65
+ )
66
+
67
+ return (
68
+ <table {...getTableProps()}>
69
+ <thead>
70
+ {headerGroups.map(headerGroup => (
71
+ <tr {...headerGroup.getHeaderGroupProps()}>
72
+ {headerGroup.headers.map(column => (
73
+ <th {...column.getHeaderProps()}>{column.render('Header')}</th>
74
+ ))}
75
+ </tr>
76
+ ))}
77
+ </thead>
78
+ <tbody {...getTableBodyProps()}>
79
+ {rows.map(
80
+ (row, i) =>
81
+ prepareRow(row) || (
82
+ <tr {...row.getRowProps()}>
83
+ <td>
84
+ <pre>Row Count {row.state.count}</pre>
85
+ <button
86
+ onClick={() =>
87
+ row.setState(old => ({
88
+ ...old,
89
+ count: old.count + 1,
90
+ }))
91
+ }
92
+ >
93
+ Row {row.id} Toggle
94
+ </button>
95
+ </td>
96
+ {row.cells.map(cell => (
97
+ <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
98
+ ))}
99
+ </tr>
100
+ )
101
+ )}
102
+ </tbody>
103
+ </table>
104
+ )
105
+ }
106
+
107
+ function App() {
108
+ const columns = React.useMemo(
109
+ () => [
110
+ {
111
+ Header: 'Name',
112
+ columns: [
113
+ {
114
+ Header: 'First Name',
115
+ accessor: 'firstName',
116
+ },
117
+ {
118
+ Header: 'Last Name',
119
+ accessor: 'lastName',
120
+ },
121
+ ],
122
+ },
123
+ {
124
+ Header: 'Info',
125
+ columns: [
126
+ {
127
+ Header: 'Age',
128
+ accessor: 'age',
129
+ },
130
+ {
131
+ Header: 'Visits',
132
+ accessor: 'visits',
133
+ },
134
+ {
135
+ Header: 'Status',
136
+ accessor: 'status',
137
+ },
138
+ {
139
+ Header: 'Profile Progress',
140
+ accessor: 'progress',
141
+ },
142
+ ],
143
+ },
144
+ ],
145
+ []
146
+ )
147
+
148
+ return <Table columns={columns} data={data} />
149
+ }
150
+
151
+ test('renders a filterable table', () => {
152
+ const rendered = render(<App />)
153
+
154
+ fireEvent.click(rendered.getByText('Row 1 Toggle'))
155
+ fireEvent.click(rendered.getByText('Row 1 Toggle'))
156
+
157
+ rendered.getByText('Row Count 2')
158
+
159
+ fireEvent.click(rendered.getByText('Row 1 Cell firstName Toggle'))
160
+
161
+ rendered.getByText('Row 1 Cell firstName Count 1')
162
+
163
+ fireEvent.click(rendered.getByText('Row 2 Cell lastName Toggle'))
164
+ fireEvent.click(rendered.getByText('Row 2 Cell lastName Toggle'))
165
+
166
+ rendered.getByText('Row 2 Cell lastName Count 2')
167
+
168
+ fireEvent.click(rendered.getByText('Row 3 Cell age Toggle'))
169
+ fireEvent.click(rendered.getByText('Row 3 Cell age Toggle'))
170
+ fireEvent.click(rendered.getByText('Row 3 Cell age Toggle'))
171
+
172
+ rendered.getByText('Row 3 Cell age Count 3')
173
+
174
+ fireEvent.click(rendered.getByText('Row 1 Toggle'))
175
+ fireEvent.click(rendered.getByText('Row 1 Toggle'))
176
+
177
+ rendered.getByText('Row Count 4')
178
+ })
@@ -0,0 +1,225 @@
1
+ import * as React from 'react'
2
+
3
+ // import { renderHook } from '@testing-library/react-hooks'
4
+ import * as RTL from '@testing-library/react'
5
+ import '@testing-library/jest-dom/extend-expect'
6
+ import { createTable } from 'react-table'
7
+
8
+ type Row = {
9
+ firstName: string
10
+ lastName: string
11
+ age: number
12
+ visits: number
13
+ status: string
14
+ progress: number
15
+ }
16
+
17
+ const table = createTable().RowType<Row>()
18
+
19
+ const defaultData: Row[] = [
20
+ {
21
+ firstName: 'tanner',
22
+ lastName: 'linsley',
23
+ age: 29,
24
+ visits: 100,
25
+ status: 'In Relationship',
26
+ progress: 50,
27
+ },
28
+ {
29
+ firstName: 'derek',
30
+ lastName: 'perkins',
31
+ age: 40,
32
+ visits: 40,
33
+ status: 'Single',
34
+ progress: 80,
35
+ },
36
+ {
37
+ firstName: 'joe',
38
+ lastName: 'bergevin',
39
+ age: 45,
40
+ visits: 20,
41
+ status: 'Complicated',
42
+ progress: 10,
43
+ },
44
+ ]
45
+
46
+ const defaultColumns = table.createColumns([
47
+ table.createGroup({
48
+ header: 'Name',
49
+ footer: props => props.column.id,
50
+ columns: [
51
+ table.createColumn('firstName', {
52
+ cell: info => info.value,
53
+ footer: props => props.column.id,
54
+ }),
55
+ table.createColumn(row => row.lastName, {
56
+ id: 'lastName',
57
+ cell: info => info.value,
58
+ header: <span>Last Name</span>,
59
+ footer: props => props.column.id,
60
+ }),
61
+ ],
62
+ }),
63
+ table.createGroup({
64
+ header: 'Info',
65
+ footer: props => props.column.id,
66
+ columns: [
67
+ table.createColumn('age', {
68
+ header: () => 'Age',
69
+ footer: props => props.column.id,
70
+ }),
71
+ table.createGroup({
72
+ header: 'More Info',
73
+ columns: [
74
+ table.createColumn('visits', {
75
+ header: () => <span>Visits</span>,
76
+ footer: props => props.column.id,
77
+ }),
78
+ table.createColumn('status', {
79
+ header: 'Status',
80
+ footer: props => props.column.id,
81
+ }),
82
+ table.createColumn('progress', {
83
+ header: 'Profile Progress',
84
+ footer: props => props.column.id,
85
+ }),
86
+ ],
87
+ }),
88
+ ],
89
+ }),
90
+ ])
91
+
92
+ describe('useTable', () => {
93
+ it('can toggle column visibility', () => {
94
+ const Table = () => {
95
+ const [data] = React.useState<Row[]>(() => [...defaultData])
96
+ const [columns] = React.useState<typeof defaultColumns>(() => [
97
+ ...defaultColumns,
98
+ ])
99
+ const [columnVisibility, setColumnVisibility] = React.useState({})
100
+
101
+ const rerender = React.useReducer(() => ({}), {})[1]
102
+
103
+ const instance = table.useTable({
104
+ data,
105
+ columns,
106
+ onColumnVisibilityChange: setColumnVisibility,
107
+ state: {
108
+ columnVisibility,
109
+ },
110
+ // debug: true,
111
+ })
112
+
113
+ return (
114
+ <div className="p-2">
115
+ <div className="inline-block border border-black shadow rounded">
116
+ <div className="px-1 border-b border-black">
117
+ <label>
118
+ <input {...instance.getToggleAllColumnsVisibilityProps()} />{' '}
119
+ Toggle All
120
+ </label>
121
+ </div>
122
+ {instance.getAllLeafColumns().map(column => {
123
+ return (
124
+ <div key={column.id} className="px-1">
125
+ <label>
126
+ <input {...column.getToggleVisibilityProps()} /> {column.id}
127
+ </label>
128
+ </div>
129
+ )
130
+ })}
131
+ </div>
132
+ <div className="h-4" />
133
+ <table {...instance.getTableProps()}>
134
+ <thead>
135
+ {instance.getHeaderGroups().map(headerGroup => (
136
+ <tr {...headerGroup.getHeaderGroupProps()}>
137
+ {headerGroup.headers.map(header => (
138
+ <th {...header.getHeaderProps()}>
139
+ {header.isPlaceholder ? null : header.renderHeader()}
140
+ </th>
141
+ ))}
142
+ </tr>
143
+ ))}
144
+ </thead>
145
+ <tbody {...instance.getTableBodyProps()}>
146
+ {instance.getRows().map(row => (
147
+ <tr {...row.getRowProps()}>
148
+ {row.getVisibleCells().map(cell => (
149
+ <td {...cell.getCellProps()}>{cell.renderCell()}</td>
150
+ ))}
151
+ </tr>
152
+ ))}
153
+ </tbody>
154
+ <tfoot>
155
+ {instance.getFooterGroups().map(footerGroup => (
156
+ <tr {...footerGroup.getFooterGroupProps()}>
157
+ {footerGroup.headers.map(header => (
158
+ <th {...header.getFooterProps()}>
159
+ {header.isPlaceholder ? null : header.renderFooter()}
160
+ </th>
161
+ ))}
162
+ </tr>
163
+ ))}
164
+ </tfoot>
165
+ </table>
166
+ <div className="h-4" />
167
+ <button onClick={() => rerender()} className="border p-2">
168
+ Rerender
169
+ </button>
170
+ </div>
171
+ )
172
+ }
173
+
174
+ // let api: any;
175
+
176
+ const rendered = RTL.render(<Table />)
177
+
178
+ // RTL.screen.logTestingPlaygroundURL()
179
+
180
+ let snapIndex = 0
181
+
182
+ const snap = (name: string) => {
183
+ expect({
184
+ headers: Array.from(
185
+ rendered.container.querySelectorAll('thead > tr')
186
+ ).map(d =>
187
+ Array.from(d.querySelectorAll('th')).map(d => [
188
+ d.innerHTML,
189
+ d.getAttribute('colspan'),
190
+ ])
191
+ ),
192
+ rows: Array.from(rendered.container.querySelectorAll('tbody > tr')).map(
193
+ d => Array.from(d.querySelectorAll('td')).map(d => d.innerHTML)
194
+ ),
195
+ footers: Array.from(
196
+ rendered.container.querySelectorAll('tfoot > tr')
197
+ ).map(d =>
198
+ Array.from(d.querySelectorAll('th')).map(d => [
199
+ d.innerHTML,
200
+ d.getAttribute('colspan'),
201
+ ])
202
+ ),
203
+ }).toMatchSnapshot(`${snapIndex++} - ${name}`)
204
+ }
205
+
206
+ RTL.fireEvent.click(rendered.getByLabelText('Toggle All'))
207
+
208
+ snap('after toggling all off')
209
+
210
+ RTL.fireEvent.click(rendered.getByLabelText('Toggle All'))
211
+
212
+ snap('after toggling all on')
213
+
214
+ RTL.fireEvent.click(rendered.getByLabelText('firstName'))
215
+
216
+ snap('after toggling firstName off')
217
+
218
+ RTL.fireEvent.click(rendered.getByLabelText('firstName'))
219
+ RTL.fireEvent.click(rendered.getByLabelText('visits'))
220
+ RTL.fireEvent.click(rendered.getByLabelText('status'))
221
+ RTL.fireEvent.click(rendered.getByLabelText('progress'))
222
+
223
+ snap('after toggling More Info off')
224
+ })
225
+ })