@dxos/react-ui-table 0.4.10-next.71cec10 → 0.5.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.
@@ -5,13 +5,13 @@
5
5
  import '@dxosTheme';
6
6
 
7
7
  import { Plugs, PlugsConnected } from '@phosphor-icons/react';
8
- import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
9
9
 
10
10
  import { create } from '@dxos/echo-schema';
11
11
  import { registerSignalRuntime } from '@dxos/echo-signals/react';
12
12
  import { PublicKey } from '@dxos/keys';
13
13
  import { faker } from '@dxos/random';
14
- import { AnchoredOverflow, Button, DensityProvider } from '@dxos/react-ui';
14
+ import { Button, DensityProvider } from '@dxos/react-ui';
15
15
  import { withTheme } from '@dxos/storybook-utils';
16
16
  import { range } from '@dxos/util';
17
17
 
@@ -116,9 +116,19 @@ const makeColumns = (onUpdate?: ValueUpdater<Item, any>): TableColumnDef<Item, a
116
116
  // Tests
117
117
  //
118
118
 
119
+ const MinimalTable = (props: any) => {
120
+ return (
121
+ <Table.Root>
122
+ <Table.Viewport classNames='fixed inset-0 overflow-auto'>
123
+ <Table.Table<any> {...props} />
124
+ </Table.Viewport>
125
+ </Table.Root>
126
+ );
127
+ };
128
+
119
129
  export default {
120
130
  title: 'react-ui-table/Table',
121
- component: Table,
131
+ component: MinimalTable,
122
132
  args: {
123
133
  header: true,
124
134
  keyAccessor: (item: Item) => item.publicKey.toHex(),
@@ -187,7 +197,6 @@ export const Empty = {
187
197
 
188
198
  export const Dynamic = {
189
199
  render: () => {
190
- const containerRef = useRef<HTMLDivElement | null>(null);
191
200
  const [items, setItems] = useState<Item[]>(createItems(50));
192
201
 
193
202
  useEffect(() => {
@@ -205,26 +214,27 @@ export const Dynamic = {
205
214
  const columns = useMemo(() => makeColumns(), []);
206
215
 
207
216
  return (
208
- <AnchoredOverflow.Root classNames='max-bs-[80dvh]' ref={containerRef}>
209
- <Table<Item>
210
- rowsSelectable='multi'
211
- keyAccessor={(row) => row.publicKey.toHex()}
212
- columns={columns}
213
- data={items}
214
- fullWidth
215
- footer
216
- stickyHeader
217
- getScrollElement={() => containerRef.current}
218
- />
219
- <AnchoredOverflow.Anchor />
220
- </AnchoredOverflow.Root>
217
+ <Table.Root>
218
+ <Table.Viewport classNames='fixed inset-0 overflow-auto'>
219
+ <Table.Table<Item>
220
+ role='grid'
221
+ rowsSelectable='multi'
222
+ keyAccessor={(row) => row.publicKey.toHex()}
223
+ columns={columns}
224
+ data={items}
225
+ fullWidth
226
+ stickyHeader
227
+ border
228
+ pinLastRow
229
+ />
230
+ </Table.Viewport>
231
+ </Table.Root>
221
232
  );
222
233
  },
223
234
  };
224
235
 
225
236
  export const Editable = {
226
237
  render: () => {
227
- const containerRef = useRef<HTMLDivElement | null>(null);
228
238
  const [items, setItems] = useState<Item[]>(createItems(200));
229
239
 
230
240
  const onUpdate: ValueUpdater<Item, any> = useCallback(
@@ -235,26 +245,27 @@ export const Editable = {
235
245
  const columns = useMemo(() => makeColumns(onUpdate), [onUpdate]);
236
246
 
237
247
  return (
238
- <div ref={containerRef} className='fixed inset-0 overflow-auto'>
239
- <Table<Item>
240
- role='grid'
241
- rowsSelectable='multi'
242
- keyAccessor={(row) => row.publicKey.toHex()}
243
- columns={columns}
244
- data={items}
245
- fullWidth
246
- stickyHeader
247
- border
248
- getScrollElement={() => containerRef.current}
249
- />
250
- </div>
248
+ <Table.Root>
249
+ <Table.Viewport classNames='fixed inset-0 overflow-auto'>
250
+ <Table.Table<Item>
251
+ role='grid'
252
+ rowsSelectable='multi'
253
+ keyAccessor={(row) => row.publicKey.toHex()}
254
+ columns={columns}
255
+ data={items}
256
+ fullWidth
257
+ stickyHeader
258
+ border
259
+ pinLastRow
260
+ />
261
+ </Table.Viewport>
262
+ </Table.Root>
251
263
  );
252
264
  },
253
265
  };
254
266
 
255
267
  export const PinnedLastRow = {
256
268
  render: () => {
257
- const containerRef = useRef<HTMLDivElement | null>(null);
258
269
  const [items, setItems] = useState<Item[]>(createItems(200));
259
270
 
260
271
  const onUpdate: ValueUpdater<Item, any> = useCallback(
@@ -265,27 +276,27 @@ export const PinnedLastRow = {
265
276
  const columns = useMemo(() => makeColumns(onUpdate), [onUpdate]);
266
277
 
267
278
  return (
268
- <div ref={containerRef} className='fixed inset-0 overflow-auto'>
269
- <Table<Item>
270
- role='grid'
271
- rowsSelectable='multi'
272
- keyAccessor={(row) => row.publicKey.toHex()}
273
- columns={columns}
274
- data={items}
275
- fullWidth
276
- stickyHeader
277
- border
278
- getScrollElement={() => containerRef.current}
279
- pinLastRow
280
- />
281
- </div>
279
+ <Table.Root>
280
+ <Table.Viewport classNames='fixed inset-0 overflow-auto'>
281
+ <Table.Table<Item>
282
+ role='grid'
283
+ rowsSelectable='multi'
284
+ keyAccessor={(row) => row.publicKey.toHex()}
285
+ columns={columns}
286
+ data={items}
287
+ fullWidth
288
+ stickyHeader
289
+ border
290
+ pinLastRow
291
+ />
292
+ </Table.Viewport>
293
+ </Table.Root>
282
294
  );
283
295
  },
284
296
  };
285
297
 
286
298
  export const InsertDelete = {
287
299
  render: () => {
288
- const containerRef = useRef<HTMLDivElement | null>(null);
289
300
  const [items, setItems] = useState<Item[]>(createItems(10));
290
301
 
291
302
  const onUpdate: ValueUpdater<Item, any> = useCallback(
@@ -319,20 +330,21 @@ export const InsertDelete = {
319
330
  <Button onClick={onDeleteFirst}>Delete first</Button>
320
331
  <Button onClick={onDeleteLast}>Delete last</Button>
321
332
  </div>
322
- <div ref={containerRef} className='fixed inset-0 top-[72px] overflow-auto'>
323
- <Table<Item>
324
- role='grid'
325
- rowsSelectable='multi'
326
- keyAccessor={(row) => row.publicKey.toHex()}
327
- columns={columns}
328
- data={items}
329
- fullWidth
330
- stickyHeader
331
- border
332
- getScrollElement={() => containerRef.current}
333
- pinLastRow
334
- />
335
- </div>
333
+ <Table.Root>
334
+ <Table.Viewport classNames='fixed inset-0 overflow-auto'>
335
+ <Table.Table<Item>
336
+ role='grid'
337
+ rowsSelectable='multi'
338
+ keyAccessor={(row) => row.publicKey.toHex()}
339
+ columns={columns}
340
+ data={items}
341
+ fullWidth
342
+ stickyHeader
343
+ border
344
+ pinLastRow
345
+ />
346
+ </Table.Viewport>
347
+ </Table.Root>
336
348
  </div>
337
349
  );
338
350
  },
@@ -340,7 +352,6 @@ export const InsertDelete = {
340
352
 
341
353
  export const Resizable = {
342
354
  render: () => {
343
- const containerRef = useRef<HTMLDivElement | null>(null);
344
355
  const [items, setItems] = useState<Item[]>(createItems(10));
345
356
 
346
357
  const onUpdate: ValueUpdater<Item, any> = useCallback(
@@ -349,25 +360,24 @@ export const Resizable = {
349
360
  );
350
361
 
351
362
  return (
352
- <div ref={containerRef} className='fixed inset-0 overflow-auto'>
353
- <Table<Item>
354
- rowsSelectable='multi'
355
- keyAccessor={(row) => row.publicKey.toHex()}
356
- columns={makeColumns(onUpdate)}
357
- data={items}
358
- fullWidth
359
- stickyHeader
360
- getScrollElement={() => containerRef.current}
361
- // onColumnResize={handleColumnResize}
362
- />
363
- </div>
363
+ <Table.Root>
364
+ <Table.Viewport classNames='fixed inset-0 overflow-auto'>
365
+ <Table.Table<Item>
366
+ rowsSelectable='multi'
367
+ keyAccessor={(row) => row.publicKey.toHex()}
368
+ columns={makeColumns(onUpdate)}
369
+ data={items}
370
+ fullWidth
371
+ stickyHeader
372
+ />
373
+ </Table.Viewport>
374
+ </Table.Root>
364
375
  );
365
376
  },
366
377
  };
367
378
 
368
379
  export const TenThousandRows = {
369
380
  render: () => {
370
- const containerRef = useRef<HTMLDivElement | null>(null);
371
381
  const [items, setItems] = useState<Item[]>(createItems(10000));
372
382
 
373
383
  const onUpdate: ValueUpdater<Item, any> = useCallback(
@@ -378,19 +388,20 @@ export const TenThousandRows = {
378
388
  const columns = useMemo(() => makeColumns(onUpdate), [onUpdate]);
379
389
 
380
390
  return (
381
- <div ref={containerRef} className='fixed inset-0 overflow-auto'>
382
- <Table<Item>
383
- role='grid'
384
- rowsSelectable='multi'
385
- keyAccessor={(row) => row.publicKey.toHex()}
386
- columns={columns}
387
- data={items}
388
- fullWidth
389
- stickyHeader
390
- border
391
- getScrollElement={() => containerRef.current}
392
- />
393
- </div>
391
+ <Table.Root>
392
+ <Table.Viewport classNames='fixed inset-0 overflow-auto'>
393
+ <Table.Table<Item>
394
+ role='grid'
395
+ rowsSelectable='multi'
396
+ keyAccessor={(row) => row.publicKey.toHex()}
397
+ columns={columns}
398
+ data={items}
399
+ fullWidth
400
+ stickyHeader
401
+ border
402
+ />{' '}
403
+ </Table.Viewport>
404
+ </Table.Root>
394
405
  );
395
406
  },
396
407
  };
@@ -475,25 +486,25 @@ export const RealTimeUpdates = {
475
486
  return () => clearInterval(interval);
476
487
  }, [periodicDeletions, deletionInterval, state.items]);
477
488
 
478
- const containerRef = useRef<HTMLDivElement | null>(null);
479
-
480
489
  const onUpdate = useCallback((...args: any[]) => {}, []);
481
490
  const columns = useMemo(() => makeColumns(onUpdate), []);
482
491
 
483
492
  return (
484
- <div ref={containerRef} className='fixed inset-0 overflow-auto'>
485
- <Table<Item>
486
- role='grid'
487
- rowsSelectable='multi'
488
- keyAccessor={(row) => row.publicKey.toHex()}
489
- columns={columns}
490
- data={state.items}
491
- fullWidth
492
- stickyHeader
493
- border
494
- getScrollElement={() => containerRef.current}
495
- />
496
- </div>
493
+ <Table.Root>
494
+ <Table.Viewport classNames='fixed inset-0 overflow-auto'>
495
+ <Table.Table<Item>
496
+ role='grid'
497
+ rowsSelectable='multi'
498
+ keyAccessor={(row) => row.publicKey.toHex()}
499
+ columns={columns}
500
+ data={state.items}
501
+ fullWidth
502
+ stickyHeader
503
+ border
504
+ pinLastRow
505
+ />
506
+ </Table.Viewport>
507
+ </Table.Root>
497
508
  );
498
509
  },
499
510
  };
@@ -1,6 +1,8 @@
1
1
  //
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
+ import { type Primitive } from '@radix-ui/react-primitive';
5
+ import { Slot } from '@radix-ui/react-slot';
4
6
  import {
5
7
  getCoreRowModel,
6
8
  getSortedRowModel,
@@ -11,21 +13,48 @@ import {
11
13
  getExpandedRowModel,
12
14
  type Row,
13
15
  } from '@tanstack/react-table';
14
- import { useVirtualizer, type VirtualizerOptions } from '@tanstack/react-virtual';
15
- import React, { Fragment, useCallback, useEffect, useState } from 'react';
16
+ import React, { type ComponentPropsWithoutRef, Fragment, useCallback, useEffect, useState, useContext } from 'react';
16
17
 
17
- import { log } from '@dxos/log';
18
- import { useDefaultValue } from '@dxos/react-ui';
18
+ import { type ThemedClassName, useDefaultValue } from '@dxos/react-ui';
19
+ import { mx } from '@dxos/react-ui-theme';
19
20
 
20
21
  import { TableBody } from './TableBody';
21
22
  import { type TypedTableProvider, TableProvider as UntypedTableProvider, useTableContext } from './TableContext';
22
23
  import { TableFooter } from './TableFooter';
23
24
  import { TableHead } from './TableHead';
25
+ import { TableRootContext, useTableRootContext } from './TableRootContext';
24
26
  import { type TableProps } from './props';
25
27
  import { useColumnResizing, usePinLastRow, useRowSelection } from '../../hooks';
26
28
  import { groupTh, tableRoot } from '../../theme';
27
29
 
28
- export const Table = <TData extends RowData>(props: TableProps<TData>) => {
30
+ type TableRootProps = { children: React.ReactNode };
31
+
32
+ const TableRoot = ({ children }: TableRootProps) => {
33
+ const contextValue = useTableRootContext();
34
+ return <TableRootContext.Provider value={contextValue}>{children}</TableRootContext.Provider>;
35
+ };
36
+
37
+ type TableViewportProps = ThemedClassName<ComponentPropsWithoutRef<typeof Primitive.div>> & {
38
+ asChild?: boolean;
39
+ };
40
+
41
+ const TableViewport = ({ children, classNames, asChild, ...props }: TableViewportProps) => {
42
+ const { scrollContextRef } = useContext(TableRootContext);
43
+
44
+ const classes = mx(classNames);
45
+
46
+ return asChild ? (
47
+ <Slot ref={scrollContextRef} {...props}>
48
+ {children}
49
+ </Slot>
50
+ ) : (
51
+ <div role='none' className={classes} ref={scrollContextRef} {...props}>
52
+ {children}
53
+ </div>
54
+ );
55
+ };
56
+
57
+ export const TablePrimitive = <TData extends RowData>(props: TableProps<TData>) => {
29
58
  const {
30
59
  role,
31
60
  onColumnResize,
@@ -34,7 +63,6 @@ export const Table = <TData extends RowData>(props: TableProps<TData>) => {
34
63
  rowsSelectable,
35
64
  debug,
36
65
  onDataSelectionChange,
37
- getScrollElement,
38
66
  pinLastRow,
39
67
  } = props;
40
68
 
@@ -111,15 +139,11 @@ export const Table = <TData extends RowData>(props: TableProps<TData>) => {
111
139
  onDataSelectionChange?.(Object.keys(rowSelection).map((id) => table.getRowModel().rowsById[id].original));
112
140
  }, [onDataSelectionChange, rowSelection, table]);
113
141
 
114
- usePinLastRow(pinLastRow, table, data, getScrollElement);
142
+ usePinLastRow(pinLastRow, table, data);
115
143
 
116
144
  // Create additional expansion column if all columns have fixed width.
117
145
  const expand = false; // columns.map((column) => column.size).filter(Boolean).length === columns?.length;
118
146
 
119
- if (!getScrollElement) {
120
- log.warn('Table: getScrollElement is not set. This is required for virtualized tables.');
121
- }
122
-
123
147
  return (
124
148
  <TableProvider
125
149
  {...props}
@@ -128,16 +152,17 @@ export const Table = <TData extends RowData>(props: TableProps<TData>) => {
128
152
  expand={expand}
129
153
  isGrid={role === 'grid' || role === 'treegrid'}
130
154
  >
131
- <TableImpl<TData> debug={false} getScrollElement={getScrollElement} {...props} />
155
+ <TableImpl<TData> debug={false} {...props} />
132
156
  </TableProvider>
133
157
  );
134
158
  };
135
159
 
160
+ // TODO(Zan): Smush this into the Table component.
136
161
  /**
137
162
  * Pure implementation of table outside of context set-up.
138
163
  */
139
164
  const TableImpl = <TData extends RowData>(props: TableProps<TData>) => {
140
- const { debug, classNames, getScrollElement, role, footer, grouping, fullWidth } = props;
165
+ const { debug, classNames, role, footer, grouping, fullWidth } = props;
141
166
  const { table } = useTableContext<TData>();
142
167
 
143
168
  if (debug) {
@@ -148,9 +173,10 @@ const TableImpl = <TData extends RowData>(props: TableProps<TData>) => {
148
173
  );
149
174
  }
150
175
 
151
- const virtualisable = getScrollElement !== undefined;
152
176
  const isResizingColumn = table.getState().columnSizingInfo.isResizingColumn;
153
177
 
178
+ const TableComponent = isResizingColumn ? MemoizedVirtualisedTableContent : VirtualizedTableContent;
179
+
154
180
  return (
155
181
  <table
156
182
  role={role}
@@ -159,44 +185,24 @@ const TableImpl = <TData extends RowData>(props: TableProps<TData>) => {
159
185
  >
160
186
  <TableHead />
161
187
 
162
- {grouping?.length !== 0 ? (
163
- virtualisable ? (
164
- isResizingColumn ? (
165
- <MemoizedVirtualisedTableContent getScrollElement={getScrollElement} />
166
- ) : (
167
- <VirtualizedTableContent getScrollElement={getScrollElement} />
168
- )
169
- ) : (
170
- <UnvirtualizedTableContent />
171
- )
172
- ) : (
173
- <GroupedTableContent />
174
- )}
188
+ {grouping?.length !== 0 ? <TableComponent /> : <GroupedTableContent />}
175
189
 
176
190
  {footer && <TableFooter />}
177
191
  </table>
178
192
  );
179
193
  };
180
194
 
181
- const UnvirtualizedTableContent = () => {
182
- const { table } = useTableContext();
183
-
184
- const centerRows = table.getCenterRows();
185
- const pinnedRows = table.getBottomRows();
186
-
187
- const rows = [...centerRows, ...pinnedRows];
188
-
189
- return <TableBody rows={rows} />;
190
- };
191
-
192
- const VirtualizedTableContent = ({
193
- getScrollElement,
194
- }: Pick<VirtualizerOptions<Element, Element>, 'getScrollElement'>) => {
195
+ const VirtualizedTableContent = () => {
195
196
  const { table } = useTableContext();
197
+ const { virtualizer, dispatch } = useContext(TableRootContext);
196
198
 
197
199
  const centerRows = table.getCenterRows();
198
200
  let pinnedRows = [] as Row<unknown>[];
199
201
 
202
+ useEffect(() => {
203
+ dispatch({ type: 'updateTableCount', count: centerRows.length });
204
+ }, [centerRows.length]);
205
+
200
206
  try {
201
207
  // TODO(zan): Work out how to sync the row pinning with rendering
202
208
  // This is a hack because the first call to this function after a row is deleted will throw an error
@@ -205,12 +211,7 @@ const VirtualizedTableContent = ({
205
211
  pinnedRows = table.getBottomRows();
206
212
  } catch (_) {} // Ignore error
207
213
 
208
- const { getTotalSize, getVirtualItems } = useVirtualizer({
209
- getScrollElement,
210
- count: centerRows.length,
211
- overscan: 8,
212
- estimateSize: () => 40,
213
- });
214
+ const { getTotalSize, getVirtualItems } = virtualizer;
214
215
 
215
216
  const virtualRows = getVirtualItems();
216
217
  const totalSize = getTotalSize();
@@ -218,10 +219,12 @@ const VirtualizedTableContent = ({
218
219
  const paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0;
219
220
  const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows?.[virtualRows.length - 1]?.end || 0) : 0;
220
221
 
221
- const rowsToRender = [...virtualRows.map((virtualRow) => centerRows[virtualRow.index]), ...pinnedRows];
222
+ const rowsToRender = [...virtualRows.map((virtualRow) => centerRows[virtualRow.index]), ...pinnedRows].filter(
223
+ (r) => !!r,
224
+ );
222
225
 
223
226
  return (
224
- <>
227
+ <Fragment>
225
228
  {paddingTop > 0 && (
226
229
  <tbody role='none'>
227
230
  <tr role='none'>
@@ -237,7 +240,7 @@ const VirtualizedTableContent = ({
237
240
  </tr>
238
241
  </tbody>
239
242
  )}
240
- </>
243
+ </Fragment>
241
244
  );
242
245
  };
243
246
 
@@ -274,3 +277,9 @@ const GroupedTableContent = () => {
274
277
  </>
275
278
  );
276
279
  };
280
+
281
+ export const Table = {
282
+ Root: TableRoot,
283
+ Table: TablePrimitive,
284
+ Viewport: TableViewport,
285
+ };
@@ -4,9 +4,10 @@
4
4
 
5
5
  import { useArrowNavigationGroup } from '@fluentui/react-tabster';
6
6
  import { flexRender, type Row, type RowData } from '@tanstack/react-table';
7
- import React from 'react';
7
+ import React, { useContext } from 'react';
8
8
 
9
9
  import { useTableContext } from './TableContext';
10
+ import { TableRootContext } from './TableRootContext';
10
11
  import { tbodyTr } from '../../theme';
11
12
  import { Cell } from '../Cell/Cell';
12
13
 
@@ -23,6 +24,8 @@ const TableBody = ({ rows }: TableBodyProps) => {
23
24
  const domAttributes = useArrowNavigationGroup({ axis: 'grid' });
24
25
  const canBeCurrent = !isGrid && !!onDatumClick;
25
26
 
27
+ const { virtualizer } = useContext(TableRootContext);
28
+
26
29
  return (
27
30
  <tbody {...(isGrid && domAttributes)}>
28
31
  {rows.map((row) => {
@@ -37,6 +40,8 @@ const TableBody = ({ rows }: TableBodyProps) => {
37
40
  <tr
38
41
  key={keyAccessor ? keyAccessor(row.original) : row.id}
39
42
  className={classNames}
43
+ data-index={row.index}
44
+ ref={virtualizer.measureElement}
40
45
  {...(isCurrent && { 'aria-current': 'location' })}
41
46
  {...(isSelected && { 'aria-selected': 'true' })}
42
47
  {...(canBeCurrent && {
@@ -0,0 +1,39 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { useVirtualizer } from '@tanstack/react-virtual';
6
+ import { createContext, useRef, useState } from 'react';
7
+
8
+ type TableRootContextActions = { type: 'updateTableCount'; count: number };
9
+
10
+ export const useTableRootContext = () => {
11
+ const scrollContextRef = useRef<HTMLDivElement>(null);
12
+ const [tableCount, setTableCount] = useState(0);
13
+
14
+ const virtualizer = useVirtualizer({
15
+ getScrollElement: () => scrollContextRef?.current ?? null,
16
+ count: tableCount,
17
+ overscan: 8,
18
+ estimateSize: () => 40,
19
+ });
20
+
21
+ const dispatch = (action: TableRootContextActions) => {
22
+ switch (action.type) {
23
+ case 'updateTableCount':
24
+ setTableCount(action.count);
25
+ break;
26
+
27
+ default:
28
+ break;
29
+ }
30
+ };
31
+
32
+ return { scrollContextRef, virtualizer, dispatch };
33
+ };
34
+
35
+ export type TableRootContextValue = ReturnType<typeof useTableRootContext>;
36
+
37
+ // Create the context without a default value.
38
+ // The expectation is that the provider will always supply a value, so no need to define a default here.
39
+ export const TableRootContext = createContext<TableRootContextValue>({} as TableRootContextValue);
@@ -4,3 +4,4 @@
4
4
 
5
5
  export * from './Table';
6
6
  export * from './props';
7
+ export * from './TableRootContext';
@@ -3,7 +3,6 @@
3
3
  //
4
4
 
5
5
  import { type RowData, type RowSelectionState, type Table, type VisibilityState } from '@tanstack/react-table';
6
- import { type VirtualizerOptions } from '@tanstack/react-virtual';
7
6
 
8
7
  import { type ClassNameValue } from '@dxos/react-ui-types';
9
8
 
@@ -31,30 +30,24 @@ export type TableCurrent<TData extends RowData> = Partial<{
31
30
  onDatumClick: (datum: TData) => void;
32
31
  }>;
33
32
 
34
- export type TableProps<
35
- TData extends RowData,
36
- ScrollElement extends Element | Window = Element,
37
- ItemElement extends Element = HTMLTableRowElement,
38
- > = TableFlags &
33
+ export type TableProps<TData extends RowData> = TableFlags &
39
34
  TableCurrent<TData> &
40
- Partial<
41
- {
42
- keyAccessor: KeyValue<TData>;
43
- data: TData[];
44
- columns: TableColumnDef<TData>[];
45
- onColumnResize: (state: Record<string, number>) => void;
46
- columnVisibility: VisibilityState;
47
- // Controllable row selection
48
- rowSelection: RowSelectionState;
49
- defaultRowSelection: RowSelectionState;
50
- onRowSelectionChange: (rowSelection: RowSelectionState) => void;
51
- // Derived from row selection
52
- onDataSelectionChange: (dataSelection: TData[]) => void;
53
- // `table` element props
54
- classNames: ClassNameValue;
55
- pinLastRow: boolean;
56
- } & Pick<VirtualizerOptions<ScrollElement, ItemElement>, 'getScrollElement'>
57
- >;
35
+ Partial<{
36
+ keyAccessor: KeyValue<TData>;
37
+ data: TData[];
38
+ columns: TableColumnDef<TData>[];
39
+ onColumnResize: (state: Record<string, number>) => void;
40
+ columnVisibility: VisibilityState;
41
+ // Controllable row selection
42
+ rowSelection: RowSelectionState;
43
+ defaultRowSelection: RowSelectionState;
44
+ onRowSelectionChange: (rowSelection: RowSelectionState) => void;
45
+ // Derived from row selection
46
+ onDataSelectionChange: (dataSelection: TData[]) => void;
47
+ // `table` element props
48
+ classNames: ClassNameValue;
49
+ pinLastRow: boolean;
50
+ }>;
58
51
 
59
52
  export type { RowSelectionState, VisibilityState, TableColumnDef, KeyValue };
60
53