trotl-table 1.0.96 → 1.0.98

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.esm.js CHANGED
@@ -9665,6 +9665,8 @@ function TableInner({
9665
9665
  tableId = "default",
9666
9666
  columns = [],
9667
9667
  data = [],
9668
+ mobileColumnCount = 2,
9669
+ mobileRowClick = null,
9668
9670
  highlightRow = null,
9669
9671
  isGrouped = false,
9670
9672
  groupKey = "groupId",
@@ -9732,6 +9734,8 @@ function TableInner({
9732
9734
  share: "Share",
9733
9735
  duplicate: "Duplicate",
9734
9736
  download: "Download",
9737
+ details: "Details",
9738
+ close: "Close",
9735
9739
  confirmDelete: "Confirm Delete",
9736
9740
  yesDelete: "Yes, Delete",
9737
9741
  areYouSureYouWantToDelete: "Are you sure you want to delete",
@@ -9755,6 +9759,7 @@ function TableInner({
9755
9759
  const duplicateCallbackRef = useRef(duplicateCallback);
9756
9760
  const downloadCallbackRef = useRef(downloadCallback);
9757
9761
  const undeleteCallbackRef = useRef(undeleteCallback);
9762
+ const mobileRowClickRef = useRef(mobileRowClick);
9758
9763
  const onCellChangeRef = useRef(onCellChange);
9759
9764
  const cellCallbackRef = useRef(cellCallback);
9760
9765
 
@@ -9766,9 +9771,16 @@ function TableInner({
9766
9771
  editCallbackRef.current = editCallback;
9767
9772
  deleteCallbackRef.current = deleteCallback;
9768
9773
  undeleteCallbackRef.current = undeleteCallback;
9774
+ mobileRowClickRef.current = mobileRowClick;
9769
9775
  onCellChangeRef.current = onCellChange;
9770
9776
  cellCallbackRef.current = cellCallback;
9771
9777
  });
9778
+ const [isMobile, setIsMobile] = useState(() => typeof window !== "undefined" && window.innerWidth <= 768);
9779
+ useEffect(() => {
9780
+ const updateMobileState = () => setIsMobile(window.innerWidth <= 768);
9781
+ window.addEventListener("resize", updateMobileState);
9782
+ return () => window.removeEventListener("resize", updateMobileState);
9783
+ }, []);
9772
9784
 
9773
9785
  // Context menu right click state
9774
9786
  const [contextMenu, setContextMenu] = useState({
@@ -9854,6 +9866,22 @@ function TableInner({
9854
9866
  flex: "1 1 0%"
9855
9867
  };
9856
9868
  }, [columnWidths, getColumnKey]);
9869
+ const allColumns = useMemo(() => {
9870
+ const composedColumns = [...columns];
9871
+ if (Array.isArray(customColumns)) {
9872
+ customColumns.forEach(col => {
9873
+ if (typeof col.place === "number") {
9874
+ composedColumns.splice(col.place, 0, {
9875
+ ...col,
9876
+ isCustom: true
9877
+ });
9878
+ }
9879
+ });
9880
+ }
9881
+ return composedColumns;
9882
+ }, [columns, customColumns]);
9883
+ const normalizedMobileColumnCount = Math.min(2, Math.max(1, Math.floor(Number(mobileColumnCount) || 2)));
9884
+ const visibleColumns = isMobile ? allColumns.slice(0, normalizedMobileColumnCount) : allColumns;
9857
9885
  const getNestedValue = useCallback((row, accessor) => {
9858
9886
  if (!row || accessor == null) return undefined;
9859
9887
  if (Array.isArray(accessor)) {
@@ -10232,6 +10260,21 @@ function TableInner({
10232
10260
  }).filter(Boolean);
10233
10261
  return [...new Set(parts)].join(", ");
10234
10262
  }, []);
10263
+ const formatMobileDetailValue = useCallback((value, col) => {
10264
+ if (value == null || value === "") return "...";
10265
+ if (typeof value === "boolean") return value ? "✓" : "✗";
10266
+ if (Array.isArray(value)) return formatArrayValue(value, col) || "...";
10267
+ if (value instanceof Date) {
10268
+ return formatDateValue(value, getColumnDateFormat(col)) || "...";
10269
+ }
10270
+ if (getColumnType(col) === "date" || col?.dateFormat) {
10271
+ return formatDateValue(value, getColumnDateFormat(col)) || String(value);
10272
+ }
10273
+ if (typeof value === "object") {
10274
+ return String(value.label ?? value.name ?? value.value ?? value);
10275
+ }
10276
+ return String(col?.translate ? translate(String(value)) : value);
10277
+ }, [formatArrayValue, translate]);
10235
10278
 
10236
10279
  // console.log(extraSearchTerm)
10237
10280
 
@@ -10546,6 +10589,7 @@ function TableInner({
10546
10589
  // DELETE
10547
10590
  const [showConfirm, setShowConfirm] = useState(false);
10548
10591
  const [pendingDelete, setPendingDelete] = useState(null);
10592
+ const [mobileDetailRow, setMobileDetailRow] = useState(null);
10549
10593
 
10550
10594
  // perform deletion for a given row (shared by immediate & modal-confirm flows)
10551
10595
  const doDelete = useCallback(async row => {
@@ -11141,19 +11185,6 @@ function TableInner({
11141
11185
  const visualIndex = tableDataFlat.slice(0, index).filter(i => i.type === "row").length + 1;
11142
11186
  const highlightRowStyle = getHighlightRowStyle(row);
11143
11187
 
11144
- // Compose columns + custom columns
11145
- const allColumns = [...columns];
11146
- // Insert custom columns at specified places
11147
- if (Array.isArray(customColumns)) {
11148
- customColumns.forEach(col => {
11149
- if (typeof col.place === "number") {
11150
- allColumns.splice(col.place, 0, {
11151
- ...col,
11152
- isCustom: true
11153
- });
11154
- }
11155
- });
11156
- }
11157
11188
  // handler called when user double-clicks the non-action portion of the row
11158
11189
  const handleRowDoubleClick = e => {
11159
11190
  if (!doubleClickEnable) return;
@@ -11163,13 +11194,24 @@ function TableInner({
11163
11194
  }
11164
11195
  editCallbackRef.current(row);
11165
11196
  };
11197
+ const handleMobileRowClick = event => {
11198
+ if (!isMobile || event.target.closest(".checkbox-cell, .action-cell, button, input, select, textarea, a, [contenteditable='true']")) {
11199
+ return;
11200
+ }
11201
+ if (typeof mobileRowClickRef.current === "function") {
11202
+ mobileRowClickRef.current(row);
11203
+ } else {
11204
+ setMobileDetailRow(row);
11205
+ }
11206
+ };
11166
11207
  const content = /*#__PURE__*/React__default.createElement("div", {
11167
11208
  key: key,
11168
11209
  style: highlightRowStyle ? {
11169
11210
  ...style,
11170
11211
  ...highlightRowStyle
11171
11212
  } : style,
11172
- className: "table-row",
11213
+ className: isMobile ? "table-row mobile-clickable" : "table-row",
11214
+ onClick: isMobile ? handleMobileRowClick : undefined,
11173
11215
  onContextMenu: e => {
11174
11216
  if (!Array.isArray(enableMouseRightClick) || enableMouseRightClick.length === 0) return;
11175
11217
  e.preventDefault();
@@ -11203,14 +11245,20 @@ function TableInner({
11203
11245
  minWidth: keyWidth,
11204
11246
  maxWidth: keyWidth
11205
11247
  } : undefined
11206
- }, visualIndex), allColumns.map((col, i) => {
11248
+ }, visualIndex), visibleColumns.map((col, i) => {
11207
11249
  const resolvedAccessor = getAccessorKey(row, col.accessor);
11208
11250
  const cellValue = getAccessorValue(row, col.accessor);
11209
11251
  const cellStyle = getCellStyle(col, i);
11210
11252
  return /*#__PURE__*/React__default.createElement("div", {
11211
11253
  key: i,
11212
11254
  className: "table-cell",
11213
- style: cellStyle,
11255
+ style: isMobile ? {
11256
+ ...cellStyle,
11257
+ flex: "1 1 0%",
11258
+ width: undefined,
11259
+ minWidth: 0,
11260
+ maxWidth: "100%"
11261
+ } : cellStyle,
11214
11262
  onClick: () => triggerCellCallback(row, col)
11215
11263
  }, col.isCustom ? typeof col.render === "function" ? col.render(row, i) : col.render : renderCell(cellValue, resolvedAccessor, row, col));
11216
11264
  })), showActions && /*#__PURE__*/React__default.createElement("div", {
@@ -11295,7 +11343,7 @@ function TableInner({
11295
11343
  }, content);
11296
11344
  }
11297
11345
  return content;
11298
- }, [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, getHighlightRowStyle, triggerCellCallback, getAccessorKey, getAccessorValue]);
11346
+ }, [tableDataFlat, visibleColumns, selectedRows, toggleRowSelection, groupRowsById, renderCell, getCellStyle, showActions, showDelete, showEdit, showKey, showView, translate, enableDragRow, moveRow, enableMultiSelect, rowHeight, tableId, customColumns, isMobile, doubleClickEnable, keyWidth, actionColumnStyle, showDuplicate, showDownload, showIcons, showShare, getHighlightRowStyle, triggerCellCallback, getAccessorKey, getAccessorValue]);
11299
11347
  const rightClickActions = Array.isArray(enableMouseRightClick) ? enableMouseRightClick : [];
11300
11348
  const [hoveredActionIndex, setHoveredActionIndex] = useState(null);
11301
11349
  const rowHeightGetter = ({
@@ -11325,19 +11373,6 @@ function TableInner({
11325
11373
  externalDrop(node);
11326
11374
  }
11327
11375
  }, [useExternalDndContext, enableExternalRowDrop, externalDrop]);
11328
-
11329
- // Compose columns + custom columns for header
11330
- const allColumns = [...columns];
11331
- if (Array.isArray(customColumns)) {
11332
- customColumns.forEach(col => {
11333
- if (typeof col.place === "number") {
11334
- allColumns.splice(col.place, 0, {
11335
- ...col,
11336
- isCustom: true
11337
- });
11338
- }
11339
- });
11340
- }
11341
11376
  const tableMarkup = /*#__PURE__*/React__default.createElement("div", {
11342
11377
  className: "table-container",
11343
11378
  ref: setTableRef,
@@ -11378,14 +11413,20 @@ function TableInner({
11378
11413
  minWidth: keyWidth,
11379
11414
  maxWidth: keyWidth
11380
11415
  } : undefined
11381
- }, "#"), allColumns.map((col, i) => {
11416
+ }, "#"), visibleColumns.map((col, i) => {
11382
11417
  const cellStyle = getCellStyle(col, i);
11383
11418
  const translatedHeader = typeof col.header === "string" ? translate(col.header) : col.header;
11384
11419
  const headerTitle = typeof translatedHeader === "string" ? translatedHeader : undefined;
11385
11420
  return /*#__PURE__*/React__default.createElement("div", {
11386
11421
  key: i,
11387
11422
  className: "table-cell header-cell",
11388
- style: cellStyle,
11423
+ style: isMobile ? {
11424
+ ...cellStyle,
11425
+ flex: "1 1 0%",
11426
+ width: undefined,
11427
+ minWidth: 0,
11428
+ maxWidth: "100%"
11429
+ } : cellStyle,
11389
11430
  title: headerTitle,
11390
11431
  onClick: col.isCustom ? undefined : () => setSort(col.accessor)
11391
11432
  }, col.isCustom ? translatedHeader ?? "" : translatedHeader, !col.isCustom && isSameAccessor(sorting?.column, col.accessor) && (sorting.direction === "asc" ? " ↑" : " ↓"), /*#__PURE__*/React__default.createElement("div", {
@@ -11478,7 +11519,22 @@ function TableInner({
11478
11519
  }, typeof contextMenuModal.component === "function" ? /*#__PURE__*/React__default.createElement(contextMenuModal.component, {
11479
11520
  row: contextMenu.row
11480
11521
  }) : contextMenuModal.component) : null;
11481
- return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, tableMarkup, contextMenuMarkup, contextMenuModalMarkup);
11522
+ const mobileDetailModalMarkup = mobileDetailRow ? /*#__PURE__*/React__default.createElement(Modal, {
11523
+ isOpen: true,
11524
+ title: String(mobileDetailRow.name ?? mobileDetailRow.title ?? translate("details")),
11525
+ onCancel: () => setMobileDetailRow(null),
11526
+ cancelLabel: translate("close"),
11527
+ showCancel: true
11528
+ }, /*#__PURE__*/React__default.createElement("dl", {
11529
+ className: "mobile-row-details"
11530
+ }, allColumns.map((col, index) => {
11531
+ const header = typeof col.header === "string" ? translate(col.header) : col.header;
11532
+ const value = col.isCustom ? typeof col.render === "function" ? col.render(mobileDetailRow, index) : col.render ?? "..." : formatMobileDetailValue(getAccessorValue(mobileDetailRow, col.accessor), col);
11533
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, {
11534
+ key: index
11535
+ }, /*#__PURE__*/React__default.createElement("dt", null, header), /*#__PURE__*/React__default.createElement("dd", null, value));
11536
+ }))) : null;
11537
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, tableMarkup, contextMenuMarkup, contextMenuModalMarkup, mobileDetailModalMarkup);
11482
11538
  }
11483
11539
  function Table(props) {
11484
11540
  const {