playbook_ui 14.21.2.pre.alpha.PLAY2020sidebarfilterPOC8265 → 14.21.2.pre.alpha.PLAY2241tablestickycolumnsdatanotids8357

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/Components/CustomCell.tsx +1 -1
  3. data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +12 -4
  4. data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +25 -5
  5. data/app/pb_kits/playbook/pb_advanced_table/Components/VirtualizedTableView.tsx +36 -16
  6. data/app/pb_kits/playbook/pb_advanced_table/Context/AdvancedTableContext.tsx +18 -5
  7. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableActions.ts +37 -17
  8. data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableBody.tsx +3 -0
  9. data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableHeader.tsx +91 -40
  10. data/app/pb_kits/playbook/pb_advanced_table/Utilities/ColumnStylingHelper.ts +15 -0
  11. data/app/pb_kits/playbook/pb_advanced_table/Utilities/TableContainerStyles.ts +3 -2
  12. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +49 -4
  13. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +32 -18
  14. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +80 -1
  15. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_sort.html.erb +1 -1
  16. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_subrow_headers.html.erb +1 -1
  17. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color_rails.html.erb +1 -1
  18. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.jsx +51 -0
  19. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.md +7 -0
  20. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers.jsx +77 -0
  21. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers.md +1 -0
  22. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers_rails.html.erb +63 -0
  23. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers_rails.md +1 -0
  24. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_rails.html.erb +38 -0
  25. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_rails.md +7 -0
  26. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_infinite_scroll.md +3 -0
  27. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_loading.html.erb +1 -1
  28. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions.jsx +2 -2
  29. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions_rails.html.erb +3 -2
  30. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.html.erb +1 -1
  31. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +5 -0
  32. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +3 -0
  33. data/app/pb_kits/playbook/pb_advanced_table/index.js +21 -0
  34. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +1 -1
  35. data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +5 -0
  36. data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +2 -2
  37. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +33 -0
  38. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_columns.html.erb +8 -8
  39. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_columns_rails.md +1 -1
  40. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_left_columns.html.erb +12 -12
  41. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_left_columns_rails.md +2 -2
  42. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_right_columns.html.erb +12 -12
  43. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_right_columns_rails.md +2 -2
  44. data/app/pb_kits/playbook/pb_table/index.ts +4 -4
  45. data/dist/chunks/{_typeahead-CoOpeYom.js → _typeahead-BmfmVMFP.js} +3 -3
  46. data/dist/chunks/_weekday_stacked-DAC7yY_H.js +45 -0
  47. data/dist/chunks/lazysizes-B7xYodB-.js +1 -0
  48. data/dist/chunks/{lib-D7Va7yqa.js → lib-C2o6nu8G.js} +1 -1
  49. data/dist/chunks/{pb_form_validation-DSkdRDMf.js → pb_form_validation-EyK6DbAT.js} +1 -1
  50. data/dist/chunks/vendor.js +1 -1
  51. data/dist/playbook-doc.js +1 -1
  52. data/dist/playbook-rails-react-bindings.js +1 -1
  53. data/dist/playbook-rails.js +1 -1
  54. data/dist/playbook.css +1 -1
  55. data/lib/playbook/version.rb +1 -1
  56. metadata +17 -7
  57. data/dist/chunks/_weekday_stacked-BitxTXxk.js +0 -45
  58. data/dist/chunks/lazysizes-DHz07jlL.js +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 110027cf4b6fc7f41901f5d8a95eeee3cabd472a0f64d95870e83cac6155d44f
4
- data.tar.gz: 96c09cbb3a87483920bfd554a727e6663767bc3447cc2e363af5adcb09d6a5c7
3
+ metadata.gz: dcb903e9fac61dab1799f3b2480e1107fbe15b44cc240a7b47d203c96caecd13
4
+ data.tar.gz: d6114a181c65aa31d5c7f30bb729652ebb30b59ea8cf71946294c1d81c9206e2
5
5
  SHA512:
6
- metadata.gz: 14c26029d6c5254a2f62b2ea222c4cd5d06ffb3e6586d36d506dfaeed57c4f824e41418e9ce5533838e720d94c1257bace7f55a78da5a2d6ee6dd6768d066fdf
7
- data.tar.gz: 0cd5c076dfb211d337b2de733d3b4a94b09c208b00261b74bcd2eeae88c255b59cd6849025ad1f3548be3f1a910244d6b8e6f689dd413b210a8903855b656a90
6
+ metadata.gz: f322fb4c59317a1f6d71ed145305656f34c3461b585904996b63c5f8b76fc175374dd9c82fc5ff2ab7f4d8830da244c1208ed44a3b29ae1fd334b12c7086dd5d
7
+ data.tar.gz: 60dbd83fd98aab746396b84410bc7c52125fcced4261870642be768fd6ce1db41dbc61f59ff845bcb76edcdbda826a4839397d3d39cc114b0c7a6a16c2e222f3
@@ -47,7 +47,7 @@ export const CustomCell = ({
47
47
  <Flex
48
48
  alignItems="center"
49
49
  columnGap="xs"
50
- justify={"start"}
50
+ justify="start"
51
51
  orientation="row"
52
52
  >
53
53
  {
@@ -4,6 +4,7 @@ import { flexRender, Row, Cell } from "@tanstack/react-table"
4
4
 
5
5
  import { GenericObject } from "../../types"
6
6
  import { isChrome } from "../Utilities/BrowserCheck"
7
+ import { findColumnDefByAccessor } from "../Utilities/ColumnStylingHelper"
7
8
 
8
9
  import LoadingInline from "../../pb_loading_inline/_loading_inline"
9
10
  import Checkbox from "../../pb_checkbox/_checkbox"
@@ -25,13 +26,15 @@ const TableCellRenderer = ({
25
26
  collapsibleTrail = true,
26
27
  loading = false,
27
28
  stickyLeftColumn,
28
- columnPinning
29
+ columnPinning,
30
+ columnDefinitions,
29
31
  }: {
30
32
  row: Row<GenericObject>
31
33
  collapsibleTrail?: boolean
32
34
  loading?: boolean | string
33
35
  stickyLeftColumn?: string[]
34
36
  columnPinning: { left: string[] }
37
+ columnDefinitions?: {[key:string]:any}[]
35
38
  }) => {
36
39
  return (
37
40
  <>
@@ -49,10 +52,14 @@ const TableCellRenderer = ({
49
52
  })();
50
53
 
51
54
  const { column } = cell;
52
-
55
+
56
+ // Find the “owning” colDefinition by accessor. Needed for multi column logic
57
+ const colDef = findColumnDefByAccessor(columnDefinitions ?? [], column.id)
58
+ const cellAlignment = colDef?.columnStyling?.cellAlignment ?? "right"
59
+
53
60
  return (
54
61
  <td
55
- align="right"
62
+ align={cellAlignment}
56
63
  className={classnames(
57
64
  `${cell.id}-cell position_relative`,
58
65
  isChrome() ? "chrome-styles" : "",
@@ -117,7 +124,6 @@ export const RegularTableView = ({
117
124
 
118
125
  const columnPinning = table.getState().columnPinning || { left: [] };
119
126
  const columnDefinitions = table.options.meta?.columnDefinitions || [];
120
-
121
127
  // Row pinning
122
128
  function PinnedRow({ row }: { row: Row<any> }) {
123
129
  return (
@@ -137,6 +143,7 @@ export const RegularTableView = ({
137
143
  >
138
144
  <TableCellRenderer
139
145
  collapsibleTrail={collapsibleTrail}
146
+ columnDefinitions={columnDefinitions}
140
147
  columnPinning={columnPinning}
141
148
  loading={loading}
142
149
  row={row}
@@ -197,6 +204,7 @@ export const RegularTableView = ({
197
204
  )}
198
205
  <TableCellRenderer
199
206
  collapsibleTrail={collapsibleTrail}
207
+ columnDefinitions={columnDefinitions}
200
208
  columnPinning={columnPinning}
201
209
  loading={loading}
202
210
  row={row}
@@ -15,6 +15,7 @@ import Icon from "../../pb_icon/_icon"
15
15
  import { SortIconButton } from "./SortIconButton"
16
16
  import { ToggleIconButton } from "./ToggleIconButton"
17
17
  import { displayIcon } from "../Utilities/IconHelpers"
18
+ import { findColumnDefByAccessor } from "../Utilities/ColumnStylingHelper"
18
19
  import { updateExpandAndCollapseState } from "../Utilities/ExpansionControlHelpers"
19
20
 
20
21
  import { isChrome } from "../Utilities/BrowserCheck"
@@ -45,6 +46,7 @@ export const TableHeaderCell = ({
45
46
  table
46
47
  }: TableHeaderCellProps) => {
47
48
  const {
49
+ columnDefinitions,
48
50
  expanded,
49
51
  setExpanded,
50
52
  expandByDepth,
@@ -72,6 +74,18 @@ export const TableHeaderCell = ({
72
74
  header?.column.getToggleSortingHandler()(event)
73
75
  }
74
76
  }
77
+ const alignmentMap: Record<string, "start" | "center" | "end"> = {
78
+ left: "start",
79
+ center: "center",
80
+ right: "end",
81
+ };
82
+
83
+ // Look up the “owning” columnDefinition by accessor. Needed for multi column logic
84
+ const colDef = header
85
+ ? findColumnDefByAccessor(columnDefinitions, header.column.id)
86
+ : undefined
87
+
88
+ const headerAlignment = colDef?.columnStyling?.headerAlignment ?? colDef?.columnStyling?.headerAligment
75
89
 
76
90
  const isLeafColumn =
77
91
  header?.column.getLeafColumns().length === 1 &&
@@ -126,9 +140,15 @@ const isToggleExpansionEnabled =
126
140
  (enableToggleExpansion === "all" || "header") &&
127
141
  enableToggleExpansion !== "none"
128
142
 
129
- let justifyHeader:justifyTypes;
143
+ let justifyHeader: justifyTypes;
130
144
 
131
- if (header?.index === 0 && hasAnySubRows || (header?.index === 0 && inlineRowLoading) || (header?.index === 0 && isToggleExpansionEnabled)) {
145
+ if (headerAlignment && alignmentMap[headerAlignment]) {
146
+ justifyHeader = alignmentMap[headerAlignment];
147
+ } else if (
148
+ (header?.index === 0 && hasAnySubRows) ||
149
+ (header?.index === 0 && inlineRowLoading) ||
150
+ (header?.index === 0 && isToggleExpansionEnabled)
151
+ ) {
132
152
  justifyHeader = enableSorting ? "between" : "start";
133
153
  } else {
134
154
  justifyHeader = isLeafColumn ? "end" : "center";
@@ -165,7 +185,7 @@ const isToggleExpansionEnabled =
165
185
 
166
186
  return (
167
187
  <th
168
- align="right"
188
+ align={headerAlignment ? headerAlignment : "right"}
169
189
  className={cellClassName}
170
190
  colSpan={header?.colSpan}
171
191
  id={cellId}
@@ -253,8 +273,8 @@ const isToggleExpansionEnabled =
253
273
  tabIndex: 0,
254
274
  },
255
275
  })}
256
- justify={header?.index === 0 && enableSorting ? "between" : "none"}
257
- paddingLeft={enableSorting ? "xxs" : "xs"}
276
+ justify={header?.index === 0 && enableSorting ? "between" : headerAlignment ? alignmentMap[headerAlignment] : "none"}
277
+ paddingLeft={header?.index === 0 ? enableSorting ? "xxs" : "xs" : "none"}
258
278
  >
259
279
  <div>
260
280
  {flexRender(header?.column.columnDef.header, header?.getContext())}
@@ -1,6 +1,6 @@
1
- import React, { useContext, useLayoutEffect, useState, useEffect } from "react"
1
+ import React, { useContext, useLayoutEffect, useState, useEffect, useRef } from "react"
2
2
  import classnames from "classnames"
3
- import { flexRender, Cell } from "@tanstack/react-table"
3
+ import { flexRender, Cell, Row } from "@tanstack/react-table"
4
4
  import { VirtualItem } from "@tanstack/react-virtual"
5
5
 
6
6
  import { GenericObject } from "../../types"
@@ -10,6 +10,8 @@ import { getVirtualizedRowStyle } from "../Utilities/TableContainerStyles"
10
10
 
11
11
  import LoadingInline from "../../pb_loading_inline/_loading_inline"
12
12
  import Checkbox from "../../pb_checkbox/_checkbox"
13
+ import Detail from "../../pb_detail/_detail"
14
+ import Flex from "../../pb_flex/_flex"
13
15
 
14
16
  import { SubRowHeaderRow } from "../Components/SubRowHeaderRow"
15
17
  import { LoadingCell } from "../Components/LoadingCell"
@@ -20,11 +22,13 @@ import AdvancedTableContext from "../Context/AdvancedTableContext"
20
22
  type VirtualizedTableViewProps = {
21
23
  collapsibleTrail?: boolean
22
24
  subRowHeaders?: string[]
25
+ isFetching: boolean
23
26
  }
24
27
 
25
28
  export const VirtualizedTableView = ({
26
29
  collapsibleTrail = true,
27
30
  subRowHeaders,
31
+ isFetching,
28
32
  }: VirtualizedTableViewProps) => {
29
33
  const {
30
34
  enableToggleExpansion,
@@ -36,6 +40,7 @@ export const VirtualizedTableView = ({
36
40
  hasAnySubRows,
37
41
  virtualizer,
38
42
  flattenedItems,
43
+ totalAvailableCount,
39
44
  } = useContext(AdvancedTableContext)
40
45
 
41
46
  const columnPinning = table.getState().columnPinning || { left: [] };
@@ -121,19 +126,7 @@ export const VirtualizedTableView = ({
121
126
  }
122
127
 
123
128
  // Get virtual items
124
- let virtualItems: VirtualItem[] = [];
125
- try {
126
- virtualItems = virtualizer.getVirtualItems();
127
- } catch (err) {
128
- return (
129
- <tr>
130
- <td colSpan={table.getAllFlatColumns().length || 1}>
131
- Error loading virtualized data.
132
- </td>
133
- </tr>
134
- );
135
- }
136
-
129
+ const virtualItems: VirtualItem[] = virtualizer.getVirtualItems?.() || [];
137
130
  if (!virtualItems.length) {
138
131
  return (
139
132
  <tr>
@@ -143,6 +136,9 @@ export const VirtualizedTableView = ({
143
136
  </tr>
144
137
  );
145
138
  }
139
+
140
+ // Establish # of Parent Rows (so that Footer count does not include every single row)
141
+ const topLevelRowCount = table.getRowModel().flatRows.filter((row: Row<GenericObject>) => row.depth === 0).length;
146
142
 
147
143
  return (
148
144
  <>
@@ -177,7 +173,7 @@ export const VirtualizedTableView = ({
177
173
  if (item.type === 'row') {
178
174
  const row = item.row;
179
175
  const isExpandable = row.getIsExpanded();
180
- const rowHasNoChildren = row.original?.children && !row.original.children.length ? true : false;
176
+ const rowHasNoChildren = row.original?.children && !row.original.children.length;
181
177
  const rowBackground = isExpandable && ((!inlineRowLoading && row.getCanExpand()) || (inlineRowLoading && rowHasNoChildren));
182
178
  const rowColor = row.getIsSelected() ? "bg-row-selection" : rowBackground ? "bg-silver" : "bg-white";
183
179
 
@@ -266,6 +262,30 @@ export const VirtualizedTableView = ({
266
262
  );
267
263
  }
268
264
 
265
+ if (item.type === 'footer') {
266
+ // Render footer
267
+ return (
268
+ <tr
269
+ className="virtualized-table-row virtualized-footer"
270
+ key={`footer-row`}
271
+ style={virtualItemStyle}
272
+ >
273
+ <td colSpan={table.getAllFlatColumns().length}>
274
+ <Flex align="center"
275
+ justify="center"
276
+ >
277
+
278
+ {isFetching ? (
279
+ <LoadingInline />
280
+ ) : (
281
+ <Detail text={`Showing ${topLevelRowCount} of ${totalAvailableCount} rows`} />
282
+ )}
283
+ </Flex>
284
+ </td>
285
+ </tr>
286
+ )
287
+ }
288
+
269
289
  return null;
270
290
  })}
271
291
  </>
@@ -8,7 +8,7 @@ import { getRowHeightEstimate } from '../Utilities/TableContainerStyles';
8
8
  const AdvancedTableContext = createContext<any>({});
9
9
 
10
10
  interface FlattenedItem {
11
- type: 'header' | 'row' | 'loading';
11
+ type: 'header' | 'row' | 'loading' | 'footer';
12
12
  row: Row<GenericObject>;
13
13
  id: string;
14
14
  }
@@ -116,6 +116,17 @@ export const AdvancedTableProvider = ({ children, ...props }: {
116
116
  }
117
117
  });
118
118
 
119
+ const isFetching = props.isFetching || false;
120
+ const shouldAddFooter = table && !isFetching && tableRows.length > 0
121
+
122
+ if (shouldAddFooter) {
123
+ items.push({
124
+ type: 'footer',
125
+ row: {} as Row<GenericObject>,
126
+ id: `footer-row`,
127
+ });
128
+ }
129
+
119
130
  return items;
120
131
  }, [
121
132
  isVirtualized,
@@ -159,10 +170,11 @@ export const AdvancedTableProvider = ({ children, ...props }: {
159
170
  useEffect(() => {
160
171
  if (isVirtualized && virtualizer && table && containerRef.current) {
161
172
  // Force recalculation of all virtual items
173
+ virtualizer.setOptions({
174
+ ...virtualizer.options,
175
+ count: flattenedItems.length,
176
+ });
162
177
  virtualizer.measure();
163
-
164
- // Reset scroll position when sorting changes
165
- containerRef.current.scrollTop = 0;
166
178
  }
167
179
  }, [
168
180
  isVirtualized,
@@ -170,7 +182,8 @@ export const AdvancedTableProvider = ({ children, ...props }: {
170
182
  table,
171
183
  containerRef,
172
184
  JSON.stringify(table?.getState().sorting || []),
173
- JSON.stringify(table?.getState().expanded || {})
185
+ JSON.stringify(table?.getState().expanded || {}),
186
+ flattenedItems.length,
174
187
  ]);
175
188
 
176
189
  const contextValue = {
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect } from 'react';
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
2
  import { Row, RowPinningState } from "@tanstack/react-table";
3
3
  import { GenericObject } from "../../types";
4
4
  import { updateExpandAndCollapseState } from "../Utilities/ExpansionControlHelpers";
@@ -19,13 +19,21 @@ export function useTableActions({
19
19
  onRowSelectionChange
20
20
  }: UseTableActionsProps) {
21
21
 
22
+ // State to achieve 1 second delay before fetching more rows
23
+ const [bottomReached, setBottomReached] = useState(false)
24
+ const bottomTimeout = useRef<NodeJS.Timeout | null>(null)
25
+
22
26
  // Handle expand/collapse
23
27
  const handleExpandOrCollapse = useCallback(async (row: Row<GenericObject>) => {
24
- onToggleExpansionClick && onToggleExpansionClick(row);
25
- const expandedState = expanded;
26
- const targetParent = row?.parentId;
27
- const updatedRows = await updateExpandAndCollapseState(table.getRowModel(), expandedState, targetParent, undefined);
28
- setExpanded(updatedRows);
28
+ if (onToggleExpansionClick) onToggleExpansionClick(row)
29
+ const updatedExpandedState = await updateExpandAndCollapseState(
30
+ table.getRowModel(),
31
+ expanded,
32
+ row?.parentId,
33
+ undefined
34
+ )
35
+
36
+ setExpanded(updatedExpandedState)
29
37
  }, [expanded, setExpanded, onToggleExpansionClick, table]);
30
38
 
31
39
  // Handle pagination
@@ -35,20 +43,32 @@ export function useTableActions({
35
43
 
36
44
  // Handle scroll detection for infinite scroll/virtualization
37
45
  const fetchMoreOnBottomReached = useCallback((
38
- containerRefElement: HTMLDivElement | null,
39
- fetchNextPage: () => void,
40
- isFetching: boolean,
41
- totalFetched: number,
42
- totalDBRowCount: number
46
+ containerRef: HTMLDivElement | null,
47
+ fetchNextPage: () => void,
48
+ isFetching: boolean,
49
+ totalFetched: number,
50
+ totalDBRowCount: number
43
51
  ) => {
44
- if (containerRefElement) {
45
- const { scrollHeight, scrollTop, clientHeight } = containerRefElement;
46
- // If user scrolls near bottom, fetch more data
47
- if (scrollHeight - scrollTop - clientHeight < 500 && !isFetching && totalFetched < totalDBRowCount) {
48
- fetchNextPage();
52
+ if (!containerRef || isFetching || totalFetched >= totalDBRowCount) return
53
+ const { scrollTop, scrollHeight, clientHeight } = containerRef
54
+ const distanceFromBottom = scrollHeight - scrollTop - clientHeight
55
+ // If user scrolls near bottom, fetch more data after 1 second delay
56
+ if (distanceFromBottom < 50) {
57
+ if (!bottomReached) {
58
+ setBottomReached(true)
59
+ bottomTimeout.current = setTimeout(() => {
60
+ fetchNextPage()
61
+ setBottomReached(false)
62
+ }, 1000)
63
+ }
64
+ } else {
65
+ setBottomReached(false)
66
+ if (bottomTimeout.current) {
67
+ clearTimeout(bottomTimeout.current)
68
+ bottomTimeout.current = null
49
69
  }
50
70
  }
51
- }, []);
71
+ },[bottomReached]);
52
72
 
53
73
  // Update selection state
54
74
  useEffect(() => {
@@ -16,6 +16,7 @@ type TableBodyProps = {
16
16
  dark?: boolean
17
17
  id?: string
18
18
  subRowHeaders?: string[]
19
+ isFetching: boolean
19
20
  }
20
21
 
21
22
  export const TableBody = ({
@@ -24,6 +25,7 @@ export const TableBody = ({
24
25
  dark = false,
25
26
  id,
26
27
  subRowHeaders,
28
+ isFetching,
27
29
  ...props
28
30
  }: TableBodyProps) => {
29
31
 
@@ -63,6 +65,7 @@ export const TableBody = ({
63
65
  // Virtualized table view
64
66
  <VirtualizedTableView
65
67
  collapsibleTrail={collapsibleTrail}
68
+ isFetching={isFetching}
66
69
  subRowHeaders={subRowHeaders}
67
70
  />
68
71
  ) : (
@@ -40,9 +40,13 @@ export const TableHeader = ({
40
40
  showActionsBar,
41
41
  selectableRows,
42
42
  responsive,
43
- headerRef
43
+ headerRef,
44
+ virtualizedRows,
45
+ enableVirtualization,
44
46
  } = useContext(AdvancedTableContext)
45
47
 
48
+ const isVirtualized = virtualizedRows || enableVirtualization;
49
+
46
50
  const classes = classnames(
47
51
  buildCss("pb_advanced_table_header"),
48
52
  globalProps(props),
@@ -57,46 +61,93 @@ export const TableHeader = ({
57
61
  `${isChrome() ? "chrome-styles" : ""}`,
58
62
  `${responsive === "scroll" && "pinned-left"}`,
59
63
  );
64
+
65
+ const renderRegularTableHeader = () => (
66
+ <thead className={classes}
67
+ id={id}
68
+ >
69
+ {table.getHeaderGroups().map((headerGroup: HeaderGroup<GenericObject>, index: number) => (
70
+ <tr
71
+ key={`${headerGroup.id}-headerGroup`}
72
+ ref={index === 0 ? headerRef : null}
73
+ >
74
+ {!hasAnySubRows && selectableRows && (
75
+ <th className={customCellClassnames}>
76
+ <Checkbox
77
+ checked={table?.getIsAllRowsSelected()}
78
+ indeterminate={table?.getIsSomeRowsSelected()}
79
+ onChange={table?.getToggleAllRowsSelectedHandler()}
80
+ />
81
+ </th>
82
+ )}
83
+ {headerGroup.headers.map(header => {
84
+ const isPinnedLeft = columnPinning.left.includes(header.id)
85
+ return (
86
+ <TableHeaderCell
87
+ enableSorting={enableSorting}
88
+ enableToggleExpansion={enableToggleExpansion}
89
+ handleExpandOrCollapse={handleExpandOrCollapse}
90
+ header={header}
91
+ headerChildren={children}
92
+ isPinnedLeft={isPinnedLeft}
93
+ key={`${header.id}-header`}
94
+ loading={loading}
95
+ sortIcon={sortIcon}
96
+ table={table}
97
+ />
98
+ )
99
+ })}
100
+ </tr>
101
+ ))}
102
+ </thead>
103
+ );
104
+
105
+ const renderVirtualizedTableHeader = () => (
106
+ <thead
107
+ className={classes}
108
+ data-virtualized="true"
109
+ id={id}
110
+ >
111
+ {table.getHeaderGroups().map((headerGroup: HeaderGroup<GenericObject>, index: number) => (
112
+ <tr
113
+ className="virtualized-header-row-header"
114
+ key={`${headerGroup.id}-headerGroup-virtualized`}
115
+ ref={index === 0 ? headerRef : null}
116
+ >
117
+ {!hasAnySubRows && selectableRows && (
118
+ <th className={classnames(customCellClassnames, "virtualized-header-cell")}>
119
+ <Checkbox
120
+ checked={table?.getIsAllRowsSelected()}
121
+ indeterminate={table?.getIsSomeRowsSelected()}
122
+ onChange={table?.getToggleAllRowsSelectedHandler()}
123
+ />
124
+ </th>
125
+ )}
126
+ {headerGroup.headers.map(header => {
127
+ const isPinnedLeft = columnPinning.left.includes(header.id)
128
+ return (
129
+ <TableHeaderCell
130
+ enableSorting={enableSorting}
131
+ enableToggleExpansion={enableToggleExpansion}
132
+ handleExpandOrCollapse={handleExpandOrCollapse}
133
+ header={header}
134
+ headerChildren={children}
135
+ isPinnedLeft={isPinnedLeft}
136
+ isVirtualized
137
+ key={`${header.id}-header-virtualized`}
138
+ loading={loading}
139
+ sortIcon={sortIcon}
140
+ table={table}
141
+ />
142
+ )
143
+ })}
144
+ </tr>
145
+ ))}
146
+ </thead>
147
+ );
60
148
  return (
61
- <>
62
- <thead className={classes}
63
- id={id}
64
- >
65
- {/* Get the header groups (only one in this example) */}
66
- {table.getHeaderGroups().map((headerGroup: HeaderGroup<GenericObject>, index: number) => (
67
- <tr
68
- key={`${headerGroup.id}-headerGroup`}
69
- ref={index === 0 ? headerRef : null}
70
- >
71
- {!hasAnySubRows && selectableRows && (
72
- <th className={customCellClassnames}>
73
- <Checkbox
74
- checked={table?.getIsAllRowsSelected()}
75
- indeterminate={table?.getIsSomeRowsSelected()}
76
- onChange={table?.getToggleAllRowsSelectedHandler()}
77
- />
78
- </th>
79
- )}
80
- {headerGroup.headers.map(header => {
81
- const isPinnedLeft = columnPinning.left.includes(header.id)
82
- return (
83
- <TableHeaderCell
84
- enableSorting={enableSorting}
85
- enableToggleExpansion={enableToggleExpansion}
86
- handleExpandOrCollapse={handleExpandOrCollapse}
87
- header={header}
88
- headerChildren={children}
89
- isPinnedLeft={isPinnedLeft}
90
- key={`${header.id}-header`}
91
- loading={loading}
92
- sortIcon={sortIcon}
93
- table={table}
94
- />
95
- )
96
- })}
97
- </tr>
98
- ))}
99
- </thead>
149
+ <>
150
+ {isVirtualized ? renderVirtualizedTableHeader() : renderRegularTableHeader()}
100
151
  </>
101
152
  )
102
153
  }
@@ -0,0 +1,15 @@
1
+ export const findColumnDefByAccessor = (
2
+ defs: any[],
3
+ targetAccessor: string
4
+ ): any | undefined => {
5
+ for (const def of defs) {
6
+ if (def.accessor === targetAccessor) {
7
+ return def;
8
+ }
9
+ if (Array.isArray(def.columns) && def.columns.length) {
10
+ const found = findColumnDefByAccessor(def.columns, targetAccessor);
11
+ if (found) return found;
12
+ }
13
+ }
14
+ return undefined;
15
+ };
@@ -57,7 +57,6 @@ export const getVirtualizedContainerStyles = (maxHeight?: string): React.CSSProp
57
57
  position: 'absolute',
58
58
  top: 0,
59
59
  left: 0,
60
- width: '100%',
61
60
  height: '40px', // Match standard table row height
62
61
  transform: `translateY(${startPosition}px)`,
63
62
  tableLayout: 'fixed',
@@ -67,12 +66,14 @@ export const getVirtualizedContainerStyles = (maxHeight?: string): React.CSSProp
67
66
  /**
68
67
  * Get height estimates for different row types
69
68
  */
70
- export const getRowHeightEstimate = (rowType: 'header' | 'row' | 'loading') => {
69
+ export const getRowHeightEstimate = (rowType: 'header' | 'row' | 'loading' | 'footer') => {
71
70
  switch (rowType) {
72
71
  case 'header':
73
72
  return 40; // Header height
74
73
  case 'loading':
75
74
  return 30; // Loading indicator height
75
+ case 'footer':
76
+ return 40
76
77
  case 'row':
77
78
  default:
78
79
  return 40; // Standard row height - match this to your design system