trotl-table 1.0.101 → 1.0.103

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/README.md CHANGED
@@ -88,11 +88,10 @@ export default function Demo() {
88
88
  tableId="demo-grouped"
89
89
  columns={columns}
90
90
  data={data}
91
+ styles="professional"
91
92
  isGrouped={false}
92
93
  groupKey="groupId"
93
94
  extraSearchTerm=""
94
- rowHeight={40}
95
- groupHeaderHeight={40}
96
95
  showKey={true}
97
96
  enableDragRow={true}
98
97
  selectedRowsCallback={(arr) => console.log("selected", arr)}
@@ -122,11 +121,12 @@ export default function Demo() {
122
121
  - `tableId`: unique string ID for the table
123
122
  - `columns`: array of `{ header, accessor }`
124
123
  - `data`: array of row objects
124
+ - `styles`: optional table theme. Set to `"professional"` for a compact premium business grid: a graphite-navy header, fine horizontal separators, subtle row banding, outlined action icons, and blue selection/focus states. Other values retain the default appearance.
125
125
  - `isGrouped`: enable grouped mode (true/false)
126
126
  - `groupKey`: key to group rows by
127
127
  - `extraSearchTerm`: string to filter + highlight rows
128
- - `rowHeight`: row height in px
129
- - `groupHeaderHeight`: group header height in px
128
+ - `rowHeight`: row height in px (default `34`). Ignored with `styles="professional"`, which always uses `30px` rows.
129
+ - `groupHeaderHeight`: group header height in px (default `36`). Ignored with `styles="professional"`, which always uses `32px` group headers.
130
130
  - `mobileColumnCount`: number of data columns shown at viewport widths of 768px or less (1 or 2; default `2`). The full row details are shown in a modal when a mobile row is clicked.
131
131
  - `mobileRowClick`: optional callback `(row) => {}` invoked instead of opening the built-in details modal when a mobile row is clicked. Clicks on row controls and action buttons keep their existing behavior.
132
132
  - On mobile, when `enableMouseRightClick` actions are provided, double-tapping a row opens the same context menu as a right click (a single tap then opens details after a short ~280ms delay).
package/dist/Table.cjs.js CHANGED
@@ -9546,6 +9546,33 @@ _defineProperty(WindowScroller, "defaultProps", {
9546
9546
  });
9547
9547
 
9548
9548
  const ITEM_TYPE = "ROW";
9549
+ const actionIconPaths = {
9550
+ view: "M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0",
9551
+ edit: "m15 5 4 4 M4 20l4-1L20 7a2.8 2.8 0 0 0-4-4L4 15v5Z",
9552
+ duplicate: "M9 9h11v11H9Z M15 5V3H3v12h2",
9553
+ delete: "M3 6h18 M9 6V3h6v3 M5 6l1 15h12l1-15 M10 10v7 M14 10v7",
9554
+ undelete: "M3 4v6h6 M3 10a9 9 0 1 1 1 8",
9555
+ share: "M10 14 21 3 M14 3h7v7 M10 3H3v18h18v-7",
9556
+ download: "M12 3v12 m-5-5 5 5 5-5 M3 16v5h18v-5"
9557
+ };
9558
+ function ActionIcon({
9559
+ name
9560
+ }) {
9561
+ return /*#__PURE__*/React.createElement("svg", {
9562
+ width: "14",
9563
+ height: "14",
9564
+ viewBox: "0 0 24 24",
9565
+ fill: "none",
9566
+ stroke: "currentColor",
9567
+ strokeWidth: "1.7",
9568
+ strokeLinecap: "round",
9569
+ strokeLinejoin: "round",
9570
+ "aria-hidden": "true",
9571
+ focusable: "false"
9572
+ }, /*#__PURE__*/React.createElement("path", {
9573
+ d: actionIconPaths[name]
9574
+ }));
9575
+ }
9549
9576
  const getColumnType = column => Array.isArray(column?.type) ? column.type[0] : column?.type;
9550
9577
  const getColumnDateFormat = column => {
9551
9578
  if (Array.isArray(column?.type)) return column.type[1] || null;
@@ -9694,8 +9721,9 @@ function TableInner({
9694
9721
  groupKey = "groupId",
9695
9722
  routePath = null,
9696
9723
  extraSearchTerm = "",
9697
- rowHeight = 34,
9698
- groupHeaderHeight = 36,
9724
+ styles,
9725
+ rowHeight: requestedRowHeight = 34,
9726
+ groupHeaderHeight: requestedGroupHeaderHeight = 36,
9699
9727
  showKey = false,
9700
9728
  keyWidth = null,
9701
9729
  selectedRowsCallback = () => {},
@@ -9734,6 +9762,13 @@ function TableInner({
9734
9762
  timeoutLoading = 5,
9735
9763
  t
9736
9764
  }) {
9765
+ const isProfessional = styles === "professional";
9766
+ const rowHeight = isProfessional ? 30 : requestedRowHeight;
9767
+ const groupHeaderHeight = isProfessional ? 32 : requestedGroupHeaderHeight;
9768
+ const virtualizedListRef = React.useRef(null);
9769
+ React.useEffect(() => {
9770
+ virtualizedListRef.current?.recomputeRowHeights();
9771
+ }, [rowHeight, groupHeaderHeight]);
9737
9772
  let translate;
9738
9773
  if (t) {
9739
9774
  translate = t;
@@ -10833,10 +10868,6 @@ function TableInner({
10833
10868
  } catch (err) {
10834
10869
  console.error("onCellChange error", err);
10835
10870
  }
10836
- },
10837
- style: {
10838
- border: "1px solid var(--border-light, #ccc)",
10839
- padding: "2px 4px"
10840
10871
  }
10841
10872
  });
10842
10873
  }
@@ -10875,10 +10906,6 @@ function TableInner({
10875
10906
  } catch (err) {
10876
10907
  console.error("onCellChange error", err);
10877
10908
  }
10878
- },
10879
- style: {
10880
- border: "1px solid var(--border-light, #ccc)",
10881
- padding: "2px 4px"
10882
10909
  }
10883
10910
  });
10884
10911
  }
@@ -11134,10 +11161,10 @@ function TableInner({
11134
11161
  key: key,
11135
11162
  style: {
11136
11163
  ...style,
11137
- background: "#f6f6fa",
11138
- border: "2px dashed #bbb",
11164
+ background: "var(--table-group-bg, #f6f6fa)",
11165
+ border: "2px dashed var(--table-group-border, #bbb)",
11139
11166
  textAlign: "center",
11140
- color: "#888",
11167
+ color: "var(--table-group-color, #888)",
11141
11168
  minHeight: rowHeight,
11142
11169
  display: "flex",
11143
11170
  alignItems: "center"
@@ -11278,6 +11305,8 @@ function TableInner({
11278
11305
  ...highlightRowStyle
11279
11306
  } : style,
11280
11307
  className: isMobile ? "table-row mobile-clickable" : "table-row",
11308
+ "data-stripe": visualIndex % 2 === 0 ? "even" : "odd",
11309
+ "data-selected": selectedRows.includes(row.id) ? "true" : undefined,
11281
11310
  onClick: isMobile ? handleMobileRowClick : undefined,
11282
11311
  onContextMenu: e => {
11283
11312
  if (!Array.isArray(enableMouseRightClick) || enableMouseRightClick.length === 0) return;
@@ -11340,7 +11369,9 @@ function TableInner({
11340
11369
  role: "img",
11341
11370
  "aria-hidden": "false",
11342
11371
  title: translate("view")
11343
- }, "\uD83D\uDC41\uFE0F") : translate("view")), showEdit && /*#__PURE__*/React.createElement("button", {
11372
+ }, isProfessional ? /*#__PURE__*/React.createElement(ActionIcon, {
11373
+ name: "view"
11374
+ }) : "👁️") : translate("view")), showEdit && /*#__PURE__*/React.createElement("button", {
11344
11375
  className: "action-btn-table",
11345
11376
  onClick: () => editCallbackRef.current(row),
11346
11377
  onDoubleClick: e => e.stopPropagation(),
@@ -11349,20 +11380,25 @@ function TableInner({
11349
11380
  role: "img",
11350
11381
  "aria-hidden": "false",
11351
11382
  title: translate("edit")
11352
- }, "\u270F\uFE0F") : translate("edit")), showDuplicate && /*#__PURE__*/React.createElement("button", {
11383
+ }, isProfessional ? /*#__PURE__*/React.createElement(ActionIcon, {
11384
+ name: "edit"
11385
+ }) : "✏️") : translate("edit")), showDuplicate && /*#__PURE__*/React.createElement("button", {
11353
11386
  className: "action-btn-table",
11354
11387
  onClick: () => duplicateCallbackRef.current(row),
11355
11388
  onDoubleClick: e => e.stopPropagation(),
11356
11389
  "aria-label": translate("duplicate")
11357
11390
  }, showIcons ? /*#__PURE__*/React.createElement("span", {
11358
- style: {
11391
+ style: isProfessional ? undefined : {
11359
11392
  color: "black"
11360
11393
  },
11361
11394
  role: "img",
11362
11395
  "aria-hidden": "false",
11363
11396
  title: translate("duplicate")
11364
- }, "\uD83D\uDDD0") : translate("duplicate")), showDelete && /*#__PURE__*/React.createElement("button", {
11397
+ }, isProfessional ? /*#__PURE__*/React.createElement(ActionIcon, {
11398
+ name: "duplicate"
11399
+ }) : "🗐") : translate("duplicate")), showDelete && /*#__PURE__*/React.createElement("button", {
11365
11400
  className: "action-btn-table",
11401
+ "data-action": "delete",
11366
11402
  onClick: () => deleteCallbackRef.current(row),
11367
11403
  onDoubleClick: e => e.stopPropagation(),
11368
11404
  "aria-label": translate("delete")
@@ -11370,7 +11406,9 @@ function TableInner({
11370
11406
  role: "img",
11371
11407
  "aria-hidden": "false",
11372
11408
  title: translate("delete")
11373
- }, "\uD83D\uDDD1\uFE0F") : translate("delete")), showUndelete && /*#__PURE__*/React.createElement("button", {
11409
+ }, isProfessional ? /*#__PURE__*/React.createElement(ActionIcon, {
11410
+ name: "delete"
11411
+ }) : "🗑️") : translate("delete")), showUndelete && /*#__PURE__*/React.createElement("button", {
11374
11412
  className: "action-btn-table",
11375
11413
  onClick: () => undeleteCallbackRef.current(row),
11376
11414
  onDoubleClick: e => e.stopPropagation(),
@@ -11379,7 +11417,9 @@ function TableInner({
11379
11417
  role: "img",
11380
11418
  "aria-hidden": "false",
11381
11419
  title: translate("undelete")
11382
- }, "\u267B\uFE0F") : translate("undelete")), showShare && /*#__PURE__*/React.createElement("button", {
11420
+ }, isProfessional ? /*#__PURE__*/React.createElement(ActionIcon, {
11421
+ name: "undelete"
11422
+ }) : "♻️") : translate("undelete")), showShare && /*#__PURE__*/React.createElement("button", {
11383
11423
  className: "action-btn-table",
11384
11424
  onClick: () => shareCallbackRef.current(row),
11385
11425
  onDoubleClick: e => e.stopPropagation(),
@@ -11388,7 +11428,9 @@ function TableInner({
11388
11428
  role: "img",
11389
11429
  "aria-hidden": "false",
11390
11430
  title: translate("share")
11391
- }, "\uD83D\uDD17") : translate("share")), showDownload && /*#__PURE__*/React.createElement("button", {
11431
+ }, isProfessional ? /*#__PURE__*/React.createElement(ActionIcon, {
11432
+ name: "share"
11433
+ }) : "🔗") : translate("share")), showDownload && /*#__PURE__*/React.createElement("button", {
11392
11434
  className: "action-btn-table",
11393
11435
  onClick: () => downloadCallbackRef.current(row),
11394
11436
  onDoubleClick: e => e.stopPropagation(),
@@ -11397,7 +11439,9 @@ function TableInner({
11397
11439
  role: "img",
11398
11440
  "aria-hidden": "false",
11399
11441
  title: translate("download") || "Download"
11400
- }, "\uD83D\uDCE5") : translate("download") || "Download")));
11442
+ }, isProfessional ? /*#__PURE__*/React.createElement(ActionIcon, {
11443
+ name: "download"
11444
+ }) : "📥") : translate("download") || "Download")));
11401
11445
  if (enableDragRow && item.type === "row") {
11402
11446
  return /*#__PURE__*/React.createElement(DraggableRow, {
11403
11447
  key: key,
@@ -11410,7 +11454,7 @@ function TableInner({
11410
11454
  }, content);
11411
11455
  }
11412
11456
  return content;
11413
- }, [tableDataFlat, visibleColumns, selectedRows, toggleRowSelection, groupRowsById, renderCell, getCellStyle, showActions, showDelete, showEdit, showKey, showView, translate, enableDragRow, moveRow, enableMultiSelect, rowHeight, tableId, customColumns, isMobile, enableMouseRightClick, doubleClickEnable, keyWidth, actionColumnStyle, showDuplicate, showDownload, showIcons, showShare, getHighlightRowStyle, triggerCellCallback, getAccessorKey, getAccessorValue]);
11457
+ }, [tableDataFlat, visibleColumns, selectedRows, toggleRowSelection, groupRowsById, renderCell, getCellStyle, showActions, showDelete, showEdit, showKey, showView, translate, enableDragRow, moveRow, enableMultiSelect, rowHeight, tableId, customColumns, isMobile, enableMouseRightClick, doubleClickEnable, keyWidth, actionColumnStyle, showDuplicate, showDownload, showIcons, isProfessional, showShare, getHighlightRowStyle, triggerCellCallback, getAccessorKey, getAccessorValue]);
11414
11458
  const rightClickActions = Array.isArray(enableMouseRightClick) ? enableMouseRightClick : [];
11415
11459
  const [hoveredActionIndex, setHoveredActionIndex] = React.useState(null);
11416
11460
  const rowHeightGetter = ({
@@ -11442,6 +11486,7 @@ function TableInner({
11442
11486
  }, [useExternalDndContext, enableExternalRowDrop, externalDrop]);
11443
11487
  const tableMarkup = /*#__PURE__*/React.createElement("div", {
11444
11488
  className: "table-container",
11489
+ "data-table-style": isProfessional ? styles : undefined,
11445
11490
  ref: setTableRef,
11446
11491
  style: useExternalDndContext && enableExternalRowDrop ? {
11447
11492
  transition: "background 0.15s",
@@ -11455,7 +11500,7 @@ function TableInner({
11455
11500
  position: "sticky",
11456
11501
  top: 0,
11457
11502
  zIndex: 10,
11458
- background: "#fff",
11503
+ background: "var(--table-header-bg, var(--table-bg))",
11459
11504
  paddingRight: headerPadRight || undefined
11460
11505
  }
11461
11506
  }, /*#__PURE__*/React.createElement("div", {
@@ -11505,7 +11550,7 @@ function TableInner({
11505
11550
  className: "table-cell action-cell",
11506
11551
  style: actionColumnStyle,
11507
11552
  title: translate("action")
11508
- }, showIcons ? /*#__PURE__*/React.createElement("span", {
11553
+ }, showIcons && !isProfessional ? /*#__PURE__*/React.createElement("span", {
11509
11554
  title: translate("action")
11510
11555
  }, "\u2699\uFE0F") : translate("action")))), /*#__PURE__*/React.createElement("div", {
11511
11556
  className: "main-table",
@@ -11524,6 +11569,7 @@ function TableInner({
11524
11569
  height,
11525
11570
  width
11526
11571
  }) => /*#__PURE__*/React.createElement(List, {
11572
+ ref: virtualizedListRef,
11527
11573
  width: width,
11528
11574
  height: height,
11529
11575
  rowCount: tableDataFlat.length,