react-science 16.0.0 → 17.0.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 (103) hide show
  1. package/lib/components/fullscreen/fullscreen_context.provider.d.ts +6 -2
  2. package/lib/components/fullscreen/fullscreen_context.provider.d.ts.map +1 -1
  3. package/lib/components/fullscreen/fullscreen_context.provider.js +1 -5
  4. package/lib/components/fullscreen/fullscreen_context.provider.js.map +1 -1
  5. package/lib/components/pdnd.cjs +29 -0
  6. package/lib/components/pdnd.cjs.map +1 -0
  7. package/lib/components/pdnd.d.cts +10 -0
  8. package/lib/components/pdnd.d.cts.map +1 -0
  9. package/lib/components/root-layout/css-reset/customPreflight.d.ts.map +1 -1
  10. package/lib/components/root-layout/css-reset/customPreflight.js +6 -0
  11. package/lib/components/root-layout/css-reset/customPreflight.js.map +1 -1
  12. package/lib/components/root-layout/root_layout.d.ts.map +1 -1
  13. package/lib/components/root-layout/root_layout.js +12 -5
  14. package/lib/components/root-layout/root_layout.js.map +1 -1
  15. package/lib/components/table/flash_row/flashed_row_context.d.ts +3 -0
  16. package/lib/components/table/flash_row/flashed_row_context.d.ts.map +1 -0
  17. package/lib/components/table/flash_row/flashed_row_context.js +10 -0
  18. package/lib/components/table/flash_row/flashed_row_context.js.map +1 -0
  19. package/lib/components/table/{reorder_rows/dropped_item_provider.d.ts → flash_row/flashed_row_provider.d.ts} +2 -2
  20. package/lib/components/table/flash_row/flashed_row_provider.d.ts.map +1 -0
  21. package/lib/components/table/flash_row/flashed_row_provider.js +8 -0
  22. package/lib/components/table/flash_row/flashed_row_provider.js.map +1 -0
  23. package/lib/components/table/flash_row/use_flash_row_effect.d.ts +3 -0
  24. package/lib/components/table/flash_row/use_flash_row_effect.d.ts.map +1 -0
  25. package/lib/components/table/flash_row/use_flash_row_effect.js +21 -0
  26. package/lib/components/table/flash_row/use_flash_row_effect.js.map +1 -0
  27. package/lib/components/table/index.d.ts +1 -0
  28. package/lib/components/table/index.d.ts.map +1 -1
  29. package/lib/components/table/index.js +1 -0
  30. package/lib/components/table/index.js.map +1 -1
  31. package/lib/components/table/preview_table.d.ts +5 -0
  32. package/lib/components/table/preview_table.d.ts.map +1 -0
  33. package/lib/components/table/preview_table.js +8 -0
  34. package/lib/components/table/preview_table.js.map +1 -0
  35. package/lib/components/table/preview_table_context.d.ts +9 -0
  36. package/lib/components/table/preview_table_context.d.ts.map +1 -0
  37. package/lib/components/table/preview_table_context.js +15 -0
  38. package/lib/components/table/preview_table_context.js.map +1 -0
  39. package/lib/components/table/reorder_rows/draggable_row_tr.d.ts +3 -3
  40. package/lib/components/table/reorder_rows/draggable_row_tr.d.ts.map +1 -1
  41. package/lib/components/table/reorder_rows/draggable_row_tr.js +15 -25
  42. package/lib/components/table/reorder_rows/draggable_row_tr.js.map +1 -1
  43. package/lib/components/table/reorder_rows/item_order_provider.d.ts.map +1 -1
  44. package/lib/components/table/reorder_rows/item_order_provider.js +1 -2
  45. package/lib/components/table/reorder_rows/item_order_provider.js.map +1 -1
  46. package/lib/components/table/reorder_rows/table_drag_row_handler.d.ts +3 -1
  47. package/lib/components/table/reorder_rows/table_drag_row_handler.d.ts.map +1 -1
  48. package/lib/components/table/reorder_rows/table_drag_row_handler.js +12 -2
  49. package/lib/components/table/reorder_rows/table_drag_row_handler.js.map +1 -1
  50. package/lib/components/table/reorder_rows/use_drop_monitor.d.ts.map +1 -1
  51. package/lib/components/table/reorder_rows/use_drop_monitor.js +5 -8
  52. package/lib/components/table/reorder_rows/use_drop_monitor.js.map +1 -1
  53. package/lib/components/table/table_body.d.ts.map +1 -1
  54. package/lib/components/table/table_body.js +3 -3
  55. package/lib/components/table/table_body.js.map +1 -1
  56. package/lib/components/table/table_root.d.ts +5 -1
  57. package/lib/components/table/table_root.d.ts.map +1 -1
  58. package/lib/components/table/table_root.js +44 -45
  59. package/lib/components/table/table_root.js.map +1 -1
  60. package/lib/components/table/table_row.d.ts +8 -0
  61. package/lib/components/table/table_row.d.ts.map +1 -0
  62. package/lib/components/table/table_row.js +10 -0
  63. package/lib/components/table/table_row.js.map +1 -0
  64. package/lib/components/table/table_scroll_container.d.ts +33 -0
  65. package/lib/components/table/table_scroll_container.d.ts.map +1 -0
  66. package/lib/components/table/table_scroll_container.js +33 -0
  67. package/lib/components/table/table_scroll_container.js.map +1 -0
  68. package/lib/components/table/table_utils.d.ts +13 -4
  69. package/lib/components/table/table_utils.d.ts.map +1 -1
  70. package/lib/components/table/use_table_scroll.d.ts +20 -1
  71. package/lib/components/table/use_table_scroll.d.ts.map +1 -1
  72. package/lib/components/table/use_table_scroll.js +16 -8
  73. package/lib/components/table/use_table_scroll.js.map +1 -1
  74. package/package.json +1 -1
  75. package/src/components/fullscreen/fullscreen_context.provider.tsx +7 -14
  76. package/src/components/pdnd.cts +20 -0
  77. package/src/components/root-layout/css-reset/customPreflight.ts +6 -0
  78. package/src/components/root-layout/root_layout.tsx +30 -18
  79. package/src/components/table/flash_row/flashed_row_context.ts +23 -0
  80. package/src/components/table/flash_row/flashed_row_provider.tsx +13 -0
  81. package/src/components/table/flash_row/use_flash_row_effect.ts +30 -0
  82. package/src/components/table/index.ts +1 -0
  83. package/src/components/table/preview_table.tsx +18 -0
  84. package/src/components/table/preview_table_context.ts +33 -0
  85. package/src/components/table/reorder_rows/draggable_row_tr.tsx +30 -38
  86. package/src/components/table/reorder_rows/item_order_provider.tsx +2 -2
  87. package/src/components/table/reorder_rows/table_drag_row_handler.tsx +25 -4
  88. package/src/components/table/reorder_rows/use_drop_monitor.ts +10 -8
  89. package/src/components/table/table_body.tsx +6 -8
  90. package/src/components/table/table_root.tsx +112 -123
  91. package/src/components/table/table_row.tsx +17 -0
  92. package/src/components/table/table_scroll_container.tsx +103 -0
  93. package/src/components/table/table_utils.ts +20 -4
  94. package/src/components/table/use_table_scroll.ts +48 -20
  95. package/lib/components/table/reorder_rows/dropped_item_context.d.ts +0 -3
  96. package/lib/components/table/reorder_rows/dropped_item_context.d.ts.map +0 -1
  97. package/lib/components/table/reorder_rows/dropped_item_context.js +0 -10
  98. package/lib/components/table/reorder_rows/dropped_item_context.js.map +0 -1
  99. package/lib/components/table/reorder_rows/dropped_item_provider.d.ts.map +0 -1
  100. package/lib/components/table/reorder_rows/dropped_item_provider.js +0 -8
  101. package/lib/components/table/reorder_rows/dropped_item_provider.js.map +0 -1
  102. package/src/components/table/reorder_rows/dropped_item_context.ts +0 -23
  103. package/src/components/table/reorder_rows/dropped_item_provider.tsx +0 -13
@@ -1,21 +1,29 @@
1
1
  import { HTMLTable } from '@blueprintjs/core';
2
2
  import styled from '@emotion/styled';
3
- import type { Header, RowData, TableOptions } from '@tanstack/react-table';
3
+ import type {
4
+ Header,
5
+ RowData,
6
+ Table as TanstackTable,
7
+ TableOptions,
8
+ } from '@tanstack/react-table';
4
9
  import {
5
10
  getCoreRowModel,
6
11
  getSortedRowModel,
7
12
  useReactTable,
8
13
  } from '@tanstack/react-table';
9
14
  import { useVirtualizer } from '@tanstack/react-virtual';
10
- import type { ReactNode, RefObject, TableHTMLAttributes } from 'react';
11
- import { useEffect, useRef } from 'react';
15
+ import type { RefObject, TableHTMLAttributes } from 'react';
16
+ import { useEffect, useMemo, useRef } from 'react';
17
+ import { match } from 'ts-pattern';
12
18
 
13
- import { DroppedItemProvider } from './reorder_rows/dropped_item_provider.js';
19
+ import { FlashedRowProvider } from './flash_row/flashed_row_provider.js';
20
+ import type { PreviewTablePropsContextValue } from './preview_table_context.js';
21
+ import { PreviewTablePropsContextProvider } from './preview_table_context.js';
14
22
  import { ItemOrderProvider } from './reorder_rows/item_order_provider.js';
15
- import { useDropMonitor } from './reorder_rows/use_drop_monitor.js';
16
23
  import { TableBody } from './table_body.js';
17
24
  import { TableHeader } from './table_header.js';
18
25
  import type { HeaderCellRenderer } from './table_header_cell.js';
26
+ import { ScrollContainer } from './table_scroll_container.js';
19
27
  import type {
20
28
  GetTdProps,
21
29
  Scroller,
@@ -25,33 +33,40 @@ import type {
25
33
  VirtualScroller,
26
34
  } from './table_utils.js';
27
35
  import { useTableColumns } from './use_table_columns.js';
28
- import { useTableScroll } from './use_table_scroll.js';
36
+
37
+ const nonForwardedProps = new Set<keyof TableProps<unknown>>([
38
+ 'striped',
39
+ 'stickyHeader',
40
+ 'noHeader',
41
+ ]) as Set<string>;
29
42
 
30
43
  const CustomHTMLTable = styled(HTMLTable, {
31
- shouldForwardProp: (prop) => prop !== 'striped' && prop !== 'stickyHeader',
32
- })<{ stickyHeader: boolean }>`
44
+ shouldForwardProp: (prop) => !nonForwardedProps.has(prop),
45
+ })<{ stickyHeader: boolean; noHeader: boolean }>`
33
46
  /* When using a sticky header, ensure that the borders are located below the last header instead of above the first row. */
34
- ${(props) => {
35
- if (!props.stickyHeader) return '';
36
-
37
- return `
47
+ ${(props) =>
48
+ match(props)
49
+ .with({ stickyHeader: false, noHeader: false }, () => '')
50
+ .otherwise(
51
+ (props) => `
38
52
  thead tr:last-child {
39
53
  box-shadow: inset 0 -1px #11141826;
40
54
  }
41
55
 
42
56
  tbody tr:first-of-type td {
43
- box-shadow: ${
44
- props.bordered
45
- ? 'inset 1px 0 0 0 #11141826 !important'
46
- : 'none !important'
47
- };
57
+ box-shadow: ${match(props)
58
+ .with(
59
+ { bordered: true },
60
+ () => 'inset 1px 0 0 0 #11141826 !important',
61
+ )
62
+ .otherwise(() => 'none !important')};
48
63
  }
49
64
 
50
65
  tbody tr:first-of-type td:first-of-type {
51
66
  box-shadow: none !important;
52
67
  }
53
- `;
54
- }}
68
+ `,
69
+ )}
55
70
 
56
71
  /* Blueprint's HTMLTable \`striped\` prop's implementation is based on nth-child odd / even */
57
72
  /* We cannot use that with virtualization, so we override its implementation here. */
@@ -88,6 +103,10 @@ interface TableBaseProps<TData extends RowData> {
88
103
  * Alternate between gray and white background for each row.
89
104
  */
90
105
  striped?: boolean;
106
+ /**
107
+ * Do not render the table header.
108
+ */
109
+ noHeader?: boolean;
91
110
  /**
92
111
  * Enable header rows which stick to the top of the table.
93
112
  */
@@ -134,7 +153,7 @@ interface TableBaseProps<TData extends RowData> {
134
153
  * A ref which will be set with a callback to scroll to a row in the
135
154
  * table, specified by the row's ID.
136
155
  */
137
- scrollToRowRef?: RefObject<VirtualScroller | ScrollToOptions | undefined>;
156
+ scrollToRowRef?: RefObject<VirtualScroller | Scroller | undefined>;
138
157
 
139
158
  /**
140
159
  * An accessor which should return a unique identifier for the row.
@@ -199,6 +218,7 @@ export function Table<TData extends RowData>(props: TableProps<TData>) {
199
218
  compact = false,
200
219
  interactive = false,
201
220
  striped = false,
221
+ noHeader = false,
202
222
  stickyHeader = false,
203
223
 
204
224
  reactTable,
@@ -212,9 +232,11 @@ export function Table<TData extends RowData>(props: TableProps<TData>) {
212
232
  getRowId,
213
233
  onRowOrderChanged,
214
234
  renderRowPreview,
235
+
236
+ scrollToRowRef,
215
237
  } = props;
216
238
  const isReorderingEnabled = !!onRowOrderChanged;
217
- const scrollElementRef = useRef<HTMLDivElement>(null);
239
+ const virtualScrollElementRef = useRef<HTMLDivElement>(null);
218
240
  const columnDefs = useTableColumns(columns);
219
241
  const table = useReactTable<TData>({
220
242
  ...reactTable,
@@ -228,13 +250,13 @@ export function Table<TData extends RowData>(props: TableProps<TData>) {
228
250
  const tanstackVirtualizer = useVirtualizer({
229
251
  enabled: virtualizeRows,
230
252
  count: data.length,
231
- getScrollElement: () => scrollElementRef.current,
253
+ getScrollElement: () => virtualScrollElementRef.current,
232
254
  estimateSize:
233
255
  (props.virtualizeRows && props.estimatedRowHeight) || (() => 0),
234
256
  overscan: 5,
235
257
  });
236
258
 
237
- const tableRef = useTableScroll(props, table, tanstackVirtualizer);
259
+ const tableRef = useRef<HTMLTableElement>(null);
238
260
 
239
261
  // Make the table component compatible with styled components libraries.
240
262
  let finalClassName: string | undefined;
@@ -251,113 +273,80 @@ export function Table<TData extends RowData>(props: TableProps<TData>) {
251
273
  props as TableProps<unknown>,
252
274
  tableHeaders as Array<Header<unknown, unknown>>,
253
275
  );
276
+
277
+ const tablePreviewProps = useMemo<PreviewTablePropsContextValue<TData>>(
278
+ () => ({
279
+ className,
280
+ getTdProps,
281
+ renderRowTr,
282
+ columns,
283
+ compact,
284
+ }),
285
+ [className, getTdProps, renderRowTr, columns, compact],
286
+ );
254
287
  return (
255
- <DroppedItemProvider>
256
- <ItemOrderProvider
257
- items={table.getRowModel().rows}
258
- onOrderChanged={(items) => {
259
- onRowOrderChanged?.(items.map((item) => item.original));
260
- }}
288
+ <FlashedRowProvider>
289
+ <PreviewTablePropsContextProvider
290
+ value={tablePreviewProps as PreviewTablePropsContextValue<unknown>}
261
291
  >
262
- <Container
263
- virtualizeRows={virtualizeRows}
264
- scrollRef={
265
- virtualizeRows
266
- ? scrollElementRef
267
- : props.scrollableElementRef || tableRef
268
- }
269
- isReorderingEnabled={isReorderingEnabled}
292
+ <ItemOrderProvider
293
+ items={table.getRowModel().rows}
294
+ onOrderChanged={(items) => {
295
+ onRowOrderChanged?.(items.map((item) => item.original));
296
+ }}
270
297
  >
271
- <CustomHTMLTable
272
- ref={tableRef}
273
- bordered={bordered}
274
- compact={compact}
275
- interactive={interactive}
276
- striped={striped}
277
- stickyHeader={stickyHeader}
278
- {...tableProps}
279
- className={finalClassName}
298
+ <ScrollContainer
299
+ virtualizeRows={virtualizeRows}
300
+ virtualizer={tanstackVirtualizer}
301
+ table={table as TanstackTable<unknown>}
302
+ scrollRef={
303
+ virtualizeRows
304
+ ? // When virtualized, ScrollContainer will render a scrollable element associated to this ref.
305
+ virtualScrollElementRef
306
+ : // When not virtualized, ScrollContainer does not render a container, only its children,
307
+ // And the scrollable element is provided by the user or by default, the <table> element.
308
+ props.scrollableElementRef || tableRef
309
+ }
310
+ scrollToRowRef={scrollToRowRef}
311
+ isReorderingEnabled={isReorderingEnabled}
280
312
  >
281
- <TableHeader
282
- sticky={stickyHeader}
283
- headers={tableHeaders}
284
- renderHeaderCell={renderHeaderCell}
285
- />
286
- <TableBody
287
- rows={table.getRowModel().rows}
288
- renderRowTr={renderRowTr}
289
- getTdProps={getTdProps}
290
- virtualizer={tanstackVirtualizer}
291
- virtualizeRows={virtualizeRows}
292
- renderRowPreview={renderRowPreview}
293
- isReorderingEnabled={isReorderingEnabled}
294
- />
295
- </CustomHTMLTable>
296
- </Container>
297
- </ItemOrderProvider>
298
- </DroppedItemProvider>
299
- );
300
- }
301
-
302
- const ScrollRefDiv = styled.div`
303
- height: 100%;
304
- overflow: auto;
305
- `;
306
-
307
- interface ContainerProps {
308
- virtualizeRows?: boolean;
309
- children: ReactNode;
310
- scrollRef: RefObject<Element>;
311
- isReorderingEnabled: boolean;
312
- }
313
-
314
- function Container(props: ContainerProps) {
315
- const { virtualizeRows, scrollRef, isReorderingEnabled, children } = props;
316
- if (virtualizeRows) {
317
- return (
318
- <ContainerVirtual
319
- scrollElementRef={scrollRef}
320
- enabled={isReorderingEnabled}
321
- >
322
- {children}
323
- </ContainerVirtual>
324
- );
325
- }
326
- return (
327
- <ContainerTable scrollElementRef={scrollRef} enabled={isReorderingEnabled}>
328
- {children}
329
- </ContainerTable>
313
+ <CustomHTMLTable
314
+ // Props which are not forwarded to the HTMLTable component
315
+ striped={striped}
316
+ noHeader={noHeader}
317
+ stickyHeader={stickyHeader}
318
+ // Props which are forwarded to the HTMLTable component
319
+ ref={tableRef}
320
+ bordered={bordered}
321
+ compact={compact}
322
+ interactive={interactive}
323
+ {...tableProps}
324
+ className={finalClassName}
325
+ >
326
+ {!noHeader && (
327
+ <TableHeader
328
+ sticky={stickyHeader}
329
+ headers={tableHeaders}
330
+ renderHeaderCell={renderHeaderCell}
331
+ />
332
+ )}
333
+ <TableBody
334
+ rows={table.getRowModel().rows}
335
+ renderRowTr={renderRowTr}
336
+ getTdProps={getTdProps}
337
+ virtualizer={tanstackVirtualizer}
338
+ virtualizeRows={virtualizeRows}
339
+ renderRowPreview={renderRowPreview}
340
+ isReorderingEnabled={isReorderingEnabled}
341
+ />
342
+ </CustomHTMLTable>
343
+ </ScrollContainer>
344
+ </ItemOrderProvider>
345
+ </PreviewTablePropsContextProvider>
346
+ </FlashedRowProvider>
330
347
  );
331
348
  }
332
349
 
333
- interface ContainerWithReorderingProps {
334
- scrollElementRef: RefObject<Element>;
335
- enabled: boolean;
336
- children: ReactNode;
337
- }
338
-
339
- function ContainerVirtual(props: ContainerWithReorderingProps) {
340
- const { scrollElementRef, enabled, children } = props;
341
- useDropMonitor(scrollElementRef, enabled);
342
-
343
- return (
344
- <ScrollRefDiv ref={scrollElementRef as RefObject<HTMLDivElement>}>
345
- {children}
346
- </ScrollRefDiv>
347
- );
348
- }
349
-
350
- interface ContainerTableProps {
351
- scrollElementRef: RefObject<Element>;
352
- enabled: boolean;
353
- children: ReactNode;
354
- }
355
- function ContainerTable(props: ContainerTableProps) {
356
- const { scrollElementRef, enabled, children } = props;
357
- useDropMonitor(scrollElementRef, enabled);
358
- return <>{children}</>;
359
- }
360
-
361
350
  function useCheckProps(
362
351
  props: TableProps<unknown>,
363
352
  headers: Array<Header<unknown, unknown>>,
@@ -0,0 +1,17 @@
1
+ import type { Row } from '@tanstack/react-table';
2
+ import type { JSX } from 'react';
3
+ import { useRef } from 'react';
4
+
5
+ import { useFlashRowEffect } from './flash_row/use_flash_row_effect.js';
6
+
7
+ export interface TableRowTrProps {
8
+ row: Row<unknown>;
9
+ trProps: JSX.IntrinsicElements['tr'];
10
+ }
11
+
12
+ export function TableRowTr(props: TableRowTrProps) {
13
+ const { row, trProps } = props;
14
+ const tableRowRef = useRef<HTMLTableRowElement>(null);
15
+ useFlashRowEffect(row.id, tableRowRef);
16
+ return <tr ref={tableRowRef} {...trProps} />;
17
+ }
@@ -0,0 +1,103 @@
1
+ import styled from '@emotion/styled';
2
+ import type { Virtualizer } from '@tanstack/react-virtual';
3
+ import type { Table as TanstackTable } from '@tanstack/table-core';
4
+ import type { ReactNode, RefObject } from 'react';
5
+
6
+ import { useDropMonitor } from './reorder_rows/use_drop_monitor.js';
7
+ import type { TableProps } from './table_root.js';
8
+ import { useTableScroll } from './use_table_scroll.js';
9
+
10
+ const ScrollRefDiv = styled.div`
11
+ height: 100%;
12
+ overflow: auto;
13
+ `;
14
+
15
+ interface ScrollContainerProps {
16
+ /**
17
+ * Whether the table rows are virtualized.
18
+ */
19
+ virtualizeRows?: boolean;
20
+ /**
21
+ * The tanstack virtualizer.
22
+ */
23
+ virtualizer: Virtualizer<HTMLDivElement, Element>;
24
+ /**
25
+ * The tanstack table.
26
+ */
27
+ table: TanstackTable<unknown>;
28
+ /**
29
+ * A ref to the effective scroll container.
30
+ */
31
+ scrollRef: RefObject<Element>;
32
+ /**
33
+ * The user provided ref to attach the scroll callbacks to.
34
+ * It is set by the ScrollContainer component if the table is virtualized.
35
+ * It is an external ref when the table is not virtualized.
36
+ */
37
+ scrollToRowRef?: TableProps<unknown>['scrollToRowRef'];
38
+ isReorderingEnabled: boolean;
39
+ children: ReactNode;
40
+ }
41
+
42
+ export function ScrollContainer(props: ScrollContainerProps) {
43
+ const {
44
+ virtualizeRows,
45
+ table,
46
+ virtualizer,
47
+ scrollRef,
48
+ scrollToRowRef,
49
+ isReorderingEnabled,
50
+ children,
51
+ } = props;
52
+ useTableScroll({
53
+ virtualizeRows,
54
+ table,
55
+ virtualizer,
56
+ scrollRef,
57
+ scrollToRowRef,
58
+ });
59
+ if (virtualizeRows) {
60
+ return (
61
+ <ContainerVirtual
62
+ scrollElementRef={scrollRef}
63
+ isReorderingEnabled={isReorderingEnabled}
64
+ >
65
+ {children}
66
+ </ContainerVirtual>
67
+ );
68
+ }
69
+ return (
70
+ <NoContainer scrollElementRef={scrollRef} enabled={isReorderingEnabled}>
71
+ {children}
72
+ </NoContainer>
73
+ );
74
+ }
75
+
76
+ interface ContainerWithReorderingProps {
77
+ scrollElementRef: RefObject<Element>;
78
+ isReorderingEnabled: boolean;
79
+ children: ReactNode;
80
+ }
81
+
82
+ function ContainerVirtual(props: ContainerWithReorderingProps) {
83
+ const { scrollElementRef, isReorderingEnabled, children } = props;
84
+ useDropMonitor(scrollElementRef, isReorderingEnabled);
85
+
86
+ return (
87
+ <ScrollRefDiv ref={scrollElementRef as RefObject<HTMLDivElement>}>
88
+ {children}
89
+ </ScrollRefDiv>
90
+ );
91
+ }
92
+
93
+ interface NoContainerProps {
94
+ scrollElementRef: RefObject<Element>;
95
+ enabled: boolean;
96
+ children: ReactNode;
97
+ }
98
+
99
+ function NoContainer(props: NoContainerProps) {
100
+ const { scrollElementRef, enabled, children } = props;
101
+ useDropMonitor(scrollElementRef, enabled);
102
+ return <>{children}</>;
103
+ }
@@ -18,7 +18,7 @@ export function createTableColumnHelper<TData extends RowData>() {
18
18
  return createColumnHelper<TData>();
19
19
  }
20
20
 
21
- export interface TableRowTrProps {
21
+ export interface TableRowTrRenderProps {
22
22
  className: string;
23
23
  style: CSSProperties;
24
24
  children: ReactNode;
@@ -27,7 +27,7 @@ export interface TableRowTrProps {
27
27
  }
28
28
 
29
29
  export type TableRowTrRenderer<TData extends RowData> = (
30
- trProps: TableRowTrProps,
30
+ trProps: TableRowTrRenderProps,
31
31
  row: Row<TData>,
32
32
  ) => ReactNode;
33
33
 
@@ -38,10 +38,26 @@ export type TableRowPreviewRenderer<TData extends RowData> = (
38
38
  row: Row<TData>,
39
39
  ) => ReactNode;
40
40
 
41
+ interface FlashRowOptions {
42
+ /**
43
+ * Whether to flash the row when scrolling into view.
44
+ * The option is only supported when there is no scroll animation, i.e. `behavior` is not `smooth`.
45
+ */
46
+ flashRow?: boolean;
47
+ }
48
+
49
+ export type TableScrollIntoViewOptions = ScrollIntoViewOptions &
50
+ FlashRowOptions;
51
+ export type TableVirtualScrollIntoViewOptions = ScrollToOptions &
52
+ FlashRowOptions;
53
+
41
54
  export interface VirtualScroller {
42
- scrollIntoView: (id: string, options?: ScrollToOptions) => void;
55
+ scrollIntoView: (
56
+ id: string,
57
+ options?: TableVirtualScrollIntoViewOptions,
58
+ ) => void;
43
59
  }
44
60
 
45
61
  export interface Scroller {
46
- scrollIntoView: (id: string, options?: ScrollIntoViewOptions) => void;
62
+ scrollIntoView: (id: string, options?: TableScrollIntoViewOptions) => void;
47
63
  }
@@ -1,26 +1,46 @@
1
1
  import type { RowData, Table } from '@tanstack/react-table';
2
- import type {
3
- ScrollToOptions,
4
- ScrollToOptions as VirtualScrollToOptions,
5
- Virtualizer,
6
- } from '@tanstack/react-virtual';
7
- import { useImperativeHandle, useRef } from 'react';
2
+ import type { Virtualizer } from '@tanstack/react-virtual';
3
+ import type { RefObject } from 'react';
4
+ import { useImperativeHandle } from 'react';
8
5
 
6
+ import { useFlashedRowContext } from './flash_row/flashed_row_context.js';
9
7
  import type { TableProps } from './table_root.js';
8
+ import type { TableVirtualScrollIntoViewOptions } from './table_utils.js';
10
9
 
11
- export function useTableScroll<TData extends RowData>(
12
- tableProps: TableProps<TData>,
13
- table: Table<TData>,
14
- virtualizer: Virtualizer<HTMLDivElement, Element>,
15
- ) {
16
- const tableRef = useRef<HTMLTableElement>(null);
17
- const { scrollToRowRef, virtualizeRows } = tableProps;
10
+ export function useTableScroll<TData extends RowData>(options: {
11
+ /**
12
+ * The user provided ref to attach the scroll callbacks to.
13
+ */
14
+ scrollToRowRef: TableProps<TData>['scrollToRowRef'];
15
+ /**
16
+ * Whether the table rows are virtualized.
17
+ */
18
+ virtualizeRows: TableProps<TData>['virtualizeRows'];
19
+ /**
20
+ * A ref to the effective scroll container.
21
+ */
22
+ scrollRef: RefObject<Element>;
23
+ /*
24
+ Tanstack table instance.
25
+ */
26
+ table: Table<TData>;
27
+ /**
28
+ * Tanstack virtualizer instance.
29
+ */
30
+ virtualizer: Virtualizer<HTMLDivElement, Element>;
31
+ }) {
32
+ const [, setFlashedRow] = useFlashedRowContext();
33
+ const { scrollToRowRef, virtualizeRows, scrollRef, table, virtualizer } =
34
+ options;
18
35
 
19
36
  // @ts-expect-error We cannot call the hook conditionally to satisfy the type checker
20
37
  useImperativeHandle(scrollToRowRef, () => {
21
38
  if (virtualizeRows) {
22
39
  return {
23
- scrollIntoView(id: string, options?: VirtualScrollToOptions) {
40
+ scrollIntoView(
41
+ id: string,
42
+ options?: TableVirtualScrollIntoViewOptions,
43
+ ) {
24
44
  const sortedRows = table.getRowModel().rows; // Get sorted rows
25
45
  const rowIndex = sortedRows.findIndex((row) => row.id === id); // Find the index of the row by ID
26
46
  if (rowIndex === -1) {
@@ -29,14 +49,21 @@ export function useTableScroll<TData extends RowData>(
29
49
  console.warn(
30
50
  `Could not scroll to row with ID ${id}, the row does not exist`,
31
51
  );
52
+ } else {
53
+ virtualizer.scrollToIndex(rowIndex, options);
54
+ if (options?.flashRow && options.behavior !== 'smooth') {
55
+ setFlashedRow(sortedRows[rowIndex].id);
56
+ }
32
57
  }
33
- virtualizer.scrollToIndex(rowIndex, options);
34
58
  },
35
59
  };
36
60
  } else {
37
61
  return {
38
- scrollIntoView(id: string, options?: ScrollToOptions) {
39
- const element = tableRef.current?.querySelector(
62
+ scrollIntoView(
63
+ id: string,
64
+ options?: TableVirtualScrollIntoViewOptions,
65
+ ) {
66
+ const element = scrollRef.current?.querySelector(
40
67
  `tr[data-row-id="${id}"]`,
41
68
  );
42
69
  if (!element) {
@@ -46,10 +73,11 @@ export function useTableScroll<TData extends RowData>(
46
73
  );
47
74
  }
48
75
  element?.scrollIntoView(options);
76
+ if (options?.flashRow && options.behavior !== 'smooth') {
77
+ setFlashedRow(id);
78
+ }
49
79
  },
50
80
  };
51
81
  }
52
- }, [virtualizeRows, table, virtualizer]);
53
-
54
- return tableRef;
82
+ }, [virtualizeRows, scrollRef, table, virtualizer, setFlashedRow]);
55
83
  }
@@ -1,3 +0,0 @@
1
- export declare const droppedItemContext: import("react").Context<[string | undefined, import("react").Dispatch<import("react").SetStateAction<string | undefined>>] | null>;
2
- export declare function useDroppedItemContext(): [string | undefined, import("react").Dispatch<import("react").SetStateAction<string | undefined>>];
3
- //# sourceMappingURL=dropped_item_context.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dropped_item_context.d.ts","sourceRoot":"","sources":["../../../../src/components/table/reorder_rows/dropped_item_context.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,kBAAkB,oIAE9B,CAAC;AAEF,wBAAgB,qBAAqB,uGAUpC"}
@@ -1,10 +0,0 @@
1
- import { createContext, useContext } from 'react';
2
- export const droppedItemContext = createContext(null);
3
- export function useDroppedItemContext() {
4
- const context = useContext(droppedItemContext);
5
- if (!context) {
6
- throw new Error('useDroppedItemId must be used within a DroppedItemProvider');
7
- }
8
- return context;
9
- }
10
- //# sourceMappingURL=dropped_item_context.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dropped_item_context.js","sourceRoot":"","sources":["../../../../src/components/table/reorder_rows/dropped_item_context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAOlD,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAC7C,IAAI,CACL,CAAC;AAEF,MAAM,UAAU,qBAAqB;IACnC,MAAM,OAAO,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAE/C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,4DAA4D,CAC7D,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"dropped_item_provider.d.ts","sourceRoot":"","sources":["../../../../src/components/table/reorder_rows/dropped_item_provider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAOjE"}
@@ -1,8 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { droppedItemContext } from './dropped_item_context.js';
4
- export function DroppedItemProvider(props) {
5
- const value = useState();
6
- return (_jsx(droppedItemContext.Provider, { value: value, children: props.children }));
7
- }
8
- //# sourceMappingURL=dropped_item_provider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dropped_item_provider.js","sourceRoot":"","sources":["../../../../src/components/table/reorder_rows/dropped_item_provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,UAAU,mBAAmB,CAAC,KAA8B;IAChE,MAAM,KAAK,GAAG,QAAQ,EAAU,CAAC;IACjC,OAAO,CACL,KAAC,kBAAkB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACtC,KAAK,CAAC,QAAQ,GACa,CAC/B,CAAC;AACJ,CAAC"}
@@ -1,23 +0,0 @@
1
- import type { useState } from 'react';
2
- import { createContext, useContext } from 'react';
3
-
4
- /**
5
- * ID of the dropped item
6
- */
7
- type DroppedItemContextValue = ReturnType<typeof useState<string>>;
8
-
9
- export const droppedItemContext = createContext<DroppedItemContextValue | null>(
10
- null,
11
- );
12
-
13
- export function useDroppedItemContext() {
14
- const context = useContext(droppedItemContext);
15
-
16
- if (!context) {
17
- throw new Error(
18
- 'useDroppedItemId must be used within a DroppedItemProvider',
19
- );
20
- }
21
-
22
- return context;
23
- }
@@ -1,13 +0,0 @@
1
- import { useState } from 'react';
2
- import type { ReactNode } from 'react';
3
-
4
- import { droppedItemContext } from './dropped_item_context.js';
5
-
6
- export function DroppedItemProvider(props: { children: ReactNode }) {
7
- const value = useState<string>();
8
- return (
9
- <droppedItemContext.Provider value={value}>
10
- {props.children}
11
- </droppedItemContext.Provider>
12
- );
13
- }