bolt-table 0.1.12 → 0.1.13
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.
- package/dist/index.d.mts +83 -2
- package/dist/index.d.ts +83 -2
- package/dist/index.js +231 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +231 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -569,6 +569,38 @@ interface PaginationType {
|
|
|
569
569
|
*/
|
|
570
570
|
showTotal?: (total: number, range: [number, number]) => ReactNode;
|
|
571
571
|
}
|
|
572
|
+
/**
|
|
573
|
+
* Configuration for row pinning.
|
|
574
|
+
* When provided, the specified rows are rendered as sticky rows at the top
|
|
575
|
+
* and/or bottom of the table body, remaining visible during vertical scroll.
|
|
576
|
+
*
|
|
577
|
+
* Pinned rows are excluded from pagination — they are always visible regardless
|
|
578
|
+
* of which page the user is on. Filtering still applies: if a pinned row's key
|
|
579
|
+
* doesn't exist in the (filtered) data, it simply won't appear.
|
|
580
|
+
*
|
|
581
|
+
* @example
|
|
582
|
+
* // Pin two rows to the top and one to the bottom
|
|
583
|
+
* rowPinning={{ top: ['row-1', 'row-3'], bottom: ['row-10'] }}
|
|
584
|
+
*
|
|
585
|
+
* @example
|
|
586
|
+
* // Controlled pinning — manage pinned keys in parent state
|
|
587
|
+
* const [pinning, setPinning] = useState<RowPinningConfig>({ top: ['header-row'] });
|
|
588
|
+
* <BoltTable rowPinning={pinning} ... />
|
|
589
|
+
*/
|
|
590
|
+
interface RowPinningConfig {
|
|
591
|
+
/**
|
|
592
|
+
* Row keys to pin at the top of the table.
|
|
593
|
+
* These rows stick below the column headers during vertical scroll.
|
|
594
|
+
* Order is preserved — rows are rendered in the order listed here.
|
|
595
|
+
*/
|
|
596
|
+
top?: React.Key[];
|
|
597
|
+
/**
|
|
598
|
+
* Row keys to pin at the bottom of the table.
|
|
599
|
+
* These rows stick to the bottom of the visible area during vertical scroll.
|
|
600
|
+
* Order is preserved — rows are rendered in the order listed here.
|
|
601
|
+
*/
|
|
602
|
+
bottom?: React.Key[];
|
|
603
|
+
}
|
|
572
604
|
/**
|
|
573
605
|
* The base type for a row record in BoltTable.
|
|
574
606
|
* All row data objects must be indexable by string keys.
|
|
@@ -910,6 +942,17 @@ interface BoltTableProps<T extends DataRecord = DataRecord> {
|
|
|
910
942
|
* }}
|
|
911
943
|
*/
|
|
912
944
|
readonly rowSelection?: RowSelectionConfig<T>;
|
|
945
|
+
/**
|
|
946
|
+
* Row pinning configuration. When provided, the specified rows are rendered
|
|
947
|
+
* as sticky rows at the top and/or bottom of the table body.
|
|
948
|
+
*
|
|
949
|
+
* Pinned rows transcend pagination — they are always visible regardless of
|
|
950
|
+
* which page the user is on. Filtering still applies.
|
|
951
|
+
*
|
|
952
|
+
* @example
|
|
953
|
+
* rowPinning={{ top: ['row-1', 'row-3'], bottom: ['row-10'] }}
|
|
954
|
+
*/
|
|
955
|
+
readonly rowPinning?: RowPinningConfig;
|
|
913
956
|
/**
|
|
914
957
|
* Called when the user scrolls near the bottom of the table.
|
|
915
958
|
* Use this for infinite scroll / load-more behavior.
|
|
@@ -1106,6 +1149,11 @@ interface ClassNamesTypes {
|
|
|
1106
1149
|
* Does not affect the row itself, only the expanded panel.
|
|
1107
1150
|
*/
|
|
1108
1151
|
expandedRow?: string;
|
|
1152
|
+
/**
|
|
1153
|
+
* Applied to each pinned row's wrapper div (the grid row containing all cells).
|
|
1154
|
+
* Use this to add a border, background, or separator for pinned rows.
|
|
1155
|
+
*/
|
|
1156
|
+
pinnedRow?: string;
|
|
1109
1157
|
}
|
|
1110
1158
|
/**
|
|
1111
1159
|
* Inline style overrides for specific regions of BoltTable.
|
|
@@ -1146,6 +1194,17 @@ interface StylesTypes {
|
|
|
1146
1194
|
pinnedCell?: CSSProperties;
|
|
1147
1195
|
/** Inline styles for the expanded row content panel */
|
|
1148
1196
|
expandedRow?: CSSProperties;
|
|
1197
|
+
/** Inline styles for pinned row wrappers (the grid row containing all cells) */
|
|
1198
|
+
pinnedRow?: CSSProperties;
|
|
1199
|
+
/**
|
|
1200
|
+
* CSS color string for the background of pinned row cells.
|
|
1201
|
+
* Should be opaque so that scrolling content behind pinned rows is hidden.
|
|
1202
|
+
* Falls back to `pinnedBg` if not set.
|
|
1203
|
+
*
|
|
1204
|
+
* @example
|
|
1205
|
+
* pinnedRowBg: 'rgba(255, 255, 255, 0.98)'
|
|
1206
|
+
*/
|
|
1207
|
+
pinnedRowBg?: string;
|
|
1149
1208
|
/**
|
|
1150
1209
|
* CSS color string applied as the background of hovered rows.
|
|
1151
1210
|
* Defaults to `hsl(var(--muted) / 0.5)` if omitted.
|
|
@@ -1210,7 +1269,7 @@ interface StylesTypes {
|
|
|
1210
1269
|
* autoHeight={false}
|
|
1211
1270
|
* />
|
|
1212
1271
|
*/
|
|
1213
|
-
declare function BoltTable<T extends DataRecord = DataRecord>({ columns: initialColumns, data, rowHeight, expandedRowHeight, maxExpandedRowHeight, accentColor, className, classNames, styles, gripIcon, hideGripIcon, icons, pagination, onPaginationChange, onColumnResize, onColumnOrderChange, onColumnPin, onColumnHide, rowSelection, expandable, rowKey, onEndReached, onEndReachedThreshold, isLoading, onSortChange, onFilterChange, columnContextMenuItems, autoHeight, layoutLoading, emptyRenderer, }: BoltTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
1272
|
+
declare function BoltTable<T extends DataRecord = DataRecord>({ columns: initialColumns, data, rowHeight, expandedRowHeight, maxExpandedRowHeight, accentColor, className, classNames, styles, gripIcon, hideGripIcon, icons, pagination, onPaginationChange, onColumnResize, onColumnOrderChange, onColumnPin, onColumnHide, rowSelection, rowPinning, expandable, rowKey, onEndReached, onEndReachedThreshold, isLoading, onSortChange, onFilterChange, columnContextMenuItems, autoHeight, layoutLoading, emptyRenderer, }: BoltTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
1214
1273
|
|
|
1215
1274
|
/**
|
|
1216
1275
|
* Props for the DraggableHeader component.
|
|
@@ -1569,6 +1628,28 @@ interface TableBodyProps {
|
|
|
1569
1628
|
* maxExpandedRowHeight={300}
|
|
1570
1629
|
*/
|
|
1571
1630
|
maxExpandedRowHeight?: number;
|
|
1631
|
+
/**
|
|
1632
|
+
* Rows pinned to the top of the table body.
|
|
1633
|
+
* Rendered as non-virtualized sticky rows below the column headers.
|
|
1634
|
+
*/
|
|
1635
|
+
pinnedTopData?: DataRecord[];
|
|
1636
|
+
/**
|
|
1637
|
+
* Rows pinned to the bottom of the table body.
|
|
1638
|
+
* Rendered as non-virtualized sticky rows at the bottom of the visible area.
|
|
1639
|
+
*/
|
|
1640
|
+
pinnedBottomData?: DataRecord[];
|
|
1641
|
+
/**
|
|
1642
|
+
* The CSS `gridTemplateColumns` string matching the parent grid.
|
|
1643
|
+
* Needed for pinned row sub-grids to align with the main column layout.
|
|
1644
|
+
*/
|
|
1645
|
+
gridTemplateColumns?: string;
|
|
1646
|
+
/**
|
|
1647
|
+
* Height of the column header row in pixels.
|
|
1648
|
+
* Used to position the sticky top pinned rows below the headers.
|
|
1649
|
+
*
|
|
1650
|
+
* @default 36
|
|
1651
|
+
*/
|
|
1652
|
+
headerHeight?: number;
|
|
1572
1653
|
}
|
|
1573
1654
|
/**
|
|
1574
1655
|
* TableBody — the virtualized body renderer for BoltTable.
|
|
@@ -1590,4 +1671,4 @@ interface TableBodyProps {
|
|
|
1590
1671
|
*/
|
|
1591
1672
|
declare const TableBody: React$1.FC<TableBodyProps>;
|
|
1592
1673
|
|
|
1593
|
-
export { BoltTable, type BoltTableIcons, type ColumnContextMenuItem, type ColumnType, type DataRecord, DraggableHeader, type ExpandableConfig, type PaginationType, ResizeOverlay, type RowSelectionConfig, type SortDirection, TableBody };
|
|
1674
|
+
export { BoltTable, type BoltTableIcons, type ColumnContextMenuItem, type ColumnType, type DataRecord, DraggableHeader, type ExpandableConfig, type PaginationType, ResizeOverlay, type RowPinningConfig, type RowSelectionConfig, type SortDirection, TableBody };
|
package/dist/index.d.ts
CHANGED
|
@@ -569,6 +569,38 @@ interface PaginationType {
|
|
|
569
569
|
*/
|
|
570
570
|
showTotal?: (total: number, range: [number, number]) => ReactNode;
|
|
571
571
|
}
|
|
572
|
+
/**
|
|
573
|
+
* Configuration for row pinning.
|
|
574
|
+
* When provided, the specified rows are rendered as sticky rows at the top
|
|
575
|
+
* and/or bottom of the table body, remaining visible during vertical scroll.
|
|
576
|
+
*
|
|
577
|
+
* Pinned rows are excluded from pagination — they are always visible regardless
|
|
578
|
+
* of which page the user is on. Filtering still applies: if a pinned row's key
|
|
579
|
+
* doesn't exist in the (filtered) data, it simply won't appear.
|
|
580
|
+
*
|
|
581
|
+
* @example
|
|
582
|
+
* // Pin two rows to the top and one to the bottom
|
|
583
|
+
* rowPinning={{ top: ['row-1', 'row-3'], bottom: ['row-10'] }}
|
|
584
|
+
*
|
|
585
|
+
* @example
|
|
586
|
+
* // Controlled pinning — manage pinned keys in parent state
|
|
587
|
+
* const [pinning, setPinning] = useState<RowPinningConfig>({ top: ['header-row'] });
|
|
588
|
+
* <BoltTable rowPinning={pinning} ... />
|
|
589
|
+
*/
|
|
590
|
+
interface RowPinningConfig {
|
|
591
|
+
/**
|
|
592
|
+
* Row keys to pin at the top of the table.
|
|
593
|
+
* These rows stick below the column headers during vertical scroll.
|
|
594
|
+
* Order is preserved — rows are rendered in the order listed here.
|
|
595
|
+
*/
|
|
596
|
+
top?: React.Key[];
|
|
597
|
+
/**
|
|
598
|
+
* Row keys to pin at the bottom of the table.
|
|
599
|
+
* These rows stick to the bottom of the visible area during vertical scroll.
|
|
600
|
+
* Order is preserved — rows are rendered in the order listed here.
|
|
601
|
+
*/
|
|
602
|
+
bottom?: React.Key[];
|
|
603
|
+
}
|
|
572
604
|
/**
|
|
573
605
|
* The base type for a row record in BoltTable.
|
|
574
606
|
* All row data objects must be indexable by string keys.
|
|
@@ -910,6 +942,17 @@ interface BoltTableProps<T extends DataRecord = DataRecord> {
|
|
|
910
942
|
* }}
|
|
911
943
|
*/
|
|
912
944
|
readonly rowSelection?: RowSelectionConfig<T>;
|
|
945
|
+
/**
|
|
946
|
+
* Row pinning configuration. When provided, the specified rows are rendered
|
|
947
|
+
* as sticky rows at the top and/or bottom of the table body.
|
|
948
|
+
*
|
|
949
|
+
* Pinned rows transcend pagination — they are always visible regardless of
|
|
950
|
+
* which page the user is on. Filtering still applies.
|
|
951
|
+
*
|
|
952
|
+
* @example
|
|
953
|
+
* rowPinning={{ top: ['row-1', 'row-3'], bottom: ['row-10'] }}
|
|
954
|
+
*/
|
|
955
|
+
readonly rowPinning?: RowPinningConfig;
|
|
913
956
|
/**
|
|
914
957
|
* Called when the user scrolls near the bottom of the table.
|
|
915
958
|
* Use this for infinite scroll / load-more behavior.
|
|
@@ -1106,6 +1149,11 @@ interface ClassNamesTypes {
|
|
|
1106
1149
|
* Does not affect the row itself, only the expanded panel.
|
|
1107
1150
|
*/
|
|
1108
1151
|
expandedRow?: string;
|
|
1152
|
+
/**
|
|
1153
|
+
* Applied to each pinned row's wrapper div (the grid row containing all cells).
|
|
1154
|
+
* Use this to add a border, background, or separator for pinned rows.
|
|
1155
|
+
*/
|
|
1156
|
+
pinnedRow?: string;
|
|
1109
1157
|
}
|
|
1110
1158
|
/**
|
|
1111
1159
|
* Inline style overrides for specific regions of BoltTable.
|
|
@@ -1146,6 +1194,17 @@ interface StylesTypes {
|
|
|
1146
1194
|
pinnedCell?: CSSProperties;
|
|
1147
1195
|
/** Inline styles for the expanded row content panel */
|
|
1148
1196
|
expandedRow?: CSSProperties;
|
|
1197
|
+
/** Inline styles for pinned row wrappers (the grid row containing all cells) */
|
|
1198
|
+
pinnedRow?: CSSProperties;
|
|
1199
|
+
/**
|
|
1200
|
+
* CSS color string for the background of pinned row cells.
|
|
1201
|
+
* Should be opaque so that scrolling content behind pinned rows is hidden.
|
|
1202
|
+
* Falls back to `pinnedBg` if not set.
|
|
1203
|
+
*
|
|
1204
|
+
* @example
|
|
1205
|
+
* pinnedRowBg: 'rgba(255, 255, 255, 0.98)'
|
|
1206
|
+
*/
|
|
1207
|
+
pinnedRowBg?: string;
|
|
1149
1208
|
/**
|
|
1150
1209
|
* CSS color string applied as the background of hovered rows.
|
|
1151
1210
|
* Defaults to `hsl(var(--muted) / 0.5)` if omitted.
|
|
@@ -1210,7 +1269,7 @@ interface StylesTypes {
|
|
|
1210
1269
|
* autoHeight={false}
|
|
1211
1270
|
* />
|
|
1212
1271
|
*/
|
|
1213
|
-
declare function BoltTable<T extends DataRecord = DataRecord>({ columns: initialColumns, data, rowHeight, expandedRowHeight, maxExpandedRowHeight, accentColor, className, classNames, styles, gripIcon, hideGripIcon, icons, pagination, onPaginationChange, onColumnResize, onColumnOrderChange, onColumnPin, onColumnHide, rowSelection, expandable, rowKey, onEndReached, onEndReachedThreshold, isLoading, onSortChange, onFilterChange, columnContextMenuItems, autoHeight, layoutLoading, emptyRenderer, }: BoltTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
1272
|
+
declare function BoltTable<T extends DataRecord = DataRecord>({ columns: initialColumns, data, rowHeight, expandedRowHeight, maxExpandedRowHeight, accentColor, className, classNames, styles, gripIcon, hideGripIcon, icons, pagination, onPaginationChange, onColumnResize, onColumnOrderChange, onColumnPin, onColumnHide, rowSelection, rowPinning, expandable, rowKey, onEndReached, onEndReachedThreshold, isLoading, onSortChange, onFilterChange, columnContextMenuItems, autoHeight, layoutLoading, emptyRenderer, }: BoltTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
1214
1273
|
|
|
1215
1274
|
/**
|
|
1216
1275
|
* Props for the DraggableHeader component.
|
|
@@ -1569,6 +1628,28 @@ interface TableBodyProps {
|
|
|
1569
1628
|
* maxExpandedRowHeight={300}
|
|
1570
1629
|
*/
|
|
1571
1630
|
maxExpandedRowHeight?: number;
|
|
1631
|
+
/**
|
|
1632
|
+
* Rows pinned to the top of the table body.
|
|
1633
|
+
* Rendered as non-virtualized sticky rows below the column headers.
|
|
1634
|
+
*/
|
|
1635
|
+
pinnedTopData?: DataRecord[];
|
|
1636
|
+
/**
|
|
1637
|
+
* Rows pinned to the bottom of the table body.
|
|
1638
|
+
* Rendered as non-virtualized sticky rows at the bottom of the visible area.
|
|
1639
|
+
*/
|
|
1640
|
+
pinnedBottomData?: DataRecord[];
|
|
1641
|
+
/**
|
|
1642
|
+
* The CSS `gridTemplateColumns` string matching the parent grid.
|
|
1643
|
+
* Needed for pinned row sub-grids to align with the main column layout.
|
|
1644
|
+
*/
|
|
1645
|
+
gridTemplateColumns?: string;
|
|
1646
|
+
/**
|
|
1647
|
+
* Height of the column header row in pixels.
|
|
1648
|
+
* Used to position the sticky top pinned rows below the headers.
|
|
1649
|
+
*
|
|
1650
|
+
* @default 36
|
|
1651
|
+
*/
|
|
1652
|
+
headerHeight?: number;
|
|
1572
1653
|
}
|
|
1573
1654
|
/**
|
|
1574
1655
|
* TableBody — the virtualized body renderer for BoltTable.
|
|
@@ -1590,4 +1671,4 @@ interface TableBodyProps {
|
|
|
1590
1671
|
*/
|
|
1591
1672
|
declare const TableBody: React$1.FC<TableBodyProps>;
|
|
1592
1673
|
|
|
1593
|
-
export { BoltTable, type BoltTableIcons, type ColumnContextMenuItem, type ColumnType, type DataRecord, DraggableHeader, type ExpandableConfig, type PaginationType, ResizeOverlay, type RowSelectionConfig, type SortDirection, TableBody };
|
|
1674
|
+
export { BoltTable, type BoltTableIcons, type ColumnContextMenuItem, type ColumnType, type DataRecord, DraggableHeader, type ExpandableConfig, type PaginationType, ResizeOverlay, type RowPinningConfig, type RowSelectionConfig, type SortDirection, TableBody };
|
package/dist/index.js
CHANGED
|
@@ -1034,15 +1034,26 @@ var TableBody = ({
|
|
|
1034
1034
|
expandable,
|
|
1035
1035
|
resolvedExpandedKeys,
|
|
1036
1036
|
rowHeight = 40,
|
|
1037
|
+
totalTableWidth,
|
|
1037
1038
|
scrollAreaWidth,
|
|
1038
1039
|
accentColor,
|
|
1039
1040
|
isLoading = false,
|
|
1040
1041
|
onExpandedRowResize,
|
|
1041
|
-
maxExpandedRowHeight
|
|
1042
|
+
maxExpandedRowHeight,
|
|
1043
|
+
pinnedTopData = [],
|
|
1044
|
+
pinnedBottomData = [],
|
|
1045
|
+
gridTemplateColumns,
|
|
1046
|
+
headerHeight = 36
|
|
1042
1047
|
}) => {
|
|
1043
1048
|
const virtualItems = rowVirtualizer.getVirtualItems();
|
|
1044
1049
|
const totalSize = rowVirtualizer.getTotalSize();
|
|
1045
1050
|
const selectedKeySet = (0, import_react3.useMemo)(() => new Set(normalizedSelectedKeys), [normalizedSelectedKeys]);
|
|
1051
|
+
const allDataForSelection = (0, import_react3.useMemo)(() => {
|
|
1052
|
+
if (pinnedTopData.length === 0 && pinnedBottomData.length === 0)
|
|
1053
|
+
return data;
|
|
1054
|
+
return [...pinnedTopData, ...data, ...pinnedBottomData];
|
|
1055
|
+
}, [pinnedTopData, data, pinnedBottomData]);
|
|
1056
|
+
const pinnedRowBg = styles?.pinnedRowBg ?? styles?.pinnedBg;
|
|
1046
1057
|
const columnStyles = (0, import_react3.useMemo)(() => {
|
|
1047
1058
|
return orderedColumns.map((col, colIndex) => {
|
|
1048
1059
|
const stickyOffset = columnOffsets.get(col.key);
|
|
@@ -1128,7 +1139,7 @@ var TableBody = ({
|
|
|
1128
1139
|
rowSelection,
|
|
1129
1140
|
normalizedSelectedKeys,
|
|
1130
1141
|
rowKey,
|
|
1131
|
-
allData:
|
|
1142
|
+
allData: allDataForSelection,
|
|
1132
1143
|
getRowKey,
|
|
1133
1144
|
accentColor,
|
|
1134
1145
|
isLoading: isRowShimmer,
|
|
@@ -1206,6 +1217,181 @@ var TableBody = ({
|
|
|
1206
1217
|
);
|
|
1207
1218
|
})
|
|
1208
1219
|
}
|
|
1220
|
+
),
|
|
1221
|
+
pinnedTopData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1222
|
+
"div",
|
|
1223
|
+
{
|
|
1224
|
+
style: {
|
|
1225
|
+
gridColumn: "1 / -1",
|
|
1226
|
+
gridRow: 2,
|
|
1227
|
+
position: "sticky",
|
|
1228
|
+
top: headerHeight,
|
|
1229
|
+
zIndex: 20,
|
|
1230
|
+
boxShadow: "0 2px 6px -1px rgba(0,0,0,0.08)"
|
|
1231
|
+
},
|
|
1232
|
+
children: pinnedTopData.map((row, rowIdx) => {
|
|
1233
|
+
const rk = getRowKey ? getRowKey(row, rowIdx) : String(rowIdx);
|
|
1234
|
+
const isSelected = selectedKeySet.has(rk);
|
|
1235
|
+
const isExpanded = resolvedExpandedKeys?.has(rk) ?? false;
|
|
1236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1237
|
+
"div",
|
|
1238
|
+
{
|
|
1239
|
+
className: classNames?.pinnedRow ?? "",
|
|
1240
|
+
style: {
|
|
1241
|
+
display: "grid",
|
|
1242
|
+
gridTemplateColumns: gridTemplateColumns ?? "",
|
|
1243
|
+
minWidth: totalTableWidth ? `${totalTableWidth}px` : void 0,
|
|
1244
|
+
...styles?.pinnedRow
|
|
1245
|
+
},
|
|
1246
|
+
children: orderedColumns.map((col) => {
|
|
1247
|
+
const cellValue = row[col.dataIndex];
|
|
1248
|
+
const stickyOffset = columnOffsets.get(col.key);
|
|
1249
|
+
const isPinned = Boolean(col.pinned);
|
|
1250
|
+
let zIndex = 0;
|
|
1251
|
+
if (col.key === "__select__" || col.key === "__expand__")
|
|
1252
|
+
zIndex = 11;
|
|
1253
|
+
else if (isPinned) zIndex = 2;
|
|
1254
|
+
const recordFingerprint = col.render ? JSON.stringify(row) : void 0;
|
|
1255
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1256
|
+
"div",
|
|
1257
|
+
{
|
|
1258
|
+
"data-row-key": rk,
|
|
1259
|
+
"data-selected": isSelected || void 0,
|
|
1260
|
+
style: {
|
|
1261
|
+
position: isPinned ? "sticky" : "relative",
|
|
1262
|
+
...col.pinned === "left" && stickyOffset !== void 0 ? { left: `${stickyOffset}px` } : {},
|
|
1263
|
+
...col.pinned === "right" && stickyOffset !== void 0 ? { right: `${stickyOffset}px` } : {},
|
|
1264
|
+
zIndex,
|
|
1265
|
+
backgroundColor: pinnedRowBg,
|
|
1266
|
+
...isPinned && styles?.pinnedCell ? styles.pinnedCell : {}
|
|
1267
|
+
},
|
|
1268
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1269
|
+
"div",
|
|
1270
|
+
{
|
|
1271
|
+
style: {
|
|
1272
|
+
height: `${rowHeight}px`,
|
|
1273
|
+
position: "relative"
|
|
1274
|
+
},
|
|
1275
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1276
|
+
Cell,
|
|
1277
|
+
{
|
|
1278
|
+
value: cellValue,
|
|
1279
|
+
record: row,
|
|
1280
|
+
column: col,
|
|
1281
|
+
rowIndex: rowIdx,
|
|
1282
|
+
classNames,
|
|
1283
|
+
styles,
|
|
1284
|
+
isSelected,
|
|
1285
|
+
isExpanded,
|
|
1286
|
+
rowSelection,
|
|
1287
|
+
normalizedSelectedKeys,
|
|
1288
|
+
rowKey: rk,
|
|
1289
|
+
allData: allDataForSelection,
|
|
1290
|
+
getRowKey,
|
|
1291
|
+
accentColor,
|
|
1292
|
+
isLoading: false,
|
|
1293
|
+
recordFingerprint
|
|
1294
|
+
}
|
|
1295
|
+
)
|
|
1296
|
+
}
|
|
1297
|
+
)
|
|
1298
|
+
},
|
|
1299
|
+
col.key
|
|
1300
|
+
);
|
|
1301
|
+
})
|
|
1302
|
+
},
|
|
1303
|
+
`pinned-top-${rk}`
|
|
1304
|
+
);
|
|
1305
|
+
})
|
|
1306
|
+
}
|
|
1307
|
+
),
|
|
1308
|
+
pinnedBottomData.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1309
|
+
"div",
|
|
1310
|
+
{
|
|
1311
|
+
style: {
|
|
1312
|
+
gridColumn: "1 / -1",
|
|
1313
|
+
gridRow: 2,
|
|
1314
|
+
position: "sticky",
|
|
1315
|
+
bottom: 0,
|
|
1316
|
+
alignSelf: "end",
|
|
1317
|
+
zIndex: 20,
|
|
1318
|
+
boxShadow: "0 -2px 6px -1px rgba(0,0,0,0.08)"
|
|
1319
|
+
},
|
|
1320
|
+
children: pinnedBottomData.map((row, rowIdx) => {
|
|
1321
|
+
const rk = getRowKey ? getRowKey(row, rowIdx) : String(rowIdx);
|
|
1322
|
+
const isSelected = selectedKeySet.has(rk);
|
|
1323
|
+
const isExpanded = resolvedExpandedKeys?.has(rk) ?? false;
|
|
1324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1325
|
+
"div",
|
|
1326
|
+
{
|
|
1327
|
+
className: classNames?.pinnedRow ?? "",
|
|
1328
|
+
style: {
|
|
1329
|
+
display: "grid",
|
|
1330
|
+
gridTemplateColumns: gridTemplateColumns ?? "",
|
|
1331
|
+
minWidth: totalTableWidth ? `${totalTableWidth}px` : void 0,
|
|
1332
|
+
...styles?.pinnedRow
|
|
1333
|
+
},
|
|
1334
|
+
children: orderedColumns.map((col) => {
|
|
1335
|
+
const cellValue = row[col.dataIndex];
|
|
1336
|
+
const stickyOffset = columnOffsets.get(col.key);
|
|
1337
|
+
const isPinned = Boolean(col.pinned);
|
|
1338
|
+
let zIndex = 0;
|
|
1339
|
+
if (col.key === "__select__" || col.key === "__expand__")
|
|
1340
|
+
zIndex = 11;
|
|
1341
|
+
else if (isPinned) zIndex = 2;
|
|
1342
|
+
const recordFingerprint = col.render ? JSON.stringify(row) : void 0;
|
|
1343
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1344
|
+
"div",
|
|
1345
|
+
{
|
|
1346
|
+
"data-row-key": rk,
|
|
1347
|
+
"data-selected": isSelected || void 0,
|
|
1348
|
+
style: {
|
|
1349
|
+
position: isPinned ? "sticky" : "relative",
|
|
1350
|
+
...col.pinned === "left" && stickyOffset !== void 0 ? { left: `${stickyOffset}px` } : {},
|
|
1351
|
+
...col.pinned === "right" && stickyOffset !== void 0 ? { right: `${stickyOffset}px` } : {},
|
|
1352
|
+
zIndex,
|
|
1353
|
+
backgroundColor: pinnedRowBg,
|
|
1354
|
+
...isPinned && styles?.pinnedCell ? styles.pinnedCell : {}
|
|
1355
|
+
},
|
|
1356
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1357
|
+
"div",
|
|
1358
|
+
{
|
|
1359
|
+
style: {
|
|
1360
|
+
height: `${rowHeight}px`,
|
|
1361
|
+
position: "relative"
|
|
1362
|
+
},
|
|
1363
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1364
|
+
Cell,
|
|
1365
|
+
{
|
|
1366
|
+
value: cellValue,
|
|
1367
|
+
record: row,
|
|
1368
|
+
column: col,
|
|
1369
|
+
rowIndex: rowIdx,
|
|
1370
|
+
classNames,
|
|
1371
|
+
styles,
|
|
1372
|
+
isSelected,
|
|
1373
|
+
isExpanded,
|
|
1374
|
+
rowSelection,
|
|
1375
|
+
normalizedSelectedKeys,
|
|
1376
|
+
rowKey: rk,
|
|
1377
|
+
allData: allDataForSelection,
|
|
1378
|
+
getRowKey,
|
|
1379
|
+
accentColor,
|
|
1380
|
+
isLoading: false,
|
|
1381
|
+
recordFingerprint
|
|
1382
|
+
}
|
|
1383
|
+
)
|
|
1384
|
+
}
|
|
1385
|
+
)
|
|
1386
|
+
},
|
|
1387
|
+
col.key
|
|
1388
|
+
);
|
|
1389
|
+
})
|
|
1390
|
+
},
|
|
1391
|
+
`pinned-bottom-${rk}`
|
|
1392
|
+
);
|
|
1393
|
+
})
|
|
1394
|
+
}
|
|
1209
1395
|
)
|
|
1210
1396
|
] });
|
|
1211
1397
|
};
|
|
@@ -1241,6 +1427,7 @@ function BoltTable({
|
|
|
1241
1427
|
onColumnPin,
|
|
1242
1428
|
onColumnHide,
|
|
1243
1429
|
rowSelection,
|
|
1430
|
+
rowPinning,
|
|
1244
1431
|
expandable,
|
|
1245
1432
|
rowKey = "id",
|
|
1246
1433
|
onEndReached,
|
|
@@ -1781,6 +1968,35 @@ function BoltTable({
|
|
|
1781
1968
|
}
|
|
1782
1969
|
return result;
|
|
1783
1970
|
}, [data, sortState, columnFilters]);
|
|
1971
|
+
const { pinnedTopRows, pinnedBottomRows, unpinnedProcessedData } = (0, import_react4.useMemo)(() => {
|
|
1972
|
+
if (!rowPinning || !rowPinning.top?.length && !rowPinning.bottom?.length) {
|
|
1973
|
+
return {
|
|
1974
|
+
pinnedTopRows: [],
|
|
1975
|
+
pinnedBottomRows: [],
|
|
1976
|
+
unpinnedProcessedData: processedData
|
|
1977
|
+
};
|
|
1978
|
+
}
|
|
1979
|
+
const topKeySet = new Set((rowPinning.top ?? []).map(String));
|
|
1980
|
+
const bottomKeySet = new Set((rowPinning.bottom ?? []).map(String));
|
|
1981
|
+
const topMap = /* @__PURE__ */ new Map();
|
|
1982
|
+
const bottomMap = /* @__PURE__ */ new Map();
|
|
1983
|
+
const rest = [];
|
|
1984
|
+
processedData.forEach((row, idx) => {
|
|
1985
|
+
const key = getRowKey(row, idx);
|
|
1986
|
+
if (topKeySet.has(key)) topMap.set(key, row);
|
|
1987
|
+
else if (bottomKeySet.has(key)) bottomMap.set(key, row);
|
|
1988
|
+
else rest.push(row);
|
|
1989
|
+
});
|
|
1990
|
+
const orderedTop = (rowPinning.top ?? []).map((k) => topMap.get(String(k))).filter((r) => r !== void 0);
|
|
1991
|
+
const orderedBottom = (rowPinning.bottom ?? []).map((k) => bottomMap.get(String(k))).filter((r) => r !== void 0);
|
|
1992
|
+
return {
|
|
1993
|
+
pinnedTopRows: orderedTop,
|
|
1994
|
+
pinnedBottomRows: orderedBottom,
|
|
1995
|
+
unpinnedProcessedData: rest
|
|
1996
|
+
};
|
|
1997
|
+
}, [processedData, rowPinning, getRowKey]);
|
|
1998
|
+
const pinnedTopHeight = pinnedTopRows.length * rowHeight;
|
|
1999
|
+
const pinnedBottomHeight = pinnedBottomRows.length * rowHeight;
|
|
1784
2000
|
const columnFiltersKey = Object.keys(columnFilters).sort().map((k) => `${k}:${columnFilters[k]}`).join("|");
|
|
1785
2001
|
import_react4.default.useEffect(() => {
|
|
1786
2002
|
tableAreaRef.current?.scrollTo({ top: 0 });
|
|
@@ -1788,12 +2004,12 @@ function BoltTable({
|
|
|
1788
2004
|
const pgEnabled = pagination !== false && !!pagination;
|
|
1789
2005
|
const pgSize = pgEnabled ? pagination.pageSize ?? 10 : 10;
|
|
1790
2006
|
const pgCurrent = pgEnabled ? Number(pagination.current ?? 1) : 1;
|
|
1791
|
-
const needsClientPagination = pgEnabled &&
|
|
2007
|
+
const needsClientPagination = pgEnabled && unpinnedProcessedData.length > pgSize;
|
|
1792
2008
|
const paginatedData = (0, import_react4.useMemo)(() => {
|
|
1793
|
-
if (!needsClientPagination) return
|
|
2009
|
+
if (!needsClientPagination) return unpinnedProcessedData;
|
|
1794
2010
|
const start = (pgCurrent - 1) * pgSize;
|
|
1795
|
-
return
|
|
1796
|
-
}, [
|
|
2011
|
+
return unpinnedProcessedData.slice(start, start + pgSize);
|
|
2012
|
+
}, [unpinnedProcessedData, needsClientPagination, pgCurrent, pgSize]);
|
|
1797
2013
|
const shimmerCount = pgEnabled ? pgSize : 15;
|
|
1798
2014
|
const showShimmer = isLoading && processedData.length === 0;
|
|
1799
2015
|
const shimmerData = (0, import_react4.useMemo)(() => {
|
|
@@ -1851,8 +2067,9 @@ function BoltTable({
|
|
|
1851
2067
|
return cached ? rowHeight + cached : rowHeight + expandedRowHeight;
|
|
1852
2068
|
},
|
|
1853
2069
|
overscan: 5,
|
|
1854
|
-
|
|
1855
|
-
|
|
2070
|
+
getItemKey: (index) => shimmerData ? `__shimmer_${index}__` : getRowKey(displayData[index], index),
|
|
2071
|
+
paddingStart: pinnedTopHeight,
|
|
2072
|
+
paddingEnd: pinnedBottomHeight
|
|
1856
2073
|
});
|
|
1857
2074
|
const rowVirtualizerRef = (0, import_react4.useRef)(rowVirtualizer);
|
|
1858
2075
|
rowVirtualizerRef.current = rowVirtualizer;
|
|
@@ -1892,7 +2109,7 @@ function BoltTable({
|
|
|
1892
2109
|
const activeColumn = activeId ? orderedColumns.find((col) => col.key === activeId) : null;
|
|
1893
2110
|
const currentPage = pgCurrent;
|
|
1894
2111
|
const pageSize = pgSize;
|
|
1895
|
-
const rawTotal = pgEnabled ? pagination.total ?? (needsClientPagination ?
|
|
2112
|
+
const rawTotal = pgEnabled ? pagination.total ?? (needsClientPagination ? unpinnedProcessedData.length : data.length) : data.length;
|
|
1896
2113
|
const lastKnownTotalRef = (0, import_react4.useRef)(0);
|
|
1897
2114
|
if (!isLoading || rawTotal > 0) {
|
|
1898
2115
|
lastKnownTotalRef.current = rawTotal;
|
|
@@ -2329,7 +2546,11 @@ function BoltTable({
|
|
|
2329
2546
|
scrollContainerRef: tableAreaRef,
|
|
2330
2547
|
isLoading: showShimmer,
|
|
2331
2548
|
onExpandedRowResize: handleExpandedRowResize,
|
|
2332
|
-
maxExpandedRowHeight
|
|
2549
|
+
maxExpandedRowHeight,
|
|
2550
|
+
pinnedTopData: pinnedTopRows,
|
|
2551
|
+
pinnedBottomData: pinnedBottomRows,
|
|
2552
|
+
gridTemplateColumns,
|
|
2553
|
+
headerHeight: HEADER_HEIGHT
|
|
2333
2554
|
}
|
|
2334
2555
|
)
|
|
2335
2556
|
)
|