bolt-table 0.1.27 → 0.1.29

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 CHANGED
@@ -281,6 +281,10 @@ interface BoltTableProps<T extends DataRecord = DataRecord> {
281
281
  readonly globalSearchValue?: string;
282
282
  /** Called when the global search value changes. */
283
283
  readonly onGlobalSearchChange?: (value: string) => void;
284
+ /** Extra content rendered in the toolbar between the search bar and the column-settings button. */
285
+ readonly toolbarContent?: React$1.ReactNode;
286
+ /** Label for the column-settings button. Defaults to "Columns". */
287
+ readonly columnSettingsLabel?: React$1.ReactNode;
284
288
  }
285
289
  interface ClassNamesTypes {
286
290
  /** Applied to all non-pinned column header cells. */
@@ -348,7 +352,7 @@ interface StylesTypes {
348
352
  /** Inline styles for the "X–Y of Z" info text. */
349
353
  paginationInfo?: CSSProperties;
350
354
  }
351
- declare function BoltTable<T extends DataRecord = DataRecord>({ columns: rawInitialColumns, data: rawData, rowHeight, expandedRowHeight, maxExpandedRowHeight, accentColor, className, classNames, styles, gripIcon, hideGripIcon, icons, pagination, onPaginationChange, onColumnResize, onColumnOrderChange, onColumnPin, onColumnHide, rowSelection, rowPinning, onRowPin, expandable, rowKey, onEndReached, onEndReachedThreshold, isLoading, onSortChange, onFilterChange, columnContextMenuItems, autoHeight, layoutLoading, emptyRenderer, rowClassName, rowStyle, disabledFilters, onCopy, keepPinnedRowsAcrossPages, onEdit, onRowClick, enableColumnVirtualization, enableDynamicRowHeight, columnPersistence, showColumnSettings, hideGlobalSearch, globalSearchValue, onGlobalSearchChange, }: BoltTableProps<T>): react_jsx_runtime.JSX.Element;
355
+ declare function BoltTable<T extends DataRecord = DataRecord>({ columns: rawInitialColumns, data: rawData, rowHeight, expandedRowHeight, maxExpandedRowHeight, accentColor, className, classNames, styles, gripIcon, hideGripIcon, icons, pagination, onPaginationChange, onColumnResize, onColumnOrderChange, onColumnPin, onColumnHide, rowSelection, rowPinning, onRowPin, expandable, rowKey, onEndReached, onEndReachedThreshold, isLoading, onSortChange, onFilterChange, columnContextMenuItems, autoHeight, layoutLoading, emptyRenderer, rowClassName, rowStyle, disabledFilters, onCopy, keepPinnedRowsAcrossPages, onEdit, onRowClick, enableColumnVirtualization, enableDynamicRowHeight, columnPersistence, showColumnSettings, hideGlobalSearch, globalSearchValue, onGlobalSearchChange, toolbarContent, columnSettingsLabel, }: BoltTableProps<T>): react_jsx_runtime.JSX.Element;
352
356
 
353
357
  interface DraggableHeaderProps {
354
358
  /** Column definition for this header cell. */
@@ -483,6 +487,8 @@ interface TableBodyProps {
483
487
  enableDynamicRowHeight?: boolean;
484
488
  /** Called when a row's measured height changes. Used by the parent to update the virtualizer. */
485
489
  onRowHeightChange?: (index: number, height: number) => void;
490
+ /** Maps column key → 1-based CSS grid column index in the full (non-virtualized) grid. Required for correct placement when column virtualization is enabled. */
491
+ columnGridIndexMap?: Map<string, number>;
486
492
  }
487
493
  declare const TableBody: React$1.FC<TableBodyProps>;
488
494
 
package/dist/index.d.ts CHANGED
@@ -281,6 +281,10 @@ interface BoltTableProps<T extends DataRecord = DataRecord> {
281
281
  readonly globalSearchValue?: string;
282
282
  /** Called when the global search value changes. */
283
283
  readonly onGlobalSearchChange?: (value: string) => void;
284
+ /** Extra content rendered in the toolbar between the search bar and the column-settings button. */
285
+ readonly toolbarContent?: React$1.ReactNode;
286
+ /** Label for the column-settings button. Defaults to "Columns". */
287
+ readonly columnSettingsLabel?: React$1.ReactNode;
284
288
  }
285
289
  interface ClassNamesTypes {
286
290
  /** Applied to all non-pinned column header cells. */
@@ -348,7 +352,7 @@ interface StylesTypes {
348
352
  /** Inline styles for the "X–Y of Z" info text. */
349
353
  paginationInfo?: CSSProperties;
350
354
  }
351
- declare function BoltTable<T extends DataRecord = DataRecord>({ columns: rawInitialColumns, data: rawData, rowHeight, expandedRowHeight, maxExpandedRowHeight, accentColor, className, classNames, styles, gripIcon, hideGripIcon, icons, pagination, onPaginationChange, onColumnResize, onColumnOrderChange, onColumnPin, onColumnHide, rowSelection, rowPinning, onRowPin, expandable, rowKey, onEndReached, onEndReachedThreshold, isLoading, onSortChange, onFilterChange, columnContextMenuItems, autoHeight, layoutLoading, emptyRenderer, rowClassName, rowStyle, disabledFilters, onCopy, keepPinnedRowsAcrossPages, onEdit, onRowClick, enableColumnVirtualization, enableDynamicRowHeight, columnPersistence, showColumnSettings, hideGlobalSearch, globalSearchValue, onGlobalSearchChange, }: BoltTableProps<T>): react_jsx_runtime.JSX.Element;
355
+ declare function BoltTable<T extends DataRecord = DataRecord>({ columns: rawInitialColumns, data: rawData, rowHeight, expandedRowHeight, maxExpandedRowHeight, accentColor, className, classNames, styles, gripIcon, hideGripIcon, icons, pagination, onPaginationChange, onColumnResize, onColumnOrderChange, onColumnPin, onColumnHide, rowSelection, rowPinning, onRowPin, expandable, rowKey, onEndReached, onEndReachedThreshold, isLoading, onSortChange, onFilterChange, columnContextMenuItems, autoHeight, layoutLoading, emptyRenderer, rowClassName, rowStyle, disabledFilters, onCopy, keepPinnedRowsAcrossPages, onEdit, onRowClick, enableColumnVirtualization, enableDynamicRowHeight, columnPersistence, showColumnSettings, hideGlobalSearch, globalSearchValue, onGlobalSearchChange, toolbarContent, columnSettingsLabel, }: BoltTableProps<T>): react_jsx_runtime.JSX.Element;
352
356
 
353
357
  interface DraggableHeaderProps {
354
358
  /** Column definition for this header cell. */
@@ -483,6 +487,8 @@ interface TableBodyProps {
483
487
  enableDynamicRowHeight?: boolean;
484
488
  /** Called when a row's measured height changes. Used by the parent to update the virtualizer. */
485
489
  onRowHeightChange?: (index: number, height: number) => void;
490
+ /** Maps column key → 1-based CSS grid column index in the full (non-virtualized) grid. Required for correct placement when column virtualization is enabled. */
491
+ columnGridIndexMap?: Map<string, number>;
486
492
  }
487
493
  declare const TableBody: React$1.FC<TableBodyProps>;
488
494
 
package/dist/index.js CHANGED
@@ -258,10 +258,11 @@ var DraggableHeader = import_react.default.memo(
258
258
  overflow: "hidden",
259
259
  textOverflow: "ellipsis",
260
260
  whiteSpace: "nowrap",
261
+ boxSizing: "border-box",
261
262
  borderTop: "none",
262
- borderRight: "0.5px solid rgba(128,128,128,0.2)",
263
+ borderLeft: "none",
263
264
  borderBottom: "1px solid rgba(128,128,128,0.2)",
264
- borderLeft: isFirstColumn ? "none" : "0.5px solid rgba(128,128,128,0.2)",
265
+ borderRight: isLastColumn ? "none" : "1px solid rgba(128,128,128,0.2)",
265
266
  ...column.pinned === "left" && stickyOffset !== void 0 ? { left: `${stickyOffset}px` } : {},
266
267
  ...column.pinned === "right" && stickyOffset !== void 0 ? { right: `${stickyOffset}px` } : {},
267
268
  ...column.style,
@@ -308,7 +309,6 @@ var DraggableHeader = import_react.default.memo(
308
309
  whiteSpace: "nowrap",
309
310
  paddingLeft: 8,
310
311
  paddingRight: 8,
311
- borderLeft: isFirstColumn ? "none" : "1px solid rgba(128,128,128,0.2)",
312
312
  fontWeight: 500,
313
313
  cursor: isPinned ? "default" : "grab"
314
314
  },
@@ -1173,7 +1173,8 @@ var TableBody = ({
1173
1173
  editingCell,
1174
1174
  onEditComplete,
1175
1175
  enableDynamicRowHeight = false,
1176
- onRowHeightChange
1176
+ onRowHeightChange,
1177
+ columnGridIndexMap
1177
1178
  }) => {
1178
1179
  const virtualItems = rowVirtualizer.getVirtualItems();
1179
1180
  const totalSize = rowVirtualizer.getTotalSize();
@@ -1196,8 +1197,9 @@ var TableBody = ({
1196
1197
  let zIndex = 0;
1197
1198
  if (col.key === "__select__" || col.key === "__expand__") zIndex = 11;
1198
1199
  else if (isPinned) zIndex = 2;
1200
+ const gridCol = columnGridIndexMap?.get(col.key) ?? colIndex + 1;
1199
1201
  const style = {
1200
- gridColumn: colIndex + 1,
1202
+ gridColumn: gridCol,
1201
1203
  gridRow: bodyGridRow,
1202
1204
  height: `${totalSize}px`,
1203
1205
  position: isPinned ? "sticky" : "relative",
@@ -1212,7 +1214,7 @@ var TableBody = ({
1212
1214
  }
1213
1215
  return { key: col.key, style, isPinned };
1214
1216
  });
1215
- }, [safeColumns, columnOffsets, totalSize, styles, bodyGridRow]);
1217
+ }, [safeColumns, columnOffsets, totalSize, styles, bodyGridRow, columnGridIndexMap]);
1216
1218
  if (safeData.length === 0 || safeColumns.length === 0) return null;
1217
1219
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1218
1220
  columnStyles.map((colStyle, colIndex) => {
@@ -1749,7 +1751,9 @@ function BoltTable({
1749
1751
  showColumnSettings = true,
1750
1752
  hideGlobalSearch = false,
1751
1753
  globalSearchValue,
1752
- onGlobalSearchChange
1754
+ onGlobalSearchChange,
1755
+ toolbarContent,
1756
+ columnSettingsLabel
1753
1757
  }) {
1754
1758
  const data = (0, import_react4.useMemo)(() => {
1755
1759
  if (!Array.isArray(rawData)) return STABLE_EMPTY_DATA;
@@ -2402,6 +2406,11 @@ function BoltTable({
2402
2406
  }
2403
2407
  return offsets;
2404
2408
  }, [leftPinned, rightPinned]);
2409
+ const columnGridIndexMap = (0, import_react4.useMemo)(() => {
2410
+ const map = /* @__PURE__ */ new Map();
2411
+ orderedColumns.forEach((col, i) => map.set(col.key, i + 1));
2412
+ return map;
2413
+ }, [orderedColumns]);
2405
2414
  const handleTogglePin = (columnKey, pinned) => {
2406
2415
  setColumns(
2407
2416
  (prev) => prev.map((col) => col.key === columnKey ? { ...col, pinned } : col)
@@ -3049,6 +3058,7 @@ function BoltTable({
3049
3058
  ]
3050
3059
  }
3051
3060
  ),
3061
+ toolbarContent,
3052
3062
  showColumnSettings && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { position: "relative", flexShrink: 0 }, children: [
3053
3063
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3054
3064
  "button",
@@ -3071,7 +3081,7 @@ function BoltTable({
3071
3081
  title: "Column settings",
3072
3082
  children: [
3073
3083
  icons?.columns ?? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ColumnsIcon, { style: { width: 14, height: 14 } }),
3074
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Columns" })
3084
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: columnSettingsLabel ?? "Columns" })
3075
3085
  ]
3076
3086
  }
3077
3087
  ),
@@ -3402,6 +3412,7 @@ function BoltTable({
3402
3412
  }
3403
3413
  });
3404
3414
  if (minIdx === Infinity) return null;
3415
+ const groupEndsAtLastCol = maxIdx === orderedColumns.length - 1;
3405
3416
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3406
3417
  "div",
3407
3418
  {
@@ -3420,7 +3431,9 @@ function BoltTable({
3420
3431
  overflow: "hidden",
3421
3432
  textOverflow: "ellipsis",
3422
3433
  whiteSpace: "nowrap",
3434
+ boxSizing: "border-box",
3423
3435
  borderBottom: "1px solid rgba(128,128,128,0.2)",
3436
+ borderRight: groupEndsAtLastCol ? "none" : "1px solid rgba(128,128,128,0.2)",
3424
3437
  fontWeight: 500,
3425
3438
  userSelect: "none",
3426
3439
  ...group.style,
@@ -3455,7 +3468,9 @@ function BoltTable({
3455
3468
  overflow: "hidden",
3456
3469
  textOverflow: "ellipsis",
3457
3470
  whiteSpace: "nowrap",
3471
+ boxSizing: "border-box",
3458
3472
  borderBottom: "1px solid rgba(128,128,128,0.2)",
3473
+ borderRight: "1px solid rgba(128,128,128,0.2)",
3459
3474
  position: "sticky",
3460
3475
  left: columnOffsets.get("__select__") ?? 0,
3461
3476
  top: 0,
@@ -3521,7 +3536,9 @@ function BoltTable({
3521
3536
  overflow: "hidden",
3522
3537
  textOverflow: "ellipsis",
3523
3538
  whiteSpace: "nowrap",
3539
+ boxSizing: "border-box",
3524
3540
  borderBottom: "1px solid rgba(128,128,128,0.2)",
3541
+ borderRight: "1px solid rgba(128,128,128,0.2)",
3525
3542
  position: "sticky",
3526
3543
  left: columnOffsets.get("__expand__") ?? 0,
3527
3544
  top: 0,
@@ -3644,7 +3661,8 @@ function BoltTable({
3644
3661
  editingCell,
3645
3662
  onEditComplete: handleEditComplete,
3646
3663
  enableDynamicRowHeight,
3647
- onRowHeightChange: handleRowHeightChange
3664
+ onRowHeightChange: handleRowHeightChange,
3665
+ columnGridIndexMap
3648
3666
  }
3649
3667
  )
3650
3668
  ]
package/dist/index.mjs CHANGED
@@ -224,10 +224,11 @@ var DraggableHeader = React.memo(
224
224
  overflow: "hidden",
225
225
  textOverflow: "ellipsis",
226
226
  whiteSpace: "nowrap",
227
+ boxSizing: "border-box",
227
228
  borderTop: "none",
228
- borderRight: "0.5px solid rgba(128,128,128,0.2)",
229
+ borderLeft: "none",
229
230
  borderBottom: "1px solid rgba(128,128,128,0.2)",
230
- borderLeft: isFirstColumn ? "none" : "0.5px solid rgba(128,128,128,0.2)",
231
+ borderRight: isLastColumn ? "none" : "1px solid rgba(128,128,128,0.2)",
231
232
  ...column.pinned === "left" && stickyOffset !== void 0 ? { left: `${stickyOffset}px` } : {},
232
233
  ...column.pinned === "right" && stickyOffset !== void 0 ? { right: `${stickyOffset}px` } : {},
233
234
  ...column.style,
@@ -274,7 +275,6 @@ var DraggableHeader = React.memo(
274
275
  whiteSpace: "nowrap",
275
276
  paddingLeft: 8,
276
277
  paddingRight: 8,
277
- borderLeft: isFirstColumn ? "none" : "1px solid rgba(128,128,128,0.2)",
278
278
  fontWeight: 500,
279
279
  cursor: isPinned ? "default" : "grab"
280
280
  },
@@ -1145,7 +1145,8 @@ var TableBody = ({
1145
1145
  editingCell,
1146
1146
  onEditComplete,
1147
1147
  enableDynamicRowHeight = false,
1148
- onRowHeightChange
1148
+ onRowHeightChange,
1149
+ columnGridIndexMap
1149
1150
  }) => {
1150
1151
  const virtualItems = rowVirtualizer.getVirtualItems();
1151
1152
  const totalSize = rowVirtualizer.getTotalSize();
@@ -1168,8 +1169,9 @@ var TableBody = ({
1168
1169
  let zIndex = 0;
1169
1170
  if (col.key === "__select__" || col.key === "__expand__") zIndex = 11;
1170
1171
  else if (isPinned) zIndex = 2;
1172
+ const gridCol = columnGridIndexMap?.get(col.key) ?? colIndex + 1;
1171
1173
  const style = {
1172
- gridColumn: colIndex + 1,
1174
+ gridColumn: gridCol,
1173
1175
  gridRow: bodyGridRow,
1174
1176
  height: `${totalSize}px`,
1175
1177
  position: isPinned ? "sticky" : "relative",
@@ -1184,7 +1186,7 @@ var TableBody = ({
1184
1186
  }
1185
1187
  return { key: col.key, style, isPinned };
1186
1188
  });
1187
- }, [safeColumns, columnOffsets, totalSize, styles, bodyGridRow]);
1189
+ }, [safeColumns, columnOffsets, totalSize, styles, bodyGridRow, columnGridIndexMap]);
1188
1190
  if (safeData.length === 0 || safeColumns.length === 0) return null;
1189
1191
  return /* @__PURE__ */ jsxs4(Fragment3, { children: [
1190
1192
  columnStyles.map((colStyle, colIndex) => {
@@ -1721,7 +1723,9 @@ function BoltTable({
1721
1723
  showColumnSettings = true,
1722
1724
  hideGlobalSearch = false,
1723
1725
  globalSearchValue,
1724
- onGlobalSearchChange
1726
+ onGlobalSearchChange,
1727
+ toolbarContent,
1728
+ columnSettingsLabel
1725
1729
  }) {
1726
1730
  const data = useMemo2(() => {
1727
1731
  if (!Array.isArray(rawData)) return STABLE_EMPTY_DATA;
@@ -2374,6 +2378,11 @@ function BoltTable({
2374
2378
  }
2375
2379
  return offsets;
2376
2380
  }, [leftPinned, rightPinned]);
2381
+ const columnGridIndexMap = useMemo2(() => {
2382
+ const map = /* @__PURE__ */ new Map();
2383
+ orderedColumns.forEach((col, i) => map.set(col.key, i + 1));
2384
+ return map;
2385
+ }, [orderedColumns]);
2377
2386
  const handleTogglePin = (columnKey, pinned) => {
2378
2387
  setColumns(
2379
2388
  (prev) => prev.map((col) => col.key === columnKey ? { ...col, pinned } : col)
@@ -3021,6 +3030,7 @@ function BoltTable({
3021
3030
  ]
3022
3031
  }
3023
3032
  ),
3033
+ toolbarContent,
3024
3034
  showColumnSettings && /* @__PURE__ */ jsxs5("div", { style: { position: "relative", flexShrink: 0 }, children: [
3025
3035
  /* @__PURE__ */ jsxs5(
3026
3036
  "button",
@@ -3043,7 +3053,7 @@ function BoltTable({
3043
3053
  title: "Column settings",
3044
3054
  children: [
3045
3055
  icons?.columns ?? /* @__PURE__ */ jsx5(ColumnsIcon, { style: { width: 14, height: 14 } }),
3046
- /* @__PURE__ */ jsx5("span", { children: "Columns" })
3056
+ /* @__PURE__ */ jsx5("span", { children: columnSettingsLabel ?? "Columns" })
3047
3057
  ]
3048
3058
  }
3049
3059
  ),
@@ -3374,6 +3384,7 @@ function BoltTable({
3374
3384
  }
3375
3385
  });
3376
3386
  if (minIdx === Infinity) return null;
3387
+ const groupEndsAtLastCol = maxIdx === orderedColumns.length - 1;
3377
3388
  return /* @__PURE__ */ jsx5(
3378
3389
  "div",
3379
3390
  {
@@ -3392,7 +3403,9 @@ function BoltTable({
3392
3403
  overflow: "hidden",
3393
3404
  textOverflow: "ellipsis",
3394
3405
  whiteSpace: "nowrap",
3406
+ boxSizing: "border-box",
3395
3407
  borderBottom: "1px solid rgba(128,128,128,0.2)",
3408
+ borderRight: groupEndsAtLastCol ? "none" : "1px solid rgba(128,128,128,0.2)",
3396
3409
  fontWeight: 500,
3397
3410
  userSelect: "none",
3398
3411
  ...group.style,
@@ -3427,7 +3440,9 @@ function BoltTable({
3427
3440
  overflow: "hidden",
3428
3441
  textOverflow: "ellipsis",
3429
3442
  whiteSpace: "nowrap",
3443
+ boxSizing: "border-box",
3430
3444
  borderBottom: "1px solid rgba(128,128,128,0.2)",
3445
+ borderRight: "1px solid rgba(128,128,128,0.2)",
3431
3446
  position: "sticky",
3432
3447
  left: columnOffsets.get("__select__") ?? 0,
3433
3448
  top: 0,
@@ -3493,7 +3508,9 @@ function BoltTable({
3493
3508
  overflow: "hidden",
3494
3509
  textOverflow: "ellipsis",
3495
3510
  whiteSpace: "nowrap",
3511
+ boxSizing: "border-box",
3496
3512
  borderBottom: "1px solid rgba(128,128,128,0.2)",
3513
+ borderRight: "1px solid rgba(128,128,128,0.2)",
3497
3514
  position: "sticky",
3498
3515
  left: columnOffsets.get("__expand__") ?? 0,
3499
3516
  top: 0,
@@ -3616,7 +3633,8 @@ function BoltTable({
3616
3633
  editingCell,
3617
3634
  onEditComplete: handleEditComplete,
3618
3635
  enableDynamicRowHeight,
3619
- onRowHeightChange: handleRowHeightChange
3636
+ onRowHeightChange: handleRowHeightChange,
3637
+ columnGridIndexMap
3620
3638
  }
3621
3639
  )
3622
3640
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bolt-table",
3
- "version": "0.1.27",
3
+ "version": "0.1.29",
4
4
  "description": "Virtualized React table with column drag & drop, pinning, resizing, sorting, filtering, and pagination.",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",