@payfit/unity-components 3.1.27 → 3.1.29

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payfit/unity-components",
3
- "version": "3.1.27",
3
+ "version": "3.1.29",
4
4
  "module": "./dist/esm/index.js",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -103,7 +103,7 @@
103
103
  "@formatjs/intl": "4.1.12",
104
104
  "@internationalized/date": "3.12.4",
105
105
  "minimatch": "10.2.5",
106
- "@payfit/unity-illustrations": "3.1.27",
106
+ "@payfit/unity-illustrations": "3.1.29",
107
107
  "@radix-ui/react-avatar": "1.2.6",
108
108
  "@radix-ui/react-slot": "1.3.3",
109
109
  "@react-aria/interactions": "3.28.1",
@@ -133,8 +133,8 @@
133
133
  },
134
134
  "peerDependencies": {
135
135
  "@hookform/devtools": "4.4.0",
136
- "@payfit/unity-icons": "3.1.27",
137
- "@payfit/unity-themes": "3.1.27",
136
+ "@payfit/unity-icons": "3.1.29",
137
+ "@payfit/unity-themes": "3.1.29",
138
138
  "@storybook/react-vite": "^10",
139
139
  "@tanstack/react-query": "^5",
140
140
  "@tanstack/form-core": "1.33.5",
@@ -157,9 +157,9 @@
157
157
  "@payfit/storybook-addon-console-errors": "0.0.0-use.local",
158
158
  "@payfit/storybook-addon-datadog-rum": "0.0.0-use.local",
159
159
  "@payfit/storybook-config": "0.0.0-use.local",
160
- "@payfit/unity-icons": "3.1.27",
161
- "@payfit/unity-illustrations": "3.1.27",
162
- "@payfit/unity-themes": "3.1.27",
160
+ "@payfit/unity-icons": "3.1.29",
161
+ "@payfit/unity-illustrations": "3.1.29",
162
+ "@payfit/unity-themes": "3.1.29",
163
163
  "@payfit/vite-configs": "0.0.0-use.local",
164
164
  "@storybook/addon-a11y": "10.6.0",
165
165
  "@storybook/addon-designs": "11.1.4",
@@ -188,7 +188,7 @@
188
188
  "eslint-plugin-storybook": "10.3.2",
189
189
  "glob": "11.1.0",
190
190
  "msw": "2.14.6",
191
- "msw-storybook-addon": "3.0.0",
191
+ "msw-storybook-addon": "3.0.3",
192
192
  "playwright": "1.55.1",
193
193
  "prettier": "3.8.3",
194
194
  "react-docgen-typescript": "2.2.2",
@@ -29,7 +29,7 @@ stable across renders. Define static columns outside the component or memoize
29
29
  them; memoize derived data when its source would otherwise create a new array.
30
30
 
31
31
  ```tsx
32
- import { useMemo, useState } from 'react'
32
+ import { useMemo } from 'react'
33
33
 
34
34
  import {
35
35
  DataTable,
@@ -39,10 +39,11 @@ import {
39
39
  } from '@payfit/unity-components'
40
40
  import {
41
41
  createColumnHelper,
42
+ createPaginatedRowModel,
42
43
  flexRender,
43
- getCoreRowModel,
44
- getPaginationRowModel,
45
- useReactTable,
44
+ rowPaginationFeature,
45
+ tableFeatures,
46
+ useTable,
46
47
  } from '@tanstack/react-table'
47
48
 
48
49
  type Employee = {
@@ -52,11 +53,14 @@ type Employee = {
52
53
  status: 'active' | 'inactive'
53
54
  }
54
55
 
55
- const columnHelper = createColumnHelper<Employee>()
56
+ const features = tableFeatures({
57
+ rowPaginationFeature,
58
+ paginatedRowModel: createPaginatedRowModel(),
59
+ })
60
+
61
+ const columnHelper = createColumnHelper<typeof features, Employee>()
56
62
 
57
63
  export function EmployeeTable({ employees }: { employees: Employee[] }) {
58
- const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 })
59
-
60
64
  const columns = useMemo(
61
65
  () => [
62
66
  columnHelper.accessor('name', {
@@ -71,14 +75,10 @@ export function EmployeeTable({ employees }: { employees: Employee[] }) {
71
75
 
72
76
  const data = useMemo(() => employees, [employees])
73
77
 
74
- const table = useReactTable({
78
+ const table = useTable({
79
+ features,
75
80
  data,
76
81
  columns,
77
- getRowId: row => row.id,
78
- state: { pagination },
79
- onPaginationChange: setPagination,
80
- getCoreRowModel: getCoreRowModel(),
81
- getPaginationRowModel: getPaginationRowModel(),
82
82
  })
83
83
 
84
84
  return (
@@ -125,7 +125,7 @@ function MyTable() {
125
125
  { accessorKey: 'name', header: 'Name' },
126
126
  { accessorKey: 'status', header: 'Status' },
127
127
  ]
128
- const table = useReactTable({ data, columns, ... })
128
+ const table = useTable({ features, data, columns, ... })
129
129
  return <DataTable table={table}>{row => ...}</DataTable>
130
130
  }
131
131
  ```
@@ -138,7 +138,7 @@ function MyTable() {
138
138
  { accessorKey: 'name', header: 'Name' },
139
139
  { accessorKey: 'status', header: 'Status' },
140
140
  ], [])
141
- const table = useReactTable({ data, columns, ... })
141
+ const table = useTable({ features, data, columns, ... })
142
142
  return <DataTable table={table}>{row => ...}</DataTable>
143
143
  }
144
144
  ```
@@ -182,8 +182,11 @@ Wrong:
182
182
  Correct:
183
183
 
184
184
  ```tsx
185
- const table = useReactTable({ data, columns, getCoreRowModel(),
186
- getPaginationRowModel(), state: { pagination }, onPaginationChange: setPagination })
185
+ const features = tableFeatures({
186
+ rowPaginationFeature,
187
+ paginatedRowModel: createPaginatedRowModel(),
188
+ })
189
+ const table = useTable({ features, data, columns })
187
190
  <DataTableRoot>
188
191
  <DataTable table={table}>{row => /* ... */}</DataTable>
189
192
  </DataTableRoot>
@@ -206,9 +209,12 @@ Correct:
206
209
  ```tsx
207
210
  const [columnFilters, setColumnFilters] = useState([])
208
211
  const [globalFilter, setGlobalFilter] = useState('')
209
- const table = useReactTable({ /* … */ state: { columnFilters, globalFilter },
210
- onGlobalFilterChange: setGlobalFilter, onColumnFiltersChange: setColumnFilters,
211
- getFilteredRowModel() })
212
+ const features = tableFeatures({
213
+ columnFilteringFeature,
214
+ globalFilteringFeature,
215
+ filteredRowModel: createFilteredRowModel(),
216
+ })
217
+ const table = useTable({ features, data, columns })
212
218
  <FilterToolbar filterDefs={…} onChange={mapToTableState(setColumnFilters, setGlobalFilter)} />
213
219
  ```
214
220
 
@@ -219,24 +225,29 @@ FilterToolbar.onChange emits AppliedFilter[]. Agent stores them locally without
219
225
  Wrong:
220
226
 
221
227
  ```tsx
222
- useReactTable({
228
+ useTable({
229
+ features: tableFeatures({ rowPaginationFeature }),
223
230
  data: allEmployees,
224
231
  manualPagination: true,
225
- pageCount: Math.ceil(allEmployees.length / 10),
232
+ rowCount: allEmployees.length,
226
233
  })
227
234
  ```
228
235
 
229
236
  Correct for locally held data:
230
237
 
231
238
  ```tsx
239
+ import { useMemo, useState } from 'react'
240
+
241
+ const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 })
232
242
  const currentData = useMemo(() => {
233
243
  const start = pagination.pageIndex * pagination.pageSize
234
244
  return allEmployees.slice(start, start + pagination.pageSize)
235
245
  }, [pagination])
236
- useReactTable({
246
+ useTable({
247
+ features: tableFeatures({ rowPaginationFeature }),
237
248
  data: currentData,
238
249
  manualPagination: true,
239
- pageCount: Math.ceil(allEmployees.length / pagination.pageSize),
250
+ rowCount: allEmployees.length,
240
251
  state: { pagination },
241
252
  onPaginationChange: setPagination,
242
253
  })
@@ -245,9 +256,9 @@ useReactTable({
245
256
  manualPagination: true tells Tanstack not to slice. Agents pass the full dataset and expect TanStack to paginate anyway.
246
257
 
247
258
  For server-side pagination, fetch and pass only the current server page and
248
- set `pageCount` from the server's total count. When all rows are local and
249
- TanStack should paginate them automatically, omit `manualPagination` and use
250
- `getPaginationRowModel()` instead.
259
+ set `rowCount` or `pageCount` from the server response. When all rows are local
260
+ and TanStack should paginate them automatically, omit `manualPagination` and
261
+ register `paginatedRowModel: createPaginatedRowModel()` in `tableFeatures`.
251
262
 
252
263
  ### MEDIUM Render large datasets without enableVirtualization
253
264
 
@@ -9,9 +9,23 @@ checkboxes), `helperText` (renders a tooltip next to the header), and
9
9
 
10
10
  ```tsx
11
11
  import { Badge } from '@payfit/unity-components'
12
- import { createColumnHelper } from '@tanstack/react-table'
12
+ import {
13
+ columnFilteringFeature,
14
+ createColumnHelper,
15
+ createFilteredRowModel,
16
+ createSortedRowModel,
17
+ filterFn_equalsString,
18
+ rowSortingFeature,
19
+ tableFeatures,
20
+ } from '@tanstack/react-table'
13
21
 
14
- const columnHelper = createColumnHelper<Employee>()
22
+ const features = tableFeatures({
23
+ columnFilteringFeature,
24
+ filteredRowModel: createFilteredRowModel(),
25
+ rowSortingFeature,
26
+ sortedRowModel: createSortedRowModel(),
27
+ })
28
+ const columnHelper = createColumnHelper<typeof features, Employee>()
15
29
 
16
30
  export const employeeColumns = [
17
31
  columnHelper.accessor('name', {
@@ -23,7 +37,7 @@ export const employeeColumns = [
23
37
  columnHelper.accessor('status', {
24
38
  header: 'Status',
25
39
  enableColumnFilter: true,
26
- filterFn: 'arrIncludesSome',
40
+ filterFn: filterFn_equalsString,
27
41
  cell: info => {
28
42
  const status = info.getValue()
29
43
  return (
@@ -46,12 +60,16 @@ export const employeeColumns = [
46
60
  ### Server-side pagination
47
61
 
48
62
  `manualPagination: true` disables Tanstack's internal slicing. Pass only the
49
- current page's slice as `data` and supply `pageCount`.
63
+ current page's slice as `data` and supply `rowCount` or `pageCount`.
50
64
 
51
65
  ```tsx
52
66
  import { useMemo, useState } from 'react'
53
67
 
54
- import { getCoreRowModel, useReactTable } from '@tanstack/react-table'
68
+ import {
69
+ rowPaginationFeature,
70
+ tableFeatures,
71
+ useTable,
72
+ } from '@tanstack/react-table'
55
73
 
56
74
  export function ServerTable({ totalCount, fetchPage }: Props) {
57
75
  const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 20 })
@@ -63,14 +81,15 @@ export function ServerTable({ totalCount, fetchPage }: Props) {
63
81
  const columns = useMemo(() => employeeColumns, [])
64
82
  const data = useMemo(() => pageRows, [pageRows])
65
83
 
66
- const table = useReactTable({
84
+ const features = tableFeatures({ rowPaginationFeature })
85
+ const table = useTable({
86
+ features,
67
87
  data,
68
88
  columns,
69
- manualPagination: true,
70
- pageCount: Math.ceil(totalCount / pagination.pageSize),
71
89
  state: { pagination },
72
90
  onPaginationChange: setPagination,
73
- getCoreRowModel: getCoreRowModel(),
91
+ manualPagination: true,
92
+ rowCount: totalCount,
74
93
  })
75
94
 
76
95
  return (
@@ -102,7 +121,12 @@ multi-selects, text fields, etc.
102
121
  import type { FilterDef } from '@payfit/unity-components'
103
122
 
104
123
  import { FilterToolbar, Select, SelectItem } from '@payfit/unity-components'
105
- import { getFilteredRowModel } from '@tanstack/react-table'
124
+ import {
125
+ columnFilteringFeature,
126
+ createFilteredRowModel,
127
+ tableFeatures,
128
+ useTable,
129
+ } from '@tanstack/react-table'
106
130
 
107
131
  const filterDefs: FilterDef[] = [
108
132
  {
@@ -119,17 +143,14 @@ const filterDefs: FilterDef[] = [
119
143
  ]
120
144
 
121
145
  export function FilteredTable() {
122
- const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
123
-
124
- const table = useReactTable({
146
+ const features = tableFeatures({
147
+ columnFilteringFeature,
148
+ filteredRowModel: createFilteredRowModel(),
149
+ })
150
+ const table = useTable({
151
+ features,
125
152
  data,
126
153
  columns,
127
- state: { columnFilters, pagination },
128
- onColumnFiltersChange: setColumnFilters,
129
- onPaginationChange: setPagination,
130
- getCoreRowModel: getCoreRowModel(),
131
- getFilteredRowModel: getFilteredRowModel(),
132
- getPaginationRowModel: getPaginationRowModel(),
133
154
  })
134
155
 
135
156
  return (
@@ -137,7 +158,9 @@ export function FilteredTable() {
137
158
  <FilterToolbar
138
159
  filterDefs={filterDefs}
139
160
  onChange={applied =>
140
- setColumnFilters(applied.map(f => ({ id: f.id, value: f.value })))
161
+ table.setColumnFilters(
162
+ applied.map(f => ({ id: f.id, value: f.value })),
163
+ )
141
164
  }
142
165
  />
143
166
  <DataTableRoot>
@@ -198,17 +221,13 @@ const checkboxColumn = columnHelper.display({
198
221
  })
199
222
 
200
223
  export function BulkTable() {
201
- const [rowSelection, setRowSelection] = useState({})
202
224
  const columns = useMemo(() => [checkboxColumn, ...employeeColumns], [])
203
- const table = useReactTable({
225
+ const features = tableFeatures({ rowSelectionFeature, rowPaginationFeature })
226
+ const table = useTable({
227
+ features,
204
228
  data,
205
229
  columns,
206
- state: { rowSelection, pagination },
207
- onRowSelectionChange: setRowSelection,
208
- onPaginationChange: setPagination,
209
230
  enableRowSelection: true,
210
- getCoreRowModel: getCoreRowModel(),
211
- getPaginationRowModel: getPaginationRowModel(),
212
231
  })
213
232
 
214
233
  return (