@linzjs/step-ag-grid 29.11.4 → 29.13.0

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.
Files changed (87) hide show
  1. package/dist/src/components/Grid.d.ts +7 -12
  2. package/dist/src/components/GridCell.d.ts +2 -19
  3. package/dist/src/components/GridCellFiller.d.ts +1 -1
  4. package/dist/src/components/GridCellMultiEditor.d.ts +1 -2
  5. package/dist/src/components/GridPopoverHook.d.ts +1 -1
  6. package/dist/src/components/gridFilter/GridFilterButtons.d.ts +1 -1
  7. package/dist/src/components/gridFilter/useGridFilter.d.ts +1 -1
  8. package/dist/src/components/gridForm/GridFormDropDown.d.ts +1 -1
  9. package/dist/src/components/gridForm/GridFormEditBearing.d.ts +1 -1
  10. package/dist/src/components/gridForm/GridFormMessage.d.ts +1 -1
  11. package/dist/src/components/gridForm/GridFormMultiSelect.d.ts +1 -1
  12. package/dist/src/components/gridForm/GridFormMultiSelectGrid.d.ts +1 -1
  13. package/dist/src/components/gridForm/GridFormPopoverMenu.d.ts +1 -1
  14. package/dist/src/components/gridForm/GridFormSubComponentTextArea.d.ts +1 -1
  15. package/dist/src/components/gridForm/GridFormSubComponentTextInput.d.ts +1 -1
  16. package/dist/src/components/gridForm/GridFormTextArea.d.ts +1 -1
  17. package/dist/src/components/gridForm/GridFormTextInput.d.ts +1 -1
  18. package/dist/src/components/gridHook/useGridContextMenu.d.ts +1 -1
  19. package/dist/src/components/gridPopoverEdit/GridButton.d.ts +1 -2
  20. package/dist/src/components/gridPopoverEdit/GridEditBoolean.d.ts +2 -2
  21. package/dist/src/components/gridPopoverEdit/GridPopoutEditMultiSelect.d.ts +2 -2
  22. package/dist/src/components/gridPopoverEdit/GridPopoutEditMultiSelectGrid.d.ts +2 -2
  23. package/dist/src/components/gridPopoverEdit/GridPopoverEditBearing.d.ts +2 -2
  24. package/dist/src/components/gridPopoverEdit/GridPopoverEditDropDown.d.ts +2 -2
  25. package/dist/src/components/gridPopoverEdit/GridPopoverMenu.d.ts +2 -2
  26. package/dist/src/components/gridPopoverEdit/GridPopoverMessage.d.ts +2 -2
  27. package/dist/src/components/gridPopoverEdit/GridPopoverTextArea.d.ts +2 -2
  28. package/dist/src/components/gridPopoverEdit/GridPopoverTextInput.d.ts +2 -2
  29. package/dist/src/components/gridRender/GridRenderGenericCell.d.ts +1 -2
  30. package/dist/src/components/index.d.ts +1 -0
  31. package/dist/src/components/types.d.ts +26 -0
  32. package/dist/src/contexts/GridContext.d.ts +12 -12
  33. package/dist/src/contexts/GridPopoverContext.d.ts +1 -1
  34. package/dist/src/utils/__tests__/storybookTestUtil.ts +28 -1
  35. package/dist/src/utils/__tests__/testQuick.ts +2 -0
  36. package/dist/src/utils/textValidator.d.ts +1 -1
  37. package/dist/src/utils/util.d.ts +1 -0
  38. package/dist/step-ag-grid.cjs +326 -214
  39. package/dist/step-ag-grid.cjs.map +1 -1
  40. package/dist/step-ag-grid.esm.js +327 -216
  41. package/dist/step-ag-grid.esm.js.map +1 -1
  42. package/package.json +5 -2
  43. package/src/components/Grid.tsx +130 -65
  44. package/src/components/GridCell.tsx +1 -25
  45. package/src/components/GridCellFiller.tsx +1 -1
  46. package/src/components/GridCellMultiEditor.tsx +2 -2
  47. package/src/components/GridPopoverHook.tsx +1 -1
  48. package/src/components/gridFilter/GridFilterButtons.tsx +1 -1
  49. package/src/components/gridFilter/useGridFilter.ts +1 -1
  50. package/src/components/gridForm/GridFormDropDown.tsx +1 -1
  51. package/src/components/gridForm/GridFormEditBearing.tsx +1 -1
  52. package/src/components/gridForm/GridFormMessage.tsx +1 -1
  53. package/src/components/gridForm/GridFormMultiSelect.tsx +1 -1
  54. package/src/components/gridForm/GridFormMultiSelectGrid.tsx +1 -1
  55. package/src/components/gridForm/GridFormPopoverMenu.tsx +1 -1
  56. package/src/components/gridForm/GridFormSubComponentTextArea.tsx +1 -1
  57. package/src/components/gridForm/GridFormSubComponentTextInput.tsx +1 -1
  58. package/src/components/gridForm/GridFormTextArea.tsx +1 -1
  59. package/src/components/gridForm/GridFormTextInput.tsx +1 -1
  60. package/src/components/gridHook/useGridContextMenu.tsx +1 -1
  61. package/src/components/gridPopoverEdit/GridButton.tsx +2 -2
  62. package/src/components/gridPopoverEdit/GridEditBoolean.tsx +2 -2
  63. package/src/components/gridPopoverEdit/GridPopoutEditMultiSelect.ts +2 -2
  64. package/src/components/gridPopoverEdit/GridPopoutEditMultiSelectGrid.ts +2 -2
  65. package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +2 -2
  66. package/src/components/gridPopoverEdit/GridPopoverEditDropDown.ts +2 -2
  67. package/src/components/gridPopoverEdit/GridPopoverMenu.tsx +2 -2
  68. package/src/components/gridPopoverEdit/GridPopoverMessage.ts +2 -2
  69. package/src/components/gridPopoverEdit/GridPopoverTextArea.ts +2 -2
  70. package/src/components/gridPopoverEdit/GridPopoverTextInput.ts +2 -2
  71. package/src/components/gridRender/GridRenderGenericCell.tsx +1 -2
  72. package/src/components/index.ts +1 -0
  73. package/src/components/types.ts +32 -0
  74. package/src/contexts/GridContext.tsx +55 -148
  75. package/src/contexts/GridContextProvider.tsx +61 -56
  76. package/src/contexts/GridPopoverContext.tsx +1 -1
  77. package/src/contexts/GridPopoverContextProvider.tsx +1 -1
  78. package/src/react-menu3/components/MenuButton.tsx +2 -2
  79. package/src/react-menu3/hooks/useItemState.ts +1 -1
  80. package/src/stories/grid/GridPopoverEditDropDown.stories.tsx +3 -3
  81. package/src/stories/grid/GridReadOnly.stories.tsx +3 -3
  82. package/src/stories/grid/GridSorting.stories.tsx +189 -0
  83. package/src/utils/__tests__/storybookTestUtil.ts +28 -1
  84. package/src/utils/__tests__/testQuick.ts +2 -0
  85. package/src/utils/textValidator.test.ts +1 -1
  86. package/src/utils/textValidator.ts +1 -1
  87. package/src/utils/util.ts +19 -0
@@ -428,147 +428,53 @@ function useInterval(callback, delay) {
428
428
  }, [delay]);
429
429
  }
430
430
 
431
+ const NoContext = () => {
432
+ console.error('Missing GridContextProvider');
433
+ return null;
434
+ };
431
435
  const GridContext = React.createContext({
432
436
  gridReady: false,
433
437
  gridRenderState: () => null,
434
- getColDef: () => {
435
- console.error('no context provider for getColDef');
436
- return undefined;
437
- },
438
- getColumns: () => {
439
- console.error('no context provider for getColumns');
440
- return [];
441
- },
442
- getColumnIds: () => {
443
- console.error('no context provider for getColumnIds');
444
- return [];
445
- },
438
+ getColDef: NoContext,
439
+ getColumns: NoContext,
440
+ getColumnIds: NoContext,
446
441
  invisibleColumnIds: undefined,
447
- setInvisibleColumnIds: () => {
448
- console.error('no context provider for setInvisibleColumnIds');
449
- },
450
- prePopupOps: () => {
451
- console.error('no context provider for prePopupOps');
452
- },
442
+ setInvisibleColumnIds: NoContext,
443
+ prePopupOps: NoContext,
453
444
  externallySelectedItemsAreInSync: false,
454
- setApis: () => {
455
- console.error('no context provider for setApis');
456
- },
457
- setQuickFilter: () => {
458
- console.error('no context provider for setQuickFilter');
459
- },
460
- selectRowsById: () => {
461
- console.error('no context provider for selectRows');
462
- },
463
- getSelectedRows: () => {
464
- console.error('no context provider for getSelectedRows');
465
- return [];
466
- },
467
- getFilteredSelectedRows: () => {
468
- console.error('no context provider for getFilteredSelectedRows');
469
- return [];
470
- },
471
- getSelectedRowIds: () => {
472
- console.error('no context provider for getSelectedRowIds');
473
- return [];
474
- },
475
- getFilteredSelectedRowIds: () => {
476
- console.error('no context provider for getFilteredSelectedRowIds');
477
- return [];
478
- },
479
- // eslint-disable-next-line @typescript-eslint/require-await
480
- selectRowsDiff: async () => {
481
- console.error('no context provider for selectRowsDiff');
482
- },
483
- selectRowsByIdWithFlash: () => {
484
- console.error('no context provider for selectRowsWithFlash');
485
- },
486
- // eslint-disable-next-line @typescript-eslint/require-await
487
- selectRowsWithFlashDiff: async () => {
488
- console.error('no context provider for selectRowsWithFlashDiff');
489
- },
490
- flashRows: () => {
491
- console.error('no context provider for flashRows');
492
- },
493
- // eslint-disable-next-line @typescript-eslint/require-await
494
- flashRowsDiff: async () => {
495
- console.error('no context provider for flashRows');
496
- },
497
- // eslint-disable-next-line @typescript-eslint/require-await,@typescript-eslint/no-misused-promises
498
- focusByRowById: async () => {
499
- console.error('no context provider for focusByRowById');
500
- },
501
- ensureRowVisible: () => {
502
- console.error('no context provider for ensureRowVisible');
503
- return true;
504
- },
505
- ensureSelectedRowIsVisible: () => {
506
- console.error('no context provider for ensureSelectedRowIsVisible');
507
- },
508
- getFirstRowId: () => {
509
- console.error('no context provider for getFirstRowId');
510
- return -1;
511
- },
512
- autoSizeColumns: async () => {
513
- console.error('no context provider for autoSizeColumns');
514
- return Promise.resolve(null);
515
- },
516
- sizeColumnsToFit: () => {
517
- console.error('no context provider for autoSizeAllColumns');
518
- return null;
519
- },
520
- editingCells: () => {
521
- console.error('no context provider for editingCells');
522
- return false;
523
- },
524
- // eslint-disable-next-line @typescript-eslint/require-await
525
- startCellEditing: async () => {
526
- console.error('no context provider for startCellEditing');
527
- },
528
- resetFocusedCellAfterCellEditing: () => {
529
- console.error('no context provider for resetFocusedCellAfterCellEditing');
530
- },
531
- // eslint-disable-next-line @typescript-eslint/require-await
532
- updatingCells: async () => {
533
- console.error('no context provider for modifyUpdating');
534
- return false;
535
- },
536
- redrawRows: () => {
537
- console.error('no context provider for redrawRows');
538
- },
539
- setExternallySelectedItemsAreInSync: () => {
540
- console.error('no context provider for setExternallySelectedItemsAreInSync');
541
- },
542
- // eslint-disable-next-line @typescript-eslint/require-await
543
- waitForExternallySelectedItemsToBeInSync: async () => {
544
- console.error('no context provider for waitForExternallySelectedItemsToBeInSync');
545
- },
546
- addExternalFilter: () => {
547
- console.error('no context provider for addExternalFilter');
548
- },
549
- removeExternalFilter: () => {
550
- console.error('no context provider for removeExternalFilter');
551
- },
552
- isExternalFilterPresent: () => {
553
- console.error('no context provider for isExternalFilterPresent');
554
- return false;
555
- },
556
- doesExternalFilterPass: () => {
557
- console.error('no context provider for doesExternalFilterPass');
558
- return true;
559
- },
560
- downloadCsv: () => {
561
- console.error('no context provider for downloadCsv');
562
- },
563
- onBulkEditingComplete: () => {
564
- console.error('no context provider for onBulkEditingComplete');
565
- },
566
- setOnBulkEditingComplete: () => {
567
- console.error('no context provider for setOnBulkEditingComplete');
568
- },
569
- showNoRowsOverlay: () => {
570
- console.error('no context provider for showLoadingOverlay');
571
- },
445
+ setApis: NoContext,
446
+ setQuickFilter: NoContext,
447
+ selectRowsById: NoContext,
448
+ getSelectedRows: NoContext,
449
+ getFilteredSelectedRows: NoContext,
450
+ getSelectedRowIds: NoContext,
451
+ getFilteredSelectedRowIds: NoContext,
452
+ selectRowsDiff: NoContext,
453
+ selectRowsByIdWithFlash: NoContext,
454
+ selectRowsWithFlashDiff: NoContext,
455
+ flashRows: NoContext,
456
+ flashRowsDiff: NoContext,
457
+ focusByRowById: NoContext,
458
+ ensureRowVisible: NoContext,
459
+ ensureSelectedRowIsVisible: NoContext,
460
+ getFirstRowId: NoContext,
461
+ autoSizeColumns: NoContext,
462
+ sizeColumnsToFit: NoContext,
463
+ editingCells: NoContext,
464
+ startCellEditing: NoContext,
465
+ resetFocusedCellAfterCellEditing: NoContext,
466
+ updatingCells: NoContext,
467
+ redrawRows: NoContext,
468
+ setExternallySelectedItemsAreInSync: NoContext,
469
+ waitForExternallySelectedItemsToBeInSync: NoContext,
470
+ addExternalFilter: NoContext,
471
+ removeExternalFilter: NoContext,
472
+ isExternalFilterPresent: NoContext,
473
+ doesExternalFilterPass: NoContext,
474
+ downloadCsv: NoContext,
475
+ onBulkEditingComplete: NoContext,
476
+ setOnBulkEditingComplete: NoContext,
477
+ showNoRowsOverlay: NoContext,
572
478
  });
573
479
  const useGridContext = () => React.useContext(GridContext);
574
480
 
@@ -592,6 +498,131 @@ const GridUpdatingContext = React.createContext({
592
498
  updatedDep: 0,
593
499
  });
594
500
 
501
+ var lib = {};
502
+
503
+ var hasRequiredLib;
504
+
505
+ function requireLib () {
506
+ if (hasRequiredLib) return lib;
507
+ hasRequiredLib = 1;
508
+ Object.defineProperty(lib, "__esModule", { value: true });
509
+ function natsort(options) {
510
+ if (options === void 0) { options = {}; }
511
+ var ore = /^0/;
512
+ var sre = /\s+/g;
513
+ var tre = /^\s+|\s+$/g;
514
+ // unicode
515
+ var ure = /[^\x00-\x80]/;
516
+ // hex
517
+ var hre = /^0x[0-9a-f]+$/i;
518
+ // numeric
519
+ var nre = /(0x[\da-fA-F]+|(^[\+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|\d+)/g;
520
+ // datetime
521
+ var dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/; // tslint:disable-line
522
+ var toLowerCase = String.prototype.toLocaleLowerCase || String.prototype.toLowerCase;
523
+ var GREATER = options.desc ? -1 : 1;
524
+ var SMALLER = -GREATER;
525
+ var normalize = options.insensitive
526
+ ? function (s) { return toLowerCase.call("" + s).replace(tre, ''); }
527
+ : function (s) { return ("" + s).replace(tre, ''); };
528
+ function tokenize(s) {
529
+ return s.replace(nre, '\0$1\0')
530
+ .replace(/\0$/, '')
531
+ .replace(/^\0/, '')
532
+ .split('\0');
533
+ }
534
+ function parse(s, l) {
535
+ // normalize spaces; find floats not starting with '0',
536
+ // string or 0 if not defined (Clint Priest)
537
+ return (!s.match(ore) || l === 1)
538
+ && parseFloat(s)
539
+ || s.replace(sre, ' ').replace(tre, '')
540
+ || 0;
541
+ }
542
+ return function (a, b) {
543
+ // trim pre-post whitespace
544
+ var aa = normalize(a);
545
+ var bb = normalize(b);
546
+ // return immediately if at least one of the values is empty.
547
+ // empty string < any others
548
+ if (!aa && !bb) {
549
+ return 0;
550
+ }
551
+ if (!aa && bb) {
552
+ return SMALLER;
553
+ }
554
+ if (aa && !bb) {
555
+ return GREATER;
556
+ }
557
+ // tokenize: split numeric strings and default strings
558
+ var aArr = tokenize(aa);
559
+ var bArr = tokenize(bb);
560
+ // hex or date detection
561
+ var aHex = aa.match(hre);
562
+ var bHex = bb.match(hre);
563
+ var av = (aHex && bHex) ? parseInt(aHex[0], 16) : (aArr.length !== 1 && Date.parse(aa));
564
+ var bv = (aHex && bHex)
565
+ ? parseInt(bHex[0], 16)
566
+ : av && bb.match(dre) && Date.parse(bb) || null;
567
+ // try and sort Hex codes or Dates
568
+ if (bv) {
569
+ if (av === bv) {
570
+ return 0;
571
+ }
572
+ if (av < bv) {
573
+ return SMALLER;
574
+ }
575
+ if (av > bv) {
576
+ return GREATER;
577
+ }
578
+ }
579
+ var al = aArr.length;
580
+ var bl = bArr.length;
581
+ // handle numeric strings and default strings
582
+ for (var i = 0, l = Math.max(al, bl); i < l; i += 1) {
583
+ var af = parse(aArr[i] || '', al);
584
+ var bf = parse(bArr[i] || '', bl);
585
+ // handle numeric vs string comparison.
586
+ // numeric < string
587
+ if (isNaN(af) !== isNaN(bf)) {
588
+ return isNaN(af) ? GREATER : SMALLER;
589
+ }
590
+ // if unicode use locale comparison
591
+ if (ure.test(af + bf) && af.localeCompare) {
592
+ var comp = af.localeCompare(bf);
593
+ if (comp > 0) {
594
+ return GREATER;
595
+ }
596
+ if (comp < 0) {
597
+ return SMALLER;
598
+ }
599
+ if (i === l - 1) {
600
+ return 0;
601
+ }
602
+ }
603
+ if (af < bf) {
604
+ return SMALLER;
605
+ }
606
+ if (af > bf) {
607
+ return GREATER;
608
+ }
609
+ if ("" + af < "" + bf) {
610
+ return SMALLER;
611
+ }
612
+ if ("" + af > "" + bf) {
613
+ return GREATER;
614
+ }
615
+ }
616
+ return 0;
617
+ };
618
+ }
619
+ lib.default = natsort;
620
+ return lib;
621
+ }
622
+
623
+ var libExports = requireLib();
624
+ var natsort = /*@__PURE__*/getDefaultExportFromCjs(libExports);
625
+
595
626
  const isNotEmpty = lodashEs.negate(lodashEs.isEmpty);
596
627
  const wait = (timeoutMs) => new Promise((resolve) => {
597
628
  setTimeout(resolve, timeoutMs);
@@ -643,6 +674,20 @@ const sanitiseFileName = (filename) => {
643
674
  return valid.slice().slice(0, 64);
644
675
  return valid.slice(0, -fileExt.length - 1).slice(0, 64) + '.' + fileExt;
645
676
  };
677
+ const naturalSortInsensitive = natsort({ insensitive: true });
678
+ const santitizeNaturalValue = (v) => {
679
+ if (v === '–' || v === '-' || v == null) {
680
+ return '';
681
+ }
682
+ return String(v);
683
+ };
684
+ const compareNaturalInsensitive = (a, b) => {
685
+ if ((a !== null && typeof a === 'object') || (b !== null && typeof b === 'object')) {
686
+ // We can't compare objects
687
+ return 0;
688
+ }
689
+ return naturalSortInsensitive(santitizeNaturalValue(a), santitizeNaturalValue(b));
690
+ };
646
691
 
647
692
  /**
648
693
  * AgGrid checkbox select does not pass clicks within cell but not on the checkbox to checkbox.
@@ -2763,7 +2808,7 @@ agGridCommunity.ModuleRegistry.registerModules([agGridCommunity.AllCommunityModu
2763
2808
  /**
2764
2809
  * Wrapper for AgGrid to add commonly used functionality.
2765
2810
  */
2766
- const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection = 'multiple', suppressColumnVirtualization = true, theme = 'ag-theme-step-default', sizeColumns = 'auto', selectColumnPinned = 'left', contextMenuSelectRow = false, singleClickEdit = false, rowData, rowHeight = theme === 'ag-theme-step-default' ? 40 : theme === 'ag-theme-step-compact' ? 36 : 40, selectable, onCellFocused: paramsOnCellFocused, maxInitialWidth, suppressReadOnlyStyle = false, ...params }) => {
2811
+ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection = 'multiple', suppressColumnVirtualization = true, theme = 'ag-theme-step-default', sizeColumns = 'auto', selectColumnPinned = 'left', contextMenuSelectRow = false, singleClickEdit = false, rowData, rowHeight = theme === 'ag-theme-step-default' ? 40 : theme === 'ag-theme-step-compact' ? 36 : 40, selectable, autoSelectFirstRow, onCellFocused: paramsOnCellFocused, maxInitialWidth, suppressReadOnlyStyle = false, externalSelectedItems, setExternalSelectedItems, externalSelectedIds, setExternalSelectedIds, ...params }) => {
2767
2812
  const { gridReady, gridRenderState, setApis, ensureRowVisible, getFirstRowId, selectRowsById, focusByRowById, ensureSelectedRowIsVisible, autoSizeColumns, sizeColumnsToFit, externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync, isExternalFilterPresent, doesExternalFilterPass, setOnBulkEditingComplete, getColDef, showNoRowsOverlay, prePopupOps, startCellEditing: propStartCellEditing, } = useGridContext();
2768
2813
  // CellEditingStop event happens too much for one edit
2769
2814
  const startedEditRef = React.useRef(false);
@@ -2773,7 +2818,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2773
2818
  }, [propStartCellEditing]);
2774
2819
  const { updatedDep, anyUpdating, updatingCols } = React.useContext(GridUpdatingContext);
2775
2820
  const gridDivRef = React.useRef(null);
2776
- const lastSelectedIds = React.useRef([]);
2821
+ const lastSelectedIds = React.useRef();
2777
2822
  const [staleGrid, setStaleGrid] = React.useState(false);
2778
2823
  const [autoSized, setAutoSized] = React.useState(false);
2779
2824
  const postSortRows = usePostSortRowsHook({ setStaleGrid });
@@ -2899,12 +2944,13 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2899
2944
  */
2900
2945
  const hasSelectedFirstItem = React.useRef(false);
2901
2946
  React.useEffect(() => {
2902
- if (!gridReady || hasSelectedFirstItem.current || !rowData || !externallySelectedItemsAreInSync)
2947
+ if (!gridReady || hasSelectedFirstItem.current || !rowData || !externallySelectedItemsAreInSync) {
2903
2948
  return;
2949
+ }
2904
2950
  hasSelectedFirstItem.current = true;
2905
- if (isNotEmpty(rowData) && lodashEs.isEmpty(params.externalSelectedItems)) {
2951
+ if (isNotEmpty(rowData) && lodashEs.isEmpty(externalSelectedItems)) {
2906
2952
  const firstRowId = getFirstRowId();
2907
- if (params.autoSelectFirstRow) {
2953
+ if (autoSelectFirstRow && selectable) {
2908
2954
  selectRowsById([firstRowId]);
2909
2955
  }
2910
2956
  else {
@@ -2915,31 +2961,51 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2915
2961
  externallySelectedItemsAreInSync,
2916
2962
  focusByRowById,
2917
2963
  gridReady,
2918
- params.externalSelectedItems,
2919
- params.autoSelectFirstRow,
2964
+ externalSelectedItems,
2965
+ autoSelectFirstRow,
2920
2966
  rowData,
2921
2967
  selectRowsById,
2922
2968
  getFirstRowId,
2969
+ selectable,
2923
2970
  ]);
2924
2971
  /**
2925
2972
  * Ensure external selected items list is in sync with panel.
2926
2973
  */
2927
2974
  const synchroniseExternalStateToGridSelection = React.useCallback(({ api }) => {
2928
- if (!params.externalSelectedItems || !params.setExternalSelectedItems) {
2929
- setExternallySelectedItemsAreInSync(true);
2930
- return;
2975
+ if (externalSelectedIds && setExternalSelectedIds) {
2976
+ const selectedRowsIds = api.getSelectedRows().map((row) => row.id);
2977
+ // We don't want to update selected Items if it hasn't changed to prevent excess renders
2978
+ if (externalSelectedIds.length !== selectedRowsIds.length ||
2979
+ isNotEmpty(lodashEs.xorBy(selectedRowsIds, externalSelectedIds))) {
2980
+ setExternallySelectedItemsAreInSync(false);
2981
+ setExternalSelectedIds([...selectedRowsIds]);
2982
+ }
2983
+ else {
2984
+ setExternallySelectedItemsAreInSync(true);
2985
+ }
2931
2986
  }
2932
- const selectedRows = api.getSelectedRows();
2933
- // We don't want to update selected Items if it hasn't changed to prevent excess renders
2934
- if (params.externalSelectedItems.length !== selectedRows.length ||
2935
- isNotEmpty(lodashEs.xorBy(selectedRows, params.externalSelectedItems, (row) => row.id))) {
2936
- setExternallySelectedItemsAreInSync(false);
2937
- params.setExternalSelectedItems([...selectedRows]);
2987
+ else if (externalSelectedItems && setExternalSelectedItems) {
2988
+ const selectedRows = api.getSelectedRows();
2989
+ // We don't want to update selected Items if it hasn't changed to prevent excess renders
2990
+ if (externalSelectedItems.length !== selectedRows.length ||
2991
+ isNotEmpty(lodashEs.xorBy(selectedRows, externalSelectedItems, (row) => row.id))) {
2992
+ setExternallySelectedItemsAreInSync(false);
2993
+ setExternalSelectedItems([...selectedRows]);
2994
+ }
2995
+ else {
2996
+ setExternallySelectedItemsAreInSync(true);
2997
+ }
2938
2998
  }
2939
2999
  else {
2940
3000
  setExternallySelectedItemsAreInSync(true);
2941
3001
  }
2942
- }, [params, setExternallySelectedItemsAreInSync]);
3002
+ }, [
3003
+ externalSelectedIds,
3004
+ externalSelectedItems,
3005
+ setExternalSelectedIds,
3006
+ setExternalSelectedItems,
3007
+ setExternallySelectedItemsAreInSync,
3008
+ ]);
2943
3009
  /**
2944
3010
  * Synchronise externally selected items to grid.
2945
3011
  * If new ids are selected scroll them into view.
@@ -2947,19 +3013,26 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2947
3013
  const synchroniseExternallySelectedItemsToGrid = React.useCallback(() => {
2948
3014
  if (!gridReady)
2949
3015
  return;
2950
- if (!params.externalSelectedItems) {
3016
+ if (!externalSelectedItems && !externalSelectedIds) {
2951
3017
  setExternallySelectedItemsAreInSync(true);
2952
3018
  return;
2953
3019
  }
2954
- const selectedIds = params.externalSelectedItems.map((row) => row.id);
2955
- const lastNewId = lodashEs.last(lodashEs.difference(selectedIds, lastSelectedIds.current));
3020
+ const selectedIds = externalSelectedIds ?? externalSelectedItems?.map((row) => row.id);
3021
+ const lastNewId = lodashEs.last(lodashEs.difference(selectedIds, lastSelectedIds.current ?? []));
2956
3022
  if (lastNewId != null) {
2957
3023
  ensureRowVisible(lastNewId);
2958
3024
  }
2959
3025
  lastSelectedIds.current = selectedIds;
2960
3026
  selectRowsById(selectedIds);
2961
3027
  setExternallySelectedItemsAreInSync(true);
2962
- }, [gridReady, params.externalSelectedItems, ensureRowVisible, selectRowsById, setExternallySelectedItemsAreInSync]);
3028
+ }, [
3029
+ gridReady,
3030
+ externalSelectedItems,
3031
+ externalSelectedIds,
3032
+ selectRowsById,
3033
+ setExternallySelectedItemsAreInSync,
3034
+ ensureRowVisible,
3035
+ ]);
2963
3036
  /**
2964
3037
  * Combine grid and cell editable into one function
2965
3038
  */
@@ -3001,7 +3074,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
3001
3074
  const columnDefs = React.useMemo(() => {
3002
3075
  return params.columnDefs.map(mapColDef);
3003
3076
  }, [params.columnDefs, mapColDef]);
3004
- const hasExternallySelectedItems = !!params.setExternalSelectedItems;
3077
+ const hasExternallySelectedItems = !!setExternalSelectedItems || !!setExternalSelectedIds;
3005
3078
  /**
3006
3079
  * When grid is ready set the apis to the grid context and sync selected items to grid.
3007
3080
  */
@@ -3126,18 +3199,48 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
3126
3199
  });
3127
3200
  const adjustColDef = (colDef) => {
3128
3201
  const flex = colDef.flex ?? (sizeColumns === 'fit' ? 1 : undefined);
3129
- return {
3202
+ const valueFormatter = colDef.valueFormatter;
3203
+ const sortable = colDef.sortable && params.defaultColDef?.sortable !== false;
3204
+ let comparator = colDef.comparator;
3205
+ if (sortable && !comparator) {
3206
+ comparator = (value1, value2, node1, node2) => {
3207
+ let r;
3208
+ if (typeof valueFormatter === 'function') {
3209
+ r = compareNaturalInsensitive(valueFormatter({
3210
+ data: node1.data,
3211
+ value: value1,
3212
+ node: node1,
3213
+ colDef: adjustedColDef,
3214
+ ...NotAGridValueFormatterCall,
3215
+ }), valueFormatter({
3216
+ data: node2.data,
3217
+ value: value2,
3218
+ node: node2,
3219
+ colDef: adjustedColDef,
3220
+ ...NotAGridValueFormatterCall,
3221
+ }));
3222
+ }
3223
+ else {
3224
+ r = compareNaturalInsensitive(value1, value2);
3225
+ }
3226
+ // secondary compare as primary sort column rows are equal
3227
+ return r === 0 ? compareNaturalInsensitive(node1.data?.id, node2.data?.id) : r;
3228
+ };
3229
+ }
3230
+ const adjustedColDef = {
3130
3231
  ...colDef,
3131
3232
  // You cannot pass a width to a flex
3132
3233
  width: !!colDef.flex ? undefined : colDef.width,
3133
- flexAutoSizeWidth: colDef.width,
3234
+ ...(!!colDef.flex && { flexAutoSizeWidth: colDef.width }),
3134
3235
  // If this is allowed flex columns don't size based on flex
3135
3236
  suppressSizeToFit: true,
3136
3237
  // Auto-sizing flex columns breaks everything
3137
3238
  flex,
3138
3239
  suppressAutoSize: !!flex,
3139
- sortable: colDef.sortable && params.defaultColDef?.sortable !== false,
3240
+ sortable,
3241
+ comparator,
3140
3242
  };
3243
+ return adjustedColDef;
3141
3244
  };
3142
3245
  return columnDefs.map((colDef) => adjustColDefOrGroup(colDef));
3143
3246
  }, [columnDefs, params.defaultColDef?.sortable, sizeColumns]);
@@ -3298,11 +3401,14 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
3298
3401
  }
3299
3402
  }, [params, clearHighlightRowClasses]);
3300
3403
  React.useEffect(() => {
3301
- if (params.setExternalSelectedItems && selectable == null) {
3302
- console.warn('<Grid/> has setExternalSelectedItems parameter, but is missing selectable parameter,' +
3404
+ if ((setExternalSelectedItems || setExternalSelectedIds) && selectable == null) {
3405
+ console.warn('<Grid/> has setExternalSelectedItems/setExternalSelectedIds parameter, but is missing selectable parameter,' +
3303
3406
  'this will cause weird delays in editing.\nIf you need to hide selection column use hideSelectColumn=true');
3304
3407
  }
3305
- }, [params.setExternalSelectedItems, selectable]);
3408
+ },
3409
+ // Only needs to run on startup
3410
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3411
+ [selectable]);
3306
3412
  // This is setting a ref in the GridContext so won't be triggering an update loop
3307
3413
  setOnBulkEditingComplete(params.onBulkEditingComplete);
3308
3414
  const getRowId = React.useCallback((params) => `${params.data.id}`, []);
@@ -3346,19 +3452,9 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
3346
3452
  }
3347
3453
  return false;
3348
3454
  },
3349
- onCellClicked: params.enableSelectionWithoutKeys || params.enableClickSelection
3350
- ? undefined
3351
- : clickInputWhenContainingCellClicked,
3455
+ onCellClicked: clickInputWhenContainingCellClicked,
3352
3456
  };
3353
- }, [
3354
- params.enableClickSelection,
3355
- params.enableSelectionWithoutKeys,
3356
- params.hideSelectColumn,
3357
- params.onRowDragEnd,
3358
- rowSelection,
3359
- selectColumnPinned,
3360
- selectable,
3361
- ]);
3457
+ }, [params.hideSelectColumn, params.onRowDragEnd, rowSelection, selectColumnPinned, selectable]);
3362
3458
  const onGridSizeChanged = React.useCallback((event) => {
3363
3459
  if (sizeColumns === 'fit' || (['auto', 'auto-skip-headers'].includes(sizeColumns) && hasSetContentSize.current)) {
3364
3460
  event.api.sizeColumnsToFit();
@@ -3380,6 +3476,15 @@ const quickFilterParser = (filterStr) => {
3380
3476
  // filter is exact matches exactly groups separated by commas
3381
3477
  return filterStr.split(',').map((str) => str.trim());
3382
3478
  };
3479
+ /**
3480
+ * Columns to indicate to user when they debug why things are broken in the default comparator if their valueFormatter
3481
+ * is too complicated.
3482
+ */
3483
+ const NotAGridValueFormatterCall = {
3484
+ column: 'Default comparator has no access to column, write your own comparator',
3485
+ api: 'Default comparator has no access to api, write your own comparator',
3486
+ context: 'Default comparator has no access to context, write your own comparator',
3487
+ };
3383
3488
 
3384
3489
  const GridPopoverContext = React.createContext({
3385
3490
  anchorRef: { current: null },
@@ -5642,47 +5747,53 @@ const GridContextProvider = (props) => {
5642
5747
  if (!gridApi || !gridApi.getColumnState()) {
5643
5748
  return null;
5644
5749
  }
5645
- const colIdsSet = colIds instanceof Set ? colIds : new Set(colIds);
5646
- const getVisibleColStates = () => {
5647
- const colStates = gridApi.getColumnState();
5648
- return colStates.filter((colState) => {
5649
- const colId = colState.colId;
5650
- return (lodashEs.isEmpty(colIdsSet) || colIdsSet.has(colId)) && !userSizedColIds?.has(colId);
5750
+ try {
5751
+ const colIdsSet = colIds instanceof Set ? colIds : new Set(colIds);
5752
+ const getVisibleColStates = () => {
5753
+ const colStates = gridApi.getColumnState();
5754
+ return colStates.filter((colState) => {
5755
+ const colId = colState.colId;
5756
+ return (lodashEs.isEmpty(colIdsSet) || colIdsSet.has(colId)) && !userSizedColIds?.has(colId);
5757
+ });
5758
+ };
5759
+ const getFlexColStates = () => getVisibleColStates().filter(colStateFlexed);
5760
+ const getNonFlexColStates = () => getVisibleColStates().filter(colStateNotFlexed);
5761
+ // You cannot autosize flex columns it will break layout randomly
5762
+ // So, a flex column is assumed to be 150 wide, unless width is provided
5763
+ const flexColumns = getFlexColStates().map(colStateId);
5764
+ let width = 0;
5765
+ flexColumns.forEach((colId) => {
5766
+ const colDef = gridApi.getColumnDef(colId);
5767
+ width += colDef?.flexAutoSizeWidth ?? 200;
5651
5768
  });
5652
- };
5653
- const getFlexColStates = () => getVisibleColStates().filter(colStateFlexed);
5654
- const getNonFlexColStates = () => getVisibleColStates().filter(colStateNotFlexed);
5655
- // You cannot autosize flex columns it will break layout randomly
5656
- // So, a flex column is assumed to be 150 wide, unless width is provided
5657
- const flexColumns = getFlexColStates().map(colStateId);
5658
- let width = 0;
5659
- flexColumns.forEach((colId) => {
5660
- const colDef = gridApi.getColumnDef(colId);
5661
- width += colDef?.flexAutoSizeWidth ?? 200;
5662
- });
5663
- const nonFlexColumns = getNonFlexColStates();
5664
- const nonFlexColumnIds = nonFlexColumns.map(colStateId);
5665
- gridApi.autoSizeColumns({ colIds: nonFlexColumnIds, skipHeader });
5666
- const calcSubWidth = () => {
5667
- const updatedFlexColumns = getVisibleColStates().filter((colState) => nonFlexColumnIds.includes(colState.colId));
5668
- return lodashEs.sumBy(updatedFlexColumns.filter((col) => !col.hide), 'width');
5669
- };
5670
- // ag-grid updates widths asynchronously, so we wait here for the default calculated width to change
5671
- let lastSubWidth = calcSubWidth();
5672
- const endTime = Date.now() + 1000;
5673
- while (Date.now() < endTime) {
5674
- await wait(40);
5675
- const newSubWidth = calcSubWidth();
5676
- if (lastSubWidth !== newSubWidth) {
5677
- lastSubWidth = newSubWidth;
5678
- break;
5769
+ const nonFlexColumns = getNonFlexColStates();
5770
+ const nonFlexColumnIds = nonFlexColumns.map(colStateId);
5771
+ gridApi.autoSizeColumns({ colIds: nonFlexColumnIds, skipHeader });
5772
+ const calcSubWidth = () => {
5773
+ const updatedFlexColumns = getVisibleColStates().filter((colState) => nonFlexColumnIds.includes(colState.colId));
5774
+ return lodashEs.sumBy(updatedFlexColumns.filter((col) => !col.hide), 'width');
5775
+ };
5776
+ // ag-grid updates widths asynchronously, so we wait here for the default calculated width to change
5777
+ let lastSubWidth = calcSubWidth();
5778
+ const endTime = Date.now() + 1000;
5779
+ while (Date.now() < endTime) {
5780
+ await wait(40);
5781
+ const newSubWidth = calcSubWidth();
5782
+ if (lastSubWidth !== newSubWidth) {
5783
+ lastSubWidth = newSubWidth;
5784
+ break;
5785
+ }
5679
5786
  }
5787
+ width += lastSubWidth;
5788
+ gridApi.sizeColumnsToFit();
5789
+ return {
5790
+ width,
5791
+ };
5792
+ }
5793
+ catch (ex) {
5794
+ console.info('autosize failed', ex);
5795
+ return null;
5680
5796
  }
5681
- width += lastSubWidth;
5682
- gridApi.sizeColumnsToFit();
5683
- return {
5684
- width,
5685
- };
5686
5797
  }, [gridApi]);
5687
5798
  /**
5688
5799
  * Resize columns to fit container
@@ -6249,6 +6360,7 @@ exports.bearingValueFormatter = bearingValueFormatter;
6249
6360
  exports.colStateFlexed = colStateFlexed;
6250
6361
  exports.colStateId = colStateId;
6251
6362
  exports.colStateNotFlexed = colStateNotFlexed;
6363
+ exports.compareNaturalInsensitive = compareNaturalInsensitive;
6252
6364
  exports.convertDDToDMS = convertDDToDMS;
6253
6365
  exports.createCheckboxMultiFilterParams = createCheckboxMultiFilterParams;
6254
6366
  exports.defaultValueFormatter = defaultValueFormatter;