trotl-table 1.0.70 → 1.0.72
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/Table.cjs.js +114 -28
- package/dist/Table.cjs.js.map +1 -1
- package/dist/Table.esm.js +114 -28
- package/dist/Table.esm.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/package.json +1 -1
package/dist/Table.cjs.js
CHANGED
|
@@ -9787,6 +9787,82 @@ function TableInner({
|
|
|
9787
9787
|
|
|
9788
9788
|
// Local selection & sorting state (removed TableContext dependency)
|
|
9789
9789
|
const [selectedRows, setSelectedRows] = React.useState(() => resolvedInitialSelectedRows);
|
|
9790
|
+
const [columnWidths, setColumnWidths] = React.useState(() => ({}));
|
|
9791
|
+
const columnResizeRef = React.useRef(null);
|
|
9792
|
+
const getColumnKey = React.useCallback((col, index) => {
|
|
9793
|
+
if (col?.key != null) return `col-${String(col.key)}`;
|
|
9794
|
+
if (col?.accessor != null && (typeof col.accessor === "string" || typeof col.accessor === "number")) {
|
|
9795
|
+
return `col-${String(col.accessor)}`;
|
|
9796
|
+
}
|
|
9797
|
+
return `col-${index}`;
|
|
9798
|
+
}, []);
|
|
9799
|
+
const getCellStyle = React.useCallback((col, index) => {
|
|
9800
|
+
const key = getColumnKey(col, index);
|
|
9801
|
+
const width = columnWidths[key] ?? col?.style?.width;
|
|
9802
|
+
const baseStyle = col?.style ? {
|
|
9803
|
+
...col.style
|
|
9804
|
+
} : {};
|
|
9805
|
+
if (width) {
|
|
9806
|
+
return {
|
|
9807
|
+
...baseStyle,
|
|
9808
|
+
flex: "0 0 auto",
|
|
9809
|
+
width,
|
|
9810
|
+
minWidth: width,
|
|
9811
|
+
maxWidth: width
|
|
9812
|
+
};
|
|
9813
|
+
}
|
|
9814
|
+
return {
|
|
9815
|
+
...baseStyle,
|
|
9816
|
+
flex: "1 1 0%"
|
|
9817
|
+
};
|
|
9818
|
+
}, [columnWidths, getColumnKey]);
|
|
9819
|
+
const updateColumnWidth = React.useCallback((key, nextWidth) => {
|
|
9820
|
+
setColumnWidths(prev => ({
|
|
9821
|
+
...prev,
|
|
9822
|
+
[key]: `${Math.max(60, Math.round(nextWidth))}px`
|
|
9823
|
+
}));
|
|
9824
|
+
}, []);
|
|
9825
|
+
const handleDocumentMouseMove = React.useCallback(event => {
|
|
9826
|
+
const state = columnResizeRef.current;
|
|
9827
|
+
if (!state) return;
|
|
9828
|
+
const delta = event.clientX - state.startX;
|
|
9829
|
+
updateColumnWidth(state.key, state.startWidth + delta);
|
|
9830
|
+
}, [updateColumnWidth]);
|
|
9831
|
+
const stopColumnResize = React.useCallback(() => {
|
|
9832
|
+
if (!columnResizeRef.current) return;
|
|
9833
|
+
columnResizeRef.current = null;
|
|
9834
|
+
document.removeEventListener("mousemove", handleDocumentMouseMove);
|
|
9835
|
+
document.removeEventListener("mouseup", stopColumnResize);
|
|
9836
|
+
document.body.style.cursor = "";
|
|
9837
|
+
document.body.style.userSelect = "";
|
|
9838
|
+
}, [handleDocumentMouseMove]);
|
|
9839
|
+
const startColumnResize = React.useCallback((event, col, index) => {
|
|
9840
|
+
event.preventDefault();
|
|
9841
|
+
event.stopPropagation();
|
|
9842
|
+
const key = getColumnKey(col, index);
|
|
9843
|
+
const headerCell = event.currentTarget.parentElement;
|
|
9844
|
+
const startWidth = headerCell?.getBoundingClientRect().width || 120;
|
|
9845
|
+
columnResizeRef.current = {
|
|
9846
|
+
key,
|
|
9847
|
+
startX: event.clientX,
|
|
9848
|
+
startWidth
|
|
9849
|
+
};
|
|
9850
|
+
document.addEventListener("mousemove", handleDocumentMouseMove);
|
|
9851
|
+
document.addEventListener("mouseup", stopColumnResize);
|
|
9852
|
+
document.body.style.cursor = "col-resize";
|
|
9853
|
+
document.body.style.userSelect = "none";
|
|
9854
|
+
}, [getColumnKey, handleDocumentMouseMove, stopColumnResize]);
|
|
9855
|
+
React.useEffect(() => {
|
|
9856
|
+
return () => {
|
|
9857
|
+
if (columnResizeRef.current) {
|
|
9858
|
+
document.removeEventListener("mousemove", handleDocumentMouseMove);
|
|
9859
|
+
document.removeEventListener("mouseup", stopColumnResize);
|
|
9860
|
+
document.body.style.cursor = "";
|
|
9861
|
+
document.body.style.userSelect = "";
|
|
9862
|
+
columnResizeRef.current = null;
|
|
9863
|
+
}
|
|
9864
|
+
};
|
|
9865
|
+
}, [handleDocumentMouseMove, stopColumnResize]);
|
|
9790
9866
|
const [sorting, setSorting] = React.useState(null);
|
|
9791
9867
|
|
|
9792
9868
|
// Initialize localData early so it's available for the sync effect below
|
|
@@ -9965,6 +10041,19 @@ function TableInner({
|
|
|
9965
10041
|
}
|
|
9966
10042
|
return a === b;
|
|
9967
10043
|
}, []);
|
|
10044
|
+
const formatArrayValue = React.useCallback((value, col) => {
|
|
10045
|
+
if (!Array.isArray(value)) return value;
|
|
10046
|
+
const objectKey = col?.objectKey;
|
|
10047
|
+
const parts = value.map(item => {
|
|
10048
|
+
if (item == null) return "";
|
|
10049
|
+
if (typeof item !== "object") return String(item);
|
|
10050
|
+
if (objectKey && item?.[objectKey] !== undefined) return String(item[objectKey]);
|
|
10051
|
+
if (item.label !== undefined) return String(item.label);
|
|
10052
|
+
if (item.value !== undefined) return String(item.value);
|
|
10053
|
+
return JSON.stringify(item);
|
|
10054
|
+
}).filter(item => item !== "");
|
|
10055
|
+
return parts.join(", ");
|
|
10056
|
+
}, []);
|
|
9968
10057
|
|
|
9969
10058
|
// console.log(extraSearchTerm)
|
|
9970
10059
|
|
|
@@ -10051,13 +10140,16 @@ function TableInner({
|
|
|
10051
10140
|
const query = searchTerm.toLowerCase();
|
|
10052
10141
|
return dateFiltered.filter(row => columns.some(col => {
|
|
10053
10142
|
const val = getAccessorValue(row, col.accessor);
|
|
10054
|
-
|
|
10055
|
-
|
|
10143
|
+
const normalized = Array.isArray(val) ? formatArrayValue(val, col) : val;
|
|
10144
|
+
if (normalized == null) return false;
|
|
10145
|
+
return String(normalized).toLowerCase().includes(query);
|
|
10056
10146
|
}));
|
|
10057
|
-
}, [searchTerm, columns, urlSearchString, getAccessorValue]);
|
|
10147
|
+
}, [searchTerm, columns, urlSearchString, getAccessorValue, formatArrayValue]);
|
|
10058
10148
|
|
|
10059
10149
|
// Natural-ish comparator: handles nulls, numbers, strings, ISO dates
|
|
10060
10150
|
const compare = (x, y, dir = "asc") => {
|
|
10151
|
+
if (Array.isArray(x)) x = formatArrayValue(x);
|
|
10152
|
+
if (Array.isArray(y)) y = formatArrayValue(y);
|
|
10061
10153
|
const nullCmp = () => {
|
|
10062
10154
|
if (x == null && y == null) return 0;
|
|
10063
10155
|
if (x == null) return 1; // nulls last
|
|
@@ -10492,6 +10584,15 @@ function TableInner({
|
|
|
10492
10584
|
title: formatted
|
|
10493
10585
|
}, formatted);
|
|
10494
10586
|
}
|
|
10587
|
+
if (col && col.type === 'array') {
|
|
10588
|
+
const arr = Array.isArray(v) ? v : [];
|
|
10589
|
+
const list = formatArrayValue(arr, col);
|
|
10590
|
+
const count = arr.length;
|
|
10591
|
+
const display = count > 0 ? `${count}: ${list}` : "...";
|
|
10592
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
10593
|
+
title: list || translate("noData")
|
|
10594
|
+
}, display);
|
|
10595
|
+
}
|
|
10495
10596
|
|
|
10496
10597
|
// If column has dateFormat, format value as date/time
|
|
10497
10598
|
if (col && col.dateFormat && v) {
|
|
@@ -10537,7 +10638,7 @@ function TableInner({
|
|
|
10537
10638
|
}
|
|
10538
10639
|
// existing highlight logic for other fields
|
|
10539
10640
|
return highlight(String(v));
|
|
10540
|
-
}, [highlight, isGrouped, triggerCellCallback, translate]);
|
|
10641
|
+
}, [highlight, isGrouped, triggerCellCallback, translate, formatArrayValue]);
|
|
10541
10642
|
const showView = buttons.includes("view");
|
|
10542
10643
|
const showEdit = buttons.includes("edit");
|
|
10543
10644
|
// show delete only when view is also shown (per request)
|
|
@@ -10887,15 +10988,7 @@ function TableInner({
|
|
|
10887
10988
|
}, visualIndex), allColumns.map((col, i) => {
|
|
10888
10989
|
const resolvedAccessor = getAccessorKey(row, col.accessor);
|
|
10889
10990
|
const cellValue = getAccessorValue(row, col.accessor);
|
|
10890
|
-
|
|
10891
|
-
...col.style
|
|
10892
|
-
} : undefined;
|
|
10893
|
-
if (col.style && col.style.width) {
|
|
10894
|
-
cellStyle = cellStyle || {};
|
|
10895
|
-
cellStyle.minWidth = col.style.width;
|
|
10896
|
-
cellStyle.maxWidth = col.style.width;
|
|
10897
|
-
cellStyle.width = col.style.width;
|
|
10898
|
-
}
|
|
10991
|
+
const cellStyle = getCellStyle(col, i);
|
|
10899
10992
|
return /*#__PURE__*/React.createElement("div", {
|
|
10900
10993
|
key: i,
|
|
10901
10994
|
className: "table-cell",
|
|
@@ -10975,7 +11068,7 @@ function TableInner({
|
|
|
10975
11068
|
}, content);
|
|
10976
11069
|
}
|
|
10977
11070
|
return content;
|
|
10978
|
-
}, [tableDataFlat, columns, selectedRows, toggleRowSelection, groupRowsById, renderCell, showActions, showDelete, showEdit, showKey, showView, translate, enableDragRow, moveRow, enableMultiSelect, rowHeight, tableId, customColumns, doubleClickEnable, keyWidth, actionColumnStyle, showDuplicate, showDownload, showIcons, showShare, triggerCellCallback, getAccessorKey, getAccessorValue]);
|
|
11071
|
+
}, [tableDataFlat, columns, selectedRows, toggleRowSelection, groupRowsById, renderCell, getCellStyle, showActions, showDelete, showEdit, showKey, showView, translate, enableDragRow, moveRow, enableMultiSelect, rowHeight, tableId, customColumns, doubleClickEnable, keyWidth, actionColumnStyle, showDuplicate, showDownload, showIcons, showShare, triggerCellCallback, getAccessorKey, getAccessorValue]);
|
|
10979
11072
|
const rightClickActions = Array.isArray(enableMouseRightClick) ? enableMouseRightClick : [];
|
|
10980
11073
|
const [hoveredActionIndex, setHoveredActionIndex] = React.useState(null);
|
|
10981
11074
|
const rowHeightGetter = ({
|
|
@@ -11056,27 +11149,20 @@ function TableInner({
|
|
|
11056
11149
|
maxWidth: keyWidth
|
|
11057
11150
|
} : undefined
|
|
11058
11151
|
}, "#"), allColumns.map((col, i) => {
|
|
11059
|
-
|
|
11060
|
-
...col.style,
|
|
11061
|
-
cursor: col.isCustom ? undefined : "pointer"
|
|
11062
|
-
} : {
|
|
11063
|
-
cursor: col.isCustom ? undefined : "pointer"
|
|
11064
|
-
};
|
|
11065
|
-
if (col.style && col.style.width) {
|
|
11066
|
-
cellStyle.minWidth = col.style.width;
|
|
11067
|
-
cellStyle.maxWidth = col.style.width;
|
|
11068
|
-
cellStyle.width = col.style.width;
|
|
11069
|
-
}
|
|
11152
|
+
const cellStyle = getCellStyle(col, i);
|
|
11070
11153
|
const translatedHeader = typeof col.header === "string" ? translate(col.header) : col.header;
|
|
11071
|
-
// Keep tooltip text in sync with rendered header when it's a string.
|
|
11072
11154
|
const headerTitle = typeof translatedHeader === "string" ? translatedHeader : undefined;
|
|
11073
11155
|
return /*#__PURE__*/React.createElement("div", {
|
|
11074
11156
|
key: i,
|
|
11075
|
-
className: "table-cell",
|
|
11157
|
+
className: "table-cell header-cell",
|
|
11076
11158
|
style: cellStyle,
|
|
11077
11159
|
title: headerTitle,
|
|
11078
11160
|
onClick: col.isCustom ? undefined : () => setSort(col.accessor)
|
|
11079
|
-
}, col.isCustom ? translatedHeader ?? "" : translatedHeader, !col.isCustom && isSameAccessor(sorting?.column, col.accessor) && (sorting.direction === "asc" ? " ↑" : " ↓")
|
|
11161
|
+
}, col.isCustom ? translatedHeader ?? "" : translatedHeader, !col.isCustom && isSameAccessor(sorting?.column, col.accessor) && (sorting.direction === "asc" ? " ↑" : " ↓"), /*#__PURE__*/React.createElement("div", {
|
|
11162
|
+
className: "column-resizer",
|
|
11163
|
+
onMouseDown: event => startColumnResize(event, col, i),
|
|
11164
|
+
onClick: event => event.stopPropagation()
|
|
11165
|
+
}));
|
|
11080
11166
|
}), showActions && /*#__PURE__*/React.createElement("div", {
|
|
11081
11167
|
className: "table-cell action-cell",
|
|
11082
11168
|
style: actionColumnStyle,
|