@maestro-js/components 1.0.0-alpha.19 → 1.0.0-alpha.2

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 (56) hide show
  1. package/commands/add.ts +1 -16
  2. package/dist/components.json +1 -1
  3. package/dist/index.js +1 -14
  4. package/package.json +5 -5
  5. package/registry.json +790 -598
  6. package/scripts/build.ts +4 -11
  7. package/src/components/alert-dialog.tsx +3 -3
  8. package/src/components/avatar.tsx +1 -1
  9. package/src/components/button-link.tsx +0 -3
  10. package/src/components/button.tsx +0 -4
  11. package/src/components/checkbox.tsx +7 -7
  12. package/src/components/chip.tsx +7 -7
  13. package/src/components/container.tsx +3 -3
  14. package/src/components/dialog.tsx +7 -21
  15. package/src/components/disclosure.tsx +1 -1
  16. package/src/components/drawer.tsx +5 -19
  17. package/src/components/form.tsx +5 -27
  18. package/src/components/helpers/form-field.tsx +8 -7
  19. package/src/components/helpers/get-button-classes.ts +23 -23
  20. package/src/components/helpers/headless-button.tsx +1 -1
  21. package/src/components/inline-alert.tsx +3 -3
  22. package/src/components/labeled-value.tsx +2 -2
  23. package/src/components/menu.tsx +26 -60
  24. package/src/components/month-day-input.tsx +1 -2
  25. package/src/components/multiselect.tsx +70 -74
  26. package/src/components/radio.tsx +8 -8
  27. package/src/components/select.tsx +8 -9
  28. package/src/components/stepper.tsx +6 -6
  29. package/src/components/switch.tsx +7 -7
  30. package/src/components/tabs.tsx +1 -1
  31. package/src/components/tag-field.tsx +3 -3
  32. package/src/components/text-area.tsx +1 -1
  33. package/src/components/text-field.tsx +1 -4
  34. package/src/components/toast.tsx +6 -6
  35. package/src/components/toggle-button-group.tsx +2 -2
  36. package/src/utils/icons.d.ts +1 -2
  37. package/src/utils/use-tab-indicator.ts +9 -9
  38. package/src/components/date-range.tsx +0 -138
  39. package/src/components/optional-link.tsx +0 -15
  40. package/src/components/table/headless-templated-row-table.ts +0 -550
  41. package/src/components/table/index.tsx +0 -41
  42. package/src/components/table/server-table.ts +0 -143
  43. package/src/components/table/table-actions.tsx +0 -76
  44. package/src/components/table/table-container.tsx +0 -173
  45. package/src/components/table/table-container.type-test.ts +0 -155
  46. package/src/components/table/table-filters/date-range-filter.tsx +0 -227
  47. package/src/components/table/table-filters/select-filter.tsx +0 -211
  48. package/src/components/table/table-filters/sort.tsx +0 -85
  49. package/src/components/table/table-primitives.tsx +0 -226
  50. package/src/components/table/table-toolbar.tsx +0 -300
  51. package/src/components/table/table-types.ts +0 -61
  52. package/src/components/table/use-client-table.ts +0 -157
  53. package/src/components/table/use-client-table.type-test.ts +0 -217
  54. package/src/components/table/use-server-table.ts +0 -192
  55. package/src/components/table/use-server-table.type-test.ts +0 -174
  56. package/src/utils/use-query-state.ts +0 -626
@@ -1,157 +0,0 @@
1
- import React from 'react'
2
- import { HeadlessTemplatedRowTable } from './headless-templated-row-table'
3
- import type { MatchSorterOptions } from 'match-sorter'
4
-
5
- type ClientFeatures<
6
- TData extends HeadlessTemplatedRowTable.RowData,
7
- FC extends HeadlessTemplatedRowTable.FilterConfig<TData> = {},
8
- SC extends HeadlessTemplatedRowTable.SortConfig<TData> = {}
9
- > = [
10
- ReturnType<typeof HeadlessTemplatedRowTable.rowCount<TData>>,
11
- ReturnType<typeof HeadlessTemplatedRowTable.filtering<TData, HeadlessTemplatedRowTable.FilterConfig<TData, FC>>>,
12
- ReturnType<typeof HeadlessTemplatedRowTable.search<TData>>,
13
- ReturnType<typeof HeadlessTemplatedRowTable.sort<TData, SC>>,
14
- ReturnType<typeof HeadlessTemplatedRowTable.rowSelection<TData>>,
15
- ReturnType<typeof HeadlessTemplatedRowTable.pagination<TData>>
16
- ]
17
-
18
- export function useClientTable<
19
- TData extends HeadlessTemplatedRowTable.RowData,
20
- FC extends HeadlessTemplatedRowTable.FilterConfig<NoInfer<TData>> = {},
21
- SC extends HeadlessTemplatedRowTable.SortConfig<NoInfer<TData>> = {}
22
- >({
23
- rows: rowsInput,
24
- filters,
25
- search,
26
- sorts,
27
- getRowId,
28
- defaultPageSize,
29
- onFiltersChange,
30
- onSearchChange,
31
- onSortChange,
32
- onPaginationChange,
33
- onRowSelectionChange,
34
- manualFiltering,
35
- manualSearch,
36
- manualSort,
37
- manualPagination
38
- }: {
39
- rows: TData[]
40
- filters?: FC & HeadlessTemplatedRowTable.FilterConfig<NoInfer<TData>, FC>
41
- search?: MatchSorterOptions<TData>
42
- sorts?: SC & HeadlessTemplatedRowTable.SortConfig<NoInfer<TData>, SC>
43
- getRowId: (row: TData) => string
44
- defaultPageSize?: number
45
- manualFiltering?: boolean
46
- onFiltersChange?: (
47
- val:
48
- | HeadlessTemplatedRowTable.FilterState<TData, FC>
49
- | ((prev: HeadlessTemplatedRowTable.FilterState<TData, FC>) => HeadlessTemplatedRowTable.FilterState<TData, FC>)
50
- ) => void
51
- manualSearch?: boolean
52
- onSearchChange?: (val: string | ((prev: string) => string)) => void
53
- manualSort?: boolean
54
- onSortChange?: (
55
- val:
56
- | HeadlessTemplatedRowTable.SortState<SC>
57
- | ((prev: HeadlessTemplatedRowTable.SortState<SC>) => HeadlessTemplatedRowTable.SortState<SC>)
58
- ) => void
59
- manualPagination?: boolean
60
- onPaginationChange?: (val: any) => void
61
- onRowSelectionChange?: (val: Set<string>) => void
62
- }): HeadlessTemplatedRowTable.ReactTable<TData, ClientFeatures<TData, FC, SC>> {
63
- const tableRef = React.useRef(null as HeadlessTemplatedRowTable.ReactTable<TData, ClientFeatures<TData, FC, SC>> | null)
64
-
65
- const options = React.useMemo(() => {
66
- const applyState = (key: string, val: any) => {
67
- tableRef.current!.setState((prev: any) => ({
68
- ...prev,
69
- [key]: typeof val === 'function' ? val(prev[key]) : val
70
- }))
71
- }
72
- const resetDependentState = (resetPagination: boolean) => {
73
- tableRef.current!.setState((prev: any) => {
74
- const resetPag = resetPagination && !manualPagination && prev.pagination?.skip !== 0
75
- const resetSel = prev.rowSelection?.size > 0
76
- if (!resetPag && !resetSel) return prev
77
- return {
78
- ...prev,
79
- ...(resetPag ? { pagination: { ...prev.pagination, skip: 0 } } : {}),
80
- ...(resetSel ? { rowSelection: new Set() } : {})
81
- }
82
- })
83
- }
84
-
85
- return {
86
- onFiltersChange: (val: any) => {
87
- if (onFiltersChange) onFiltersChange(val)
88
- else applyState('filters', val)
89
- resetDependentState(true)
90
- },
91
- onSearchChange: (val: any) => {
92
- if (onSearchChange) onSearchChange(val)
93
- else applyState('search', val)
94
- resetDependentState(true)
95
- },
96
- onSortChange: (val: any) => {
97
- if (onSortChange) onSortChange(val)
98
- else applyState('sort', val)
99
- resetDependentState(true)
100
- },
101
- onPaginationChange: (val: any) => {
102
- if (onPaginationChange) onPaginationChange(val)
103
- else applyState('pagination', val)
104
- resetDependentState(false)
105
- },
106
- onRowSelectionChange,
107
- manualFiltering,
108
- manualSearch,
109
- manualSort,
110
- manualPagination
111
- }
112
- }, [
113
- onFiltersChange,
114
- onSearchChange,
115
- onSortChange,
116
- onPaginationChange,
117
- onRowSelectionChange,
118
- manualFiltering,
119
- manualSearch,
120
- manualSort,
121
- manualPagination
122
- ])
123
-
124
- if (!tableRef.current) {
125
- tableRef.current = HeadlessTemplatedRowTable.createTable({
126
- features: [
127
- HeadlessTemplatedRowTable.filtering<TData, HeadlessTemplatedRowTable.FilterConfig<TData, FC>>(
128
- (filters ?? {}) as HeadlessTemplatedRowTable.FilterConfig<TData, FC>
129
- ),
130
- HeadlessTemplatedRowTable.search<TData>(search ?? {}),
131
- HeadlessTemplatedRowTable.sort<TData, SC>((sorts ?? {}) as SC),
132
- HeadlessTemplatedRowTable.rowCount(),
133
- HeadlessTemplatedRowTable.rowSelection<TData>(getRowId),
134
- HeadlessTemplatedRowTable.pagination<TData>(defaultPageSize ?? 10)
135
- ],
136
- rows: rowsInput,
137
- ...options
138
- }) as HeadlessTemplatedRowTable.ReactTable<TData, ClientFeatures<TData, FC, SC>>
139
- }
140
- const table = tableRef.current
141
-
142
- const state = React.useSyncExternalStore(
143
- table.subscribe,
144
- () => table.state,
145
- () => table.state
146
- )
147
- table.state = state
148
-
149
- React.useEffect(() => {
150
- table.setRows(rowsInput)
151
- }, [rowsInput])
152
- React.useEffect(() => {
153
- table.setOptions(options)
154
- }, [options])
155
-
156
- return table
157
- }
@@ -1,217 +0,0 @@
1
- import { useClientTable } from './use-client-table'
2
- import type { TableLocalization } from './table-types'
3
- import type { Iso } from 'iso-fns'
4
-
5
- // =============================================================================
6
- // Helpers
7
- // =============================================================================
8
-
9
- type Expect<T extends true> = T
10
- type Equal<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2 ? true : false
11
-
12
- // =============================================================================
13
- // Setup
14
- // =============================================================================
15
-
16
- type Row = {
17
- id: string
18
- status: 'active' | 'inactive'
19
- name: string
20
- createdAt: string
21
- }
22
-
23
- // =============================================================================
24
- // Filter and sort config inference
25
- // =============================================================================
26
-
27
- function testFilterAndSortInference() {
28
- const table = useClientTable({
29
- rows: [] as Row[],
30
- getRowId: (row) => row.id,
31
- filters: {
32
- status: (row, value) => row.status === value
33
- },
34
- sorts: {
35
- newest: (a, b) => a.createdAt.localeCompare(b.createdAt),
36
- oldest: (a, b) => b.createdAt.localeCompare(a.createdAt)
37
- }
38
- })
39
-
40
- // getFilterConfig() keys match the provided filter names
41
- type _FilterKeys = Expect<Equal<keyof ReturnType<typeof table.getFilterConfig>, 'status'>>
42
-
43
- // getSortConfig() keys match the provided sort names
44
- type _SortKeys = Expect<Equal<keyof ReturnType<typeof table.getSortConfig>, 'newest' | 'oldest'>>
45
-
46
- // state.sort is the union of sort keys | null
47
- type _SortState = Expect<Equal<typeof table.state.sort, 'newest' | 'oldest' | null>>
48
-
49
- // state.filters keys match filter names
50
- type _FilterStateKeys = Expect<Equal<keyof typeof table.state.filters, 'status'>>
51
- }
52
-
53
- // =============================================================================
54
- // Localization compatibility — select filter
55
- // =============================================================================
56
-
57
- function testLocalizationWithSelectFilter() {
58
- const table = useClientTable({
59
- rows: [] as Row[],
60
- getRowId: (row) => row.id,
61
- filters: {
62
- status: (row, value) => row.status === value
63
- },
64
- sorts: {
65
- newest: (a, b) => 0,
66
- oldest: (a, b) => 0
67
- }
68
- })
69
-
70
- type Loc = TableLocalization<
71
- ReturnType<typeof table.getFilterConfig>,
72
- ReturnType<typeof table.getSortConfig>
73
- >
74
-
75
- type _LocFilterKeys = Expect<Equal<keyof Loc['filters'], 'status'>>
76
- type _LocSortKeys = Expect<Equal<keyof Loc['sorts'], 'newest' | 'oldest'>>
77
-
78
- // Valid localization with typed option values
79
- const _loc: Loc = {
80
- filters: {
81
- status: {
82
- label: 'Status',
83
- options: [
84
- { label: 'Active', value: 'active' },
85
- { label: 'Inactive', value: 'inactive' }
86
- ]
87
- }
88
- },
89
- sorts: {
90
- newest: { label: 'Newest' },
91
- oldest: { label: 'Oldest' }
92
- }
93
- }
94
- }
95
-
96
- // =============================================================================
97
- // Localization compatibility — date range filter
98
- // =============================================================================
99
-
100
- function testLocalizationWithDateRangeFilter() {
101
- type RowWithDate = {
102
- id: string
103
- dateRange: { startDate: Iso.Date; endDate: Iso.Date }
104
- }
105
-
106
- const table = useClientTable({
107
- rows: [] as RowWithDate[],
108
- getRowId: (row) => row.id,
109
- filters: {
110
- dateRange: (row, value) => true
111
- }
112
- })
113
-
114
- type Loc = TableLocalization<
115
- ReturnType<typeof table.getFilterConfig>,
116
- ReturnType<typeof table.getSortConfig>
117
- >
118
-
119
- // Valid: date-range filter accepts DateRangeTableFilter form
120
- const _loc: Loc = {
121
- filters: {
122
- dateRange: { label: 'Date Range', type: 'date-range' }
123
- },
124
- sorts: {}
125
- }
126
-
127
- // Invalid: date-range filter rejects select-style options
128
- const _badLoc: Loc = {
129
- filters: {
130
- dateRange: {
131
- label: 'Date Range',
132
- type: 'date-range',
133
- // @ts-expect-error — select-style options array is not valid for date-range
134
- options: [{ label: 'X', value: 'x' }]
135
- }
136
- },
137
- sorts: {}
138
- }
139
- }
140
-
141
- // =============================================================================
142
- // Filter predicate contextual typing — row and value are well typed
143
- // =============================================================================
144
-
145
- function testFilterPredicateContextualTyping() {
146
- useClientTable({
147
- rows: [] as Row[],
148
- getRowId: (row) => row.id,
149
- filters: {
150
- // @ts-expect-error — 'nonExistent' doesn't exist on Row
151
- status: (row, value) => row.nonExistent === value
152
- }
153
- })
154
-
155
- useClientTable({
156
- rows: [] as Row[],
157
- getRowId: (row) => row.id,
158
- filters: {
159
- // value is Row['status'], comparing to a number should error
160
- // @ts-expect-error — Row['status'] is not comparable to number
161
- status: (row, value) => value === 123
162
- }
163
- })
164
- }
165
-
166
- // =============================================================================
167
- // Sort comparator contextual typing — row is well typed
168
- // =============================================================================
169
-
170
- function testSortComparatorContextualTyping() {
171
- useClientTable({
172
- rows: [] as Row[],
173
- getRowId: (row) => row.id,
174
- sorts: {
175
- // @ts-expect-error — 'nonExistent' doesn't exist on Row
176
- byName: (a, b) => a.nonExistent.localeCompare(b.name)
177
- }
178
- })
179
- }
180
-
181
- // =============================================================================
182
- // Negative: wrong localization option value
183
- // =============================================================================
184
-
185
- declare function checkLocalization(l: TableLocalization<{ status: 'active' | 'inactive' }, {}>): void
186
-
187
- function testWrongLocalizationOptionValue() {
188
- checkLocalization({
189
- filters: {
190
- status: {
191
- label: 'Status',
192
- // @ts-expect-error — 'unknown' is not assignable to Row['status']
193
- options: [{ label: 'Unknown', value: 'unknown' }]
194
- }
195
- },
196
- sorts: {}
197
- })
198
- }
199
-
200
- // =============================================================================
201
- // No filters/sorts → empty localization
202
- // =============================================================================
203
-
204
- function testNoFiltersOrSorts() {
205
- const table = useClientTable({
206
- rows: [] as Row[],
207
- getRowId: (row) => row.id
208
- })
209
-
210
- type Loc = TableLocalization<
211
- ReturnType<typeof table.getFilterConfig>,
212
- ReturnType<typeof table.getSortConfig>
213
- >
214
-
215
- type _EmptyFilters = Expect<Equal<Loc['filters'], {}>>
216
- type _EmptySorts = Expect<Equal<Loc['sorts'], {}>>
217
- }
@@ -1,192 +0,0 @@
1
- import React from 'react'
2
- import { useSearchParams as useSearchParamsRR } from 'react-router'
3
- import { HeadlessTemplatedRowTable } from './headless-templated-row-table'
4
- import { SearchParams } from '../../utils/use-query-state'
5
- import { type ServerTable } from './server-table'
6
-
7
- type ServerFilterConfig<TData extends HeadlessTemplatedRowTable.RowData, FC extends Record<string, any>> = {
8
- [K in keyof FC & string]: HeadlessTemplatedRowTable.FilterPredicate<TData, K, NonNullable<FC[K]>>
9
- }
10
-
11
- type ServerSortConfig<TData extends HeadlessTemplatedRowTable.RowData, SortKeys extends string> = Record<
12
- SortKeys,
13
- HeadlessTemplatedRowTable.SortComparator<TData>
14
- >
15
-
16
- type ServerFeatures<
17
- TData extends HeadlessTemplatedRowTable.RowData,
18
- FC extends Record<string, any>,
19
- SC extends Record<string, any>
20
- > = [
21
- ReturnType<typeof HeadlessTemplatedRowTable.rowCount<TData>>,
22
- ReturnType<typeof HeadlessTemplatedRowTable.filtering<TData, ServerFilterConfig<TData, FC>>>,
23
- ReturnType<typeof HeadlessTemplatedRowTable.sort<TData, ServerSortConfig<TData, keyof SC & string>>>,
24
- ReturnType<typeof HeadlessTemplatedRowTable.search<TData>>,
25
- ReturnType<typeof HeadlessTemplatedRowTable.rowSelection<TData>>,
26
- ReturnType<typeof HeadlessTemplatedRowTable.pagination<TData>>
27
- ]
28
-
29
- const noopSearchCodec = SearchParams.codecs.string().default('')
30
- const noopPaginationLoader = SearchParams.createLoader({
31
- limit: SearchParams.codecs.int().default(0),
32
- skip: SearchParams.codecs.int().default(0)
33
- })
34
-
35
- export function useServerTable<
36
- TData extends HeadlessTemplatedRowTable.RowData,
37
- FC extends Record<string, any> = {},
38
- SC extends Record<string, any> = {}
39
- >(
40
- serverTable: ServerTable.ServerTable<TData, FC, SC>,
41
- _options: {
42
- getRowId: (row: TData) => string
43
- }
44
- ): HeadlessTemplatedRowTable.ReactTable<TData, ServerFeatures<TData, FC, SC>> {
45
- type SortKey = keyof SC & string
46
-
47
- const filterCodec = React.useMemo(
48
- () => SearchParams.deserializeLoader(serverTable.filters),
49
- [serverTable.filters]
50
- ) as SearchParams.QueryStateLoader<FC>
51
- const sortCodec = React.useMemo(() => SearchParams.deserializeCodec(serverTable.sorts), [serverTable.sorts])
52
- const searchCodec = React.useMemo(
53
- () => (serverTable.search ? SearchParams.deserializeCodec(serverTable.search) : noopSearchCodec),
54
- [serverTable.search]
55
- )
56
- const paginationCodec = React.useMemo(
57
- () => (serverTable.pagination ? SearchParams.deserializeLoader(serverTable.pagination) : noopPaginationLoader),
58
- [serverTable.pagination]
59
- )
60
-
61
- const [filters] = SearchParams.useSearchParams(filterCodec)
62
- const [sort] = SearchParams.useState('sort', sortCodec)
63
- const sortValues = serverTable.sorts.values
64
- const [search] = SearchParams.useState('search', searchCodec)
65
- const [pagination, setPagination] = SearchParams.useSearchParams(paginationCodec)
66
- const [, setURLParams] = useSearchParamsRR()
67
-
68
- // Build noop configs for features (manual mode — predicates/comparators won't be called)
69
- const filterConfig = React.useMemo(
70
- () => Object.fromEntries(Object.keys(filterCodec ?? {}).map((key) => [key, () => true])),
71
- [filterCodec]
72
- ) as unknown as ServerFilterConfig<TData, FC>
73
- const sortConfig = React.useMemo(
74
- () => Object.fromEntries(sortValues.map((v) => [v, () => 0])),
75
- [sortValues]
76
- ) as unknown as ServerSortConfig<TData, SortKey>
77
-
78
- const state = React.useMemo(
79
- () => ({
80
- filters,
81
- sort: sort as SortKey | null,
82
- search: search ?? '',
83
- pagination: { limit: pagination.limit, skip: pagination.skip }
84
- }),
85
- [filters, sort, search, pagination]
86
- )
87
-
88
- const options = React.useMemo(
89
- () => ({
90
- manualFiltering: true as const,
91
- manualSearch: true as const,
92
- manualSort: true as const,
93
- manualPagination: true as const,
94
- onFiltersChange: (v: any) => {
95
- setURLParams(
96
- (prev) => {
97
- const next = new URLSearchParams(prev)
98
- const oldFilters = Object.fromEntries(
99
- Object.entries(filterCodec).map(([name, codec]: [string, any]) => {
100
- try {
101
- return [name, codec.decode(next.get(name)) ?? codec._def?.defaultValue ?? null]
102
- } catch {
103
- return [name, codec._def?.defaultValue ?? null]
104
- }
105
- })
106
- )
107
- const newFilters = typeof v === 'function' ? v(oldFilters) : v
108
- for (const [name, codec] of Object.entries(filterCodec) as [string, any][]) {
109
- const encoded = codec.encode(newFilters[name])
110
- if (
111
- encoded === null ||
112
- (codec._def?.defaultValue != null &&
113
- codec._def?.clearOnDefault &&
114
- encoded === codec.encode(codec._def?.defaultValue))
115
- ) {
116
- next.delete(name)
117
- } else {
118
- next.set(name, encoded)
119
- }
120
- }
121
- next.delete('skip')
122
- return next
123
- },
124
- { preventScrollReset: true, replace: true }
125
- )
126
- table.clearRowSelection?.()
127
- },
128
- onSortChange: (v: any) => {
129
- setURLParams(
130
- (prev) => {
131
- const next = new URLSearchParams(prev)
132
- const newSort = typeof v === 'function' ? v(sortCodec.decode(next.get('sort'))) : v
133
- const encoded = sortCodec.encode(newSort)
134
- if (encoded === null) next.delete('sort')
135
- else next.set('sort', encoded)
136
- next.delete('skip')
137
- return next
138
- },
139
- { preventScrollReset: true, replace: true }
140
- )
141
- table.clearRowSelection?.()
142
- },
143
- onSearchChange: (v: any) => {
144
- setURLParams(
145
- (prev) => {
146
- const next = new URLSearchParams(prev)
147
- const newSearch = typeof v === 'function' ? v(next.get('search') ?? '') : v
148
- if (newSearch) next.set('search', newSearch)
149
- else next.delete('search')
150
- next.delete('skip')
151
- return next
152
- },
153
- { preventScrollReset: true, replace: true }
154
- )
155
- table.clearRowSelection?.()
156
- },
157
- onPaginationChange: (v: any) => setPagination(v, { preventScrollReset: true, replace: true }),
158
- rowCount: serverTable.totalRows
159
- }),
160
- [filterCodec, sortCodec, setURLParams, setPagination, serverTable.totalRows]
161
- )
162
-
163
- const { current: table } = React.useRef(
164
- HeadlessTemplatedRowTable.createTable({
165
- features: [
166
- HeadlessTemplatedRowTable.rowCount(),
167
- HeadlessTemplatedRowTable.filtering<TData, ServerFilterConfig<TData, FC>>(filterConfig),
168
- HeadlessTemplatedRowTable.sort<TData, ServerSortConfig<TData, SortKey>>(sortConfig),
169
- HeadlessTemplatedRowTable.search<TData>({} as any),
170
- HeadlessTemplatedRowTable.rowSelection<TData>(_options.getRowId),
171
- HeadlessTemplatedRowTable.pagination<TData>(pagination.limit ?? 25)
172
- ],
173
- rows: serverTable.rows,
174
- initialState: state,
175
- ...options
176
- })
177
- )
178
-
179
- table.state = React.useSyncExternalStore(
180
- table.subscribe,
181
- () => table.state,
182
- () => table.state
183
- )
184
-
185
- table.setRows(serverTable.rows)
186
-
187
- React.useEffect(() => {
188
- table.setOptions({ state, ...options })
189
- }, [state, options])
190
-
191
- return table
192
- }