@dmsi/wedgekit-react 0.0.82 → 0.0.84

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 (46) hide show
  1. package/dist/{chunk-6R2HCLEL.js → chunk-37TJJQL3.js} +2 -2
  2. package/dist/{chunk-B6PDZCU7.js → chunk-5GUW4DUY.js} +1 -1
  3. package/dist/{chunk-ATOEGP3V.js → chunk-CKSDMI2Q.js} +14 -7
  4. package/dist/{chunk-2DCVAATK.js → chunk-MQWWNAO3.js} +4 -4
  5. package/dist/{chunk-FOC6LTSX.js → chunk-UPBBOZM3.js} +1 -1
  6. package/dist/{chunk-SWA5WVQO.js → chunk-WNQ53SVY.js} +30 -0
  7. package/dist/components/DataGridCell.cjs +53 -43
  8. package/dist/components/DataGridCell.js +5 -5
  9. package/dist/components/Menu.cjs +17 -14
  10. package/dist/components/Menu.js +3 -3
  11. package/dist/components/MenuOption.cjs +10 -7
  12. package/dist/components/MenuOption.js +2 -2
  13. package/dist/components/Modal.cjs +18 -15
  14. package/dist/components/Modal.js +3 -3
  15. package/dist/components/NestedMenu.cjs +12 -9
  16. package/dist/components/NestedMenu.js +2 -2
  17. package/dist/components/PDFViewer.cjs +21 -18
  18. package/dist/components/PDFViewer.js +3 -3
  19. package/dist/components/ProjectBar.cjs +6 -3
  20. package/dist/components/ProjectBar.js +1 -1
  21. package/dist/components/TopBar.cjs +1 -1
  22. package/dist/components/TopBar.js +1 -1
  23. package/dist/components/{DataGrid.cjs → index.cjs} +1424 -1335
  24. package/dist/components/{DataGrid.js → index.js} +948 -883
  25. package/dist/components/useMenuSystem.cjs +20 -17
  26. package/dist/components/useMenuSystem.js +2 -2
  27. package/dist/hooks/index.cjs +34 -3
  28. package/dist/hooks/index.js +3 -1
  29. package/package.json +6 -1
  30. package/src/components/DataGrid/ColumnSelectorHeaderCell/ColumnSelectorMenuOption.tsx +32 -0
  31. package/src/components/DataGrid/ColumnSelectorHeaderCell/index.tsx +66 -0
  32. package/src/components/DataGrid/PinnedColumns.tsx +145 -0
  33. package/src/components/DataGrid/TableBody/LoadingCell.tsx +40 -0
  34. package/src/components/DataGrid/TableBody/TableBodyRow.tsx +129 -0
  35. package/src/components/DataGrid/TableBody/index.tsx +159 -0
  36. package/src/components/{DataGrid.tsx → DataGrid/index.tsx} +42 -678
  37. package/src/components/DataGrid/types.ts +86 -0
  38. package/src/components/DataGrid/utils.tsx +15 -0
  39. package/src/components/DataGridCell.tsx +37 -21
  40. package/src/components/TopBar.tsx +1 -1
  41. package/src/components/index.ts +20 -0
  42. package/src/hooks/index.ts +1 -0
  43. package/dist/chunk-AWQSSKCK.js +0 -32
  44. package/dist/components/useInfiniteScroll.cjs +0 -57
  45. package/dist/components/useInfiniteScroll.js +0 -8
  46. /package/src/{components → hooks}/useInfiniteScroll.tsx +0 -0
@@ -39,16 +39,19 @@ __export(useMenuSystem_exports, {
39
39
  useSubMenuSystem: () => useSubMenuSystem
40
40
  });
41
41
  module.exports = __toCommonJS(useMenuSystem_exports);
42
- var import_react3 = require("react");
42
+ var import_react4 = require("react");
43
43
 
44
44
  // src/hooks/useKeydown.ts
45
45
  var import_react = require("react");
46
46
 
47
- // src/hooks/useMatchesMedia.ts
47
+ // src/hooks/useInfiniteScroll.tsx
48
48
  var import_react2 = require("react");
49
+
50
+ // src/hooks/useMatchesMedia.ts
51
+ var import_react3 = require("react");
49
52
  var useMatchesMedia = (query) => {
50
- const [matches, setMatches] = (0, import_react2.useState)();
51
- (0, import_react2.useLayoutEffect)(() => {
53
+ const [matches, setMatches] = (0, import_react3.useState)();
54
+ (0, import_react3.useLayoutEffect)(() => {
52
55
  const mediaQueryList = window.matchMedia(query);
53
56
  const listener = () => setMatches(mediaQueryList.matches);
54
57
  listener();
@@ -61,17 +64,17 @@ var useMatchesMobile = () => useMatchesMedia("(width < 48rem)");
61
64
 
62
65
  // src/components/useMenuSystem.tsx
63
66
  function useSubMenuSystem(mobilePositionTo) {
64
- const [activeMenus, setActiveMenus] = (0, import_react3.useState)(
67
+ const [activeMenus, setActiveMenus] = (0, import_react4.useState)(
65
68
  {}
66
69
  );
67
- const [activeMenu, setActiveMenu] = (0, import_react3.useState)("");
68
- const [currentSubMenuLevel, setCurrentSubMenuLevel] = (0, import_react3.useState)(
70
+ const [activeMenu, setActiveMenu] = (0, import_react4.useState)("");
71
+ const [currentSubMenuLevel, setCurrentSubMenuLevel] = (0, import_react4.useState)(
69
72
  null
70
73
  );
71
- const menuRootRef = (0, import_react3.useRef)(null);
72
- const subMenuRefs = (0, import_react3.useRef)({});
73
- const hoverTimeoutRef = (0, import_react3.useRef)(null);
74
- const closeTimeoutRef = (0, import_react3.useRef)(null);
74
+ const menuRootRef = (0, import_react4.useRef)(null);
75
+ const subMenuRefs = (0, import_react4.useRef)({});
76
+ const hoverTimeoutRef = (0, import_react4.useRef)(null);
77
+ const closeTimeoutRef = (0, import_react4.useRef)(null);
75
78
  const isMobile = useMatchesMobile();
76
79
  const toggleMenu = (menuId, level) => {
77
80
  if (closeTimeoutRef.current) {
@@ -169,7 +172,7 @@ function useSubMenuSystem(mobilePositionTo) {
169
172
  const isMenuActive = (menuId, level) => {
170
173
  return activeMenus[level] === menuId;
171
174
  };
172
- (0, import_react3.useEffect)(() => {
175
+ (0, import_react4.useEffect)(() => {
173
176
  const handleClickOutside = (event) => {
174
177
  var _a;
175
178
  if (Object.keys(activeMenus).length === 0) return;
@@ -188,7 +191,7 @@ function useSubMenuSystem(mobilePositionTo) {
188
191
  document.removeEventListener("mousedown", handleClickOutside);
189
192
  };
190
193
  }, [activeMenus]);
191
- (0, import_react3.useEffect)(() => {
194
+ (0, import_react4.useEffect)(() => {
192
195
  return () => {
193
196
  if (hoverTimeoutRef.current) {
194
197
  clearTimeout(hoverTimeoutRef.current);
@@ -265,13 +268,13 @@ function useSubMenuSystem(mobilePositionTo) {
265
268
  };
266
269
  }
267
270
  function useMenuPosition(elementRef, position = "bottom", options) {
268
- const [menuPosition, setMenuPosition] = (0, import_react3.useState)({
271
+ const [menuPosition, setMenuPosition] = (0, import_react4.useState)({
269
272
  top: 0,
270
273
  left: 0,
271
274
  minWidth: 0
272
275
  });
273
276
  const isMobile = useMatchesMobile();
274
- const updatePosition = (0, import_react3.useCallback)(() => {
277
+ const updatePosition = (0, import_react4.useCallback)(() => {
275
278
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
276
279
  if (!(elementRef == null ? void 0 : elementRef.current)) return;
277
280
  const triggerRect = elementRef.current.getBoundingClientRect();
@@ -307,7 +310,7 @@ function useMenuPosition(elementRef, position = "bottom", options) {
307
310
  minWidth: triggerRect.width
308
311
  });
309
312
  }, [elementRef, position, options == null ? void 0 : options.menuRef, options == null ? void 0 : options.topOffset, isMobile]);
310
- (0, import_react3.useEffect)(() => {
313
+ (0, import_react4.useEffect)(() => {
311
314
  if (!(options == null ? void 0 : options.isOpen) || !(options == null ? void 0 : options.setIsOpen)) return;
312
315
  const handleClickOutside = (event) => {
313
316
  var _a, _b, _c, _d, _e;
@@ -333,7 +336,7 @@ function useMenuPosition(elementRef, position = "bottom", options) {
333
336
  options == null ? void 0 : options.menuRef,
334
337
  options == null ? void 0 : options.additionalRefs
335
338
  ]);
336
- (0, import_react3.useEffect)(() => {
339
+ (0, import_react4.useEffect)(() => {
337
340
  updatePosition();
338
341
  const resizeObserver = new ResizeObserver(updatePosition);
339
342
  if (elementRef == null ? void 0 : elementRef.current) {
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  useMenuPosition,
4
4
  useSubMenuSystem
5
- } from "../chunk-B6PDZCU7.js";
6
- import "../chunk-SWA5WVQO.js";
5
+ } from "../chunk-5GUW4DUY.js";
6
+ import "../chunk-WNQ53SVY.js";
7
7
  import "../chunk-ORMEWXMH.js";
8
8
  export {
9
9
  useMenuPosition,
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/hooks/index.ts
21
21
  var hooks_exports = {};
22
22
  __export(hooks_exports, {
23
+ useInfiniteScroll: () => useInfiniteScroll,
23
24
  useKeydown: () => useKeydown,
24
25
  useMatchesMedia: () => useMatchesMedia,
25
26
  useMatchesMobile: () => useMatchesMobile
@@ -55,11 +56,40 @@ function useKeydown(keys, isActive) {
55
56
  }, [keys, isActive]);
56
57
  }
57
58
 
58
- // src/hooks/useMatchesMedia.ts
59
+ // src/hooks/useInfiniteScroll.tsx
59
60
  var import_react2 = require("react");
61
+ function useInfiniteScroll({
62
+ containerRef,
63
+ onLoadMore,
64
+ isLoading,
65
+ offset = 50,
66
+ enabled = true
67
+ // ✅ Add this
68
+ }) {
69
+ (0, import_react2.useEffect)(() => {
70
+ if (!enabled) return;
71
+ const handleScroll = () => {
72
+ const el2 = containerRef.current;
73
+ if (!el2 || isLoading) return;
74
+ const { scrollTop, scrollHeight, clientHeight } = el2;
75
+ const isNearBottom = scrollTop + clientHeight >= scrollHeight - offset;
76
+ if (isNearBottom) {
77
+ onLoadMore();
78
+ }
79
+ };
80
+ const el = containerRef.current;
81
+ if (el) el.addEventListener("scroll", handleScroll);
82
+ return () => {
83
+ if (el) el.removeEventListener("scroll", handleScroll);
84
+ };
85
+ }, [containerRef, onLoadMore, isLoading, offset, enabled]);
86
+ }
87
+
88
+ // src/hooks/useMatchesMedia.ts
89
+ var import_react3 = require("react");
60
90
  var useMatchesMedia = (query) => {
61
- const [matches, setMatches] = (0, import_react2.useState)();
62
- (0, import_react2.useLayoutEffect)(() => {
91
+ const [matches, setMatches] = (0, import_react3.useState)();
92
+ (0, import_react3.useLayoutEffect)(() => {
63
93
  const mediaQueryList = window.matchMedia(query);
64
94
  const listener = () => setMatches(mediaQueryList.matches);
65
95
  listener();
@@ -71,6 +101,7 @@ var useMatchesMedia = (query) => {
71
101
  var useMatchesMobile = () => useMatchesMedia("(width < 48rem)");
72
102
  // Annotate the CommonJS export names for ESM import in node:
73
103
  0 && (module.exports = {
104
+ useInfiniteScroll,
74
105
  useKeydown,
75
106
  useMatchesMedia,
76
107
  useMatchesMobile
@@ -1,10 +1,12 @@
1
1
  import {
2
+ useInfiniteScroll,
2
3
  useKeydown,
3
4
  useMatchesMedia,
4
5
  useMatchesMobile
5
- } from "../chunk-SWA5WVQO.js";
6
+ } from "../chunk-WNQ53SVY.js";
6
7
  import "../chunk-ORMEWXMH.js";
7
8
  export {
9
+ useInfiniteScroll,
8
10
  useKeydown,
9
11
  useMatchesMedia,
10
12
  useMatchesMobile
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dmsi/wedgekit-react",
3
3
  "private": false,
4
- "version": "0.0.82",
4
+ "version": "0.0.84",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "build": "tsup",
@@ -22,6 +22,11 @@
22
22
  "import": "./dist/components/*.js",
23
23
  "require": "./dist/components/*.cjs"
24
24
  },
25
+ "./components": {
26
+ "types": "./src/components/index.ts",
27
+ "import": "./dist/components/index.js",
28
+ "require": "./dist/components/index.cjs"
29
+ },
25
30
  "./hooks": {
26
31
  "types": "./src/hooks/index.ts",
27
32
  "import": "./dist/hooks/index.js",
@@ -0,0 +1,32 @@
1
+ import { Column } from "@tanstack/react-table";
2
+ import { useState } from "react";
3
+ import { Checkbox, MenuOption } from "../..";
4
+
5
+ export function ColumnSelectorMenuOption<T>({
6
+ id,
7
+ column,
8
+ toggleColumnVisibility,
9
+ }: {
10
+ id?: string;
11
+ column: Column<T, unknown>;
12
+ toggleColumnVisibility: (id: string, isVisible: boolean) => void;
13
+ }) {
14
+ const [isVisible, setIsVisible] = useState(column.getIsVisible());
15
+ const label =
16
+ typeof column.columnDef.header === "string"
17
+ ? column.columnDef.header
18
+ : null;
19
+ return (
20
+ <MenuOption id={id} selected={isVisible} defaultChecked={isVisible}>
21
+ <Checkbox
22
+ id={id ? `${id}-checkbox` : undefined}
23
+ label={label ?? "Unknown"}
24
+ checked={isVisible}
25
+ onChange={(e) => {
26
+ setIsVisible(e.target.checked);
27
+ toggleColumnVisibility(column.id, e.target.checked);
28
+ }}
29
+ />
30
+ </MenuOption>
31
+ );
32
+ }
@@ -0,0 +1,66 @@
1
+ import { Table } from "@tanstack/react-table";
2
+ import { useRef, useState } from "react";
3
+ import { Button, DataGridCell, Icon, Menu } from "../..";
4
+ import { ColumnSelectorMenuOption } from "./ColumnSelectorMenuOption";
5
+
6
+ export function ColumnSelectorHeaderCell<T>({
7
+ id,
8
+ table,
9
+ toggleColumnVisibility,
10
+ resetColumnVisibility,
11
+ }: {
12
+ id?: string;
13
+ table: Table<T>;
14
+ toggleColumnVisibility: (id: string, isVisible: boolean) => void;
15
+ resetColumnVisibility: () => void;
16
+ }) {
17
+ const ref = useRef<HTMLElement>(null);
18
+ const [show, setShow] = useState(false);
19
+
20
+ return (
21
+ <DataGridCell
22
+ id={id}
23
+ width="48"
24
+ type="header"
25
+ color="text-secondary-normal"
26
+ ref={ref}
27
+ >
28
+ <Button
29
+ id={id ? `${id}-button` : undefined}
30
+ onClick={() => setShow((prev) => !prev)}
31
+ variant="navigation"
32
+ iconOnly
33
+ leftIcon={<Icon name="tune" />}
34
+ ></Button>
35
+ <Menu
36
+ id={id ? `${id}-menu` : undefined}
37
+ positionTo={ref}
38
+ position="bottom-right"
39
+ show={show}
40
+ setShow={setShow}
41
+ >
42
+ <Button
43
+ id={id ? `${id}-reset-button` : undefined}
44
+ variant="tertiary"
45
+ onClick={() => {
46
+ resetColumnVisibility();
47
+ setShow(false);
48
+ }}
49
+ >
50
+ Reset to default
51
+ </Button>
52
+ {table
53
+ .getAllColumns()
54
+ .filter((x) => x.columnDef.meta?.inVisibilityMenu)
55
+ .map((column) => (
56
+ <ColumnSelectorMenuOption
57
+ id={id ? `${id}-option-${column.id}` : undefined}
58
+ key={column.id}
59
+ column={column}
60
+ toggleColumnVisibility={toggleColumnVisibility}
61
+ />
62
+ ))}
63
+ </Menu>
64
+ </DataGridCell>
65
+ );
66
+ }
@@ -0,0 +1,145 @@
1
+ import { flexRender, RowData, Table } from "@tanstack/react-table";
2
+ import { Checkbox, DataCellHeader, DataGridCell, Subheader } from "..";
3
+ import { DataGridPagination } from "./types";
4
+ import clsx from "clsx";
5
+ import { getSortIcon } from "./utils";
6
+ import React from "react";
7
+ import { TableBody } from "./TableBody";
8
+ interface PinnedColumnsProps<TData extends RowData> {
9
+ pinDirection: "left" | "right";
10
+ table: Table<TData>;
11
+ tableContainerRef: React.RefObject<HTMLDivElement | null>;
12
+ pagination: DataGridPagination | undefined;
13
+ isLoadingMore: boolean;
14
+ hasMore: boolean;
15
+ showFilterRow: boolean;
16
+ enableColumnSelector?: boolean;
17
+ centerHeader?: boolean;
18
+ allSelectedAcrossPages?: boolean;
19
+ someSelectedAcrossPages?: boolean;
20
+ toggleSelectAllAcrossPages?: () => void;
21
+ }
22
+
23
+ export function PinnedColumns<TData>({
24
+ pinDirection = "left",
25
+ table,
26
+ centerHeader,
27
+ allSelectedAcrossPages,
28
+ someSelectedAcrossPages,
29
+ toggleSelectAllAcrossPages,
30
+ ...props
31
+ }: PinnedColumnsProps<TData>) {
32
+ const headerGroups =
33
+ pinDirection === "left"
34
+ ? table.getLeftHeaderGroups()
35
+ : table.getRightHeaderGroups();
36
+
37
+ return (
38
+ headerGroups[0]?.headers.length > 0 && (
39
+ <table
40
+ className={clsx(
41
+ "flex flex-col min-h-min sticky z-20 bg-background-grouped-primary-normal",
42
+ pinDirection === "left" ? "left-0" : "right-0",
43
+ )}
44
+ >
45
+ <thead className="sticky top-0 z-20 grid">
46
+ {headerGroups.map((headerGroup) => {
47
+ return (
48
+ <tr key={headerGroup.id} className="flex w-full">
49
+ {headerGroup.headers.map((header) => {
50
+ if (!header) {
51
+ return;
52
+ }
53
+
54
+ if (typeof header.column.columnDef.header === "string") {
55
+ const customHeaderWidth =
56
+ header.column.columnDef.meta?.headerWidth;
57
+
58
+ return (
59
+ <DataCellHeader
60
+ locked
61
+ key={header.id}
62
+ header={header}
63
+ center={centerHeader}
64
+ width={customHeaderWidth}
65
+ className={clsx(
66
+ header.column.getCanSort()
67
+ ? "cursor-pointer"
68
+ : "cursor-grab",
69
+ "group",
70
+ )}
71
+ >
72
+ <Subheader tall>
73
+ {header.column.columnDef.header}
74
+ </Subheader>
75
+
76
+ {getSortIcon(header.column.getIsSorted())}
77
+
78
+ {!header.column.getIsSorted() &&
79
+ header.column.getCanSort() &&
80
+ getSortIcon(
81
+ header.column.getNextSortingOrder(),
82
+ true,
83
+ )}
84
+
85
+ {header.column.getSortIndex() !== -1 &&
86
+ table.getState().sorting.length > 1 && (
87
+ <Subheader tall>
88
+ {header.column.getSortIndex() + 1}
89
+ </Subheader>
90
+ )}
91
+
92
+ {!header.column.columnDef.meta?.locked && (
93
+ <div
94
+ onDoubleClick={(e) => {
95
+ e.stopPropagation();
96
+ header.column.resetSize();
97
+ }}
98
+ onMouseDown={(e) => {
99
+ e.stopPropagation();
100
+ header.getResizeHandler()(e);
101
+ }}
102
+ onTouchStart={(e) => {
103
+ e.stopPropagation();
104
+ header.getResizeHandler()(e);
105
+ }}
106
+ className="absolute right-0 inset-y-0 w-px bg-black cursor-col-resize"
107
+ />
108
+ )}
109
+ </DataCellHeader>
110
+ );
111
+ }
112
+ return (
113
+ <React.Fragment key={header.id}>
114
+ {header.column.columnDef.meta?.checkbox ? (
115
+ <DataGridCell type="header" component="checkbox" locked>
116
+ <Checkbox
117
+ checked={allSelectedAcrossPages}
118
+ indeterminate={someSelectedAcrossPages}
119
+ onChange={toggleSelectAllAcrossPages}
120
+ />
121
+ </DataGridCell>
122
+ ) : (
123
+ flexRender(
124
+ header.column.columnDef.header,
125
+ header.getContext(),
126
+ )
127
+ )}
128
+ </React.Fragment>
129
+ );
130
+ })}
131
+ </tr>
132
+ );
133
+ })}
134
+ </thead>
135
+
136
+ <TableBody
137
+ {...props}
138
+ table={table}
139
+ locked={true}
140
+ pinDirection={pinDirection}
141
+ />
142
+ </table>
143
+ )
144
+ );
145
+ }
@@ -0,0 +1,40 @@
1
+ import { ColumnDef, RowData } from "@tanstack/react-table";
2
+ import { Checkbox, DataGridCell, Input } from "../..";
3
+
4
+ export function LoadingCell<T extends RowData>({
5
+ id,
6
+ column,
7
+ }: {
8
+ id?: string;
9
+ column: ColumnDef<T>;
10
+ }) {
11
+ const key = `loading-${column.id}`;
12
+ if (column.cell === "checkbox") {
13
+ return (
14
+ <DataGridCell id={id ? `${id}-${key}` : undefined} key={key}>
15
+ <Checkbox id={id ? `${id}-${key}-checkbox` : undefined} disabled />
16
+ </DataGridCell>
17
+ );
18
+ }
19
+ if (column.cell === "input") {
20
+ return (
21
+ <DataGridCell
22
+ id={id ? `${id}-${key}` : undefined}
23
+ key={key}
24
+ component="input"
25
+ >
26
+ <Input
27
+ id={id ? `${id}-${key}-input` : undefined}
28
+ align="left"
29
+ disabled
30
+ wrapperClassName="!rounded-none !border-0"
31
+ />
32
+ </DataGridCell>
33
+ );
34
+ }
35
+ return (
36
+ <DataGridCell id={id ? `${id}-${key}` : undefined} key={key}>
37
+ <div className="bg-linear-270 to-neutral-300/[24%] from-neutral-300/[12%] rounded-xs w-full max-w-25 h-6"></div>
38
+ </DataGridCell>
39
+ );
40
+ }
@@ -0,0 +1,129 @@
1
+ import clsx from "clsx";
2
+ import { Cell, flexRender, Row } from "@tanstack/react-table";
3
+ import { VirtualItem, Virtualizer } from "@tanstack/react-virtual";
4
+ import React from "react";
5
+ import { DataGridCell, DragAlongCell, Paragraph, Tooltip } from "../..";
6
+
7
+ interface TableBodyRowProps<T> {
8
+ id?: string;
9
+ columnVirtualizer?: Virtualizer<HTMLDivElement, HTMLTableCellElement>;
10
+ row: Row<T>;
11
+ rowVirtualizer: Virtualizer<HTMLDivElement, HTMLTableRowElement>;
12
+ virtualPaddingLeft?: number | undefined;
13
+ virtualPaddingRight?: number | undefined;
14
+ virtualRow: VirtualItem;
15
+ showFilterRow: boolean;
16
+ enableColumnSelector?: boolean;
17
+ locked?: boolean;
18
+ pinDirection?: "left" | "right";
19
+ }
20
+
21
+ export function TableBodyRow<T>({
22
+ id,
23
+ columnVirtualizer,
24
+ row,
25
+ // rowVirtualizer,
26
+ virtualPaddingLeft,
27
+ virtualPaddingRight,
28
+ virtualRow,
29
+ showFilterRow,
30
+ enableColumnSelector = false,
31
+ locked,
32
+ pinDirection,
33
+ }: TableBodyRowProps<T>) {
34
+ let visibleCells: Cell<T, unknown>[];
35
+
36
+ if (locked) {
37
+ visibleCells =
38
+ pinDirection === "left"
39
+ ? row.getLeftVisibleCells()
40
+ : row.getRightVisibleCells();
41
+ } else {
42
+ visibleCells = row.getCenterVisibleCells();
43
+ }
44
+
45
+ const virtualColumns = columnVirtualizer?.getVirtualItems() ?? [];
46
+ const columns = locked ? visibleCells : virtualColumns;
47
+
48
+ const isError =
49
+ typeof row.original === "object" &&
50
+ row.original !== null &&
51
+ "rowState" in row.original &&
52
+ row.original.rowState === "error";
53
+
54
+ const CellElement = locked ? DataGridCell : DragAlongCell;
55
+
56
+ return (
57
+ <tr
58
+ key={row.id}
59
+ className={clsx(
60
+ "transition-colors hover:bg-background-action-secondary-hover",
61
+ row.getIsSelected() && "!bg-background-action-secondary-hover",
62
+ isError && "!bg-background-action-critical-secondary-hover",
63
+ showFilterRow
64
+ ? "even:bg-background-grouped-primary-normal odd:bg-background-grouped-secondary-normal"
65
+ : "odd:bg-background-grouped-primary-normal even:bg-background-grouped-secondary-normal",
66
+ )}
67
+ style={{
68
+ display: "flex",
69
+ position: "absolute",
70
+ transform: `translateY(${
71
+ showFilterRow ? virtualRow.start + 40 : virtualRow.start
72
+ }px)`,
73
+ width: "100%",
74
+ }}
75
+ >
76
+ {!locked && virtualPaddingLeft ? (
77
+ // fake empty column to the left for virtualization scroll padding
78
+ <td style={{ display: "flex", width: virtualPaddingLeft }} />
79
+ ) : null}
80
+
81
+ {columns.map((column) => {
82
+ const cell = locked
83
+ ? (column as Cell<T, unknown>)
84
+ : visibleCells[(column as VirtualItem).index];
85
+
86
+ if (!cell) {
87
+ return;
88
+ }
89
+ const cellValue = cell.getValue();
90
+
91
+ return cell.column.columnDef.meta?.useCustomRenderer ? (
92
+ <React.Fragment key={cell.id}>
93
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
94
+ </React.Fragment>
95
+ ) : (
96
+ <CellElement
97
+ key={cell.id}
98
+ id={id ? `${id}-cell-${cell.id}` : undefined}
99
+ cell={cell}
100
+ className={clsx({
101
+ "justify-end": typeof cellValue === "number",
102
+ })}
103
+ width={cell.column.columnDef.meta?.headerWidth}
104
+ >
105
+ <Tooltip
106
+ id={id ? `${id}-tooltip-${cell.id}` : undefined}
107
+ showOnTruncation
108
+ message={cellValue as string}
109
+ position="bottom"
110
+ >
111
+ <Paragraph addOverflow tall>
112
+ {cellValue as React.ReactNode | string}
113
+ </Paragraph>
114
+ </Tooltip>
115
+ </CellElement>
116
+ );
117
+ })}
118
+
119
+ {!locked && virtualPaddingRight ? (
120
+ // fake empty column to the right for virtualization scroll padding
121
+ <td style={{ display: "flex", width: virtualPaddingRight }} />
122
+ ) : null}
123
+
124
+ {enableColumnSelector && !locked && (
125
+ <td className="p-2" style={{ width: "48.8px" }}></td>
126
+ )}
127
+ </tr>
128
+ );
129
+ }