bolt-table 0.1.21 → 0.1.23

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.js CHANGED
@@ -150,10 +150,11 @@ var DraggableHeader = import_react.default.memo(
150
150
  onClearFilter,
151
151
  customContextMenuItems,
152
152
  icons,
153
- onColumnDragStart
153
+ onColumnDragStart,
154
+ disabledFilters
154
155
  }) => {
155
156
  const effectivelySortable = isColumnSortable(column);
156
- const effectivelyFilterable = isColumnFilterable(column);
157
+ const effectivelyFilterable = !disabledFilters && isColumnFilterable(column);
157
158
  const [contextMenu, setContextMenu] = (0, import_react.useState)(null);
158
159
  const [showFilterInput, setShowFilterInput] = (0, import_react.useState)(false);
159
160
  const filterInputRef = (0, import_react.useRef)(null);
@@ -384,7 +385,7 @@ var DraggableHeader = import_react.default.memo(
384
385
  }
385
386
  ),
386
387
  contextMenu && typeof document !== "undefined" && (0, import_react_dom.createPortal)(
387
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
388
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
388
389
  "div",
389
390
  {
390
391
  ref: menuRef,
@@ -404,308 +405,229 @@ var DraggableHeader = import_react.default.memo(
404
405
  top: `${contextMenu.y}px`
405
406
  },
406
407
  role: "menu",
407
- children: [
408
- effectivelySortable && onSort && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
409
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
410
- "button",
411
- {
412
- "data-bt-ctx-item": "",
413
- style: {
414
- cursor: "pointer",
415
- display: "flex",
416
- width: "100%",
417
- alignItems: "center",
418
- gap: 8,
419
- paddingLeft: 12,
420
- paddingRight: 12,
421
- paddingTop: 6,
422
- paddingBottom: 6,
423
- textAlign: "left",
424
- background: "none",
425
- border: "none",
426
- fontSize: "inherit",
427
- color: "inherit",
428
- fontWeight: sortDirection === "asc" ? 600 : void 0,
429
- ...sortDirection === "asc" ? { color: accentColor } : {}
430
- },
431
- onClick: () => {
432
- onSort(column.key, "asc");
433
- setContextMenu(null);
434
- },
435
- children: [
436
- icons?.sortAsc ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ArrowUpAZIcon, { style: { width: 12, height: 12 } }),
437
- "Sort Ascending"
438
- ]
439
- }
440
- ),
441
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
442
- "button",
443
- {
444
- "data-bt-ctx-item": "",
445
- style: {
446
- cursor: "pointer",
447
- display: "flex",
448
- width: "100%",
449
- alignItems: "center",
450
- gap: 8,
451
- paddingLeft: 12,
452
- paddingRight: 12,
453
- paddingTop: 6,
454
- paddingBottom: 6,
455
- textAlign: "left",
456
- background: "none",
457
- border: "none",
458
- fontSize: "inherit",
459
- color: "inherit",
460
- fontWeight: sortDirection === "desc" ? 600 : void 0,
461
- ...sortDirection === "desc" ? { color: accentColor } : {}
462
- },
463
- onClick: () => {
464
- onSort(column.key, "desc");
465
- setContextMenu(null);
466
- },
467
- children: [
468
- icons?.sortDesc ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ArrowDownAZIcon, { style: { width: 12, height: 12 } }),
469
- "Sort Descending"
470
- ]
471
- }
472
- ),
473
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: 4, marginBottom: 4, borderTop: "1px solid rgba(128,128,128,0.2)" } })
474
- ] }),
475
- effectivelyFilterable && onFilter && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
476
- showFilterInput ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", alignItems: "center", gap: 4, paddingLeft: 8, paddingRight: 8, paddingTop: 6, paddingBottom: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
477
- "input",
478
- {
479
- ref: filterInputRef,
480
- type: "text",
481
- autoFocus: true,
482
- defaultValue: filterValue,
483
- placeholder: "Filter...",
484
- style: {
485
- width: "100%",
486
- borderRadius: 4,
487
- border: "1px solid rgba(128,128,128,0.2)",
488
- paddingLeft: 6,
489
- paddingRight: 6,
490
- paddingTop: 2,
491
- paddingBottom: 2,
492
- fontSize: 12,
493
- outline: "none",
494
- background: "inherit",
495
- color: "inherit"
496
- },
497
- onKeyDown: (e) => {
498
- if (e.key === "Enter") {
499
- onFilter(
500
- column.key,
501
- e.target.value
502
- );
503
- setShowFilterInput(false);
408
+ children: (() => {
409
+ const ctxItemBase = {
410
+ cursor: "pointer",
411
+ display: "flex",
412
+ width: "100%",
413
+ alignItems: "center",
414
+ gap: 8,
415
+ paddingLeft: 12,
416
+ paddingRight: 12,
417
+ paddingTop: 6,
418
+ paddingBottom: 6,
419
+ textAlign: "left",
420
+ background: "none",
421
+ border: "none",
422
+ fontSize: "inherit",
423
+ color: "inherit",
424
+ ...styles?.contextMenuItem
425
+ };
426
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
427
+ effectivelySortable && onSort && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
428
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
429
+ "button",
430
+ {
431
+ "data-bt-ctx-item": "",
432
+ style: {
433
+ ...ctxItemBase,
434
+ fontWeight: sortDirection === "asc" ? 600 : void 0,
435
+ ...sortDirection === "asc" ? { color: accentColor } : {}
436
+ },
437
+ onClick: () => {
438
+ onSort(column.key, "asc");
504
439
  setContextMenu(null);
440
+ },
441
+ children: [
442
+ icons?.sortAsc ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ArrowUpAZIcon, { style: { width: 12, height: 12 } }),
443
+ "Sort Ascending"
444
+ ]
445
+ }
446
+ ),
447
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
448
+ "button",
449
+ {
450
+ "data-bt-ctx-item": "",
451
+ style: {
452
+ ...ctxItemBase,
453
+ fontWeight: sortDirection === "desc" ? 600 : void 0,
454
+ ...sortDirection === "desc" ? { color: accentColor } : {}
455
+ },
456
+ onClick: () => {
457
+ onSort(column.key, "desc");
458
+ setContextMenu(null);
459
+ },
460
+ children: [
461
+ icons?.sortDesc ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ArrowDownAZIcon, { style: { width: 12, height: 12 } }),
462
+ "Sort Descending"
463
+ ]
464
+ }
465
+ ),
466
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: 4, marginBottom: 4, borderTop: "1px solid rgba(128,128,128,0.2)" } })
467
+ ] }),
468
+ effectivelyFilterable && onFilter && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
469
+ showFilterInput ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", alignItems: "center", gap: 4, paddingLeft: 8, paddingRight: 8, paddingTop: 6, paddingBottom: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
470
+ "input",
471
+ {
472
+ ref: filterInputRef,
473
+ type: "text",
474
+ autoFocus: true,
475
+ defaultValue: filterValue,
476
+ placeholder: "Filter...",
477
+ style: {
478
+ width: "100%",
479
+ borderRadius: 4,
480
+ border: "1px solid rgba(128,128,128,0.2)",
481
+ paddingLeft: 6,
482
+ paddingRight: 6,
483
+ paddingTop: 2,
484
+ paddingBottom: 2,
485
+ fontSize: 12,
486
+ outline: "none",
487
+ background: "inherit",
488
+ color: "inherit"
489
+ },
490
+ onKeyDown: (e) => {
491
+ if (e.key === "Enter") {
492
+ onFilter(
493
+ column.key,
494
+ e.target.value
495
+ );
496
+ setShowFilterInput(false);
497
+ setContextMenu(null);
498
+ }
499
+ if (e.key === "Escape") {
500
+ setShowFilterInput(false);
501
+ }
505
502
  }
506
- if (e.key === "Escape") {
503
+ }
504
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
505
+ "button",
506
+ {
507
+ "data-bt-ctx-item": "",
508
+ style: ctxItemBase,
509
+ onClick: () => {
510
+ setShowFilterInput(true);
511
+ },
512
+ children: [
513
+ icons?.filter ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FilterIcon, { style: { width: 12, height: 12 } }),
514
+ filterValue ? `Filtered: "${filterValue}"` : "Filter Column"
515
+ ]
516
+ }
517
+ ),
518
+ filterValue && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
519
+ "button",
520
+ {
521
+ "data-bt-ctx-item": "",
522
+ style: {
523
+ ...ctxItemBase,
524
+ color: "#ef4444"
525
+ },
526
+ onClick: () => {
527
+ onClearFilter?.(column.key);
507
528
  setShowFilterInput(false);
508
- }
529
+ setContextMenu(null);
530
+ },
531
+ children: [
532
+ icons?.filterClear ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FilterXIcon, { style: { width: 12, height: 12 } }),
533
+ "Clear Filter"
534
+ ]
509
535
  }
510
- }
511
- ) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
512
- "button",
513
- {
514
- "data-bt-ctx-item": "",
515
- style: {
516
- cursor: "pointer",
517
- display: "flex",
518
- width: "100%",
519
- alignItems: "center",
520
- gap: 8,
521
- paddingLeft: 12,
522
- paddingRight: 12,
523
- paddingTop: 6,
524
- paddingBottom: 6,
525
- textAlign: "left",
526
- background: "none",
527
- border: "none",
528
- fontSize: "inherit",
529
- color: "inherit"
530
- },
531
- onClick: () => {
532
- setShowFilterInput(true);
533
- },
534
- children: [
535
- icons?.filter ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FilterIcon, { style: { width: 12, height: 12 } }),
536
- filterValue ? `Filtered: "${filterValue}"` : "Filter Column"
537
- ]
538
- }
539
- ),
540
- filterValue && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
536
+ ),
537
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: 4, marginBottom: 4, borderTop: "1px solid rgba(128,128,128,0.2)" } })
538
+ ] }),
539
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
541
540
  "button",
542
541
  {
543
542
  "data-bt-ctx-item": "",
544
- style: {
545
- cursor: "pointer",
546
- display: "flex",
547
- width: "100%",
548
- alignItems: "center",
549
- gap: 8,
550
- paddingLeft: 12,
551
- paddingRight: 12,
552
- paddingTop: 6,
553
- paddingBottom: 6,
554
- textAlign: "left",
555
- background: "none",
556
- border: "none",
557
- fontSize: "inherit",
558
- color: "#ef4444"
559
- },
543
+ style: ctxItemBase,
560
544
  onClick: () => {
561
- onClearFilter?.(column.key);
562
- setShowFilterInput(false);
545
+ onTogglePin?.(
546
+ column.key,
547
+ column.pinned === "left" ? false : "left"
548
+ );
563
549
  setContextMenu(null);
564
550
  },
565
551
  children: [
566
- icons?.filterClear ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FilterXIcon, { style: { width: 12, height: 12 } }),
567
- "Clear Filter"
552
+ column.pinned === "left" ? icons?.pinOff ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PinOffIcon, { style: { width: 12, height: 12 } }) : icons?.pin ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PinIcon, { style: { width: 12, height: 12 } }),
553
+ column.pinned === "left" ? "Unpin Left" : "Pin Left"
568
554
  ]
569
555
  }
570
556
  ),
571
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: 4, marginBottom: 4, borderTop: "1px solid rgba(128,128,128,0.2)" } })
572
- ] }),
573
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
574
- "button",
575
- {
576
- "data-bt-ctx-item": "",
577
- style: {
578
- cursor: "pointer",
579
- display: "flex",
580
- width: "100%",
581
- alignItems: "center",
582
- gap: 8,
583
- paddingLeft: 12,
584
- paddingRight: 12,
585
- paddingTop: 6,
586
- paddingBottom: 6,
587
- textAlign: "left",
588
- background: "none",
589
- border: "none",
590
- fontSize: "inherit",
591
- color: "inherit"
592
- },
593
- onClick: () => {
594
- onTogglePin?.(
595
- column.key,
596
- column.pinned === "left" ? false : "left"
597
- );
598
- setContextMenu(null);
599
- },
600
- children: [
601
- column.pinned === "left" ? icons?.pinOff ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PinOffIcon, { style: { width: 12, height: 12 } }) : icons?.pin ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PinIcon, { style: { width: 12, height: 12 } }),
602
- column.pinned === "left" ? "Unpin Left" : "Pin Left"
603
- ]
604
- }
605
- ),
606
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
607
- "button",
608
- {
609
- "data-bt-ctx-item": "",
610
- style: {
611
- cursor: "pointer",
612
- display: "flex",
613
- width: "100%",
614
- alignItems: "center",
615
- gap: 8,
616
- paddingLeft: 12,
617
- paddingRight: 12,
618
- paddingTop: 6,
619
- paddingBottom: 6,
620
- textAlign: "left",
621
- background: "none",
622
- border: "none",
623
- fontSize: "inherit",
624
- color: "inherit"
625
- },
626
- onClick: () => {
627
- onTogglePin?.(
628
- column.key,
629
- column.pinned === "right" ? false : "right"
630
- );
631
- setContextMenu(null);
632
- },
633
- children: [
634
- column.pinned === "right" ? icons?.pinOff ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PinOffIcon, { style: { width: 12, height: 12 } }) : icons?.pin ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PinIcon, { style: { width: 12, height: 12 } }),
635
- column.pinned === "right" ? "Unpin Right" : "Pin Right"
636
- ]
637
- }
638
- ),
639
- !isPinned && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
640
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: 4, marginBottom: 4, borderTop: "1px solid rgba(128,128,128,0.2)" } }),
641
557
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
642
558
  "button",
643
559
  {
644
560
  "data-bt-ctx-item": "",
645
- style: {
646
- cursor: "pointer",
647
- display: "flex",
648
- width: "100%",
649
- alignItems: "center",
650
- gap: 8,
651
- paddingLeft: 12,
652
- paddingRight: 12,
653
- paddingTop: 6,
654
- paddingBottom: 6,
655
- textAlign: "left",
656
- background: "none",
657
- border: "none",
658
- fontSize: "inherit",
659
- color: "inherit"
660
- },
561
+ style: ctxItemBase,
661
562
  onClick: () => {
662
- onToggleHide?.(column.key);
563
+ onTogglePin?.(
564
+ column.key,
565
+ column.pinned === "right" ? false : "right"
566
+ );
663
567
  setContextMenu(null);
664
568
  },
665
569
  children: [
666
- icons?.eyeOff ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EyeOffIcon, { style: { width: 12, height: 12 } }),
667
- "Hide Column"
570
+ column.pinned === "right" ? icons?.pinOff ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PinOffIcon, { style: { width: 12, height: 12 } }) : icons?.pin ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PinIcon, { style: { width: 12, height: 12 } }),
571
+ column.pinned === "right" ? "Unpin Right" : "Pin Right"
668
572
  ]
669
573
  }
670
- )
671
- ] }),
672
- customContextMenuItems && customContextMenuItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
673
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: 4, marginBottom: 4, borderTop: "1px solid rgba(128,128,128,0.2)" } }),
674
- customContextMenuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
675
- "button",
676
- {
677
- "data-bt-ctx-item": "",
678
- disabled: item.disabled,
679
- style: {
680
- display: "flex",
681
- width: "100%",
682
- alignItems: "center",
683
- gap: 8,
684
- paddingLeft: 12,
685
- paddingRight: 12,
686
- paddingTop: 6,
687
- paddingBottom: 6,
688
- textAlign: "left",
689
- background: "none",
690
- border: "none",
691
- fontSize: "inherit",
692
- cursor: item.disabled ? "not-allowed" : "pointer",
693
- opacity: item.disabled ? 0.5 : 1,
694
- color: item.danger ? "#ef4444" : "inherit"
695
- },
696
- onClick: () => {
697
- item.onClick(column.key);
698
- setContextMenu(null);
574
+ ),
575
+ !isPinned && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
576
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: 4, marginBottom: 4, borderTop: "1px solid rgba(128,128,128,0.2)" } }),
577
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
578
+ "button",
579
+ {
580
+ "data-bt-ctx-item": "",
581
+ style: ctxItemBase,
582
+ onClick: () => {
583
+ onToggleHide?.(column.key);
584
+ setContextMenu(null);
585
+ },
586
+ children: [
587
+ icons?.eyeOff ?? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EyeOffIcon, { style: { width: 12, height: 12 } }),
588
+ "Hide Column"
589
+ ]
590
+ }
591
+ )
592
+ ] }),
593
+ customContextMenuItems && customContextMenuItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
594
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { marginTop: 4, marginBottom: 4, borderTop: "1px solid rgba(128,128,128,0.2)" } }),
595
+ customContextMenuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
596
+ "button",
597
+ {
598
+ "data-bt-ctx-item": "",
599
+ disabled: item.disabled,
600
+ style: {
601
+ display: "flex",
602
+ width: "100%",
603
+ alignItems: "center",
604
+ gap: 8,
605
+ paddingLeft: 12,
606
+ paddingRight: 12,
607
+ paddingTop: 6,
608
+ paddingBottom: 6,
609
+ textAlign: "left",
610
+ background: "none",
611
+ border: "none",
612
+ fontSize: "inherit",
613
+ cursor: item.disabled ? "not-allowed" : "pointer",
614
+ opacity: item.disabled ? 0.5 : 1,
615
+ color: item.danger ? "#ef4444" : "inherit"
616
+ },
617
+ onClick: () => {
618
+ item.onClick(column.key);
619
+ setContextMenu(null);
620
+ },
621
+ children: [
622
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { display: "flex", width: 12, height: 12, alignItems: "center", justifyContent: "center" }, children: item.icon }),
623
+ item.label
624
+ ]
699
625
  },
700
- children: [
701
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { display: "flex", width: 12, height: 12, alignItems: "center", justifyContent: "center" }, children: item.icon }),
702
- item.label
703
- ]
704
- },
705
- item.key
706
- ))
707
- ] })
708
- ]
626
+ item.key
627
+ ))
628
+ ] })
629
+ ] });
630
+ })()
709
631
  }
710
632
  ),
711
633
  document.body
@@ -713,7 +635,7 @@ var DraggableHeader = import_react.default.memo(
713
635
  ] });
714
636
  },
715
637
  (prevProps, nextProps) => {
716
- 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 && prevProps.classNames === nextProps.classNames && prevProps.styles === nextProps.styles && prevProps.customContextMenuItems === nextProps.customContextMenuItems;
638
+ 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 && prevProps.classNames === nextProps.classNames && prevProps.styles === nextProps.styles && prevProps.customContextMenuItems === nextProps.customContextMenuItems && prevProps.disabledFilters === nextProps.disabledFilters;
717
639
  }
718
640
  );
719
641
  DraggableHeader.displayName = "DraggableHeader";
@@ -1588,7 +1510,10 @@ function BoltTable({
1588
1510
  layoutLoading,
1589
1511
  emptyRenderer,
1590
1512
  rowClassName,
1591
- rowStyle
1513
+ rowStyle,
1514
+ disabledFilters,
1515
+ onCopy,
1516
+ keepPinnedRowsAcrossPages
1592
1517
  }) {
1593
1518
  const data = (0, import_react4.useMemo)(() => {
1594
1519
  if (!Array.isArray(rawData)) return STABLE_EMPTY_DATA;
@@ -2036,12 +1961,11 @@ function BoltTable({
2036
1961
  if (col.key === "__select__" || col.key === "__expand__") return col;
2037
1962
  const latest = latestMap.get(col.key);
2038
1963
  if (!latest) return col;
2039
- if (col.render === latest.render && col.shimmerRender === latest.shimmerRender)
2040
- return col;
2041
1964
  return {
2042
- ...col,
2043
- render: latest.render,
2044
- shimmerRender: latest.shimmerRender
1965
+ ...latest,
1966
+ width: col.width,
1967
+ hidden: col.hidden,
1968
+ pinned: col.pinned
2045
1969
  };
2046
1970
  });
2047
1971
  }, [orderedColumns, initialColumns]);
@@ -2087,6 +2011,24 @@ function BoltTable({
2087
2011
  const column = columns.find((col) => col.key === columnKey);
2088
2012
  if (column && !column.pinned) onColumnHide?.(columnKey, !column.hidden);
2089
2013
  };
2014
+ const [internalRowPinning, setInternalRowPinning] = (0, import_react4.useState)({ top: [], bottom: [] });
2015
+ const resolvedRowPinning = rowPinning === true ? internalRowPinning : rowPinning && typeof rowPinning === "object" ? rowPinning : void 0;
2016
+ const handleRowPin = (0, import_react4.useCallback)((rk, pinned) => {
2017
+ if (onRowPin) {
2018
+ onRowPin(rk, pinned);
2019
+ return;
2020
+ }
2021
+ if (rowPinning === true) {
2022
+ setInternalRowPinning((prev) => {
2023
+ const rkStr = String(rk);
2024
+ const newTop = (prev.top ?? []).filter((k) => String(k) !== rkStr);
2025
+ const newBottom = (prev.bottom ?? []).filter((k) => String(k) !== rkStr);
2026
+ if (pinned === "top") newTop.push(rk);
2027
+ else if (pinned === "bottom") newBottom.push(rk);
2028
+ return { top: newTop, bottom: newBottom };
2029
+ });
2030
+ }
2031
+ }, [onRowPin, rowPinning]);
2090
2032
  const onSortChangeRef = (0, import_react4.useRef)(onSortChange);
2091
2033
  onSortChangeRef.current = onSortChange;
2092
2034
  const [sortState, setSortState] = (0, import_react4.useState)({ key: "", direction: null });
@@ -2186,43 +2128,67 @@ function BoltTable({
2186
2128
  }
2187
2129
  return result;
2188
2130
  }, [data, sortState, columnFilters]);
2131
+ const pinnedRowCacheRef = (0, import_react4.useRef)(/* @__PURE__ */ new Map());
2189
2132
  const { pinnedTopRows, pinnedBottomRows, unpinnedProcessedData } = (0, import_react4.useMemo)(() => {
2190
- if (!rowPinning || !rowPinning.top?.length && !rowPinning.bottom?.length) {
2133
+ if (!resolvedRowPinning || !resolvedRowPinning.top?.length && !resolvedRowPinning.bottom?.length) {
2134
+ if (keepPinnedRowsAcrossPages) pinnedRowCacheRef.current.clear();
2191
2135
  return {
2192
2136
  pinnedTopRows: [],
2193
2137
  pinnedBottomRows: [],
2194
2138
  unpinnedProcessedData: processedData
2195
2139
  };
2196
2140
  }
2197
- const topKeySet = new Set((rowPinning.top ?? []).map(String));
2198
- const bottomKeySet = new Set((rowPinning.bottom ?? []).map(String));
2141
+ const topKeySet = new Set((resolvedRowPinning.top ?? []).map(String));
2142
+ const bottomKeySet = new Set((resolvedRowPinning.bottom ?? []).map(String));
2199
2143
  const topMap = /* @__PURE__ */ new Map();
2200
2144
  const bottomMap = /* @__PURE__ */ new Map();
2201
2145
  const rest = [];
2202
2146
  processedData.forEach((row, idx) => {
2203
2147
  if (row == null) return;
2204
2148
  const key = getRowKey(row, idx);
2205
- if (topKeySet.has(key)) topMap.set(key, row);
2206
- else if (bottomKeySet.has(key)) bottomMap.set(key, row);
2207
- else rest.push(row);
2149
+ if (topKeySet.has(key)) {
2150
+ topMap.set(key, row);
2151
+ if (keepPinnedRowsAcrossPages) pinnedRowCacheRef.current.set(key, row);
2152
+ } else if (bottomKeySet.has(key)) {
2153
+ bottomMap.set(key, row);
2154
+ if (keepPinnedRowsAcrossPages) pinnedRowCacheRef.current.set(key, row);
2155
+ } else {
2156
+ rest.push(row);
2157
+ }
2208
2158
  });
2209
- const orderedTop = (rowPinning.top ?? []).map((k) => topMap.get(String(k))).filter((r) => r !== void 0);
2210
- const orderedBottom = (rowPinning.bottom ?? []).map((k) => bottomMap.get(String(k))).filter((r) => r !== void 0);
2159
+ if (keepPinnedRowsAcrossPages) {
2160
+ for (const k of topKeySet) {
2161
+ if (!topMap.has(k) && pinnedRowCacheRef.current.has(k)) {
2162
+ topMap.set(k, pinnedRowCacheRef.current.get(k));
2163
+ }
2164
+ }
2165
+ for (const k of bottomKeySet) {
2166
+ if (!bottomMap.has(k) && pinnedRowCacheRef.current.has(k)) {
2167
+ bottomMap.set(k, pinnedRowCacheRef.current.get(k));
2168
+ }
2169
+ }
2170
+ const allPinnedKeys = /* @__PURE__ */ new Set([...topKeySet, ...bottomKeySet]);
2171
+ for (const cachedKey of pinnedRowCacheRef.current.keys()) {
2172
+ if (!allPinnedKeys.has(cachedKey)) pinnedRowCacheRef.current.delete(cachedKey);
2173
+ }
2174
+ }
2175
+ const orderedTop = (resolvedRowPinning.top ?? []).map((k) => topMap.get(String(k))).filter((r) => r !== void 0);
2176
+ const orderedBottom = (resolvedRowPinning.bottom ?? []).map((k) => bottomMap.get(String(k))).filter((r) => r !== void 0);
2211
2177
  return {
2212
2178
  pinnedTopRows: orderedTop,
2213
2179
  pinnedBottomRows: orderedBottom,
2214
2180
  unpinnedProcessedData: rest
2215
2181
  };
2216
- }, [processedData, rowPinning, getRowKey]);
2182
+ }, [processedData, resolvedRowPinning, getRowKey, keepPinnedRowsAcrossPages]);
2217
2183
  const pinnedTopHeight = pinnedTopRows.length * rowHeight;
2218
2184
  const pinnedBottomHeight = pinnedBottomRows.length * rowHeight;
2219
2185
  const pinnedTopKeySet = (0, import_react4.useMemo)(
2220
- () => new Set((rowPinning?.top ?? []).map(String)),
2221
- [rowPinning?.top]
2186
+ () => new Set((resolvedRowPinning?.top ?? []).map(String)),
2187
+ [resolvedRowPinning?.top]
2222
2188
  );
2223
2189
  const pinnedBottomKeySet = (0, import_react4.useMemo)(
2224
- () => new Set((rowPinning?.bottom ?? []).map(String)),
2225
- [rowPinning?.bottom]
2190
+ () => new Set((resolvedRowPinning?.bottom ?? []).map(String)),
2191
+ [resolvedRowPinning?.bottom]
2226
2192
  );
2227
2193
  const [cellContextMenu, setCellContextMenu] = (0, import_react4.useState)(null);
2228
2194
  const cellMenuRef = (0, import_react4.useRef)(null);
@@ -2644,8 +2610,8 @@ function BoltTable({
2644
2610
  const col = freshOrderedColumns.find(
2645
2611
  (c) => c.key === ck
2646
2612
  );
2647
- const hasCopy = col?.copy;
2648
- const hasRowPin = !!onRowPin;
2613
+ const hasCopy = !!col?.copy;
2614
+ const hasRowPin = !!rowPinning;
2649
2615
  const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
2650
2616
  if (!hasCopy && !hasRowPin && !hasCellItems) return;
2651
2617
  e.preventDefault();
@@ -2673,8 +2639,8 @@ function BoltTable({
2673
2639
  const col = freshOrderedColumns.find(
2674
2640
  (c) => c.key === ck
2675
2641
  );
2676
- const hasCopy = col?.copy;
2677
- const hasRowPin = !!onRowPin;
2642
+ const hasCopy = !!col?.copy;
2643
+ const hasRowPin = !!rowPinning;
2678
2644
  const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
2679
2645
  if (!hasCopy && !hasRowPin && !hasCellItems) return;
2680
2646
  setCellContextMenu({
@@ -2808,7 +2774,8 @@ function BoltTable({
2808
2774
  filterValue: columnFilters[column.key] ?? "",
2809
2775
  onFilter: handleColumnFilter,
2810
2776
  onClearFilter: handleClearFilter,
2811
- customContextMenuItems: column.columnHeaderContextMenuItems ? [...columnContextMenuItems ?? [], ...column.columnHeaderContextMenuItems] : columnContextMenuItems
2777
+ customContextMenuItems: column.columnHeaderContextMenuItems ? [...columnContextMenuItems ?? [], ...column.columnHeaderContextMenuItems] : columnContextMenuItems,
2778
+ disabledFilters
2812
2779
  },
2813
2780
  column.key
2814
2781
  );
@@ -3192,8 +3159,8 @@ function BoltTable({
3192
3159
  const isPinnedBottom = pinnedBottomKeySet.has(
3193
3160
  cellContextMenu.rowKey
3194
3161
  );
3195
- const hasCopy = menuCol?.copy;
3196
- const hasRowPin = !!onRowPin;
3162
+ const hasCopy = !!menuCol?.copy;
3163
+ const hasRowPin = !!rowPinning;
3197
3164
  let menuRecord;
3198
3165
  let menuRowIndex = 0;
3199
3166
  const allRows = [
@@ -3222,7 +3189,8 @@ function BoltTable({
3222
3189
  fontSize: 12,
3223
3190
  cursor: "pointer",
3224
3191
  color: "inherit",
3225
- whiteSpace: "nowrap"
3192
+ whiteSpace: "nowrap",
3193
+ ...styles.contextMenuItem
3226
3194
  };
3227
3195
  return (0, import_react_dom2.createPortal)(
3228
3196
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
@@ -3252,7 +3220,7 @@ function BoltTable({
3252
3220
  "data-bt-ctx-item": true,
3253
3221
  style: btnStyle,
3254
3222
  onClick: () => {
3255
- onRowPin(
3223
+ handleRowPin(
3256
3224
  cellContextMenu.rowKey,
3257
3225
  isPinnedTop ? false : "top"
3258
3226
  );
@@ -3280,7 +3248,7 @@ function BoltTable({
3280
3248
  "data-bt-ctx-item": true,
3281
3249
  style: btnStyle,
3282
3250
  onClick: () => {
3283
- onRowPin(
3251
+ handleRowPin(
3284
3252
  cellContextMenu.rowKey,
3285
3253
  isPinnedBottom ? false : "bottom"
3286
3254
  );
@@ -3325,6 +3293,7 @@ function BoltTable({
3325
3293
  onClick: () => {
3326
3294
  const text = typeof menuCol.copy === "function" ? menuCol.copy(menuValue, menuRecord, menuRowIndex) : String(menuValue ?? "");
3327
3295
  navigator.clipboard?.writeText(text);
3296
+ onCopy?.(text, menuCol.key, menuRecord, menuRowIndex);
3328
3297
  setCellContextMenu(null);
3329
3298
  },
3330
3299
  children: [