@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
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { LuiMiniSpinner, LuiStatusSpinner, LuiIcon, LuiButtonGroup, LuiButton, LuiCheckboxInput } from '@linzjs/lui';
3
3
  import { ModuleRegistry, AllCommunityModule } from 'ag-grid-community';
4
4
  import { AgGridReact } from 'ag-grid-react';
5
- import { negate, isEmpty, findIndex, defer, debounce as debounce$1, xorBy, last, difference, delay, omit, sortBy, partition, compact, pick, groupBy, fromPairs, toPairs, isEqual, pull, filter, remove, sumBy, flatten, castArray } from 'lodash-es';
5
+ import { negate, isEmpty, findIndex, defer, debounce as debounce$1, xorBy, last, difference, delay, omit, sortBy, partition, compact, pick, groupBy, fromPairs, toPairs, isEqual, pull, filter, sumBy, remove, flatten, castArray } from 'lodash-es';
6
6
  import React, { useRef, useLayoutEffect, useEffect, createContext, useContext, useState, useMemo, memo, forwardRef, useCallback, useReducer, cloneElement, useImperativeHandle, Fragment as Fragment$1, useId } from 'react';
7
7
  import { unstable_batchedUpdates, flushSync, createPortal } from 'react-dom';
8
8
  import { createRoot } from 'react-dom/client';
@@ -426,147 +426,53 @@ function useInterval(callback, delay) {
426
426
  }, [delay]);
427
427
  }
428
428
 
429
+ const NoContext = () => {
430
+ console.error('Missing GridContextProvider');
431
+ return null;
432
+ };
429
433
  const GridContext = createContext({
430
434
  gridReady: false,
431
435
  gridRenderState: () => null,
432
- getColDef: () => {
433
- console.error('no context provider for getColDef');
434
- return undefined;
435
- },
436
- getColumns: () => {
437
- console.error('no context provider for getColumns');
438
- return [];
439
- },
440
- getColumnIds: () => {
441
- console.error('no context provider for getColumnIds');
442
- return [];
443
- },
436
+ getColDef: NoContext,
437
+ getColumns: NoContext,
438
+ getColumnIds: NoContext,
444
439
  invisibleColumnIds: undefined,
445
- setInvisibleColumnIds: () => {
446
- console.error('no context provider for setInvisibleColumnIds');
447
- },
448
- prePopupOps: () => {
449
- console.error('no context provider for prePopupOps');
450
- },
440
+ setInvisibleColumnIds: NoContext,
441
+ prePopupOps: NoContext,
451
442
  externallySelectedItemsAreInSync: false,
452
- setApis: () => {
453
- console.error('no context provider for setApis');
454
- },
455
- setQuickFilter: () => {
456
- console.error('no context provider for setQuickFilter');
457
- },
458
- selectRowsById: () => {
459
- console.error('no context provider for selectRows');
460
- },
461
- getSelectedRows: () => {
462
- console.error('no context provider for getSelectedRows');
463
- return [];
464
- },
465
- getFilteredSelectedRows: () => {
466
- console.error('no context provider for getFilteredSelectedRows');
467
- return [];
468
- },
469
- getSelectedRowIds: () => {
470
- console.error('no context provider for getSelectedRowIds');
471
- return [];
472
- },
473
- getFilteredSelectedRowIds: () => {
474
- console.error('no context provider for getFilteredSelectedRowIds');
475
- return [];
476
- },
477
- // eslint-disable-next-line @typescript-eslint/require-await
478
- selectRowsDiff: async () => {
479
- console.error('no context provider for selectRowsDiff');
480
- },
481
- selectRowsByIdWithFlash: () => {
482
- console.error('no context provider for selectRowsWithFlash');
483
- },
484
- // eslint-disable-next-line @typescript-eslint/require-await
485
- selectRowsWithFlashDiff: async () => {
486
- console.error('no context provider for selectRowsWithFlashDiff');
487
- },
488
- flashRows: () => {
489
- console.error('no context provider for flashRows');
490
- },
491
- // eslint-disable-next-line @typescript-eslint/require-await
492
- flashRowsDiff: async () => {
493
- console.error('no context provider for flashRows');
494
- },
495
- // eslint-disable-next-line @typescript-eslint/require-await,@typescript-eslint/no-misused-promises
496
- focusByRowById: async () => {
497
- console.error('no context provider for focusByRowById');
498
- },
499
- ensureRowVisible: () => {
500
- console.error('no context provider for ensureRowVisible');
501
- return true;
502
- },
503
- ensureSelectedRowIsVisible: () => {
504
- console.error('no context provider for ensureSelectedRowIsVisible');
505
- },
506
- getFirstRowId: () => {
507
- console.error('no context provider for getFirstRowId');
508
- return -1;
509
- },
510
- autoSizeColumns: async () => {
511
- console.error('no context provider for autoSizeColumns');
512
- return Promise.resolve(null);
513
- },
514
- sizeColumnsToFit: () => {
515
- console.error('no context provider for autoSizeAllColumns');
516
- return null;
517
- },
518
- editingCells: () => {
519
- console.error('no context provider for editingCells');
520
- return false;
521
- },
522
- // eslint-disable-next-line @typescript-eslint/require-await
523
- startCellEditing: async () => {
524
- console.error('no context provider for startCellEditing');
525
- },
526
- resetFocusedCellAfterCellEditing: () => {
527
- console.error('no context provider for resetFocusedCellAfterCellEditing');
528
- },
529
- // eslint-disable-next-line @typescript-eslint/require-await
530
- updatingCells: async () => {
531
- console.error('no context provider for modifyUpdating');
532
- return false;
533
- },
534
- redrawRows: () => {
535
- console.error('no context provider for redrawRows');
536
- },
537
- setExternallySelectedItemsAreInSync: () => {
538
- console.error('no context provider for setExternallySelectedItemsAreInSync');
539
- },
540
- // eslint-disable-next-line @typescript-eslint/require-await
541
- waitForExternallySelectedItemsToBeInSync: async () => {
542
- console.error('no context provider for waitForExternallySelectedItemsToBeInSync');
543
- },
544
- addExternalFilter: () => {
545
- console.error('no context provider for addExternalFilter');
546
- },
547
- removeExternalFilter: () => {
548
- console.error('no context provider for removeExternalFilter');
549
- },
550
- isExternalFilterPresent: () => {
551
- console.error('no context provider for isExternalFilterPresent');
552
- return false;
553
- },
554
- doesExternalFilterPass: () => {
555
- console.error('no context provider for doesExternalFilterPass');
556
- return true;
557
- },
558
- downloadCsv: () => {
559
- console.error('no context provider for downloadCsv');
560
- },
561
- onBulkEditingComplete: () => {
562
- console.error('no context provider for onBulkEditingComplete');
563
- },
564
- setOnBulkEditingComplete: () => {
565
- console.error('no context provider for setOnBulkEditingComplete');
566
- },
567
- showNoRowsOverlay: () => {
568
- console.error('no context provider for showLoadingOverlay');
569
- },
443
+ setApis: NoContext,
444
+ setQuickFilter: NoContext,
445
+ selectRowsById: NoContext,
446
+ getSelectedRows: NoContext,
447
+ getFilteredSelectedRows: NoContext,
448
+ getSelectedRowIds: NoContext,
449
+ getFilteredSelectedRowIds: NoContext,
450
+ selectRowsDiff: NoContext,
451
+ selectRowsByIdWithFlash: NoContext,
452
+ selectRowsWithFlashDiff: NoContext,
453
+ flashRows: NoContext,
454
+ flashRowsDiff: NoContext,
455
+ focusByRowById: NoContext,
456
+ ensureRowVisible: NoContext,
457
+ ensureSelectedRowIsVisible: NoContext,
458
+ getFirstRowId: NoContext,
459
+ autoSizeColumns: NoContext,
460
+ sizeColumnsToFit: NoContext,
461
+ editingCells: NoContext,
462
+ startCellEditing: NoContext,
463
+ resetFocusedCellAfterCellEditing: NoContext,
464
+ updatingCells: NoContext,
465
+ redrawRows: NoContext,
466
+ setExternallySelectedItemsAreInSync: NoContext,
467
+ waitForExternallySelectedItemsToBeInSync: NoContext,
468
+ addExternalFilter: NoContext,
469
+ removeExternalFilter: NoContext,
470
+ isExternalFilterPresent: NoContext,
471
+ doesExternalFilterPass: NoContext,
472
+ downloadCsv: NoContext,
473
+ onBulkEditingComplete: NoContext,
474
+ setOnBulkEditingComplete: NoContext,
475
+ showNoRowsOverlay: NoContext,
570
476
  });
571
477
  const useGridContext = () => useContext(GridContext);
572
478
 
@@ -590,6 +496,131 @@ const GridUpdatingContext = createContext({
590
496
  updatedDep: 0,
591
497
  });
592
498
 
499
+ var lib = {};
500
+
501
+ var hasRequiredLib;
502
+
503
+ function requireLib () {
504
+ if (hasRequiredLib) return lib;
505
+ hasRequiredLib = 1;
506
+ Object.defineProperty(lib, "__esModule", { value: true });
507
+ function natsort(options) {
508
+ if (options === void 0) { options = {}; }
509
+ var ore = /^0/;
510
+ var sre = /\s+/g;
511
+ var tre = /^\s+|\s+$/g;
512
+ // unicode
513
+ var ure = /[^\x00-\x80]/;
514
+ // hex
515
+ var hre = /^0x[0-9a-f]+$/i;
516
+ // numeric
517
+ var nre = /(0x[\da-fA-F]+|(^[\+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|\d+)/g;
518
+ // datetime
519
+ 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
520
+ var toLowerCase = String.prototype.toLocaleLowerCase || String.prototype.toLowerCase;
521
+ var GREATER = options.desc ? -1 : 1;
522
+ var SMALLER = -GREATER;
523
+ var normalize = options.insensitive
524
+ ? function (s) { return toLowerCase.call("" + s).replace(tre, ''); }
525
+ : function (s) { return ("" + s).replace(tre, ''); };
526
+ function tokenize(s) {
527
+ return s.replace(nre, '\0$1\0')
528
+ .replace(/\0$/, '')
529
+ .replace(/^\0/, '')
530
+ .split('\0');
531
+ }
532
+ function parse(s, l) {
533
+ // normalize spaces; find floats not starting with '0',
534
+ // string or 0 if not defined (Clint Priest)
535
+ return (!s.match(ore) || l === 1)
536
+ && parseFloat(s)
537
+ || s.replace(sre, ' ').replace(tre, '')
538
+ || 0;
539
+ }
540
+ return function (a, b) {
541
+ // trim pre-post whitespace
542
+ var aa = normalize(a);
543
+ var bb = normalize(b);
544
+ // return immediately if at least one of the values is empty.
545
+ // empty string < any others
546
+ if (!aa && !bb) {
547
+ return 0;
548
+ }
549
+ if (!aa && bb) {
550
+ return SMALLER;
551
+ }
552
+ if (aa && !bb) {
553
+ return GREATER;
554
+ }
555
+ // tokenize: split numeric strings and default strings
556
+ var aArr = tokenize(aa);
557
+ var bArr = tokenize(bb);
558
+ // hex or date detection
559
+ var aHex = aa.match(hre);
560
+ var bHex = bb.match(hre);
561
+ var av = (aHex && bHex) ? parseInt(aHex[0], 16) : (aArr.length !== 1 && Date.parse(aa));
562
+ var bv = (aHex && bHex)
563
+ ? parseInt(bHex[0], 16)
564
+ : av && bb.match(dre) && Date.parse(bb) || null;
565
+ // try and sort Hex codes or Dates
566
+ if (bv) {
567
+ if (av === bv) {
568
+ return 0;
569
+ }
570
+ if (av < bv) {
571
+ return SMALLER;
572
+ }
573
+ if (av > bv) {
574
+ return GREATER;
575
+ }
576
+ }
577
+ var al = aArr.length;
578
+ var bl = bArr.length;
579
+ // handle numeric strings and default strings
580
+ for (var i = 0, l = Math.max(al, bl); i < l; i += 1) {
581
+ var af = parse(aArr[i] || '', al);
582
+ var bf = parse(bArr[i] || '', bl);
583
+ // handle numeric vs string comparison.
584
+ // numeric < string
585
+ if (isNaN(af) !== isNaN(bf)) {
586
+ return isNaN(af) ? GREATER : SMALLER;
587
+ }
588
+ // if unicode use locale comparison
589
+ if (ure.test(af + bf) && af.localeCompare) {
590
+ var comp = af.localeCompare(bf);
591
+ if (comp > 0) {
592
+ return GREATER;
593
+ }
594
+ if (comp < 0) {
595
+ return SMALLER;
596
+ }
597
+ if (i === l - 1) {
598
+ return 0;
599
+ }
600
+ }
601
+ if (af < bf) {
602
+ return SMALLER;
603
+ }
604
+ if (af > bf) {
605
+ return GREATER;
606
+ }
607
+ if ("" + af < "" + bf) {
608
+ return SMALLER;
609
+ }
610
+ if ("" + af > "" + bf) {
611
+ return GREATER;
612
+ }
613
+ }
614
+ return 0;
615
+ };
616
+ }
617
+ lib.default = natsort;
618
+ return lib;
619
+ }
620
+
621
+ var libExports = requireLib();
622
+ var natsort = /*@__PURE__*/getDefaultExportFromCjs(libExports);
623
+
593
624
  const isNotEmpty = negate(isEmpty);
594
625
  const wait = (timeoutMs) => new Promise((resolve) => {
595
626
  setTimeout(resolve, timeoutMs);
@@ -641,6 +672,20 @@ const sanitiseFileName = (filename) => {
641
672
  return valid.slice().slice(0, 64);
642
673
  return valid.slice(0, -fileExt.length - 1).slice(0, 64) + '.' + fileExt;
643
674
  };
675
+ const naturalSortInsensitive = natsort({ insensitive: true });
676
+ const santitizeNaturalValue = (v) => {
677
+ if (v === '–' || v === '-' || v == null) {
678
+ return '';
679
+ }
680
+ return String(v);
681
+ };
682
+ const compareNaturalInsensitive = (a, b) => {
683
+ if ((a !== null && typeof a === 'object') || (b !== null && typeof b === 'object')) {
684
+ // We can't compare objects
685
+ return 0;
686
+ }
687
+ return naturalSortInsensitive(santitizeNaturalValue(a), santitizeNaturalValue(b));
688
+ };
644
689
 
645
690
  /**
646
691
  * AgGrid checkbox select does not pass clicks within cell but not on the checkbox to checkbox.
@@ -2761,7 +2806,7 @@ ModuleRegistry.registerModules([AllCommunityModule]);
2761
2806
  /**
2762
2807
  * Wrapper for AgGrid to add commonly used functionality.
2763
2808
  */
2764
- 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 }) => {
2809
+ 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 }) => {
2765
2810
  const { gridReady, gridRenderState, setApis, ensureRowVisible, getFirstRowId, selectRowsById, focusByRowById, ensureSelectedRowIsVisible, autoSizeColumns, sizeColumnsToFit, externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync, isExternalFilterPresent, doesExternalFilterPass, setOnBulkEditingComplete, getColDef, showNoRowsOverlay, prePopupOps, startCellEditing: propStartCellEditing, } = useGridContext();
2766
2811
  // CellEditingStop event happens too much for one edit
2767
2812
  const startedEditRef = useRef(false);
@@ -2771,7 +2816,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2771
2816
  }, [propStartCellEditing]);
2772
2817
  const { updatedDep, anyUpdating, updatingCols } = useContext(GridUpdatingContext);
2773
2818
  const gridDivRef = useRef(null);
2774
- const lastSelectedIds = useRef([]);
2819
+ const lastSelectedIds = useRef();
2775
2820
  const [staleGrid, setStaleGrid] = useState(false);
2776
2821
  const [autoSized, setAutoSized] = useState(false);
2777
2822
  const postSortRows = usePostSortRowsHook({ setStaleGrid });
@@ -2897,12 +2942,13 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2897
2942
  */
2898
2943
  const hasSelectedFirstItem = useRef(false);
2899
2944
  useEffect(() => {
2900
- if (!gridReady || hasSelectedFirstItem.current || !rowData || !externallySelectedItemsAreInSync)
2945
+ if (!gridReady || hasSelectedFirstItem.current || !rowData || !externallySelectedItemsAreInSync) {
2901
2946
  return;
2947
+ }
2902
2948
  hasSelectedFirstItem.current = true;
2903
- if (isNotEmpty(rowData) && isEmpty(params.externalSelectedItems)) {
2949
+ if (isNotEmpty(rowData) && isEmpty(externalSelectedItems)) {
2904
2950
  const firstRowId = getFirstRowId();
2905
- if (params.autoSelectFirstRow) {
2951
+ if (autoSelectFirstRow && selectable) {
2906
2952
  selectRowsById([firstRowId]);
2907
2953
  }
2908
2954
  else {
@@ -2913,31 +2959,51 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2913
2959
  externallySelectedItemsAreInSync,
2914
2960
  focusByRowById,
2915
2961
  gridReady,
2916
- params.externalSelectedItems,
2917
- params.autoSelectFirstRow,
2962
+ externalSelectedItems,
2963
+ autoSelectFirstRow,
2918
2964
  rowData,
2919
2965
  selectRowsById,
2920
2966
  getFirstRowId,
2967
+ selectable,
2921
2968
  ]);
2922
2969
  /**
2923
2970
  * Ensure external selected items list is in sync with panel.
2924
2971
  */
2925
2972
  const synchroniseExternalStateToGridSelection = useCallback(({ api }) => {
2926
- if (!params.externalSelectedItems || !params.setExternalSelectedItems) {
2927
- setExternallySelectedItemsAreInSync(true);
2928
- return;
2973
+ if (externalSelectedIds && setExternalSelectedIds) {
2974
+ const selectedRowsIds = api.getSelectedRows().map((row) => row.id);
2975
+ // We don't want to update selected Items if it hasn't changed to prevent excess renders
2976
+ if (externalSelectedIds.length !== selectedRowsIds.length ||
2977
+ isNotEmpty(xorBy(selectedRowsIds, externalSelectedIds))) {
2978
+ setExternallySelectedItemsAreInSync(false);
2979
+ setExternalSelectedIds([...selectedRowsIds]);
2980
+ }
2981
+ else {
2982
+ setExternallySelectedItemsAreInSync(true);
2983
+ }
2929
2984
  }
2930
- const selectedRows = api.getSelectedRows();
2931
- // We don't want to update selected Items if it hasn't changed to prevent excess renders
2932
- if (params.externalSelectedItems.length !== selectedRows.length ||
2933
- isNotEmpty(xorBy(selectedRows, params.externalSelectedItems, (row) => row.id))) {
2934
- setExternallySelectedItemsAreInSync(false);
2935
- params.setExternalSelectedItems([...selectedRows]);
2985
+ else if (externalSelectedItems && setExternalSelectedItems) {
2986
+ const selectedRows = api.getSelectedRows();
2987
+ // We don't want to update selected Items if it hasn't changed to prevent excess renders
2988
+ if (externalSelectedItems.length !== selectedRows.length ||
2989
+ isNotEmpty(xorBy(selectedRows, externalSelectedItems, (row) => row.id))) {
2990
+ setExternallySelectedItemsAreInSync(false);
2991
+ setExternalSelectedItems([...selectedRows]);
2992
+ }
2993
+ else {
2994
+ setExternallySelectedItemsAreInSync(true);
2995
+ }
2936
2996
  }
2937
2997
  else {
2938
2998
  setExternallySelectedItemsAreInSync(true);
2939
2999
  }
2940
- }, [params, setExternallySelectedItemsAreInSync]);
3000
+ }, [
3001
+ externalSelectedIds,
3002
+ externalSelectedItems,
3003
+ setExternalSelectedIds,
3004
+ setExternalSelectedItems,
3005
+ setExternallySelectedItemsAreInSync,
3006
+ ]);
2941
3007
  /**
2942
3008
  * Synchronise externally selected items to grid.
2943
3009
  * If new ids are selected scroll them into view.
@@ -2945,19 +3011,26 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2945
3011
  const synchroniseExternallySelectedItemsToGrid = useCallback(() => {
2946
3012
  if (!gridReady)
2947
3013
  return;
2948
- if (!params.externalSelectedItems) {
3014
+ if (!externalSelectedItems && !externalSelectedIds) {
2949
3015
  setExternallySelectedItemsAreInSync(true);
2950
3016
  return;
2951
3017
  }
2952
- const selectedIds = params.externalSelectedItems.map((row) => row.id);
2953
- const lastNewId = last(difference(selectedIds, lastSelectedIds.current));
3018
+ const selectedIds = externalSelectedIds ?? externalSelectedItems?.map((row) => row.id);
3019
+ const lastNewId = last(difference(selectedIds, lastSelectedIds.current ?? []));
2954
3020
  if (lastNewId != null) {
2955
3021
  ensureRowVisible(lastNewId);
2956
3022
  }
2957
3023
  lastSelectedIds.current = selectedIds;
2958
3024
  selectRowsById(selectedIds);
2959
3025
  setExternallySelectedItemsAreInSync(true);
2960
- }, [gridReady, params.externalSelectedItems, ensureRowVisible, selectRowsById, setExternallySelectedItemsAreInSync]);
3026
+ }, [
3027
+ gridReady,
3028
+ externalSelectedItems,
3029
+ externalSelectedIds,
3030
+ selectRowsById,
3031
+ setExternallySelectedItemsAreInSync,
3032
+ ensureRowVisible,
3033
+ ]);
2961
3034
  /**
2962
3035
  * Combine grid and cell editable into one function
2963
3036
  */
@@ -2999,7 +3072,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2999
3072
  const columnDefs = useMemo(() => {
3000
3073
  return params.columnDefs.map(mapColDef);
3001
3074
  }, [params.columnDefs, mapColDef]);
3002
- const hasExternallySelectedItems = !!params.setExternalSelectedItems;
3075
+ const hasExternallySelectedItems = !!setExternalSelectedItems || !!setExternalSelectedIds;
3003
3076
  /**
3004
3077
  * When grid is ready set the apis to the grid context and sync selected items to grid.
3005
3078
  */
@@ -3124,18 +3197,48 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
3124
3197
  });
3125
3198
  const adjustColDef = (colDef) => {
3126
3199
  const flex = colDef.flex ?? (sizeColumns === 'fit' ? 1 : undefined);
3127
- return {
3200
+ const valueFormatter = colDef.valueFormatter;
3201
+ const sortable = colDef.sortable && params.defaultColDef?.sortable !== false;
3202
+ let comparator = colDef.comparator;
3203
+ if (sortable && !comparator) {
3204
+ comparator = (value1, value2, node1, node2) => {
3205
+ let r;
3206
+ if (typeof valueFormatter === 'function') {
3207
+ r = compareNaturalInsensitive(valueFormatter({
3208
+ data: node1.data,
3209
+ value: value1,
3210
+ node: node1,
3211
+ colDef: adjustedColDef,
3212
+ ...NotAGridValueFormatterCall,
3213
+ }), valueFormatter({
3214
+ data: node2.data,
3215
+ value: value2,
3216
+ node: node2,
3217
+ colDef: adjustedColDef,
3218
+ ...NotAGridValueFormatterCall,
3219
+ }));
3220
+ }
3221
+ else {
3222
+ r = compareNaturalInsensitive(value1, value2);
3223
+ }
3224
+ // secondary compare as primary sort column rows are equal
3225
+ return r === 0 ? compareNaturalInsensitive(node1.data?.id, node2.data?.id) : r;
3226
+ };
3227
+ }
3228
+ const adjustedColDef = {
3128
3229
  ...colDef,
3129
3230
  // You cannot pass a width to a flex
3130
3231
  width: !!colDef.flex ? undefined : colDef.width,
3131
- flexAutoSizeWidth: colDef.width,
3232
+ ...(!!colDef.flex && { flexAutoSizeWidth: colDef.width }),
3132
3233
  // If this is allowed flex columns don't size based on flex
3133
3234
  suppressSizeToFit: true,
3134
3235
  // Auto-sizing flex columns breaks everything
3135
3236
  flex,
3136
3237
  suppressAutoSize: !!flex,
3137
- sortable: colDef.sortable && params.defaultColDef?.sortable !== false,
3238
+ sortable,
3239
+ comparator,
3138
3240
  };
3241
+ return adjustedColDef;
3139
3242
  };
3140
3243
  return columnDefs.map((colDef) => adjustColDefOrGroup(colDef));
3141
3244
  }, [columnDefs, params.defaultColDef?.sortable, sizeColumns]);
@@ -3296,11 +3399,14 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
3296
3399
  }
3297
3400
  }, [params, clearHighlightRowClasses]);
3298
3401
  useEffect(() => {
3299
- if (params.setExternalSelectedItems && selectable == null) {
3300
- console.warn('<Grid/> has setExternalSelectedItems parameter, but is missing selectable parameter,' +
3402
+ if ((setExternalSelectedItems || setExternalSelectedIds) && selectable == null) {
3403
+ console.warn('<Grid/> has setExternalSelectedItems/setExternalSelectedIds parameter, but is missing selectable parameter,' +
3301
3404
  'this will cause weird delays in editing.\nIf you need to hide selection column use hideSelectColumn=true');
3302
3405
  }
3303
- }, [params.setExternalSelectedItems, selectable]);
3406
+ },
3407
+ // Only needs to run on startup
3408
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3409
+ [selectable]);
3304
3410
  // This is setting a ref in the GridContext so won't be triggering an update loop
3305
3411
  setOnBulkEditingComplete(params.onBulkEditingComplete);
3306
3412
  const getRowId = useCallback((params) => `${params.data.id}`, []);
@@ -3344,19 +3450,9 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
3344
3450
  }
3345
3451
  return false;
3346
3452
  },
3347
- onCellClicked: params.enableSelectionWithoutKeys || params.enableClickSelection
3348
- ? undefined
3349
- : clickInputWhenContainingCellClicked,
3453
+ onCellClicked: clickInputWhenContainingCellClicked,
3350
3454
  };
3351
- }, [
3352
- params.enableClickSelection,
3353
- params.enableSelectionWithoutKeys,
3354
- params.hideSelectColumn,
3355
- params.onRowDragEnd,
3356
- rowSelection,
3357
- selectColumnPinned,
3358
- selectable,
3359
- ]);
3455
+ }, [params.hideSelectColumn, params.onRowDragEnd, rowSelection, selectColumnPinned, selectable]);
3360
3456
  const onGridSizeChanged = useCallback((event) => {
3361
3457
  if (sizeColumns === 'fit' || (['auto', 'auto-skip-headers'].includes(sizeColumns) && hasSetContentSize.current)) {
3362
3458
  event.api.sizeColumnsToFit();
@@ -3378,6 +3474,15 @@ const quickFilterParser = (filterStr) => {
3378
3474
  // filter is exact matches exactly groups separated by commas
3379
3475
  return filterStr.split(',').map((str) => str.trim());
3380
3476
  };
3477
+ /**
3478
+ * Columns to indicate to user when they debug why things are broken in the default comparator if their valueFormatter
3479
+ * is too complicated.
3480
+ */
3481
+ const NotAGridValueFormatterCall = {
3482
+ column: 'Default comparator has no access to column, write your own comparator',
3483
+ api: 'Default comparator has no access to api, write your own comparator',
3484
+ context: 'Default comparator has no access to context, write your own comparator',
3485
+ };
3381
3486
 
3382
3487
  const GridPopoverContext = createContext({
3383
3488
  anchorRef: { current: null },
@@ -5640,47 +5745,53 @@ const GridContextProvider = (props) => {
5640
5745
  if (!gridApi || !gridApi.getColumnState()) {
5641
5746
  return null;
5642
5747
  }
5643
- const colIdsSet = colIds instanceof Set ? colIds : new Set(colIds);
5644
- const getVisibleColStates = () => {
5645
- const colStates = gridApi.getColumnState();
5646
- return colStates.filter((colState) => {
5647
- const colId = colState.colId;
5648
- return (isEmpty(colIdsSet) || colIdsSet.has(colId)) && !userSizedColIds?.has(colId);
5748
+ try {
5749
+ const colIdsSet = colIds instanceof Set ? colIds : new Set(colIds);
5750
+ const getVisibleColStates = () => {
5751
+ const colStates = gridApi.getColumnState();
5752
+ return colStates.filter((colState) => {
5753
+ const colId = colState.colId;
5754
+ return (isEmpty(colIdsSet) || colIdsSet.has(colId)) && !userSizedColIds?.has(colId);
5755
+ });
5756
+ };
5757
+ const getFlexColStates = () => getVisibleColStates().filter(colStateFlexed);
5758
+ const getNonFlexColStates = () => getVisibleColStates().filter(colStateNotFlexed);
5759
+ // You cannot autosize flex columns it will break layout randomly
5760
+ // So, a flex column is assumed to be 150 wide, unless width is provided
5761
+ const flexColumns = getFlexColStates().map(colStateId);
5762
+ let width = 0;
5763
+ flexColumns.forEach((colId) => {
5764
+ const colDef = gridApi.getColumnDef(colId);
5765
+ width += colDef?.flexAutoSizeWidth ?? 200;
5649
5766
  });
5650
- };
5651
- const getFlexColStates = () => getVisibleColStates().filter(colStateFlexed);
5652
- const getNonFlexColStates = () => getVisibleColStates().filter(colStateNotFlexed);
5653
- // You cannot autosize flex columns it will break layout randomly
5654
- // So, a flex column is assumed to be 150 wide, unless width is provided
5655
- const flexColumns = getFlexColStates().map(colStateId);
5656
- let width = 0;
5657
- flexColumns.forEach((colId) => {
5658
- const colDef = gridApi.getColumnDef(colId);
5659
- width += colDef?.flexAutoSizeWidth ?? 200;
5660
- });
5661
- const nonFlexColumns = getNonFlexColStates();
5662
- const nonFlexColumnIds = nonFlexColumns.map(colStateId);
5663
- gridApi.autoSizeColumns({ colIds: nonFlexColumnIds, skipHeader });
5664
- const calcSubWidth = () => {
5665
- const updatedFlexColumns = getVisibleColStates().filter((colState) => nonFlexColumnIds.includes(colState.colId));
5666
- return sumBy(updatedFlexColumns.filter((col) => !col.hide), 'width');
5667
- };
5668
- // ag-grid updates widths asynchronously, so we wait here for the default calculated width to change
5669
- let lastSubWidth = calcSubWidth();
5670
- const endTime = Date.now() + 1000;
5671
- while (Date.now() < endTime) {
5672
- await wait(40);
5673
- const newSubWidth = calcSubWidth();
5674
- if (lastSubWidth !== newSubWidth) {
5675
- lastSubWidth = newSubWidth;
5676
- break;
5767
+ const nonFlexColumns = getNonFlexColStates();
5768
+ const nonFlexColumnIds = nonFlexColumns.map(colStateId);
5769
+ gridApi.autoSizeColumns({ colIds: nonFlexColumnIds, skipHeader });
5770
+ const calcSubWidth = () => {
5771
+ const updatedFlexColumns = getVisibleColStates().filter((colState) => nonFlexColumnIds.includes(colState.colId));
5772
+ return sumBy(updatedFlexColumns.filter((col) => !col.hide), 'width');
5773
+ };
5774
+ // ag-grid updates widths asynchronously, so we wait here for the default calculated width to change
5775
+ let lastSubWidth = calcSubWidth();
5776
+ const endTime = Date.now() + 1000;
5777
+ while (Date.now() < endTime) {
5778
+ await wait(40);
5779
+ const newSubWidth = calcSubWidth();
5780
+ if (lastSubWidth !== newSubWidth) {
5781
+ lastSubWidth = newSubWidth;
5782
+ break;
5783
+ }
5677
5784
  }
5785
+ width += lastSubWidth;
5786
+ gridApi.sizeColumnsToFit();
5787
+ return {
5788
+ width,
5789
+ };
5790
+ }
5791
+ catch (ex) {
5792
+ console.info('autosize failed', ex);
5793
+ return null;
5678
5794
  }
5679
- width += lastSubWidth;
5680
- gridApi.sizeColumnsToFit();
5681
- return {
5682
- width,
5683
- };
5684
5795
  }, [gridApi]);
5685
5796
  /**
5686
5797
  * Resize columns to fit container
@@ -6164,5 +6275,5 @@ const useDeferredPromise = () => {
6164
6275
  };
6165
6276
  };
6166
6277
 
6167
- export { ActionButton, CancelPromise, ComponentLoadingWrapper, ControlledMenu, Editor, FocusableItem, FormError, GenericCellEditorComponentWrapper, Grid, GridButton, GridCell, GridCellFiller, GridCellFillerColId, GridCellMultiEditor, GridCellMultiSelectClassRules, GridCellRenderer, GridContext, GridContextProvider, GridEditBoolean, GridFilterButtons, GridFilterColumnsMultiSelect, GridFilterColumnsToggle, GridFilterDownloadCsvButton, GridFilterHeaderIconButton, GridFilterQuick, GridFilters, GridFormDropDown, GridFormEditBearing, GridFormMessage, GridFormMultiSelect, GridFormMultiSelectGrid, GridFormPopoverMenu, GridFormSubComponentTextArea, GridFormSubComponentTextInput, GridFormTextArea, GridFormTextInput, GridIcon, GridLoadableCell, GridNoRowsOverlay, GridNoRowsOverlayFr, GridPopoutEditMultiSelect, GridPopoutEditMultiSelectGrid, GridPopoverContext, GridPopoverContextProvider, GridPopoverEditBearing, GridPopoverEditBearingCorrection, GridPopoverEditBearingCorrectionEditorParams, GridPopoverEditBearingEditorParams, GridPopoverEditDropDown, GridPopoverMenu, GridPopoverMessage, GridPopoverTextArea, GridPopoverTextInput, GridRenderPopoutMenuCell, GridSubComponentContext, GridUpdatingContext, GridUpdatingContextProvider, GridWrapper, Menu, MenuButton, MenuDivider, MenuGroup, MenuHeader, MenuHeaderItem, MenuHeaderString, MenuItem, MenuRadioGroup, MenuSeparator, MenuSeparatorString, PopoutMenuSeparator, SubMenu, TextAreaInput, TextInputFormatted, TextInputValidator, bearingCorrectionRangeValidator, bearingCorrectionValueFormatter, bearingNumberParser, bearingRangeValidator, bearingStringValidator, bearingValueFormatter, colStateFlexed, colStateId, colStateNotFlexed, convertDDToDMS, createCheckboxMultiFilterParams, defaultValueFormatter, downloadCsvUseValueFormattersProcessCellCallback, findParentWithClass, fnOrVar, generateFilterGetter, hasParentClass, isFloat, isGridCellFiller, isNotEmpty, primitiveToSelectOption, sanitiseFileName, stringByteLengthIsInvalid, suppressCellKeyboardEvents, textMatch, useDeferredPromise, useGridContext, useGridContextMenu, useGridFilter, useGridPopoverContext, useGridPopoverHook, useMenuState, usePostSortRowsHook, wait, waitForCondition };
6278
+ export { ActionButton, CancelPromise, ComponentLoadingWrapper, ControlledMenu, Editor, FocusableItem, FormError, GenericCellEditorComponentWrapper, Grid, GridButton, GridCell, GridCellFiller, GridCellFillerColId, GridCellMultiEditor, GridCellMultiSelectClassRules, GridCellRenderer, GridContext, GridContextProvider, GridEditBoolean, GridFilterButtons, GridFilterColumnsMultiSelect, GridFilterColumnsToggle, GridFilterDownloadCsvButton, GridFilterHeaderIconButton, GridFilterQuick, GridFilters, GridFormDropDown, GridFormEditBearing, GridFormMessage, GridFormMultiSelect, GridFormMultiSelectGrid, GridFormPopoverMenu, GridFormSubComponentTextArea, GridFormSubComponentTextInput, GridFormTextArea, GridFormTextInput, GridIcon, GridLoadableCell, GridNoRowsOverlay, GridNoRowsOverlayFr, GridPopoutEditMultiSelect, GridPopoutEditMultiSelectGrid, GridPopoverContext, GridPopoverContextProvider, GridPopoverEditBearing, GridPopoverEditBearingCorrection, GridPopoverEditBearingCorrectionEditorParams, GridPopoverEditBearingEditorParams, GridPopoverEditDropDown, GridPopoverMenu, GridPopoverMessage, GridPopoverTextArea, GridPopoverTextInput, GridRenderPopoutMenuCell, GridSubComponentContext, GridUpdatingContext, GridUpdatingContextProvider, GridWrapper, Menu, MenuButton, MenuDivider, MenuGroup, MenuHeader, MenuHeaderItem, MenuHeaderString, MenuItem, MenuRadioGroup, MenuSeparator, MenuSeparatorString, PopoutMenuSeparator, SubMenu, TextAreaInput, TextInputFormatted, TextInputValidator, bearingCorrectionRangeValidator, bearingCorrectionValueFormatter, bearingNumberParser, bearingRangeValidator, bearingStringValidator, bearingValueFormatter, colStateFlexed, colStateId, colStateNotFlexed, compareNaturalInsensitive, convertDDToDMS, createCheckboxMultiFilterParams, defaultValueFormatter, downloadCsvUseValueFormattersProcessCellCallback, findParentWithClass, fnOrVar, generateFilterGetter, hasParentClass, isFloat, isGridCellFiller, isNotEmpty, primitiveToSelectOption, sanitiseFileName, stringByteLengthIsInvalid, suppressCellKeyboardEvents, textMatch, useDeferredPromise, useGridContext, useGridContextMenu, useGridFilter, useGridPopoverContext, useGridPopoverHook, useMenuState, usePostSortRowsHook, wait, waitForCondition };
6168
6279
  //# sourceMappingURL=step-ag-grid.esm.js.map