bolt-table 0.1.17 → 0.1.19
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 +29 -7
- package/dist/index.d.ts +29 -7
- package/dist/index.js +66 -13
- package/dist/index.mjs +66 -13
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -67,6 +67,25 @@ interface ColumnType<T = unknown> {
|
|
|
67
67
|
* `true` copies the raw value; pass a function for custom copy text.
|
|
68
68
|
*/
|
|
69
69
|
copy?: boolean | ((value: unknown, record: T, index: number) => string);
|
|
70
|
+
/** Custom context menu items appended to this column's header right-click menu. */
|
|
71
|
+
columnHeaderContextMenuItems?: ColumnContextMenuItem[];
|
|
72
|
+
/** Custom context menu items appended to every cell's right-click menu in this column. */
|
|
73
|
+
columnCellContextMenuItems?: CellContextMenuItem<T>[];
|
|
74
|
+
}
|
|
75
|
+
/** A single item in the cell right-click context menu (column-level). */
|
|
76
|
+
interface CellContextMenuItem<T = unknown> {
|
|
77
|
+
/** Unique identifier for this menu item, used as the React `key`. */
|
|
78
|
+
key: string;
|
|
79
|
+
/** The label shown in the menu. Can be a string or React node. */
|
|
80
|
+
label: React.ReactNode;
|
|
81
|
+
/** Optional icon shown to the left of the label. */
|
|
82
|
+
icon?: React.ReactNode;
|
|
83
|
+
/** When `true`, the label renders in red to indicate a destructive action. */
|
|
84
|
+
danger?: boolean;
|
|
85
|
+
/** When `true`, the item is grayed out and click handler is not called. */
|
|
86
|
+
disabled?: boolean;
|
|
87
|
+
/** Called when the user clicks this menu item. Receives the column key, row record, and row index. */
|
|
88
|
+
onClick: (columnKey: string, record: T, rowIndex: number) => void;
|
|
70
89
|
}
|
|
71
90
|
/** A single item in the column header right-click context menu. */
|
|
72
91
|
interface ColumnContextMenuItem {
|
|
@@ -201,11 +220,6 @@ interface BoltTableProps<T extends DataRecord = DataRecord> {
|
|
|
201
220
|
readonly onEndReachedThreshold?: number;
|
|
202
221
|
/** When true and data is empty, shows shimmer skeleton rows. With data, appends shimmer rows at bottom. */
|
|
203
222
|
readonly isLoading?: boolean;
|
|
204
|
-
/** Scroll indicator configuration (reserved for future use). */
|
|
205
|
-
readonly scrollIndicators?: {
|
|
206
|
-
vertical?: boolean;
|
|
207
|
-
horizontal?: boolean;
|
|
208
|
-
};
|
|
209
223
|
/** Called when the user changes sort direction. Provide for server-side sorting. */
|
|
210
224
|
readonly onSortChange?: (columnKey: string, direction: SortDirection) => void;
|
|
211
225
|
/** Called when the user applies or clears a column filter. Provide for server-side filtering. */
|
|
@@ -218,6 +232,10 @@ interface BoltTableProps<T extends DataRecord = DataRecord> {
|
|
|
218
232
|
readonly layoutLoading?: boolean;
|
|
219
233
|
/** Custom React node to render when the table has no data and is not loading. */
|
|
220
234
|
readonly emptyRenderer?: React$1.ReactNode;
|
|
235
|
+
/** Returns a CSS class name for a given row based on its record and index. Useful for Tailwind or any CSS class-based conditional row styling. */
|
|
236
|
+
readonly rowClassName?: (record: T, index: number) => string;
|
|
237
|
+
/** Returns inline CSS styles for a given row based on its record and index. Useful for dynamic per-row styling. */
|
|
238
|
+
readonly rowStyle?: (record: T, index: number) => React$1.CSSProperties;
|
|
221
239
|
}
|
|
222
240
|
interface ClassNamesTypes {
|
|
223
241
|
/** Applied to all non-pinned column header cells. */
|
|
@@ -263,7 +281,7 @@ interface StylesTypes {
|
|
|
263
281
|
/** CSS color string for pinned column cells and headers background. */
|
|
264
282
|
pinnedBg?: string;
|
|
265
283
|
}
|
|
266
|
-
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, onRowPin, expandable, rowKey, onEndReached, onEndReachedThreshold, isLoading, onSortChange, onFilterChange, columnContextMenuItems, autoHeight, layoutLoading, emptyRenderer, }: BoltTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
284
|
+
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, onRowPin, expandable, rowKey, onEndReached, onEndReachedThreshold, isLoading, onSortChange, onFilterChange, columnContextMenuItems, autoHeight, layoutLoading, emptyRenderer, rowClassName, rowStyle, }: BoltTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
267
285
|
|
|
268
286
|
interface DraggableHeaderProps {
|
|
269
287
|
/** Column definition for this header cell. */
|
|
@@ -367,7 +385,11 @@ interface TableBodyProps {
|
|
|
367
385
|
gridTemplateColumns?: string;
|
|
368
386
|
/** Height of the column header row in pixels */
|
|
369
387
|
headerHeight?: number;
|
|
388
|
+
/** Returns a CSS class name for a given row based on its record and index */
|
|
389
|
+
rowClassName?: (record: DataRecord, index: number) => string;
|
|
390
|
+
/** Returns inline CSS styles for a given row based on its record and index */
|
|
391
|
+
rowStyle?: (record: DataRecord, index: number) => React$1.CSSProperties;
|
|
370
392
|
}
|
|
371
393
|
declare const TableBody: React$1.FC<TableBodyProps>;
|
|
372
394
|
|
|
373
|
-
export { BoltTable, type BoltTableIcons, type ColumnContextMenuItem, type ColumnType, type DataRecord, DraggableHeader, type ExpandableConfig, type PaginationType, ResizeOverlay, type RowPinningConfig, type RowSelectionConfig, type SortDirection, TableBody };
|
|
395
|
+
export { BoltTable, type BoltTableIcons, type CellContextMenuItem, type ClassNamesTypes, type ColumnContextMenuItem, type ColumnType, type DataRecord, DraggableHeader, type ExpandableConfig, type PaginationType, ResizeOverlay, type RowPinningConfig, type RowSelectionConfig, type SortDirection, type StylesTypes, TableBody };
|
package/dist/index.d.ts
CHANGED
|
@@ -67,6 +67,25 @@ interface ColumnType<T = unknown> {
|
|
|
67
67
|
* `true` copies the raw value; pass a function for custom copy text.
|
|
68
68
|
*/
|
|
69
69
|
copy?: boolean | ((value: unknown, record: T, index: number) => string);
|
|
70
|
+
/** Custom context menu items appended to this column's header right-click menu. */
|
|
71
|
+
columnHeaderContextMenuItems?: ColumnContextMenuItem[];
|
|
72
|
+
/** Custom context menu items appended to every cell's right-click menu in this column. */
|
|
73
|
+
columnCellContextMenuItems?: CellContextMenuItem<T>[];
|
|
74
|
+
}
|
|
75
|
+
/** A single item in the cell right-click context menu (column-level). */
|
|
76
|
+
interface CellContextMenuItem<T = unknown> {
|
|
77
|
+
/** Unique identifier for this menu item, used as the React `key`. */
|
|
78
|
+
key: string;
|
|
79
|
+
/** The label shown in the menu. Can be a string or React node. */
|
|
80
|
+
label: React.ReactNode;
|
|
81
|
+
/** Optional icon shown to the left of the label. */
|
|
82
|
+
icon?: React.ReactNode;
|
|
83
|
+
/** When `true`, the label renders in red to indicate a destructive action. */
|
|
84
|
+
danger?: boolean;
|
|
85
|
+
/** When `true`, the item is grayed out and click handler is not called. */
|
|
86
|
+
disabled?: boolean;
|
|
87
|
+
/** Called when the user clicks this menu item. Receives the column key, row record, and row index. */
|
|
88
|
+
onClick: (columnKey: string, record: T, rowIndex: number) => void;
|
|
70
89
|
}
|
|
71
90
|
/** A single item in the column header right-click context menu. */
|
|
72
91
|
interface ColumnContextMenuItem {
|
|
@@ -201,11 +220,6 @@ interface BoltTableProps<T extends DataRecord = DataRecord> {
|
|
|
201
220
|
readonly onEndReachedThreshold?: number;
|
|
202
221
|
/** When true and data is empty, shows shimmer skeleton rows. With data, appends shimmer rows at bottom. */
|
|
203
222
|
readonly isLoading?: boolean;
|
|
204
|
-
/** Scroll indicator configuration (reserved for future use). */
|
|
205
|
-
readonly scrollIndicators?: {
|
|
206
|
-
vertical?: boolean;
|
|
207
|
-
horizontal?: boolean;
|
|
208
|
-
};
|
|
209
223
|
/** Called when the user changes sort direction. Provide for server-side sorting. */
|
|
210
224
|
readonly onSortChange?: (columnKey: string, direction: SortDirection) => void;
|
|
211
225
|
/** Called when the user applies or clears a column filter. Provide for server-side filtering. */
|
|
@@ -218,6 +232,10 @@ interface BoltTableProps<T extends DataRecord = DataRecord> {
|
|
|
218
232
|
readonly layoutLoading?: boolean;
|
|
219
233
|
/** Custom React node to render when the table has no data and is not loading. */
|
|
220
234
|
readonly emptyRenderer?: React$1.ReactNode;
|
|
235
|
+
/** Returns a CSS class name for a given row based on its record and index. Useful for Tailwind or any CSS class-based conditional row styling. */
|
|
236
|
+
readonly rowClassName?: (record: T, index: number) => string;
|
|
237
|
+
/** Returns inline CSS styles for a given row based on its record and index. Useful for dynamic per-row styling. */
|
|
238
|
+
readonly rowStyle?: (record: T, index: number) => React$1.CSSProperties;
|
|
221
239
|
}
|
|
222
240
|
interface ClassNamesTypes {
|
|
223
241
|
/** Applied to all non-pinned column header cells. */
|
|
@@ -263,7 +281,7 @@ interface StylesTypes {
|
|
|
263
281
|
/** CSS color string for pinned column cells and headers background. */
|
|
264
282
|
pinnedBg?: string;
|
|
265
283
|
}
|
|
266
|
-
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, onRowPin, expandable, rowKey, onEndReached, onEndReachedThreshold, isLoading, onSortChange, onFilterChange, columnContextMenuItems, autoHeight, layoutLoading, emptyRenderer, }: BoltTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
284
|
+
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, onRowPin, expandable, rowKey, onEndReached, onEndReachedThreshold, isLoading, onSortChange, onFilterChange, columnContextMenuItems, autoHeight, layoutLoading, emptyRenderer, rowClassName, rowStyle, }: BoltTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
267
285
|
|
|
268
286
|
interface DraggableHeaderProps {
|
|
269
287
|
/** Column definition for this header cell. */
|
|
@@ -367,7 +385,11 @@ interface TableBodyProps {
|
|
|
367
385
|
gridTemplateColumns?: string;
|
|
368
386
|
/** Height of the column header row in pixels */
|
|
369
387
|
headerHeight?: number;
|
|
388
|
+
/** Returns a CSS class name for a given row based on its record and index */
|
|
389
|
+
rowClassName?: (record: DataRecord, index: number) => string;
|
|
390
|
+
/** Returns inline CSS styles for a given row based on its record and index */
|
|
391
|
+
rowStyle?: (record: DataRecord, index: number) => React$1.CSSProperties;
|
|
370
392
|
}
|
|
371
393
|
declare const TableBody: React$1.FC<TableBodyProps>;
|
|
372
394
|
|
|
373
|
-
export { BoltTable, type BoltTableIcons, type ColumnContextMenuItem, type ColumnType, type DataRecord, DraggableHeader, type ExpandableConfig, type PaginationType, ResizeOverlay, type RowPinningConfig, type RowSelectionConfig, type SortDirection, TableBody };
|
|
395
|
+
export { BoltTable, type BoltTableIcons, type CellContextMenuItem, type ClassNamesTypes, type ColumnContextMenuItem, type ColumnType, type DataRecord, DraggableHeader, type ExpandableConfig, type PaginationType, ResizeOverlay, type RowPinningConfig, type RowSelectionConfig, type SortDirection, type StylesTypes, TableBody };
|
package/dist/index.js
CHANGED
|
@@ -713,7 +713,7 @@ var DraggableHeader = import_react.default.memo(
|
|
|
713
713
|
] });
|
|
714
714
|
},
|
|
715
715
|
(prevProps, nextProps) => {
|
|
716
|
-
return prevProps.column.width === nextProps.column.width && prevProps.column.key === nextProps.column.key && prevProps.column.pinned === nextProps.column.pinned && prevProps.column.sortable === nextProps.column.sortable && prevProps.column.filterable === nextProps.column.filterable && prevProps.column.sorter === nextProps.column.sorter && prevProps.column.filterFn === nextProps.column.filterFn && prevProps.visualIndex === nextProps.visualIndex && prevProps.stickyOffset === nextProps.stickyOffset && prevProps.isLastColumn === nextProps.isLastColumn && prevProps.sortDirection === nextProps.sortDirection && prevProps.filterValue === nextProps.filterValue && prevProps.classNames === nextProps.classNames && prevProps.styles === nextProps.styles;
|
|
716
|
+
return prevProps.column.width === nextProps.column.width && prevProps.column.key === nextProps.column.key && prevProps.column.pinned === nextProps.column.pinned && prevProps.column.sortable === nextProps.column.sortable && prevProps.column.filterable === nextProps.column.filterable && prevProps.column.sorter === nextProps.column.sorter && prevProps.column.filterFn === nextProps.column.filterFn && prevProps.visualIndex === nextProps.visualIndex && prevProps.stickyOffset === nextProps.stickyOffset && prevProps.isLastColumn === nextProps.isLastColumn && prevProps.sortDirection === nextProps.sortDirection && prevProps.filterValue === nextProps.filterValue && prevProps.classNames === nextProps.classNames && prevProps.styles === nextProps.styles && prevProps.customContextMenuItems === nextProps.customContextMenuItems;
|
|
717
717
|
}
|
|
718
718
|
);
|
|
719
719
|
DraggableHeader.displayName = "DraggableHeader";
|
|
@@ -1085,7 +1085,9 @@ var TableBody = ({
|
|
|
1085
1085
|
pinnedTopData = [],
|
|
1086
1086
|
pinnedBottomData = [],
|
|
1087
1087
|
gridTemplateColumns,
|
|
1088
|
-
headerHeight = 36
|
|
1088
|
+
headerHeight = 36,
|
|
1089
|
+
rowClassName,
|
|
1090
|
+
rowStyle
|
|
1089
1091
|
}) => {
|
|
1090
1092
|
const virtualItems = rowVirtualizer.getVirtualItems();
|
|
1091
1093
|
const totalSize = rowVirtualizer.getTotalSize();
|
|
@@ -1137,6 +1139,8 @@ var TableBody = ({
|
|
|
1137
1139
|
const cellValue = row[col.dataIndex];
|
|
1138
1140
|
const isRowShimmer = isLoading || rowKey.startsWith("__shimmer_");
|
|
1139
1141
|
const recordFingerprint = hasRender && !isRowShimmer ? JSON.stringify(row) : void 0;
|
|
1142
|
+
const rowCls = rowClassName ? rowClassName(row, virtualRow.index) : "";
|
|
1143
|
+
const rowSty = rowStyle ? rowStyle(row, virtualRow.index) : void 0;
|
|
1140
1144
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1141
1145
|
"div",
|
|
1142
1146
|
{
|
|
@@ -1144,12 +1148,14 @@ var TableBody = ({
|
|
|
1144
1148
|
"data-column-key": col.key,
|
|
1145
1149
|
"data-bt-cell": "",
|
|
1146
1150
|
"data-selected": isSelected || void 0,
|
|
1151
|
+
className: rowCls || void 0,
|
|
1147
1152
|
style: {
|
|
1148
1153
|
position: "absolute",
|
|
1149
1154
|
top: `${virtualRow.start}px`,
|
|
1150
1155
|
left: 0,
|
|
1151
1156
|
right: 0,
|
|
1152
|
-
height: `${virtualRow.size}px
|
|
1157
|
+
height: `${virtualRow.size}px`,
|
|
1158
|
+
...rowSty
|
|
1153
1159
|
},
|
|
1154
1160
|
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1155
1161
|
"div",
|
|
@@ -1271,15 +1277,18 @@ var TableBody = ({
|
|
|
1271
1277
|
const rk = getRowKey ? getRowKey(row, rowIdx) : String(rowIdx);
|
|
1272
1278
|
const isSelected = selectedKeySet.has(rk);
|
|
1273
1279
|
const isExpanded = resolvedExpandedKeys?.has(rk) ?? false;
|
|
1280
|
+
const rowCls = rowClassName ? rowClassName(row, rowIdx) : "";
|
|
1281
|
+
const rowSty = rowStyle ? rowStyle(row, rowIdx) : void 0;
|
|
1274
1282
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1275
1283
|
"div",
|
|
1276
1284
|
{
|
|
1277
|
-
className: classNames?.pinnedRow ?? "",
|
|
1285
|
+
className: `${classNames?.pinnedRow ?? ""} ${rowCls}`.trim() || void 0,
|
|
1278
1286
|
style: {
|
|
1279
1287
|
display: "grid",
|
|
1280
1288
|
gridTemplateColumns: gridTemplateColumns ?? "",
|
|
1281
1289
|
minWidth: totalTableWidth ? `${totalTableWidth}px` : void 0,
|
|
1282
|
-
...styles?.pinnedRow
|
|
1290
|
+
...styles?.pinnedRow,
|
|
1291
|
+
...rowSty
|
|
1283
1292
|
},
|
|
1284
1293
|
children: orderedColumns.map((col) => {
|
|
1285
1294
|
const cellValue = row[col.dataIndex];
|
|
@@ -1376,15 +1385,18 @@ var TableBody = ({
|
|
|
1376
1385
|
const rk = getRowKey ? getRowKey(row, rowIdx) : String(rowIdx);
|
|
1377
1386
|
const isSelected = selectedKeySet.has(rk);
|
|
1378
1387
|
const isExpanded = resolvedExpandedKeys?.has(rk) ?? false;
|
|
1388
|
+
const rowCls = rowClassName ? rowClassName(row, rowIdx) : "";
|
|
1389
|
+
const rowSty = rowStyle ? rowStyle(row, rowIdx) : void 0;
|
|
1379
1390
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1380
1391
|
"div",
|
|
1381
1392
|
{
|
|
1382
|
-
className: classNames?.pinnedRow ?? "",
|
|
1393
|
+
className: `${classNames?.pinnedRow ?? ""} ${rowCls}`.trim() || void 0,
|
|
1383
1394
|
style: {
|
|
1384
1395
|
display: "grid",
|
|
1385
1396
|
gridTemplateColumns: gridTemplateColumns ?? "",
|
|
1386
1397
|
minWidth: totalTableWidth ? `${totalTableWidth}px` : void 0,
|
|
1387
|
-
...styles?.pinnedRow
|
|
1398
|
+
...styles?.pinnedRow,
|
|
1399
|
+
...rowSty
|
|
1388
1400
|
},
|
|
1389
1401
|
children: orderedColumns.map((col) => {
|
|
1390
1402
|
const cellValue = row[col.dataIndex];
|
|
@@ -1502,7 +1514,9 @@ function BoltTable({
|
|
|
1502
1514
|
columnContextMenuItems,
|
|
1503
1515
|
autoHeight = true,
|
|
1504
1516
|
layoutLoading,
|
|
1505
|
-
emptyRenderer
|
|
1517
|
+
emptyRenderer,
|
|
1518
|
+
rowClassName,
|
|
1519
|
+
rowStyle
|
|
1506
1520
|
}) {
|
|
1507
1521
|
const [columns, setColumns] = (0, import_react4.useState)(initialColumns);
|
|
1508
1522
|
const [columnOrder, setColumnOrder] = (0, import_react4.useState)(
|
|
@@ -2489,7 +2503,8 @@ function BoltTable({
|
|
|
2489
2503
|
);
|
|
2490
2504
|
const hasCopy = col?.copy;
|
|
2491
2505
|
const hasRowPin = !!onRowPin;
|
|
2492
|
-
|
|
2506
|
+
const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
|
|
2507
|
+
if (!hasCopy && !hasRowPin && !hasCellItems) return;
|
|
2493
2508
|
e.preventDefault();
|
|
2494
2509
|
setCellContextMenu({
|
|
2495
2510
|
x: Math.min(e.clientX, window.innerWidth - 200),
|
|
@@ -2517,7 +2532,8 @@ function BoltTable({
|
|
|
2517
2532
|
);
|
|
2518
2533
|
const hasCopy = col?.copy;
|
|
2519
2534
|
const hasRowPin = !!onRowPin;
|
|
2520
|
-
|
|
2535
|
+
const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
|
|
2536
|
+
if (!hasCopy && !hasRowPin && !hasCellItems) return;
|
|
2521
2537
|
setCellContextMenu({
|
|
2522
2538
|
x: Math.min(touch.clientX, window.innerWidth - 200),
|
|
2523
2539
|
y: Math.min(touch.clientY, window.innerHeight - 200),
|
|
@@ -2649,7 +2665,7 @@ function BoltTable({
|
|
|
2649
2665
|
filterValue: columnFilters[column.key] ?? "",
|
|
2650
2666
|
onFilter: handleColumnFilter,
|
|
2651
2667
|
onClearFilter: handleClearFilter,
|
|
2652
|
-
customContextMenuItems: columnContextMenuItems
|
|
2668
|
+
customContextMenuItems: column.columnHeaderContextMenuItems ? [...columnContextMenuItems ?? [], ...column.columnHeaderContextMenuItems] : columnContextMenuItems
|
|
2653
2669
|
},
|
|
2654
2670
|
column.key
|
|
2655
2671
|
);
|
|
@@ -2717,7 +2733,9 @@ function BoltTable({
|
|
|
2717
2733
|
pinnedTopData: pinnedTopRows,
|
|
2718
2734
|
pinnedBottomData: pinnedBottomRows,
|
|
2719
2735
|
gridTemplateColumns,
|
|
2720
|
-
headerHeight: HEADER_HEIGHT
|
|
2736
|
+
headerHeight: HEADER_HEIGHT,
|
|
2737
|
+
rowClassName,
|
|
2738
|
+
rowStyle
|
|
2721
2739
|
}
|
|
2722
2740
|
)
|
|
2723
2741
|
]
|
|
@@ -3174,7 +3192,42 @@ function BoltTable({
|
|
|
3174
3192
|
"Copy"
|
|
3175
3193
|
]
|
|
3176
3194
|
}
|
|
3177
|
-
)
|
|
3195
|
+
),
|
|
3196
|
+
menuCol?.columnCellContextMenuItems && menuCol.columnCellContextMenuItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
3197
|
+
(hasCopy || hasRowPin) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3198
|
+
"div",
|
|
3199
|
+
{
|
|
3200
|
+
style: {
|
|
3201
|
+
borderTop: "1px solid rgba(128,128,128,0.2)",
|
|
3202
|
+
margin: "4px 0"
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
),
|
|
3206
|
+
menuCol.columnCellContextMenuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
3207
|
+
"button",
|
|
3208
|
+
{
|
|
3209
|
+
"data-bt-ctx-item": "",
|
|
3210
|
+
disabled: item.disabled,
|
|
3211
|
+
style: {
|
|
3212
|
+
...btnStyle,
|
|
3213
|
+
cursor: item.disabled ? "not-allowed" : "pointer",
|
|
3214
|
+
opacity: item.disabled ? 0.5 : 1,
|
|
3215
|
+
color: item.danger ? "#ef4444" : "inherit"
|
|
3216
|
+
},
|
|
3217
|
+
onClick: () => {
|
|
3218
|
+
if (menuRecord) {
|
|
3219
|
+
item.onClick(menuCol.key, menuRecord, menuRowIndex);
|
|
3220
|
+
}
|
|
3221
|
+
setCellContextMenu(null);
|
|
3222
|
+
},
|
|
3223
|
+
children: [
|
|
3224
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { display: "flex", width: 14, height: 14, alignItems: "center", justifyContent: "center", flexShrink: 0 }, children: item.icon }),
|
|
3225
|
+
item.label
|
|
3226
|
+
]
|
|
3227
|
+
},
|
|
3228
|
+
item.key
|
|
3229
|
+
))
|
|
3230
|
+
] })
|
|
3178
3231
|
]
|
|
3179
3232
|
}
|
|
3180
3233
|
),
|
package/dist/index.mjs
CHANGED
|
@@ -679,7 +679,7 @@ var DraggableHeader = React.memo(
|
|
|
679
679
|
] });
|
|
680
680
|
},
|
|
681
681
|
(prevProps, nextProps) => {
|
|
682
|
-
return prevProps.column.width === nextProps.column.width && prevProps.column.key === nextProps.column.key && prevProps.column.pinned === nextProps.column.pinned && prevProps.column.sortable === nextProps.column.sortable && prevProps.column.filterable === nextProps.column.filterable && prevProps.column.sorter === nextProps.column.sorter && prevProps.column.filterFn === nextProps.column.filterFn && prevProps.visualIndex === nextProps.visualIndex && prevProps.stickyOffset === nextProps.stickyOffset && prevProps.isLastColumn === nextProps.isLastColumn && prevProps.sortDirection === nextProps.sortDirection && prevProps.filterValue === nextProps.filterValue && prevProps.classNames === nextProps.classNames && prevProps.styles === nextProps.styles;
|
|
682
|
+
return prevProps.column.width === nextProps.column.width && prevProps.column.key === nextProps.column.key && prevProps.column.pinned === nextProps.column.pinned && prevProps.column.sortable === nextProps.column.sortable && prevProps.column.filterable === nextProps.column.filterable && prevProps.column.sorter === nextProps.column.sorter && prevProps.column.filterFn === nextProps.column.filterFn && prevProps.visualIndex === nextProps.visualIndex && prevProps.stickyOffset === nextProps.stickyOffset && prevProps.isLastColumn === nextProps.isLastColumn && prevProps.sortDirection === nextProps.sortDirection && prevProps.filterValue === nextProps.filterValue && prevProps.classNames === nextProps.classNames && prevProps.styles === nextProps.styles && prevProps.customContextMenuItems === nextProps.customContextMenuItems;
|
|
683
683
|
}
|
|
684
684
|
);
|
|
685
685
|
DraggableHeader.displayName = "DraggableHeader";
|
|
@@ -1051,7 +1051,9 @@ var TableBody = ({
|
|
|
1051
1051
|
pinnedTopData = [],
|
|
1052
1052
|
pinnedBottomData = [],
|
|
1053
1053
|
gridTemplateColumns,
|
|
1054
|
-
headerHeight = 36
|
|
1054
|
+
headerHeight = 36,
|
|
1055
|
+
rowClassName,
|
|
1056
|
+
rowStyle
|
|
1055
1057
|
}) => {
|
|
1056
1058
|
const virtualItems = rowVirtualizer.getVirtualItems();
|
|
1057
1059
|
const totalSize = rowVirtualizer.getTotalSize();
|
|
@@ -1103,6 +1105,8 @@ var TableBody = ({
|
|
|
1103
1105
|
const cellValue = row[col.dataIndex];
|
|
1104
1106
|
const isRowShimmer = isLoading || rowKey.startsWith("__shimmer_");
|
|
1105
1107
|
const recordFingerprint = hasRender && !isRowShimmer ? JSON.stringify(row) : void 0;
|
|
1108
|
+
const rowCls = rowClassName ? rowClassName(row, virtualRow.index) : "";
|
|
1109
|
+
const rowSty = rowStyle ? rowStyle(row, virtualRow.index) : void 0;
|
|
1106
1110
|
return /* @__PURE__ */ jsx4(
|
|
1107
1111
|
"div",
|
|
1108
1112
|
{
|
|
@@ -1110,12 +1114,14 @@ var TableBody = ({
|
|
|
1110
1114
|
"data-column-key": col.key,
|
|
1111
1115
|
"data-bt-cell": "",
|
|
1112
1116
|
"data-selected": isSelected || void 0,
|
|
1117
|
+
className: rowCls || void 0,
|
|
1113
1118
|
style: {
|
|
1114
1119
|
position: "absolute",
|
|
1115
1120
|
top: `${virtualRow.start}px`,
|
|
1116
1121
|
left: 0,
|
|
1117
1122
|
right: 0,
|
|
1118
|
-
height: `${virtualRow.size}px
|
|
1123
|
+
height: `${virtualRow.size}px`,
|
|
1124
|
+
...rowSty
|
|
1119
1125
|
},
|
|
1120
1126
|
children: /* @__PURE__ */ jsx4(
|
|
1121
1127
|
"div",
|
|
@@ -1237,15 +1243,18 @@ var TableBody = ({
|
|
|
1237
1243
|
const rk = getRowKey ? getRowKey(row, rowIdx) : String(rowIdx);
|
|
1238
1244
|
const isSelected = selectedKeySet.has(rk);
|
|
1239
1245
|
const isExpanded = resolvedExpandedKeys?.has(rk) ?? false;
|
|
1246
|
+
const rowCls = rowClassName ? rowClassName(row, rowIdx) : "";
|
|
1247
|
+
const rowSty = rowStyle ? rowStyle(row, rowIdx) : void 0;
|
|
1240
1248
|
return /* @__PURE__ */ jsx4(
|
|
1241
1249
|
"div",
|
|
1242
1250
|
{
|
|
1243
|
-
className: classNames?.pinnedRow ?? "",
|
|
1251
|
+
className: `${classNames?.pinnedRow ?? ""} ${rowCls}`.trim() || void 0,
|
|
1244
1252
|
style: {
|
|
1245
1253
|
display: "grid",
|
|
1246
1254
|
gridTemplateColumns: gridTemplateColumns ?? "",
|
|
1247
1255
|
minWidth: totalTableWidth ? `${totalTableWidth}px` : void 0,
|
|
1248
|
-
...styles?.pinnedRow
|
|
1256
|
+
...styles?.pinnedRow,
|
|
1257
|
+
...rowSty
|
|
1249
1258
|
},
|
|
1250
1259
|
children: orderedColumns.map((col) => {
|
|
1251
1260
|
const cellValue = row[col.dataIndex];
|
|
@@ -1342,15 +1351,18 @@ var TableBody = ({
|
|
|
1342
1351
|
const rk = getRowKey ? getRowKey(row, rowIdx) : String(rowIdx);
|
|
1343
1352
|
const isSelected = selectedKeySet.has(rk);
|
|
1344
1353
|
const isExpanded = resolvedExpandedKeys?.has(rk) ?? false;
|
|
1354
|
+
const rowCls = rowClassName ? rowClassName(row, rowIdx) : "";
|
|
1355
|
+
const rowSty = rowStyle ? rowStyle(row, rowIdx) : void 0;
|
|
1345
1356
|
return /* @__PURE__ */ jsx4(
|
|
1346
1357
|
"div",
|
|
1347
1358
|
{
|
|
1348
|
-
className: classNames?.pinnedRow ?? "",
|
|
1359
|
+
className: `${classNames?.pinnedRow ?? ""} ${rowCls}`.trim() || void 0,
|
|
1349
1360
|
style: {
|
|
1350
1361
|
display: "grid",
|
|
1351
1362
|
gridTemplateColumns: gridTemplateColumns ?? "",
|
|
1352
1363
|
minWidth: totalTableWidth ? `${totalTableWidth}px` : void 0,
|
|
1353
|
-
...styles?.pinnedRow
|
|
1364
|
+
...styles?.pinnedRow,
|
|
1365
|
+
...rowSty
|
|
1354
1366
|
},
|
|
1355
1367
|
children: orderedColumns.map((col) => {
|
|
1356
1368
|
const cellValue = row[col.dataIndex];
|
|
@@ -1468,7 +1480,9 @@ function BoltTable({
|
|
|
1468
1480
|
columnContextMenuItems,
|
|
1469
1481
|
autoHeight = true,
|
|
1470
1482
|
layoutLoading,
|
|
1471
|
-
emptyRenderer
|
|
1483
|
+
emptyRenderer,
|
|
1484
|
+
rowClassName,
|
|
1485
|
+
rowStyle
|
|
1472
1486
|
}) {
|
|
1473
1487
|
const [columns, setColumns] = useState2(initialColumns);
|
|
1474
1488
|
const [columnOrder, setColumnOrder] = useState2(
|
|
@@ -2455,7 +2469,8 @@ function BoltTable({
|
|
|
2455
2469
|
);
|
|
2456
2470
|
const hasCopy = col?.copy;
|
|
2457
2471
|
const hasRowPin = !!onRowPin;
|
|
2458
|
-
|
|
2472
|
+
const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
|
|
2473
|
+
if (!hasCopy && !hasRowPin && !hasCellItems) return;
|
|
2459
2474
|
e.preventDefault();
|
|
2460
2475
|
setCellContextMenu({
|
|
2461
2476
|
x: Math.min(e.clientX, window.innerWidth - 200),
|
|
@@ -2483,7 +2498,8 @@ function BoltTable({
|
|
|
2483
2498
|
);
|
|
2484
2499
|
const hasCopy = col?.copy;
|
|
2485
2500
|
const hasRowPin = !!onRowPin;
|
|
2486
|
-
|
|
2501
|
+
const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
|
|
2502
|
+
if (!hasCopy && !hasRowPin && !hasCellItems) return;
|
|
2487
2503
|
setCellContextMenu({
|
|
2488
2504
|
x: Math.min(touch.clientX, window.innerWidth - 200),
|
|
2489
2505
|
y: Math.min(touch.clientY, window.innerHeight - 200),
|
|
@@ -2615,7 +2631,7 @@ function BoltTable({
|
|
|
2615
2631
|
filterValue: columnFilters[column.key] ?? "",
|
|
2616
2632
|
onFilter: handleColumnFilter,
|
|
2617
2633
|
onClearFilter: handleClearFilter,
|
|
2618
|
-
customContextMenuItems: columnContextMenuItems
|
|
2634
|
+
customContextMenuItems: column.columnHeaderContextMenuItems ? [...columnContextMenuItems ?? [], ...column.columnHeaderContextMenuItems] : columnContextMenuItems
|
|
2619
2635
|
},
|
|
2620
2636
|
column.key
|
|
2621
2637
|
);
|
|
@@ -2683,7 +2699,9 @@ function BoltTable({
|
|
|
2683
2699
|
pinnedTopData: pinnedTopRows,
|
|
2684
2700
|
pinnedBottomData: pinnedBottomRows,
|
|
2685
2701
|
gridTemplateColumns,
|
|
2686
|
-
headerHeight: HEADER_HEIGHT
|
|
2702
|
+
headerHeight: HEADER_HEIGHT,
|
|
2703
|
+
rowClassName,
|
|
2704
|
+
rowStyle
|
|
2687
2705
|
}
|
|
2688
2706
|
)
|
|
2689
2707
|
]
|
|
@@ -3140,7 +3158,42 @@ function BoltTable({
|
|
|
3140
3158
|
"Copy"
|
|
3141
3159
|
]
|
|
3142
3160
|
}
|
|
3143
|
-
)
|
|
3161
|
+
),
|
|
3162
|
+
menuCol?.columnCellContextMenuItems && menuCol.columnCellContextMenuItems.length > 0 && /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
3163
|
+
(hasCopy || hasRowPin) && /* @__PURE__ */ jsx5(
|
|
3164
|
+
"div",
|
|
3165
|
+
{
|
|
3166
|
+
style: {
|
|
3167
|
+
borderTop: "1px solid rgba(128,128,128,0.2)",
|
|
3168
|
+
margin: "4px 0"
|
|
3169
|
+
}
|
|
3170
|
+
}
|
|
3171
|
+
),
|
|
3172
|
+
menuCol.columnCellContextMenuItems.map((item) => /* @__PURE__ */ jsxs5(
|
|
3173
|
+
"button",
|
|
3174
|
+
{
|
|
3175
|
+
"data-bt-ctx-item": "",
|
|
3176
|
+
disabled: item.disabled,
|
|
3177
|
+
style: {
|
|
3178
|
+
...btnStyle,
|
|
3179
|
+
cursor: item.disabled ? "not-allowed" : "pointer",
|
|
3180
|
+
opacity: item.disabled ? 0.5 : 1,
|
|
3181
|
+
color: item.danger ? "#ef4444" : "inherit"
|
|
3182
|
+
},
|
|
3183
|
+
onClick: () => {
|
|
3184
|
+
if (menuRecord) {
|
|
3185
|
+
item.onClick(menuCol.key, menuRecord, menuRowIndex);
|
|
3186
|
+
}
|
|
3187
|
+
setCellContextMenu(null);
|
|
3188
|
+
},
|
|
3189
|
+
children: [
|
|
3190
|
+
item.icon && /* @__PURE__ */ jsx5("span", { style: { display: "flex", width: 14, height: 14, alignItems: "center", justifyContent: "center", flexShrink: 0 }, children: item.icon }),
|
|
3191
|
+
item.label
|
|
3192
|
+
]
|
|
3193
|
+
},
|
|
3194
|
+
item.key
|
|
3195
|
+
))
|
|
3196
|
+
] })
|
|
3144
3197
|
]
|
|
3145
3198
|
}
|
|
3146
3199
|
),
|
package/package.json
CHANGED