bolt-table 0.1.16 → 0.1.18
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 +26 -8
- package/dist/index.d.ts +26 -8
- package/dist/index.js +133 -44
- package/dist/index.mjs +133 -44
- 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 {
|
|
@@ -133,6 +152,10 @@ interface PaginationType {
|
|
|
133
152
|
total?: number;
|
|
134
153
|
/** Custom renderer for the "showing X–Y of Z" text in the pagination footer. */
|
|
135
154
|
showTotal?: (total: number, range: [number, number]) => ReactNode;
|
|
155
|
+
/** When `true`, hides the page-size dropdown selector in the pagination footer. */
|
|
156
|
+
hidePageSelector?: boolean;
|
|
157
|
+
/** Custom page-size options shown in the dropdown. Defaults to `[10, 15, 20, 25, 50, 100]`. */
|
|
158
|
+
pageSizeOptions?: number[];
|
|
136
159
|
}
|
|
137
160
|
/** Configuration for row pinning. Pinned rows remain visible during vertical scroll. */
|
|
138
161
|
interface RowPinningConfig {
|
|
@@ -183,9 +206,9 @@ interface BoltTableProps<T extends DataRecord = DataRecord> {
|
|
|
183
206
|
readonly onColumnHide?: (columnKey: string, hidden: boolean) => void;
|
|
184
207
|
/** Determines the unique key for each row. Can be a string property name, function, number, or symbol. */
|
|
185
208
|
readonly rowKey?: string | ((record: T) => string) | number | symbol;
|
|
186
|
-
/** Row selection configuration. Prepends a checkbox/radio column when provided. */
|
|
187
|
-
expandable?: ExpandableConfig<T>;
|
|
188
209
|
/** Expandable row configuration. Prepends an expand toggle column when provided. */
|
|
210
|
+
readonly expandable?: ExpandableConfig<T>;
|
|
211
|
+
/** Row selection configuration. Prepends a checkbox/radio column when provided. */
|
|
189
212
|
readonly rowSelection?: RowSelectionConfig<T>;
|
|
190
213
|
/** Row pinning configuration. Specified rows render as sticky at top and/or bottom. */
|
|
191
214
|
readonly rowPinning?: RowPinningConfig;
|
|
@@ -197,11 +220,6 @@ interface BoltTableProps<T extends DataRecord = DataRecord> {
|
|
|
197
220
|
readonly onEndReachedThreshold?: number;
|
|
198
221
|
/** When true and data is empty, shows shimmer skeleton rows. With data, appends shimmer rows at bottom. */
|
|
199
222
|
readonly isLoading?: boolean;
|
|
200
|
-
/** Scroll indicator configuration (reserved for future use). */
|
|
201
|
-
readonly scrollIndicators?: {
|
|
202
|
-
vertical?: boolean;
|
|
203
|
-
horizontal?: boolean;
|
|
204
|
-
};
|
|
205
223
|
/** Called when the user changes sort direction. Provide for server-side sorting. */
|
|
206
224
|
readonly onSortChange?: (columnKey: string, direction: SortDirection) => void;
|
|
207
225
|
/** Called when the user applies or clears a column filter. Provide for server-side filtering. */
|
|
@@ -366,4 +384,4 @@ interface TableBodyProps {
|
|
|
366
384
|
}
|
|
367
385
|
declare const TableBody: React$1.FC<TableBodyProps>;
|
|
368
386
|
|
|
369
|
-
export { BoltTable, type BoltTableIcons, type ColumnContextMenuItem, type ColumnType, type DataRecord, DraggableHeader, type ExpandableConfig, type PaginationType, ResizeOverlay, type RowPinningConfig, type RowSelectionConfig, type SortDirection, TableBody };
|
|
387
|
+
export { BoltTable, type BoltTableIcons, type CellContextMenuItem, 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
|
@@ -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 {
|
|
@@ -133,6 +152,10 @@ interface PaginationType {
|
|
|
133
152
|
total?: number;
|
|
134
153
|
/** Custom renderer for the "showing X–Y of Z" text in the pagination footer. */
|
|
135
154
|
showTotal?: (total: number, range: [number, number]) => ReactNode;
|
|
155
|
+
/** When `true`, hides the page-size dropdown selector in the pagination footer. */
|
|
156
|
+
hidePageSelector?: boolean;
|
|
157
|
+
/** Custom page-size options shown in the dropdown. Defaults to `[10, 15, 20, 25, 50, 100]`. */
|
|
158
|
+
pageSizeOptions?: number[];
|
|
136
159
|
}
|
|
137
160
|
/** Configuration for row pinning. Pinned rows remain visible during vertical scroll. */
|
|
138
161
|
interface RowPinningConfig {
|
|
@@ -183,9 +206,9 @@ interface BoltTableProps<T extends DataRecord = DataRecord> {
|
|
|
183
206
|
readonly onColumnHide?: (columnKey: string, hidden: boolean) => void;
|
|
184
207
|
/** Determines the unique key for each row. Can be a string property name, function, number, or symbol. */
|
|
185
208
|
readonly rowKey?: string | ((record: T) => string) | number | symbol;
|
|
186
|
-
/** Row selection configuration. Prepends a checkbox/radio column when provided. */
|
|
187
|
-
expandable?: ExpandableConfig<T>;
|
|
188
209
|
/** Expandable row configuration. Prepends an expand toggle column when provided. */
|
|
210
|
+
readonly expandable?: ExpandableConfig<T>;
|
|
211
|
+
/** Row selection configuration. Prepends a checkbox/radio column when provided. */
|
|
189
212
|
readonly rowSelection?: RowSelectionConfig<T>;
|
|
190
213
|
/** Row pinning configuration. Specified rows render as sticky at top and/or bottom. */
|
|
191
214
|
readonly rowPinning?: RowPinningConfig;
|
|
@@ -197,11 +220,6 @@ interface BoltTableProps<T extends DataRecord = DataRecord> {
|
|
|
197
220
|
readonly onEndReachedThreshold?: number;
|
|
198
221
|
/** When true and data is empty, shows shimmer skeleton rows. With data, appends shimmer rows at bottom. */
|
|
199
222
|
readonly isLoading?: boolean;
|
|
200
|
-
/** Scroll indicator configuration (reserved for future use). */
|
|
201
|
-
readonly scrollIndicators?: {
|
|
202
|
-
vertical?: boolean;
|
|
203
|
-
horizontal?: boolean;
|
|
204
|
-
};
|
|
205
223
|
/** Called when the user changes sort direction. Provide for server-side sorting. */
|
|
206
224
|
readonly onSortChange?: (columnKey: string, direction: SortDirection) => void;
|
|
207
225
|
/** Called when the user applies or clears a column filter. Provide for server-side filtering. */
|
|
@@ -366,4 +384,4 @@ interface TableBodyProps {
|
|
|
366
384
|
}
|
|
367
385
|
declare const TableBody: React$1.FC<TableBodyProps>;
|
|
368
386
|
|
|
369
|
-
export { BoltTable, type BoltTableIcons, type ColumnContextMenuItem, type ColumnType, type DataRecord, DraggableHeader, type ExpandableConfig, type PaginationType, ResizeOverlay, type RowPinningConfig, type RowSelectionConfig, type SortDirection, TableBody };
|
|
387
|
+
export { BoltTable, type BoltTableIcons, type CellContextMenuItem, type ColumnContextMenuItem, type ColumnType, type DataRecord, DraggableHeader, type ExpandableConfig, type PaginationType, ResizeOverlay, type RowPinningConfig, type RowSelectionConfig, type SortDirection, TableBody };
|
package/dist/index.js
CHANGED
|
@@ -231,26 +231,21 @@ var DraggableHeader = import_react.default.memo(
|
|
|
231
231
|
...isLastColumn ? {} : { maxWidth: widthPx },
|
|
232
232
|
gridColumn: visualIndex + 1,
|
|
233
233
|
gridRow: 1,
|
|
234
|
+
display: "flex",
|
|
235
|
+
height: 36,
|
|
236
|
+
alignItems: "center",
|
|
237
|
+
overflow: "hidden",
|
|
238
|
+
textOverflow: "ellipsis",
|
|
239
|
+
whiteSpace: "nowrap",
|
|
234
240
|
borderTop: "none",
|
|
235
241
|
borderRight: "none",
|
|
236
242
|
borderBottom: "1px solid rgba(128,128,128,0.2)",
|
|
237
243
|
borderLeft: "none",
|
|
238
244
|
...column.pinned === "left" && stickyOffset !== void 0 ? { left: `${stickyOffset}px` } : {},
|
|
239
245
|
...column.pinned === "right" && stickyOffset !== void 0 ? { right: `${stickyOffset}px` } : {},
|
|
240
|
-
...isPinned ? {
|
|
241
|
-
backgroundColor: styles?.pinnedBg,
|
|
242
|
-
...styles?.pinnedHeader
|
|
243
|
-
} : {},
|
|
244
246
|
...column.style,
|
|
245
|
-
...styles?.
|
|
246
|
-
|
|
247
|
-
display: "flex",
|
|
248
|
-
height: 36,
|
|
249
|
-
alignItems: "center",
|
|
250
|
-
overflow: "hidden",
|
|
251
|
-
textOverflow: "ellipsis",
|
|
252
|
-
whiteSpace: "nowrap",
|
|
253
|
-
...isPinned ? {} : { backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)" }
|
|
247
|
+
...isPinned ? styles?.pinnedHeader : {},
|
|
248
|
+
...styles?.header
|
|
254
249
|
};
|
|
255
250
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
256
251
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
@@ -258,6 +253,7 @@ var DraggableHeader = import_react.default.memo(
|
|
|
258
253
|
{
|
|
259
254
|
"data-column-key": column.key,
|
|
260
255
|
"data-bt-header": "",
|
|
256
|
+
...isPinned ? { "data-bt-pinned": "" } : {},
|
|
261
257
|
style: headerStyle,
|
|
262
258
|
className: `${column.className ?? ""} ${classNames?.header ?? ""} ${isPinned ? classNames?.pinnedHeader ?? "" : ""}`,
|
|
263
259
|
onContextMenu: handleContextMenu,
|
|
@@ -717,7 +713,7 @@ var DraggableHeader = import_react.default.memo(
|
|
|
717
713
|
] });
|
|
718
714
|
},
|
|
719
715
|
(prevProps, nextProps) => {
|
|
720
|
-
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;
|
|
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;
|
|
721
717
|
}
|
|
722
718
|
);
|
|
723
719
|
DraggableHeader.displayName = "DraggableHeader";
|
|
@@ -907,7 +903,8 @@ var Cell = import_react3.default.memo(
|
|
|
907
903
|
height: "100%",
|
|
908
904
|
boxSizing: "border-box",
|
|
909
905
|
...column.style,
|
|
910
|
-
...isPinned ? styles?.pinnedCell : void 0
|
|
906
|
+
...isPinned ? styles?.pinnedCell : void 0,
|
|
907
|
+
...styles?.cell
|
|
911
908
|
},
|
|
912
909
|
children: shimmerContent
|
|
913
910
|
}
|
|
@@ -963,7 +960,7 @@ var Cell = import_react3.default.memo(
|
|
|
963
960
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
964
961
|
"div",
|
|
965
962
|
{
|
|
966
|
-
className: `${column.className ?? ""} ${classNames?.cell ?? ""}`,
|
|
963
|
+
className: `${column.className ?? ""} ${classNames?.cell ?? ""} ${isPinned ? classNames?.pinnedCell ?? "" : ""}`,
|
|
967
964
|
style: {
|
|
968
965
|
display: "flex",
|
|
969
966
|
alignItems: "center",
|
|
@@ -975,38 +972,55 @@ var Cell = import_react3.default.memo(
|
|
|
975
972
|
height: "100%",
|
|
976
973
|
boxSizing: "border-box",
|
|
977
974
|
...column.style,
|
|
978
|
-
...isPinned ? styles?.pinnedCell : void 0
|
|
975
|
+
...isPinned ? styles?.pinnedCell : void 0,
|
|
976
|
+
...styles?.cell
|
|
979
977
|
},
|
|
980
978
|
children: content2
|
|
981
979
|
}
|
|
982
980
|
);
|
|
983
981
|
}
|
|
984
982
|
const content = column.render ? column.render(value, record, rowIndex) : value ?? "";
|
|
983
|
+
const isSystem = column.key === "__select__" || column.key === "__expand__";
|
|
985
984
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
986
985
|
"div",
|
|
987
986
|
{
|
|
988
|
-
className: `${column.className ?? ""} ${classNames?.cell ?? ""}`,
|
|
987
|
+
className: `${column.className ?? ""} ${classNames?.cell ?? ""} ${isPinned ? classNames?.pinnedCell ?? "" : ""}`,
|
|
989
988
|
style: {
|
|
990
989
|
display: "flex",
|
|
991
990
|
alignItems: "center",
|
|
992
991
|
overflow: "hidden",
|
|
993
|
-
textOverflow: "ellipsis",
|
|
994
|
-
whiteSpace: "nowrap",
|
|
995
992
|
borderBottom: "1px solid rgba(128,128,128,0.2)",
|
|
996
993
|
paddingLeft: 8,
|
|
997
994
|
paddingRight: 8,
|
|
998
|
-
justifyContent:
|
|
995
|
+
justifyContent: isSystem ? "center" : void 0,
|
|
999
996
|
height: "100%",
|
|
1000
997
|
boxSizing: "border-box",
|
|
998
|
+
minWidth: 0,
|
|
1001
999
|
...column.style,
|
|
1002
|
-
...isPinned ? styles?.pinnedCell : void 0
|
|
1000
|
+
...isPinned ? styles?.pinnedCell : void 0,
|
|
1001
|
+
...styles?.cell
|
|
1003
1002
|
},
|
|
1004
|
-
children: content
|
|
1003
|
+
children: isSystem ? content : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1004
|
+
"div",
|
|
1005
|
+
{
|
|
1006
|
+
style: {
|
|
1007
|
+
overflow: "hidden",
|
|
1008
|
+
textOverflow: "ellipsis",
|
|
1009
|
+
whiteSpace: "nowrap",
|
|
1010
|
+
minWidth: 0,
|
|
1011
|
+
maxWidth: "100%"
|
|
1012
|
+
},
|
|
1013
|
+
children: content
|
|
1014
|
+
}
|
|
1015
|
+
)
|
|
1005
1016
|
}
|
|
1006
1017
|
);
|
|
1007
1018
|
},
|
|
1008
1019
|
(prev, next) => {
|
|
1009
1020
|
if (prev.isLoading !== next.isLoading) return false;
|
|
1021
|
+
if (prev.column.pinned !== next.column.pinned) return false;
|
|
1022
|
+
if (prev.classNames !== next.classNames) return false;
|
|
1023
|
+
if (prev.styles !== next.styles) return false;
|
|
1010
1024
|
if (prev.column.key === "__select__") {
|
|
1011
1025
|
return prev.isSelected === next.isSelected && prev.normalizedSelectedKeys === next.normalizedSelectedKeys;
|
|
1012
1026
|
}
|
|
@@ -1101,7 +1115,6 @@ var TableBody = ({
|
|
|
1101
1115
|
else if (col.pinned === "right" && stickyOffset !== void 0)
|
|
1102
1116
|
style.right = `${stickyOffset}px`;
|
|
1103
1117
|
if (isPinned) {
|
|
1104
|
-
style.backgroundColor = styles?.pinnedBg;
|
|
1105
1118
|
if (styles?.pinnedCell) Object.assign(style, styles.pinnedCell);
|
|
1106
1119
|
}
|
|
1107
1120
|
return { key: col.key, style, isPinned };
|
|
@@ -1114,6 +1127,7 @@ var TableBody = ({
|
|
|
1114
1127
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1115
1128
|
"div",
|
|
1116
1129
|
{
|
|
1130
|
+
...colStyle.isPinned ? { "data-bt-pinned": "" } : {},
|
|
1117
1131
|
style: colStyle.style,
|
|
1118
1132
|
children: virtualItems.map((virtualRow) => {
|
|
1119
1133
|
const row = data[virtualRow.index];
|
|
@@ -1454,6 +1468,8 @@ function arrayMove(arr, from, to) {
|
|
|
1454
1468
|
return result;
|
|
1455
1469
|
}
|
|
1456
1470
|
var SHIMMER_WIDTHS2 = [55, 70, 45, 80, 60, 50, 75, 65, 40, 72];
|
|
1471
|
+
var EMPTY_CLASSNAMES = {};
|
|
1472
|
+
var EMPTY_STYLES = {};
|
|
1457
1473
|
function BoltTable({
|
|
1458
1474
|
columns: initialColumns,
|
|
1459
1475
|
data,
|
|
@@ -1462,8 +1478,8 @@ function BoltTable({
|
|
|
1462
1478
|
maxExpandedRowHeight,
|
|
1463
1479
|
accentColor = "#1890ff",
|
|
1464
1480
|
className = "",
|
|
1465
|
-
classNames =
|
|
1466
|
-
styles =
|
|
1481
|
+
classNames = EMPTY_CLASSNAMES,
|
|
1482
|
+
styles = EMPTY_STYLES,
|
|
1467
1483
|
gripIcon,
|
|
1468
1484
|
hideGripIcon,
|
|
1469
1485
|
icons,
|
|
@@ -1493,6 +1509,10 @@ function BoltTable({
|
|
|
1493
1509
|
() => initialColumns.map((c) => c.key)
|
|
1494
1510
|
);
|
|
1495
1511
|
const [activeId, setActiveId] = (0, import_react4.useState)(null);
|
|
1512
|
+
const [mounted, setMounted] = (0, import_react4.useState)(false);
|
|
1513
|
+
import_react4.default.useEffect(() => {
|
|
1514
|
+
setMounted(true);
|
|
1515
|
+
}, []);
|
|
1496
1516
|
const columnsFingerprintRef = (0, import_react4.useRef)("");
|
|
1497
1517
|
const newFingerprint = initialColumns.map((c) => {
|
|
1498
1518
|
const w = typeof c.width === "number" ? Math.round(c.width) : c.width ?? "";
|
|
@@ -1728,6 +1748,9 @@ function BoltTable({
|
|
|
1728
1748
|
ghost.style.left = `${e.clientX - offsetX}px`;
|
|
1729
1749
|
ghost.style.top = `${rect.top}px`;
|
|
1730
1750
|
}
|
|
1751
|
+
const grabStyle = document.createElement("style");
|
|
1752
|
+
grabStyle.textContent = "* { cursor: grabbing !important; }";
|
|
1753
|
+
document.head.appendChild(grabStyle);
|
|
1731
1754
|
const onMove = (ev) => {
|
|
1732
1755
|
if (ghost) {
|
|
1733
1756
|
ghost.style.left = `${ev.clientX - offsetX}px`;
|
|
@@ -1756,6 +1779,7 @@ function BoltTable({
|
|
|
1756
1779
|
const onUp = () => {
|
|
1757
1780
|
document.removeEventListener("pointermove", onMove);
|
|
1758
1781
|
document.removeEventListener("pointerup", onUp);
|
|
1782
|
+
grabStyle.remove();
|
|
1759
1783
|
const scrollEl = tableAreaRef.current;
|
|
1760
1784
|
if (scrollEl) {
|
|
1761
1785
|
scrollEl.querySelectorAll("[data-dragging]").forEach((h) => h.removeAttribute("data-dragging"));
|
|
@@ -2084,11 +2108,17 @@ function BoltTable({
|
|
|
2084
2108
|
}, [cellContextMenu]);
|
|
2085
2109
|
const columnFiltersKey = Object.keys(columnFilters).sort().map((k) => `${k}:${columnFilters[k]}`).join("|");
|
|
2086
2110
|
import_react4.default.useEffect(() => {
|
|
2111
|
+
setInternalPage(1);
|
|
2087
2112
|
tableAreaRef.current?.scrollTo({ top: 0 });
|
|
2088
2113
|
}, [columnFiltersKey]);
|
|
2089
|
-
const
|
|
2090
|
-
const
|
|
2091
|
-
const
|
|
2114
|
+
const DEFAULT_PAGE_SIZE = 15;
|
|
2115
|
+
const [internalPage, setInternalPage] = (0, import_react4.useState)(1);
|
|
2116
|
+
const [internalPageSize, setInternalPageSize] = (0, import_react4.useState)(DEFAULT_PAGE_SIZE);
|
|
2117
|
+
const autoPagination = pagination === void 0 && data.length > DEFAULT_PAGE_SIZE;
|
|
2118
|
+
const pgEnabled = pagination === false ? false : !!pagination || autoPagination;
|
|
2119
|
+
const pgSize = pgEnabled && typeof pagination === "object" && pagination?.pageSize !== void 0 ? pagination.pageSize : internalPageSize;
|
|
2120
|
+
const isControlledPagination = typeof pagination === "object" && pagination?.current !== void 0;
|
|
2121
|
+
const pgCurrent = pgEnabled ? isControlledPagination ? Number(pagination.current) : internalPage : 1;
|
|
2092
2122
|
const needsClientPagination = pgEnabled && unpinnedProcessedData.length > pgSize;
|
|
2093
2123
|
const paginatedData = (0, import_react4.useMemo)(() => {
|
|
2094
2124
|
if (!needsClientPagination) return unpinnedProcessedData;
|
|
@@ -2194,17 +2224,29 @@ function BoltTable({
|
|
|
2194
2224
|
const activeColumn = activeId ? orderedColumns.find((col) => col.key === activeId) : null;
|
|
2195
2225
|
const currentPage = pgCurrent;
|
|
2196
2226
|
const pageSize = pgSize;
|
|
2197
|
-
const rawTotal = pgEnabled ? pagination
|
|
2227
|
+
const rawTotal = pgEnabled ? (typeof pagination === "object" ? pagination?.total : void 0) ?? (needsClientPagination ? unpinnedProcessedData.length : data.length) : data.length;
|
|
2198
2228
|
const lastKnownTotalRef = (0, import_react4.useRef)(0);
|
|
2199
2229
|
if (!isLoading || rawTotal > 0) {
|
|
2200
2230
|
lastKnownTotalRef.current = rawTotal;
|
|
2201
2231
|
}
|
|
2202
2232
|
const total = isLoading && lastKnownTotalRef.current > 0 ? lastKnownTotalRef.current : rawTotal;
|
|
2203
2233
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
2234
|
+
import_react4.default.useEffect(() => {
|
|
2235
|
+
if (internalPage > totalPages) {
|
|
2236
|
+
setInternalPage(Math.max(1, totalPages));
|
|
2237
|
+
}
|
|
2238
|
+
}, [totalPages, internalPage]);
|
|
2204
2239
|
const handlePageChange = (p) => {
|
|
2205
|
-
if (p >= 1 && p <= totalPages)
|
|
2240
|
+
if (p >= 1 && p <= totalPages) {
|
|
2241
|
+
setInternalPage(p);
|
|
2242
|
+
onPaginationChange?.(p, pageSize);
|
|
2243
|
+
}
|
|
2244
|
+
};
|
|
2245
|
+
const handlePageSizeChange = (s) => {
|
|
2246
|
+
setInternalPage(1);
|
|
2247
|
+
setInternalPageSize(s);
|
|
2248
|
+
onPaginationChange?.(1, s);
|
|
2206
2249
|
};
|
|
2207
|
-
const handlePageSizeChange = (s) => onPaginationChange?.(1, s);
|
|
2208
2250
|
import_react4.default.useEffect(() => {
|
|
2209
2251
|
if (needsClientPagination) {
|
|
2210
2252
|
tableAreaRef.current?.scrollTo({ top: 0 });
|
|
@@ -2260,6 +2302,14 @@ function BoltTable({
|
|
|
2260
2302
|
0%, 100% { opacity: 1; }
|
|
2261
2303
|
50% { opacity: 0.5; }
|
|
2262
2304
|
}
|
|
2305
|
+
:where([data-bt-header]) {
|
|
2306
|
+
background-color: rgba(128,128,128,0.06);
|
|
2307
|
+
backdrop-filter: blur(8px);
|
|
2308
|
+
-webkit-backdrop-filter: blur(8px);
|
|
2309
|
+
}
|
|
2310
|
+
:where([data-bt-pinned]) {
|
|
2311
|
+
background-color: ${styles.pinnedBg ?? "Canvas"};
|
|
2312
|
+
}
|
|
2263
2313
|
[data-row-key][data-hover] > div {
|
|
2264
2314
|
background-color: ${styles.rowHover?.backgroundColor ?? "rgba(128, 128, 128, 0.1)"};
|
|
2265
2315
|
}
|
|
@@ -2439,7 +2489,8 @@ function BoltTable({
|
|
|
2439
2489
|
);
|
|
2440
2490
|
const hasCopy = col?.copy;
|
|
2441
2491
|
const hasRowPin = !!onRowPin;
|
|
2442
|
-
|
|
2492
|
+
const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
|
|
2493
|
+
if (!hasCopy && !hasRowPin && !hasCellItems) return;
|
|
2443
2494
|
e.preventDefault();
|
|
2444
2495
|
setCellContextMenu({
|
|
2445
2496
|
x: Math.min(e.clientX, window.innerWidth - 200),
|
|
@@ -2467,7 +2518,8 @@ function BoltTable({
|
|
|
2467
2518
|
);
|
|
2468
2519
|
const hasCopy = col?.copy;
|
|
2469
2520
|
const hasRowPin = !!onRowPin;
|
|
2470
|
-
|
|
2521
|
+
const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
|
|
2522
|
+
if (!hasCopy && !hasRowPin && !hasCellItems) return;
|
|
2471
2523
|
setCellContextMenu({
|
|
2472
2524
|
x: Math.min(touch.clientX, window.innerWidth - 200),
|
|
2473
2525
|
y: Math.min(touch.clientY, window.innerHeight - 200),
|
|
@@ -2492,6 +2544,8 @@ function BoltTable({
|
|
|
2492
2544
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2493
2545
|
"div",
|
|
2494
2546
|
{
|
|
2547
|
+
"data-bt-header": "",
|
|
2548
|
+
"data-bt-pinned": "",
|
|
2495
2549
|
className: `${classNames.header ?? ""} ${classNames.pinnedHeader ?? ""}`,
|
|
2496
2550
|
style: {
|
|
2497
2551
|
display: "flex",
|
|
@@ -2502,7 +2556,6 @@ function BoltTable({
|
|
|
2502
2556
|
textOverflow: "ellipsis",
|
|
2503
2557
|
whiteSpace: "nowrap",
|
|
2504
2558
|
borderBottom: "1px solid rgba(128,128,128,0.2)",
|
|
2505
|
-
backgroundColor: styles?.pinnedBg,
|
|
2506
2559
|
position: "sticky",
|
|
2507
2560
|
left: columnOffsets.get("__select__") ?? 0,
|
|
2508
2561
|
top: 0,
|
|
@@ -2552,6 +2605,8 @@ function BoltTable({
|
|
|
2552
2605
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2553
2606
|
"div",
|
|
2554
2607
|
{
|
|
2608
|
+
"data-bt-header": "",
|
|
2609
|
+
"data-bt-pinned": "",
|
|
2555
2610
|
className: `${classNames.header ?? ""} ${classNames.pinnedHeader ?? ""}`,
|
|
2556
2611
|
style: {
|
|
2557
2612
|
display: "flex",
|
|
@@ -2562,7 +2617,6 @@ function BoltTable({
|
|
|
2562
2617
|
textOverflow: "ellipsis",
|
|
2563
2618
|
whiteSpace: "nowrap",
|
|
2564
2619
|
borderBottom: "1px solid rgba(128,128,128,0.2)",
|
|
2565
|
-
backgroundColor: styles?.pinnedBg,
|
|
2566
2620
|
position: "sticky",
|
|
2567
2621
|
left: columnOffsets.get("__expand__") ?? 0,
|
|
2568
2622
|
top: 0,
|
|
@@ -2597,7 +2651,7 @@ function BoltTable({
|
|
|
2597
2651
|
filterValue: columnFilters[column.key] ?? "",
|
|
2598
2652
|
onFilter: handleColumnFilter,
|
|
2599
2653
|
onClearFilter: handleClearFilter,
|
|
2600
|
-
customContextMenuItems: columnContextMenuItems
|
|
2654
|
+
customContextMenuItems: column.columnHeaderContextMenuItems ? [...columnContextMenuItems ?? [], ...column.columnHeaderContextMenuItems] : columnContextMenuItems
|
|
2601
2655
|
},
|
|
2602
2656
|
column.key
|
|
2603
2657
|
);
|
|
@@ -2676,7 +2730,7 @@ function BoltTable({
|
|
|
2676
2730
|
)
|
|
2677
2731
|
}
|
|
2678
2732
|
),
|
|
2679
|
-
|
|
2733
|
+
pgEnabled && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2680
2734
|
"div",
|
|
2681
2735
|
{
|
|
2682
2736
|
style: {
|
|
@@ -2696,7 +2750,7 @@ function BoltTable({
|
|
|
2696
2750
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { display: "flex", flex: "1 1 0%", alignItems: "center" }, children: (() => {
|
|
2697
2751
|
const rangeStart = total > 0 ? (currentPage - 1) * pageSize + 1 : 0;
|
|
2698
2752
|
const rangeEnd = Math.min(currentPage * pageSize, total);
|
|
2699
|
-
return pagination?.showTotal ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { style: { color: "GrayText", fontSize: 12 }, children: [
|
|
2753
|
+
return typeof pagination === "object" && pagination?.showTotal ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { style: { color: "GrayText", fontSize: 12 }, children: [
|
|
2700
2754
|
"Showing",
|
|
2701
2755
|
" ",
|
|
2702
2756
|
pagination.showTotal(total, [rangeStart, rangeEnd]),
|
|
@@ -2869,7 +2923,7 @@ function BoltTable({
|
|
|
2869
2923
|
justifyContent: "flex-end",
|
|
2870
2924
|
gap: 8
|
|
2871
2925
|
},
|
|
2872
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2926
|
+
children: typeof pagination === "object" && pagination?.hidePageSelector ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2873
2927
|
"select",
|
|
2874
2928
|
{
|
|
2875
2929
|
value: pageSize,
|
|
@@ -2887,7 +2941,7 @@ function BoltTable({
|
|
|
2887
2941
|
background: "inherit",
|
|
2888
2942
|
color: "inherit"
|
|
2889
2943
|
},
|
|
2890
|
-
children: [10, 15, 20, 25, 50, 100].map((size) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("option", { value: size, children: [
|
|
2944
|
+
children: (typeof pagination === "object" && pagination?.pageSizeOptions ? pagination.pageSizeOptions : [10, 15, 20, 25, 50, 100]).map((size) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("option", { value: size, children: [
|
|
2891
2945
|
size,
|
|
2892
2946
|
" / page"
|
|
2893
2947
|
] }, size))
|
|
@@ -2901,7 +2955,7 @@ function BoltTable({
|
|
|
2901
2955
|
]
|
|
2902
2956
|
}
|
|
2903
2957
|
),
|
|
2904
|
-
|
|
2958
|
+
mounted && (0, import_react_dom2.createPortal)(
|
|
2905
2959
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2906
2960
|
"div",
|
|
2907
2961
|
{
|
|
@@ -2970,7 +3024,7 @@ function BoltTable({
|
|
|
2970
3024
|
),
|
|
2971
3025
|
document.body
|
|
2972
3026
|
),
|
|
2973
|
-
cellContextMenu &&
|
|
3027
|
+
cellContextMenu && mounted && (() => {
|
|
2974
3028
|
const menuCol = freshOrderedColumns.find(
|
|
2975
3029
|
(c) => c.key === cellContextMenu.columnKey
|
|
2976
3030
|
);
|
|
@@ -3122,7 +3176,42 @@ function BoltTable({
|
|
|
3122
3176
|
"Copy"
|
|
3123
3177
|
]
|
|
3124
3178
|
}
|
|
3125
|
-
)
|
|
3179
|
+
),
|
|
3180
|
+
menuCol?.columnCellContextMenuItems && menuCol.columnCellContextMenuItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
3181
|
+
(hasCopy || hasRowPin) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3182
|
+
"div",
|
|
3183
|
+
{
|
|
3184
|
+
style: {
|
|
3185
|
+
borderTop: "1px solid rgba(128,128,128,0.2)",
|
|
3186
|
+
margin: "4px 0"
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3189
|
+
),
|
|
3190
|
+
menuCol.columnCellContextMenuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
3191
|
+
"button",
|
|
3192
|
+
{
|
|
3193
|
+
"data-bt-ctx-item": "",
|
|
3194
|
+
disabled: item.disabled,
|
|
3195
|
+
style: {
|
|
3196
|
+
...btnStyle,
|
|
3197
|
+
cursor: item.disabled ? "not-allowed" : "pointer",
|
|
3198
|
+
opacity: item.disabled ? 0.5 : 1,
|
|
3199
|
+
color: item.danger ? "#ef4444" : "inherit"
|
|
3200
|
+
},
|
|
3201
|
+
onClick: () => {
|
|
3202
|
+
if (menuRecord) {
|
|
3203
|
+
item.onClick(menuCol.key, menuRecord, menuRowIndex);
|
|
3204
|
+
}
|
|
3205
|
+
setCellContextMenu(null);
|
|
3206
|
+
},
|
|
3207
|
+
children: [
|
|
3208
|
+
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 }),
|
|
3209
|
+
item.label
|
|
3210
|
+
]
|
|
3211
|
+
},
|
|
3212
|
+
item.key
|
|
3213
|
+
))
|
|
3214
|
+
] })
|
|
3126
3215
|
]
|
|
3127
3216
|
}
|
|
3128
3217
|
),
|
package/dist/index.mjs
CHANGED
|
@@ -197,26 +197,21 @@ var DraggableHeader = React.memo(
|
|
|
197
197
|
...isLastColumn ? {} : { maxWidth: widthPx },
|
|
198
198
|
gridColumn: visualIndex + 1,
|
|
199
199
|
gridRow: 1,
|
|
200
|
+
display: "flex",
|
|
201
|
+
height: 36,
|
|
202
|
+
alignItems: "center",
|
|
203
|
+
overflow: "hidden",
|
|
204
|
+
textOverflow: "ellipsis",
|
|
205
|
+
whiteSpace: "nowrap",
|
|
200
206
|
borderTop: "none",
|
|
201
207
|
borderRight: "none",
|
|
202
208
|
borderBottom: "1px solid rgba(128,128,128,0.2)",
|
|
203
209
|
borderLeft: "none",
|
|
204
210
|
...column.pinned === "left" && stickyOffset !== void 0 ? { left: `${stickyOffset}px` } : {},
|
|
205
211
|
...column.pinned === "right" && stickyOffset !== void 0 ? { right: `${stickyOffset}px` } : {},
|
|
206
|
-
...isPinned ? {
|
|
207
|
-
backgroundColor: styles?.pinnedBg,
|
|
208
|
-
...styles?.pinnedHeader
|
|
209
|
-
} : {},
|
|
210
212
|
...column.style,
|
|
211
|
-
...styles?.
|
|
212
|
-
|
|
213
|
-
display: "flex",
|
|
214
|
-
height: 36,
|
|
215
|
-
alignItems: "center",
|
|
216
|
-
overflow: "hidden",
|
|
217
|
-
textOverflow: "ellipsis",
|
|
218
|
-
whiteSpace: "nowrap",
|
|
219
|
-
...isPinned ? {} : { backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)" }
|
|
213
|
+
...isPinned ? styles?.pinnedHeader : {},
|
|
214
|
+
...styles?.header
|
|
220
215
|
};
|
|
221
216
|
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
222
217
|
/* @__PURE__ */ jsxs2(
|
|
@@ -224,6 +219,7 @@ var DraggableHeader = React.memo(
|
|
|
224
219
|
{
|
|
225
220
|
"data-column-key": column.key,
|
|
226
221
|
"data-bt-header": "",
|
|
222
|
+
...isPinned ? { "data-bt-pinned": "" } : {},
|
|
227
223
|
style: headerStyle,
|
|
228
224
|
className: `${column.className ?? ""} ${classNames?.header ?? ""} ${isPinned ? classNames?.pinnedHeader ?? "" : ""}`,
|
|
229
225
|
onContextMenu: handleContextMenu,
|
|
@@ -683,7 +679,7 @@ var DraggableHeader = React.memo(
|
|
|
683
679
|
] });
|
|
684
680
|
},
|
|
685
681
|
(prevProps, nextProps) => {
|
|
686
|
-
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;
|
|
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;
|
|
687
683
|
}
|
|
688
684
|
);
|
|
689
685
|
DraggableHeader.displayName = "DraggableHeader";
|
|
@@ -873,7 +869,8 @@ var Cell = React3.memo(
|
|
|
873
869
|
height: "100%",
|
|
874
870
|
boxSizing: "border-box",
|
|
875
871
|
...column.style,
|
|
876
|
-
...isPinned ? styles?.pinnedCell : void 0
|
|
872
|
+
...isPinned ? styles?.pinnedCell : void 0,
|
|
873
|
+
...styles?.cell
|
|
877
874
|
},
|
|
878
875
|
children: shimmerContent
|
|
879
876
|
}
|
|
@@ -929,7 +926,7 @@ var Cell = React3.memo(
|
|
|
929
926
|
return /* @__PURE__ */ jsx4(
|
|
930
927
|
"div",
|
|
931
928
|
{
|
|
932
|
-
className: `${column.className ?? ""} ${classNames?.cell ?? ""}`,
|
|
929
|
+
className: `${column.className ?? ""} ${classNames?.cell ?? ""} ${isPinned ? classNames?.pinnedCell ?? "" : ""}`,
|
|
933
930
|
style: {
|
|
934
931
|
display: "flex",
|
|
935
932
|
alignItems: "center",
|
|
@@ -941,38 +938,55 @@ var Cell = React3.memo(
|
|
|
941
938
|
height: "100%",
|
|
942
939
|
boxSizing: "border-box",
|
|
943
940
|
...column.style,
|
|
944
|
-
...isPinned ? styles?.pinnedCell : void 0
|
|
941
|
+
...isPinned ? styles?.pinnedCell : void 0,
|
|
942
|
+
...styles?.cell
|
|
945
943
|
},
|
|
946
944
|
children: content2
|
|
947
945
|
}
|
|
948
946
|
);
|
|
949
947
|
}
|
|
950
948
|
const content = column.render ? column.render(value, record, rowIndex) : value ?? "";
|
|
949
|
+
const isSystem = column.key === "__select__" || column.key === "__expand__";
|
|
951
950
|
return /* @__PURE__ */ jsx4(
|
|
952
951
|
"div",
|
|
953
952
|
{
|
|
954
|
-
className: `${column.className ?? ""} ${classNames?.cell ?? ""}`,
|
|
953
|
+
className: `${column.className ?? ""} ${classNames?.cell ?? ""} ${isPinned ? classNames?.pinnedCell ?? "" : ""}`,
|
|
955
954
|
style: {
|
|
956
955
|
display: "flex",
|
|
957
956
|
alignItems: "center",
|
|
958
957
|
overflow: "hidden",
|
|
959
|
-
textOverflow: "ellipsis",
|
|
960
|
-
whiteSpace: "nowrap",
|
|
961
958
|
borderBottom: "1px solid rgba(128,128,128,0.2)",
|
|
962
959
|
paddingLeft: 8,
|
|
963
960
|
paddingRight: 8,
|
|
964
|
-
justifyContent:
|
|
961
|
+
justifyContent: isSystem ? "center" : void 0,
|
|
965
962
|
height: "100%",
|
|
966
963
|
boxSizing: "border-box",
|
|
964
|
+
minWidth: 0,
|
|
967
965
|
...column.style,
|
|
968
|
-
...isPinned ? styles?.pinnedCell : void 0
|
|
966
|
+
...isPinned ? styles?.pinnedCell : void 0,
|
|
967
|
+
...styles?.cell
|
|
969
968
|
},
|
|
970
|
-
children: content
|
|
969
|
+
children: isSystem ? content : /* @__PURE__ */ jsx4(
|
|
970
|
+
"div",
|
|
971
|
+
{
|
|
972
|
+
style: {
|
|
973
|
+
overflow: "hidden",
|
|
974
|
+
textOverflow: "ellipsis",
|
|
975
|
+
whiteSpace: "nowrap",
|
|
976
|
+
minWidth: 0,
|
|
977
|
+
maxWidth: "100%"
|
|
978
|
+
},
|
|
979
|
+
children: content
|
|
980
|
+
}
|
|
981
|
+
)
|
|
971
982
|
}
|
|
972
983
|
);
|
|
973
984
|
},
|
|
974
985
|
(prev, next) => {
|
|
975
986
|
if (prev.isLoading !== next.isLoading) return false;
|
|
987
|
+
if (prev.column.pinned !== next.column.pinned) return false;
|
|
988
|
+
if (prev.classNames !== next.classNames) return false;
|
|
989
|
+
if (prev.styles !== next.styles) return false;
|
|
976
990
|
if (prev.column.key === "__select__") {
|
|
977
991
|
return prev.isSelected === next.isSelected && prev.normalizedSelectedKeys === next.normalizedSelectedKeys;
|
|
978
992
|
}
|
|
@@ -1067,7 +1081,6 @@ var TableBody = ({
|
|
|
1067
1081
|
else if (col.pinned === "right" && stickyOffset !== void 0)
|
|
1068
1082
|
style.right = `${stickyOffset}px`;
|
|
1069
1083
|
if (isPinned) {
|
|
1070
|
-
style.backgroundColor = styles?.pinnedBg;
|
|
1071
1084
|
if (styles?.pinnedCell) Object.assign(style, styles.pinnedCell);
|
|
1072
1085
|
}
|
|
1073
1086
|
return { key: col.key, style, isPinned };
|
|
@@ -1080,6 +1093,7 @@ var TableBody = ({
|
|
|
1080
1093
|
return /* @__PURE__ */ jsx4(
|
|
1081
1094
|
"div",
|
|
1082
1095
|
{
|
|
1096
|
+
...colStyle.isPinned ? { "data-bt-pinned": "" } : {},
|
|
1083
1097
|
style: colStyle.style,
|
|
1084
1098
|
children: virtualItems.map((virtualRow) => {
|
|
1085
1099
|
const row = data[virtualRow.index];
|
|
@@ -1420,6 +1434,8 @@ function arrayMove(arr, from, to) {
|
|
|
1420
1434
|
return result;
|
|
1421
1435
|
}
|
|
1422
1436
|
var SHIMMER_WIDTHS2 = [55, 70, 45, 80, 60, 50, 75, 65, 40, 72];
|
|
1437
|
+
var EMPTY_CLASSNAMES = {};
|
|
1438
|
+
var EMPTY_STYLES = {};
|
|
1423
1439
|
function BoltTable({
|
|
1424
1440
|
columns: initialColumns,
|
|
1425
1441
|
data,
|
|
@@ -1428,8 +1444,8 @@ function BoltTable({
|
|
|
1428
1444
|
maxExpandedRowHeight,
|
|
1429
1445
|
accentColor = "#1890ff",
|
|
1430
1446
|
className = "",
|
|
1431
|
-
classNames =
|
|
1432
|
-
styles =
|
|
1447
|
+
classNames = EMPTY_CLASSNAMES,
|
|
1448
|
+
styles = EMPTY_STYLES,
|
|
1433
1449
|
gripIcon,
|
|
1434
1450
|
hideGripIcon,
|
|
1435
1451
|
icons,
|
|
@@ -1459,6 +1475,10 @@ function BoltTable({
|
|
|
1459
1475
|
() => initialColumns.map((c) => c.key)
|
|
1460
1476
|
);
|
|
1461
1477
|
const [activeId, setActiveId] = useState2(null);
|
|
1478
|
+
const [mounted, setMounted] = useState2(false);
|
|
1479
|
+
React4.useEffect(() => {
|
|
1480
|
+
setMounted(true);
|
|
1481
|
+
}, []);
|
|
1462
1482
|
const columnsFingerprintRef = useRef4("");
|
|
1463
1483
|
const newFingerprint = initialColumns.map((c) => {
|
|
1464
1484
|
const w = typeof c.width === "number" ? Math.round(c.width) : c.width ?? "";
|
|
@@ -1694,6 +1714,9 @@ function BoltTable({
|
|
|
1694
1714
|
ghost.style.left = `${e.clientX - offsetX}px`;
|
|
1695
1715
|
ghost.style.top = `${rect.top}px`;
|
|
1696
1716
|
}
|
|
1717
|
+
const grabStyle = document.createElement("style");
|
|
1718
|
+
grabStyle.textContent = "* { cursor: grabbing !important; }";
|
|
1719
|
+
document.head.appendChild(grabStyle);
|
|
1697
1720
|
const onMove = (ev) => {
|
|
1698
1721
|
if (ghost) {
|
|
1699
1722
|
ghost.style.left = `${ev.clientX - offsetX}px`;
|
|
@@ -1722,6 +1745,7 @@ function BoltTable({
|
|
|
1722
1745
|
const onUp = () => {
|
|
1723
1746
|
document.removeEventListener("pointermove", onMove);
|
|
1724
1747
|
document.removeEventListener("pointerup", onUp);
|
|
1748
|
+
grabStyle.remove();
|
|
1725
1749
|
const scrollEl = tableAreaRef.current;
|
|
1726
1750
|
if (scrollEl) {
|
|
1727
1751
|
scrollEl.querySelectorAll("[data-dragging]").forEach((h) => h.removeAttribute("data-dragging"));
|
|
@@ -2050,11 +2074,17 @@ function BoltTable({
|
|
|
2050
2074
|
}, [cellContextMenu]);
|
|
2051
2075
|
const columnFiltersKey = Object.keys(columnFilters).sort().map((k) => `${k}:${columnFilters[k]}`).join("|");
|
|
2052
2076
|
React4.useEffect(() => {
|
|
2077
|
+
setInternalPage(1);
|
|
2053
2078
|
tableAreaRef.current?.scrollTo({ top: 0 });
|
|
2054
2079
|
}, [columnFiltersKey]);
|
|
2055
|
-
const
|
|
2056
|
-
const
|
|
2057
|
-
const
|
|
2080
|
+
const DEFAULT_PAGE_SIZE = 15;
|
|
2081
|
+
const [internalPage, setInternalPage] = useState2(1);
|
|
2082
|
+
const [internalPageSize, setInternalPageSize] = useState2(DEFAULT_PAGE_SIZE);
|
|
2083
|
+
const autoPagination = pagination === void 0 && data.length > DEFAULT_PAGE_SIZE;
|
|
2084
|
+
const pgEnabled = pagination === false ? false : !!pagination || autoPagination;
|
|
2085
|
+
const pgSize = pgEnabled && typeof pagination === "object" && pagination?.pageSize !== void 0 ? pagination.pageSize : internalPageSize;
|
|
2086
|
+
const isControlledPagination = typeof pagination === "object" && pagination?.current !== void 0;
|
|
2087
|
+
const pgCurrent = pgEnabled ? isControlledPagination ? Number(pagination.current) : internalPage : 1;
|
|
2058
2088
|
const needsClientPagination = pgEnabled && unpinnedProcessedData.length > pgSize;
|
|
2059
2089
|
const paginatedData = useMemo2(() => {
|
|
2060
2090
|
if (!needsClientPagination) return unpinnedProcessedData;
|
|
@@ -2160,17 +2190,29 @@ function BoltTable({
|
|
|
2160
2190
|
const activeColumn = activeId ? orderedColumns.find((col) => col.key === activeId) : null;
|
|
2161
2191
|
const currentPage = pgCurrent;
|
|
2162
2192
|
const pageSize = pgSize;
|
|
2163
|
-
const rawTotal = pgEnabled ? pagination
|
|
2193
|
+
const rawTotal = pgEnabled ? (typeof pagination === "object" ? pagination?.total : void 0) ?? (needsClientPagination ? unpinnedProcessedData.length : data.length) : data.length;
|
|
2164
2194
|
const lastKnownTotalRef = useRef4(0);
|
|
2165
2195
|
if (!isLoading || rawTotal > 0) {
|
|
2166
2196
|
lastKnownTotalRef.current = rawTotal;
|
|
2167
2197
|
}
|
|
2168
2198
|
const total = isLoading && lastKnownTotalRef.current > 0 ? lastKnownTotalRef.current : rawTotal;
|
|
2169
2199
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
2200
|
+
React4.useEffect(() => {
|
|
2201
|
+
if (internalPage > totalPages) {
|
|
2202
|
+
setInternalPage(Math.max(1, totalPages));
|
|
2203
|
+
}
|
|
2204
|
+
}, [totalPages, internalPage]);
|
|
2170
2205
|
const handlePageChange = (p) => {
|
|
2171
|
-
if (p >= 1 && p <= totalPages)
|
|
2206
|
+
if (p >= 1 && p <= totalPages) {
|
|
2207
|
+
setInternalPage(p);
|
|
2208
|
+
onPaginationChange?.(p, pageSize);
|
|
2209
|
+
}
|
|
2210
|
+
};
|
|
2211
|
+
const handlePageSizeChange = (s) => {
|
|
2212
|
+
setInternalPage(1);
|
|
2213
|
+
setInternalPageSize(s);
|
|
2214
|
+
onPaginationChange?.(1, s);
|
|
2172
2215
|
};
|
|
2173
|
-
const handlePageSizeChange = (s) => onPaginationChange?.(1, s);
|
|
2174
2216
|
React4.useEffect(() => {
|
|
2175
2217
|
if (needsClientPagination) {
|
|
2176
2218
|
tableAreaRef.current?.scrollTo({ top: 0 });
|
|
@@ -2226,6 +2268,14 @@ function BoltTable({
|
|
|
2226
2268
|
0%, 100% { opacity: 1; }
|
|
2227
2269
|
50% { opacity: 0.5; }
|
|
2228
2270
|
}
|
|
2271
|
+
:where([data-bt-header]) {
|
|
2272
|
+
background-color: rgba(128,128,128,0.06);
|
|
2273
|
+
backdrop-filter: blur(8px);
|
|
2274
|
+
-webkit-backdrop-filter: blur(8px);
|
|
2275
|
+
}
|
|
2276
|
+
:where([data-bt-pinned]) {
|
|
2277
|
+
background-color: ${styles.pinnedBg ?? "Canvas"};
|
|
2278
|
+
}
|
|
2229
2279
|
[data-row-key][data-hover] > div {
|
|
2230
2280
|
background-color: ${styles.rowHover?.backgroundColor ?? "rgba(128, 128, 128, 0.1)"};
|
|
2231
2281
|
}
|
|
@@ -2405,7 +2455,8 @@ function BoltTable({
|
|
|
2405
2455
|
);
|
|
2406
2456
|
const hasCopy = col?.copy;
|
|
2407
2457
|
const hasRowPin = !!onRowPin;
|
|
2408
|
-
|
|
2458
|
+
const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
|
|
2459
|
+
if (!hasCopy && !hasRowPin && !hasCellItems) return;
|
|
2409
2460
|
e.preventDefault();
|
|
2410
2461
|
setCellContextMenu({
|
|
2411
2462
|
x: Math.min(e.clientX, window.innerWidth - 200),
|
|
@@ -2433,7 +2484,8 @@ function BoltTable({
|
|
|
2433
2484
|
);
|
|
2434
2485
|
const hasCopy = col?.copy;
|
|
2435
2486
|
const hasRowPin = !!onRowPin;
|
|
2436
|
-
|
|
2487
|
+
const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
|
|
2488
|
+
if (!hasCopy && !hasRowPin && !hasCellItems) return;
|
|
2437
2489
|
setCellContextMenu({
|
|
2438
2490
|
x: Math.min(touch.clientX, window.innerWidth - 200),
|
|
2439
2491
|
y: Math.min(touch.clientY, window.innerHeight - 200),
|
|
@@ -2458,6 +2510,8 @@ function BoltTable({
|
|
|
2458
2510
|
return /* @__PURE__ */ jsx5(
|
|
2459
2511
|
"div",
|
|
2460
2512
|
{
|
|
2513
|
+
"data-bt-header": "",
|
|
2514
|
+
"data-bt-pinned": "",
|
|
2461
2515
|
className: `${classNames.header ?? ""} ${classNames.pinnedHeader ?? ""}`,
|
|
2462
2516
|
style: {
|
|
2463
2517
|
display: "flex",
|
|
@@ -2468,7 +2522,6 @@ function BoltTable({
|
|
|
2468
2522
|
textOverflow: "ellipsis",
|
|
2469
2523
|
whiteSpace: "nowrap",
|
|
2470
2524
|
borderBottom: "1px solid rgba(128,128,128,0.2)",
|
|
2471
|
-
backgroundColor: styles?.pinnedBg,
|
|
2472
2525
|
position: "sticky",
|
|
2473
2526
|
left: columnOffsets.get("__select__") ?? 0,
|
|
2474
2527
|
top: 0,
|
|
@@ -2518,6 +2571,8 @@ function BoltTable({
|
|
|
2518
2571
|
return /* @__PURE__ */ jsx5(
|
|
2519
2572
|
"div",
|
|
2520
2573
|
{
|
|
2574
|
+
"data-bt-header": "",
|
|
2575
|
+
"data-bt-pinned": "",
|
|
2521
2576
|
className: `${classNames.header ?? ""} ${classNames.pinnedHeader ?? ""}`,
|
|
2522
2577
|
style: {
|
|
2523
2578
|
display: "flex",
|
|
@@ -2528,7 +2583,6 @@ function BoltTable({
|
|
|
2528
2583
|
textOverflow: "ellipsis",
|
|
2529
2584
|
whiteSpace: "nowrap",
|
|
2530
2585
|
borderBottom: "1px solid rgba(128,128,128,0.2)",
|
|
2531
|
-
backgroundColor: styles?.pinnedBg,
|
|
2532
2586
|
position: "sticky",
|
|
2533
2587
|
left: columnOffsets.get("__expand__") ?? 0,
|
|
2534
2588
|
top: 0,
|
|
@@ -2563,7 +2617,7 @@ function BoltTable({
|
|
|
2563
2617
|
filterValue: columnFilters[column.key] ?? "",
|
|
2564
2618
|
onFilter: handleColumnFilter,
|
|
2565
2619
|
onClearFilter: handleClearFilter,
|
|
2566
|
-
customContextMenuItems: columnContextMenuItems
|
|
2620
|
+
customContextMenuItems: column.columnHeaderContextMenuItems ? [...columnContextMenuItems ?? [], ...column.columnHeaderContextMenuItems] : columnContextMenuItems
|
|
2567
2621
|
},
|
|
2568
2622
|
column.key
|
|
2569
2623
|
);
|
|
@@ -2642,7 +2696,7 @@ function BoltTable({
|
|
|
2642
2696
|
)
|
|
2643
2697
|
}
|
|
2644
2698
|
),
|
|
2645
|
-
|
|
2699
|
+
pgEnabled && /* @__PURE__ */ jsxs5(
|
|
2646
2700
|
"div",
|
|
2647
2701
|
{
|
|
2648
2702
|
style: {
|
|
@@ -2662,7 +2716,7 @@ function BoltTable({
|
|
|
2662
2716
|
/* @__PURE__ */ jsx5("div", { style: { display: "flex", flex: "1 1 0%", alignItems: "center" }, children: (() => {
|
|
2663
2717
|
const rangeStart = total > 0 ? (currentPage - 1) * pageSize + 1 : 0;
|
|
2664
2718
|
const rangeEnd = Math.min(currentPage * pageSize, total);
|
|
2665
|
-
return pagination?.showTotal ? /* @__PURE__ */ jsxs5("span", { style: { color: "GrayText", fontSize: 12 }, children: [
|
|
2719
|
+
return typeof pagination === "object" && pagination?.showTotal ? /* @__PURE__ */ jsxs5("span", { style: { color: "GrayText", fontSize: 12 }, children: [
|
|
2666
2720
|
"Showing",
|
|
2667
2721
|
" ",
|
|
2668
2722
|
pagination.showTotal(total, [rangeStart, rangeEnd]),
|
|
@@ -2835,7 +2889,7 @@ function BoltTable({
|
|
|
2835
2889
|
justifyContent: "flex-end",
|
|
2836
2890
|
gap: 8
|
|
2837
2891
|
},
|
|
2838
|
-
children: /* @__PURE__ */ jsx5(
|
|
2892
|
+
children: typeof pagination === "object" && pagination?.hidePageSelector ? null : /* @__PURE__ */ jsx5(
|
|
2839
2893
|
"select",
|
|
2840
2894
|
{
|
|
2841
2895
|
value: pageSize,
|
|
@@ -2853,7 +2907,7 @@ function BoltTable({
|
|
|
2853
2907
|
background: "inherit",
|
|
2854
2908
|
color: "inherit"
|
|
2855
2909
|
},
|
|
2856
|
-
children: [10, 15, 20, 25, 50, 100].map((size) => /* @__PURE__ */ jsxs5("option", { value: size, children: [
|
|
2910
|
+
children: (typeof pagination === "object" && pagination?.pageSizeOptions ? pagination.pageSizeOptions : [10, 15, 20, 25, 50, 100]).map((size) => /* @__PURE__ */ jsxs5("option", { value: size, children: [
|
|
2857
2911
|
size,
|
|
2858
2912
|
" / page"
|
|
2859
2913
|
] }, size))
|
|
@@ -2867,7 +2921,7 @@ function BoltTable({
|
|
|
2867
2921
|
]
|
|
2868
2922
|
}
|
|
2869
2923
|
),
|
|
2870
|
-
|
|
2924
|
+
mounted && createPortal2(
|
|
2871
2925
|
/* @__PURE__ */ jsx5(
|
|
2872
2926
|
"div",
|
|
2873
2927
|
{
|
|
@@ -2936,7 +2990,7 @@ function BoltTable({
|
|
|
2936
2990
|
),
|
|
2937
2991
|
document.body
|
|
2938
2992
|
),
|
|
2939
|
-
cellContextMenu &&
|
|
2993
|
+
cellContextMenu && mounted && (() => {
|
|
2940
2994
|
const menuCol = freshOrderedColumns.find(
|
|
2941
2995
|
(c) => c.key === cellContextMenu.columnKey
|
|
2942
2996
|
);
|
|
@@ -3088,7 +3142,42 @@ function BoltTable({
|
|
|
3088
3142
|
"Copy"
|
|
3089
3143
|
]
|
|
3090
3144
|
}
|
|
3091
|
-
)
|
|
3145
|
+
),
|
|
3146
|
+
menuCol?.columnCellContextMenuItems && menuCol.columnCellContextMenuItems.length > 0 && /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
3147
|
+
(hasCopy || hasRowPin) && /* @__PURE__ */ jsx5(
|
|
3148
|
+
"div",
|
|
3149
|
+
{
|
|
3150
|
+
style: {
|
|
3151
|
+
borderTop: "1px solid rgba(128,128,128,0.2)",
|
|
3152
|
+
margin: "4px 0"
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
),
|
|
3156
|
+
menuCol.columnCellContextMenuItems.map((item) => /* @__PURE__ */ jsxs5(
|
|
3157
|
+
"button",
|
|
3158
|
+
{
|
|
3159
|
+
"data-bt-ctx-item": "",
|
|
3160
|
+
disabled: item.disabled,
|
|
3161
|
+
style: {
|
|
3162
|
+
...btnStyle,
|
|
3163
|
+
cursor: item.disabled ? "not-allowed" : "pointer",
|
|
3164
|
+
opacity: item.disabled ? 0.5 : 1,
|
|
3165
|
+
color: item.danger ? "#ef4444" : "inherit"
|
|
3166
|
+
},
|
|
3167
|
+
onClick: () => {
|
|
3168
|
+
if (menuRecord) {
|
|
3169
|
+
item.onClick(menuCol.key, menuRecord, menuRowIndex);
|
|
3170
|
+
}
|
|
3171
|
+
setCellContextMenu(null);
|
|
3172
|
+
},
|
|
3173
|
+
children: [
|
|
3174
|
+
item.icon && /* @__PURE__ */ jsx5("span", { style: { display: "flex", width: 14, height: 14, alignItems: "center", justifyContent: "center", flexShrink: 0 }, children: item.icon }),
|
|
3175
|
+
item.label
|
|
3176
|
+
]
|
|
3177
|
+
},
|
|
3178
|
+
item.key
|
|
3179
|
+
))
|
|
3180
|
+
] })
|
|
3092
3181
|
]
|
|
3093
3182
|
}
|
|
3094
3183
|
),
|
package/package.json
CHANGED