bolt-table 0.1.14 → 0.1.16

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.mjs CHANGED
@@ -682,9 +682,6 @@ var DraggableHeader = React.memo(
682
682
  )
683
683
  ] });
684
684
  },
685
- // ── Custom memo comparator ─────────────────────────────────────────────────
686
- // Only re-render when props that actually affect this header's output change.
687
- // This prevents a sort/filter change on one column from re-rendering all others.
688
685
  (prevProps, nextProps) => {
689
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;
690
687
  }
@@ -974,11 +971,6 @@ var Cell = React3.memo(
974
971
  }
975
972
  );
976
973
  },
977
- // ── Custom memo comparator ─────────────────────────────────────────────────
978
- // Minimizes re-renders:
979
- // - __select__ cells: re-render only when selection changes
980
- // - __expand__ cells: re-render only when expand state changes
981
- // - Normal cells: re-render only when value or rowIndex changes
982
974
  (prev, next) => {
983
975
  if (prev.isLoading !== next.isLoading) return false;
984
976
  if (prev.column.key === "__select__") {
@@ -1097,64 +1089,52 @@ var TableBody = ({
1097
1089
  const cellValue = row[col.dataIndex];
1098
1090
  const isRowShimmer = isLoading || rowKey.startsWith("__shimmer_");
1099
1091
  const recordFingerprint = hasRender && !isRowShimmer ? JSON.stringify(row) : void 0;
1100
- return (
1101
- /*
1102
- * Row wrapper div:
1103
- * - data-row-key: used by BoltTable's DOM-based hover system
1104
- * (mouseover reads this attribute to apply hover styles
1105
- * across all column divs for the same row simultaneously)
1106
- * - data-selected: presence/absence attribute consumed by the
1107
- * CSS injected by BoltTable for selected row background
1108
- * - Absolute positioned at virtualRow.start for virtualization
1109
- * - Height = virtualRow.size (includes expanded row height)
1110
- */
1111
- /* @__PURE__ */ jsx4(
1112
- "div",
1113
- {
1114
- "data-row-key": rowKey,
1115
- "data-column-key": col.key,
1116
- "data-bt-cell": "",
1117
- "data-selected": isSelected || void 0,
1118
- style: {
1119
- position: "absolute",
1120
- top: `${virtualRow.start}px`,
1121
- left: 0,
1122
- right: 0,
1123
- height: `${virtualRow.size}px`
1124
- },
1125
- children: /* @__PURE__ */ jsx4(
1126
- "div",
1127
- {
1128
- style: {
1129
- height: `${rowHeight}px`,
1130
- position: "relative"
1131
- },
1132
- children: /* @__PURE__ */ jsx4(
1133
- Cell,
1134
- {
1135
- value: cellValue,
1136
- record: row,
1137
- column: col,
1138
- rowIndex: virtualRow.index,
1139
- classNames,
1140
- styles,
1141
- isSelected,
1142
- isExpanded,
1143
- rowSelection,
1144
- normalizedSelectedKeys,
1145
- rowKey,
1146
- allData: allDataForSelection,
1147
- getRowKey,
1148
- accentColor,
1149
- isLoading: isRowShimmer,
1150
- recordFingerprint
1151
- }
1152
- )
1153
- }
1154
- )
1092
+ return /* @__PURE__ */ jsx4(
1093
+ "div",
1094
+ {
1095
+ "data-row-key": rowKey,
1096
+ "data-column-key": col.key,
1097
+ "data-bt-cell": "",
1098
+ "data-selected": isSelected || void 0,
1099
+ style: {
1100
+ position: "absolute",
1101
+ top: `${virtualRow.start}px`,
1102
+ left: 0,
1103
+ right: 0,
1104
+ height: `${virtualRow.size}px`
1155
1105
  },
1156
- `${rowKey}-${col.key}`
1157
- )
1106
+ children: /* @__PURE__ */ jsx4(
1107
+ "div",
1108
+ {
1109
+ style: {
1110
+ height: `${rowHeight}px`,
1111
+ position: "relative"
1112
+ },
1113
+ children: /* @__PURE__ */ jsx4(
1114
+ Cell,
1115
+ {
1116
+ value: cellValue,
1117
+ record: row,
1118
+ column: col,
1119
+ rowIndex: virtualRow.index,
1120
+ classNames,
1121
+ styles,
1122
+ isSelected,
1123
+ isExpanded,
1124
+ rowSelection,
1125
+ normalizedSelectedKeys,
1126
+ rowKey,
1127
+ allData: allDataForSelection,
1128
+ getRowKey,
1129
+ accentColor,
1130
+ isLoading: isRowShimmer,
1131
+ recordFingerprint
1132
+ }
1133
+ )
1134
+ }
1135
+ )
1136
+ },
1137
+ `${rowKey}-${col.key}`
1158
1138
  );
1159
1139
  })
1160
1140
  },
@@ -1170,8 +1150,6 @@ var TableBody = ({
1170
1150
  height: `${totalSize}px`,
1171
1151
  position: "relative",
1172
1152
  zIndex: 15,
1173
- // pointerEvents: none on the overlay so hover/click pass through
1174
- // to the cells below for rows that are NOT expanded
1175
1153
  pointerEvents: "none"
1176
1154
  },
1177
1155
  children: virtualItems.map((virtualRow) => {
@@ -1203,7 +1181,6 @@ var TableBody = ({
1203
1181
  {
1204
1182
  style: {
1205
1183
  position: "absolute",
1206
- // Position immediately below the row's base height
1207
1184
  top: virtualRow.start + rowHeight,
1208
1185
  left: 0,
1209
1186
  right: 0
@@ -1724,7 +1701,7 @@ function BoltTable({
1724
1701
  }
1725
1702
  const scrollEl = tableAreaRef.current;
1726
1703
  if (!scrollEl) return;
1727
- const headers = scrollEl.querySelectorAll("[data-column-key]");
1704
+ const headers = scrollEl.querySelectorAll("[data-bt-header][data-column-key]");
1728
1705
  let newOverId = null;
1729
1706
  headers.forEach((h) => {
1730
1707
  const key = h.dataset.columnKey;
@@ -1811,7 +1788,6 @@ function BoltTable({
1811
1788
  areaRect,
1812
1789
  headerLeftInContent,
1813
1790
  40,
1814
- // minimum column width
1815
1791
  scrollTop,
1816
1792
  scrollLeft,
1817
1793
  headerLeftInContent + startWidth
@@ -2268,10 +2244,10 @@ function BoltTable({
2268
2244
  [data-bt-ctx-item]:not(:disabled):hover {
2269
2245
  background-color: rgba(128, 128, 128, 0.15);
2270
2246
  }
2271
- [data-column-key][data-dragging] {
2247
+ [data-bt-header][data-dragging] {
2272
2248
  opacity: 0.3 !important;
2273
2249
  }
2274
- [data-column-key][data-drag-over] {
2250
+ [data-bt-header][data-drag-over] {
2275
2251
  border: 1px dashed ${accentColor} !important;
2276
2252
  }
2277
2253
  ` }),
@@ -2287,157 +2263,170 @@ function BoltTable({
2287
2263
  flexGrow: 0
2288
2264
  } : { flex: "1 1 0%" }
2289
2265
  },
2290
- children: layoutLoading ? (
2291
- /*
2292
- * ── Layout loading skeleton ──────────────────────────────────
2293
- * Shown when layoutLoading=true. Renders real column headers
2294
- * (based on orderedColumns) alongside shimmer body rows.
2295
- * Used for initial page load when column widths are not yet known.
2296
- */
2297
- /* @__PURE__ */ jsx5(
2298
- "div",
2299
- {
2300
- style: {
2301
- position: "absolute",
2302
- inset: 0,
2303
- overflow: "auto",
2304
- contain: "layout paint"
2305
- },
2306
- children: /* @__PURE__ */ jsxs5(
2266
+ children: layoutLoading ? /* @__PURE__ */ jsx5(
2267
+ "div",
2268
+ {
2269
+ style: {
2270
+ position: "absolute",
2271
+ inset: 0,
2272
+ overflow: "auto",
2273
+ contain: "layout paint"
2274
+ },
2275
+ children: /* @__PURE__ */ jsxs5(
2276
+ "div",
2277
+ {
2278
+ style: {
2279
+ display: "grid",
2280
+ gridTemplateColumns,
2281
+ gridTemplateRows: "36px auto",
2282
+ minWidth: `${totalTableWidth}px`,
2283
+ width: "100%",
2284
+ position: "relative"
2285
+ },
2286
+ children: [
2287
+ orderedColumns.map((column) => {
2288
+ const isPinned = !!column.pinned;
2289
+ const offset = columnOffsets.get(column.key);
2290
+ const isSystem = column.key === "__select__" || column.key === "__expand__";
2291
+ return /* @__PURE__ */ jsx5(
2292
+ "div",
2293
+ {
2294
+ className: isPinned ? classNames.pinnedHeader ?? "" : classNames.header ?? "",
2295
+ style: {
2296
+ display: "flex",
2297
+ height: 36,
2298
+ alignItems: "center",
2299
+ overflow: "hidden",
2300
+ textOverflow: "ellipsis",
2301
+ whiteSpace: "nowrap",
2302
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
2303
+ backdropFilter: "blur(8px)",
2304
+ position: "sticky",
2305
+ top: 0,
2306
+ zIndex: isPinned ? 13 : 10,
2307
+ ...isPinned ? {
2308
+ [column.pinned]: offset ?? 0,
2309
+ ...styles.pinnedHeader
2310
+ } : styles.header,
2311
+ paddingLeft: isSystem ? 0 : 8,
2312
+ paddingRight: isSystem ? 0 : 8
2313
+ }
2314
+ },
2315
+ column.key
2316
+ );
2317
+ }),
2318
+ /* @__PURE__ */ jsx5("div", { style: { gridColumn: "1 / -1" }, children: Array.from({ length: shimmerCount }).map((_, rowIndex) => /* @__PURE__ */ jsx5(
2319
+ "div",
2320
+ {
2321
+ style: {
2322
+ display: "grid",
2323
+ gridTemplateColumns,
2324
+ height: rowHeight
2325
+ },
2326
+ children: orderedColumns.map((column, colIndex) => {
2327
+ const isPinned = !!column.pinned;
2328
+ const offset = columnOffsets.get(column.key);
2329
+ const isSystem = column.key === "__select__" || column.key === "__expand__";
2330
+ const widthPercent = SHIMMER_WIDTHS2[(rowIndex * 7 + colIndex) % SHIMMER_WIDTHS2.length];
2331
+ return /* @__PURE__ */ jsx5(
2332
+ "div",
2333
+ {
2334
+ className: isPinned ? classNames.pinnedCell ?? "" : "",
2335
+ style: {
2336
+ display: "flex",
2337
+ alignItems: "center",
2338
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
2339
+ ...isPinned ? {
2340
+ position: "sticky",
2341
+ [column.pinned]: offset ?? 0,
2342
+ zIndex: 5,
2343
+ ...styles.pinnedCell
2344
+ } : {},
2345
+ paddingLeft: isSystem ? 0 : 8,
2346
+ paddingRight: isSystem ? 0 : 8,
2347
+ justifyContent: isSystem ? "center" : void 0
2348
+ },
2349
+ children: /* @__PURE__ */ jsx5(
2350
+ "div",
2351
+ {
2352
+ style: {
2353
+ backgroundColor: "rgba(100, 116, 139, 0.15)",
2354
+ animation: "bt-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
2355
+ borderRadius: isSystem ? 3 : 4,
2356
+ height: isSystem ? 16 : 14,
2357
+ width: isSystem ? 16 : `${widthPercent}%`,
2358
+ animationDelay: `${(rowIndex * 7 + colIndex) * 50}ms`
2359
+ }
2360
+ }
2361
+ )
2362
+ },
2363
+ column.key
2364
+ );
2365
+ })
2366
+ },
2367
+ rowIndex
2368
+ )) })
2369
+ ]
2370
+ }
2371
+ )
2372
+ }
2373
+ ) : /* @__PURE__ */ jsxs5(
2374
+ "div",
2375
+ {
2376
+ ref: tableAreaCallbackRef,
2377
+ style: {
2378
+ position: "absolute",
2379
+ inset: 0,
2380
+ overflow: "auto",
2381
+ contain: "layout paint"
2382
+ },
2383
+ children: [
2384
+ /* @__PURE__ */ jsx5(ResizeOverlay_default, { ref: resizeOverlayRef, accentColor }),
2385
+ /* @__PURE__ */ jsxs5(
2307
2386
  "div",
2308
2387
  {
2309
2388
  style: {
2310
2389
  display: "grid",
2311
2390
  gridTemplateColumns,
2312
- gridTemplateRows: "36px auto",
2391
+ gridTemplateRows: isEmpty ? "36px 1fr" : `36px ${virtualTotalSize}px`,
2313
2392
  minWidth: `${totalTableWidth}px`,
2314
2393
  width: "100%",
2315
- position: "relative"
2394
+ position: "relative",
2395
+ ...isEmpty ? { height: "100%" } : {}
2316
2396
  },
2317
- children: [
2318
- orderedColumns.map((column) => {
2319
- const isPinned = !!column.pinned;
2320
- const offset = columnOffsets.get(column.key);
2321
- const isSystem = column.key === "__select__" || column.key === "__expand__";
2322
- return /* @__PURE__ */ jsx5(
2323
- "div",
2324
- {
2325
- className: isPinned ? classNames.pinnedHeader ?? "" : classNames.header ?? "",
2326
- style: {
2327
- display: "flex",
2328
- height: 36,
2329
- alignItems: "center",
2330
- overflow: "hidden",
2331
- textOverflow: "ellipsis",
2332
- whiteSpace: "nowrap",
2333
- borderBottom: "1px solid rgba(128,128,128,0.2)",
2334
- backdropFilter: "blur(8px)",
2335
- position: "sticky",
2336
- top: 0,
2337
- zIndex: isPinned ? 13 : 10,
2338
- ...isPinned ? {
2339
- [column.pinned]: offset ?? 0,
2340
- ...styles.pinnedHeader
2341
- } : styles.header,
2342
- paddingLeft: isSystem ? 0 : 8,
2343
- paddingRight: isSystem ? 0 : 8
2344
- }
2345
- },
2346
- column.key
2347
- );
2348
- }),
2349
- /* @__PURE__ */ jsx5("div", { style: { gridColumn: "1 / -1" }, children: Array.from({ length: shimmerCount }).map((_, rowIndex) => /* @__PURE__ */ jsx5(
2350
- "div",
2351
- {
2352
- style: {
2353
- display: "grid",
2354
- gridTemplateColumns,
2355
- height: rowHeight
2356
- },
2357
- children: orderedColumns.map((column, colIndex) => {
2358
- const isPinned = !!column.pinned;
2359
- const offset = columnOffsets.get(column.key);
2360
- const isSystem = column.key === "__select__" || column.key === "__expand__";
2361
- const widthPercent = SHIMMER_WIDTHS2[(rowIndex * 7 + colIndex) % SHIMMER_WIDTHS2.length];
2362
- return /* @__PURE__ */ jsx5(
2363
- "div",
2364
- {
2365
- className: isPinned ? classNames.pinnedCell ?? "" : "",
2366
- style: {
2367
- display: "flex",
2368
- alignItems: "center",
2369
- borderBottom: "1px solid rgba(128,128,128,0.2)",
2370
- ...isPinned ? {
2371
- position: "sticky",
2372
- [column.pinned]: offset ?? 0,
2373
- zIndex: 5,
2374
- ...styles.pinnedCell
2375
- } : {},
2376
- paddingLeft: isSystem ? 0 : 8,
2377
- paddingRight: isSystem ? 0 : 8,
2378
- justifyContent: isSystem ? "center" : void 0
2379
- },
2380
- children: /* @__PURE__ */ jsx5(
2381
- "div",
2382
- {
2383
- style: {
2384
- backgroundColor: "rgba(100, 116, 139, 0.15)",
2385
- animation: "bt-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
2386
- borderRadius: isSystem ? 3 : 4,
2387
- height: isSystem ? 16 : 14,
2388
- width: isSystem ? 16 : `${widthPercent}%`,
2389
- animationDelay: `${(rowIndex * 7 + colIndex) * 50}ms`
2390
- }
2391
- }
2392
- )
2393
- },
2394
- column.key
2395
- );
2396
- })
2397
- },
2398
- rowIndex
2399
- )) })
2400
- ]
2401
- }
2402
- )
2403
- }
2404
- )
2405
- ) : (
2406
- /*
2407
- * ── Main scroll container ────────────────────────────────────
2408
- * absolute inset-0 so it fills whatever height the wrapper resolves to.
2409
- * contain: layout paint — browser optimization hint that this element
2410
- * is a layout and paint boundary (improves compositing performance).
2411
- */
2412
- /* @__PURE__ */ jsxs5(
2413
- "div",
2414
- {
2415
- ref: tableAreaCallbackRef,
2416
- style: {
2417
- position: "absolute",
2418
- inset: 0,
2419
- overflow: "auto",
2420
- contain: "layout paint"
2421
- },
2422
- children: [
2423
- /* @__PURE__ */ jsx5(ResizeOverlay_default, { ref: resizeOverlayRef, accentColor }),
2424
- /* @__PURE__ */ jsxs5(
2425
- "div",
2426
- {
2427
- style: {
2428
- display: "grid",
2429
- gridTemplateColumns,
2430
- gridTemplateRows: isEmpty ? "36px 1fr" : `36px ${virtualTotalSize}px`,
2431
- minWidth: `${totalTableWidth}px`,
2432
- width: "100%",
2433
- position: "relative",
2434
- ...isEmpty ? { height: "100%" } : {}
2435
- },
2436
- onContextMenu: (e) => {
2437
- const cell = e.target.closest("[data-bt-cell]");
2438
- if (!cell) return;
2439
- const rk = cell.dataset.rowKey;
2440
- const ck = cell.dataset.columnKey;
2397
+ onContextMenu: (e) => {
2398
+ const cell = e.target.closest("[data-bt-cell]");
2399
+ if (!cell) return;
2400
+ const rk = cell.dataset.rowKey;
2401
+ const ck = cell.dataset.columnKey;
2402
+ if (!rk || !ck) return;
2403
+ const col = freshOrderedColumns.find(
2404
+ (c) => c.key === ck
2405
+ );
2406
+ const hasCopy = col?.copy;
2407
+ const hasRowPin = !!onRowPin;
2408
+ if (!hasCopy && !hasRowPin) return;
2409
+ e.preventDefault();
2410
+ setCellContextMenu({
2411
+ x: Math.min(e.clientX, window.innerWidth - 200),
2412
+ y: Math.min(e.clientY, window.innerHeight - 200),
2413
+ rowKey: rk,
2414
+ columnKey: ck
2415
+ });
2416
+ },
2417
+ onTouchStart: (e) => {
2418
+ cancelCellLongPress();
2419
+ const cell = e.target.closest("[data-bt-cell]");
2420
+ if (!cell) return;
2421
+ const touch = e.touches[0];
2422
+ cellTouchStart.current = {
2423
+ x: touch.clientX,
2424
+ y: touch.clientY
2425
+ };
2426
+ const rk = cell.dataset.rowKey;
2427
+ const ck = cell.dataset.columnKey;
2428
+ cellLongPressTimer.current = setTimeout(() => {
2429
+ cellLongPressTimer.current = null;
2441
2430
  if (!rk || !ck) return;
2442
2431
  const col = freshOrderedColumns.find(
2443
2432
  (c) => c.key === ck
@@ -2445,254 +2434,211 @@ function BoltTable({
2445
2434
  const hasCopy = col?.copy;
2446
2435
  const hasRowPin = !!onRowPin;
2447
2436
  if (!hasCopy && !hasRowPin) return;
2448
- e.preventDefault();
2449
2437
  setCellContextMenu({
2450
- x: Math.min(e.clientX, window.innerWidth - 200),
2451
- y: Math.min(e.clientY, window.innerHeight - 200),
2438
+ x: Math.min(touch.clientX, window.innerWidth - 200),
2439
+ y: Math.min(touch.clientY, window.innerHeight - 200),
2452
2440
  rowKey: rk,
2453
2441
  columnKey: ck
2454
2442
  });
2455
- },
2456
- onTouchStart: (e) => {
2443
+ }, 500);
2444
+ },
2445
+ onTouchMove: (e) => {
2446
+ if (!cellTouchStart.current) return;
2447
+ const touch = e.touches[0];
2448
+ const dx = touch.clientX - cellTouchStart.current.x;
2449
+ const dy = touch.clientY - cellTouchStart.current.y;
2450
+ if (Math.abs(dx) > 10 || Math.abs(dy) > 10)
2457
2451
  cancelCellLongPress();
2458
- const cell = e.target.closest("[data-bt-cell]");
2459
- if (!cell) return;
2460
- const touch = e.touches[0];
2461
- cellTouchStart.current = {
2462
- x: touch.clientX,
2463
- y: touch.clientY
2464
- };
2465
- const rk = cell.dataset.rowKey;
2466
- const ck = cell.dataset.columnKey;
2467
- cellLongPressTimer.current = setTimeout(() => {
2468
- cellLongPressTimer.current = null;
2469
- if (!rk || !ck) return;
2470
- const col = freshOrderedColumns.find(
2471
- (c) => c.key === ck
2472
- );
2473
- const hasCopy = col?.copy;
2474
- const hasRowPin = !!onRowPin;
2475
- if (!hasCopy && !hasRowPin) return;
2476
- setCellContextMenu({
2477
- x: Math.min(touch.clientX, window.innerWidth - 200),
2478
- y: Math.min(touch.clientY, window.innerHeight - 200),
2479
- rowKey: rk,
2480
- columnKey: ck
2481
- });
2482
- }, 500);
2483
- },
2484
- onTouchMove: (e) => {
2485
- if (!cellTouchStart.current) return;
2486
- const touch = e.touches[0];
2487
- const dx = touch.clientX - cellTouchStart.current.x;
2488
- const dy = touch.clientY - cellTouchStart.current.y;
2489
- if (Math.abs(dx) > 10 || Math.abs(dy) > 10)
2490
- cancelCellLongPress();
2491
- },
2492
- onTouchEnd: cancelCellLongPress,
2493
- onTouchCancel: cancelCellLongPress,
2494
- children: [
2495
- orderedColumns.map((column, visualIndex) => {
2496
- if (column.key === "__select__" && rowSelection) {
2497
- return /* @__PURE__ */ jsx5(
2498
- "div",
2499
- {
2500
- className: `${classNames.header ?? ""} ${classNames.pinnedHeader ?? ""}`,
2501
- style: {
2502
- display: "flex",
2503
- height: 36,
2504
- alignItems: "center",
2505
- justifyContent: "center",
2506
- overflow: "hidden",
2507
- textOverflow: "ellipsis",
2508
- whiteSpace: "nowrap",
2509
- borderBottom: "1px solid rgba(128,128,128,0.2)",
2510
- backgroundColor: styles?.pinnedBg,
2511
- position: "sticky",
2512
- left: columnOffsets.get("__select__") ?? 0,
2513
- top: 0,
2514
- zIndex: 13,
2515
- width: "48px",
2516
- ...styles.header,
2517
- ...styles.pinnedHeader
2518
- },
2519
- children: rowSelection.type !== "radio" && !rowSelection.hideSelectAll && /* @__PURE__ */ jsx5(
2520
- "input",
2521
- {
2522
- type: "checkbox",
2523
- checked: data.length > 0 && normalizedSelectedKeys.length === data.length,
2524
- ref: (input) => {
2525
- if (input) {
2526
- input.indeterminate = normalizedSelectedKeys.length > 0 && normalizedSelectedKeys.length < data.length;
2527
- }
2528
- },
2529
- onChange: (e) => {
2530
- if (e.target.checked) {
2531
- const allKeys = data.map(
2532
- (row, idx) => getRowKey(row, idx)
2533
- );
2534
- rowSelection.onSelectAll?.(
2535
- true,
2536
- data,
2537
- data
2538
- );
2539
- rowSelection.onChange?.(allKeys, data, {
2540
- type: "all"
2541
- });
2542
- } else {
2543
- rowSelection.onSelectAll?.(false, [], data);
2544
- rowSelection.onChange?.([], [], {
2545
- type: "all"
2546
- });
2547
- }
2548
- },
2549
- style: { cursor: "pointer", accentColor }
2550
- }
2551
- )
2452
+ },
2453
+ onTouchEnd: cancelCellLongPress,
2454
+ onTouchCancel: cancelCellLongPress,
2455
+ children: [
2456
+ orderedColumns.map((column, visualIndex) => {
2457
+ if (column.key === "__select__" && rowSelection) {
2458
+ return /* @__PURE__ */ jsx5(
2459
+ "div",
2460
+ {
2461
+ className: `${classNames.header ?? ""} ${classNames.pinnedHeader ?? ""}`,
2462
+ style: {
2463
+ display: "flex",
2464
+ height: 36,
2465
+ alignItems: "center",
2466
+ justifyContent: "center",
2467
+ overflow: "hidden",
2468
+ textOverflow: "ellipsis",
2469
+ whiteSpace: "nowrap",
2470
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
2471
+ backgroundColor: styles?.pinnedBg,
2472
+ position: "sticky",
2473
+ left: columnOffsets.get("__select__") ?? 0,
2474
+ top: 0,
2475
+ zIndex: 13,
2476
+ width: "48px",
2477
+ ...styles.header,
2478
+ ...styles.pinnedHeader
2552
2479
  },
2553
- "__select__"
2554
- );
2555
- }
2556
- if (column.key === "__expand__") {
2557
- return /* @__PURE__ */ jsx5(
2558
- "div",
2559
- {
2560
- className: `${classNames.header ?? ""} ${classNames.pinnedHeader ?? ""}`,
2561
- style: {
2562
- display: "flex",
2563
- height: 36,
2564
- alignItems: "center",
2565
- justifyContent: "center",
2566
- overflow: "hidden",
2567
- textOverflow: "ellipsis",
2568
- whiteSpace: "nowrap",
2569
- borderBottom: "1px solid rgba(128,128,128,0.2)",
2570
- backgroundColor: styles?.pinnedBg,
2571
- position: "sticky",
2572
- left: columnOffsets.get("__expand__") ?? 0,
2573
- top: 0,
2574
- zIndex: 13,
2575
- width: "40px",
2576
- ...styles.header,
2577
- ...styles.pinnedHeader
2480
+ children: rowSelection.type !== "radio" && !rowSelection.hideSelectAll && /* @__PURE__ */ jsx5(
2481
+ "input",
2482
+ {
2483
+ type: "checkbox",
2484
+ checked: data.length > 0 && normalizedSelectedKeys.length === data.length,
2485
+ ref: (input) => {
2486
+ if (input) {
2487
+ input.indeterminate = normalizedSelectedKeys.length > 0 && normalizedSelectedKeys.length < data.length;
2488
+ }
2489
+ },
2490
+ onChange: (e) => {
2491
+ if (e.target.checked) {
2492
+ const allKeys = data.map(
2493
+ (row, idx) => getRowKey(row, idx)
2494
+ );
2495
+ rowSelection.onSelectAll?.(
2496
+ true,
2497
+ data,
2498
+ data
2499
+ );
2500
+ rowSelection.onChange?.(allKeys, data, {
2501
+ type: "all"
2502
+ });
2503
+ } else {
2504
+ rowSelection.onSelectAll?.(false, [], data);
2505
+ rowSelection.onChange?.([], [], {
2506
+ type: "all"
2507
+ });
2508
+ }
2509
+ },
2510
+ style: { cursor: "pointer", accentColor }
2578
2511
  }
2579
- },
2580
- "__expand__"
2581
- );
2582
- }
2512
+ )
2513
+ },
2514
+ "__select__"
2515
+ );
2516
+ }
2517
+ if (column.key === "__expand__") {
2583
2518
  return /* @__PURE__ */ jsx5(
2584
- DraggableHeader_default,
2519
+ "div",
2585
2520
  {
2586
- column,
2587
- accentColor,
2588
- visualIndex,
2589
- onResizeStart: handleResizeStart,
2590
- onColumnDragStart: handleColumnDragStart,
2591
- styles,
2592
- classNames,
2593
- gripIcon,
2594
- hideGripIcon,
2595
- icons,
2596
- stickyOffset: columnOffsets.get(column.key),
2597
- onTogglePin: handleTogglePin,
2598
- onToggleHide: handleToggleHide,
2599
- isLastColumn: visualIndex === orderedColumns.length - 1,
2600
- sortDirection: sortState.key === column.key ? sortState.direction : null,
2601
- onSort: handleSort,
2602
- filterValue: columnFilters[column.key] ?? "",
2603
- onFilter: handleColumnFilter,
2604
- onClearFilter: handleClearFilter,
2605
- customContextMenuItems: columnContextMenuItems
2521
+ className: `${classNames.header ?? ""} ${classNames.pinnedHeader ?? ""}`,
2522
+ style: {
2523
+ display: "flex",
2524
+ height: 36,
2525
+ alignItems: "center",
2526
+ justifyContent: "center",
2527
+ overflow: "hidden",
2528
+ textOverflow: "ellipsis",
2529
+ whiteSpace: "nowrap",
2530
+ borderBottom: "1px solid rgba(128,128,128,0.2)",
2531
+ backgroundColor: styles?.pinnedBg,
2532
+ position: "sticky",
2533
+ left: columnOffsets.get("__expand__") ?? 0,
2534
+ top: 0,
2535
+ zIndex: 13,
2536
+ width: "40px",
2537
+ ...styles.header,
2538
+ ...styles.pinnedHeader
2539
+ }
2606
2540
  },
2607
- column.key
2541
+ "__expand__"
2608
2542
  );
2609
- }),
2610
- isEmpty ? (
2611
- /*
2612
- * ── Empty state ────────────────────────────────────────
2613
- * col-span-full + height:100% fills the 1fr body grid row.
2614
- *
2615
- * The inner div uses `position: sticky; left: 0` with a fixed
2616
- * width (scrollAreaWidth) to viewport-lock the empty state panel.
2617
- * Without this, the empty message would scroll horizontally
2618
- * with the grid content when there are many columns.
2619
- */
2620
- /* @__PURE__ */ jsx5(
2543
+ }
2544
+ return /* @__PURE__ */ jsx5(
2545
+ DraggableHeader_default,
2546
+ {
2547
+ column,
2548
+ accentColor,
2549
+ visualIndex,
2550
+ onResizeStart: handleResizeStart,
2551
+ onColumnDragStart: handleColumnDragStart,
2552
+ styles,
2553
+ classNames,
2554
+ gripIcon,
2555
+ hideGripIcon,
2556
+ icons,
2557
+ stickyOffset: columnOffsets.get(column.key),
2558
+ onTogglePin: handleTogglePin,
2559
+ onToggleHide: handleToggleHide,
2560
+ isLastColumn: visualIndex === orderedColumns.length - 1,
2561
+ sortDirection: sortState.key === column.key ? sortState.direction : null,
2562
+ onSort: handleSort,
2563
+ filterValue: columnFilters[column.key] ?? "",
2564
+ onFilter: handleColumnFilter,
2565
+ onClearFilter: handleClearFilter,
2566
+ customContextMenuItems: columnContextMenuItems
2567
+ },
2568
+ column.key
2569
+ );
2570
+ }),
2571
+ isEmpty ? /* @__PURE__ */ jsx5(
2572
+ "div",
2573
+ {
2574
+ style: {
2575
+ gridColumn: "1 / -1",
2576
+ height: "100%",
2577
+ position: "relative"
2578
+ },
2579
+ children: /* @__PURE__ */ jsx5(
2621
2580
  "div",
2622
2581
  {
2623
2582
  style: {
2624
- gridColumn: "1 / -1",
2583
+ position: "sticky",
2584
+ left: 0,
2585
+ width: scrollAreaWidth > 0 ? `${scrollAreaWidth}px` : "100%",
2625
2586
  height: "100%",
2626
- position: "relative"
2587
+ display: "flex",
2588
+ alignItems: "center",
2589
+ justifyContent: "center"
2627
2590
  },
2628
- children: /* @__PURE__ */ jsx5(
2591
+ children: emptyRenderer ?? /* @__PURE__ */ jsx5(
2629
2592
  "div",
2630
2593
  {
2631
2594
  style: {
2632
- position: "sticky",
2633
- left: 0,
2634
- width: scrollAreaWidth > 0 ? `${scrollAreaWidth}px` : "100%",
2635
- height: "100%",
2636
2595
  display: "flex",
2596
+ flexDirection: "column",
2637
2597
  alignItems: "center",
2638
- justifyContent: "center"
2598
+ gap: 8,
2599
+ paddingTop: 32,
2600
+ paddingBottom: 32,
2601
+ color: "GrayText"
2639
2602
  },
2640
- children: emptyRenderer ?? /* @__PURE__ */ jsx5(
2641
- "div",
2642
- {
2643
- style: {
2644
- display: "flex",
2645
- flexDirection: "column",
2646
- alignItems: "center",
2647
- gap: 8,
2648
- paddingTop: 32,
2649
- paddingBottom: 32,
2650
- color: "GrayText"
2651
- },
2652
- children: /* @__PURE__ */ jsx5("span", { style: { fontSize: 14 }, children: "No data" })
2653
- }
2654
- )
2603
+ children: /* @__PURE__ */ jsx5("span", { style: { fontSize: 14 }, children: "No data" })
2655
2604
  }
2656
2605
  )
2657
2606
  }
2658
2607
  )
2659
- ) : (
2660
- /* ── Virtualized table body ─────────────────────────── */
2661
- /* @__PURE__ */ jsx5(
2662
- TableBody_default,
2663
- {
2664
- data: displayData,
2665
- orderedColumns: freshOrderedColumns,
2666
- rowVirtualizer,
2667
- columnOffsets,
2668
- styles,
2669
- classNames,
2670
- rowSelection: !showShimmer ? rowSelection : void 0,
2671
- normalizedSelectedKeys,
2672
- getRowKey,
2673
- expandable: !showShimmer ? expandable : void 0,
2674
- resolvedExpandedKeys,
2675
- rowHeight,
2676
- totalTableWidth,
2677
- scrollAreaWidth,
2678
- accentColor,
2679
- scrollContainerRef: tableAreaRef,
2680
- isLoading: showShimmer,
2681
- onExpandedRowResize: handleExpandedRowResize,
2682
- maxExpandedRowHeight,
2683
- pinnedTopData: pinnedTopRows,
2684
- pinnedBottomData: pinnedBottomRows,
2685
- gridTemplateColumns,
2686
- headerHeight: HEADER_HEIGHT
2687
- }
2688
- )
2689
- )
2690
- ]
2691
- }
2692
- )
2693
- ]
2694
- }
2695
- )
2608
+ }
2609
+ ) : /* @__PURE__ */ jsx5(
2610
+ TableBody_default,
2611
+ {
2612
+ data: displayData,
2613
+ orderedColumns: freshOrderedColumns,
2614
+ rowVirtualizer,
2615
+ columnOffsets,
2616
+ styles,
2617
+ classNames,
2618
+ rowSelection: !showShimmer ? rowSelection : void 0,
2619
+ normalizedSelectedKeys,
2620
+ getRowKey,
2621
+ expandable: !showShimmer ? expandable : void 0,
2622
+ resolvedExpandedKeys,
2623
+ rowHeight,
2624
+ totalTableWidth,
2625
+ scrollAreaWidth,
2626
+ accentColor,
2627
+ scrollContainerRef: tableAreaRef,
2628
+ isLoading: showShimmer,
2629
+ onExpandedRowResize: handleExpandedRowResize,
2630
+ maxExpandedRowHeight,
2631
+ pinnedTopData: pinnedTopRows,
2632
+ pinnedBottomData: pinnedBottomRows,
2633
+ gridTemplateColumns,
2634
+ headerHeight: HEADER_HEIGHT
2635
+ }
2636
+ )
2637
+ ]
2638
+ }
2639
+ )
2640
+ ]
2641
+ }
2696
2642
  )
2697
2643
  }
2698
2644
  ),
@@ -3157,4 +3103,3 @@ export {
3157
3103
  ResizeOverlay_default as ResizeOverlay,
3158
3104
  TableBody_default as TableBody
3159
3105
  };
3160
- //# sourceMappingURL=index.mjs.map